Skip to content

Commit d7d51dd

Browse files
committed
[MC] output inlined-at debug info
Currently MC print source location of instructions in comments in assembly when debug info is available, however, it does not include inlined-at locations when a function is inlined. For example, function foo is defined in header file a.h and is called multiple times in b.cpp. If foo is inlined, current assembly will only show its instructions with their line numbers in a.h. With inlined-at locations, the assembly will also show where foo is called in b.cpp. This patch adds inlined-at locations to the comments by using DebugLoc::print. It makes the printed source location info consistent with those printed by machine passes.
1 parent c2e9677 commit d7d51dd

File tree

10 files changed

+104
-25
lines changed

10 files changed

+104
-25
lines changed

llvm/include/llvm/MC/MCObjectStreamer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ class MCObjectStreamer : public MCStreamer {
141141
SMLoc Loc) override;
142142
void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
143143
unsigned Flags, unsigned Isa,
144-
unsigned Discriminator,
145-
StringRef FileName) override;
144+
unsigned Discriminator, StringRef FileName,
145+
StringRef Comment = {}) override;
146146
void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
147147
const MCSymbol *Label,
148148
unsigned PointerSize) override;

llvm/include/llvm/MC/MCStreamer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,8 @@ class MCStreamer {
928928
virtual void emitDwarfLocDirective(unsigned FileNo, unsigned Line,
929929
unsigned Column, unsigned Flags,
930930
unsigned Isa, unsigned Discriminator,
931-
StringRef FileName);
931+
StringRef FileName,
932+
StringRef Comment = {});
932933

933934
/// This implements the '.loc_label Name' directive.
934935
virtual void emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name);

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2057,6 +2057,14 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
20572057
}
20582058
}
20592059

2060+
auto RecordSourceLine = [&](auto &DL, auto Flags) {
2061+
SmallString<128> LocationString;
2062+
raw_svector_ostream OS(LocationString);
2063+
DL.print(OS);
2064+
2065+
const MDNode *Scope = DL.getScope();
2066+
recordSourceLine(DL.getLine(), DL.getCol(), Scope, Flags, LocationString);
2067+
};
20602068
// When we emit a line-0 record, we don't update PrevInstLoc; so look at
20612069
// the last line number actually emitted, to see if it was line 0.
20622070
unsigned LastAsmLine =
@@ -2084,8 +2092,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
20842092
// But we might be coming back to it after a line 0 record.
20852093
if ((LastAsmLine == 0 && DL.getLine() != 0) || Flags) {
20862094
// Reinstate the source location but not marked as a statement.
2087-
const MDNode *Scope = DL.getScope();
2088-
recordSourceLine(DL.getLine(), DL.getCol(), Scope, Flags);
2095+
RecordSourceLine(DL, Flags);
20892096
}
20902097
return;
20912098
}
@@ -2136,8 +2143,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
21362143
if (DL.getLine() && (DL.getLine() != OldLine || ForceIsStmt))
21372144
Flags |= DWARF2_FLAG_IS_STMT;
21382145

2139-
const MDNode *Scope = DL.getScope();
2140-
recordSourceLine(DL.getLine(), DL.getCol(), Scope, Flags);
2146+
RecordSourceLine(DL, Flags);
21412147

21422148
// If we're not at line 0, remember this location.
21432149
if (DL.getLine())
@@ -2272,7 +2278,8 @@ findPrologueEndLoc(const MachineFunction *MF) {
22722278
static void recordSourceLine(AsmPrinter &Asm, unsigned Line, unsigned Col,
22732279
const MDNode *S, unsigned Flags, unsigned CUID,
22742280
uint16_t DwarfVersion,
2275-
ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs) {
2281+
ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs,
2282+
StringRef Comment = {}) {
22762283
StringRef Fn;
22772284
unsigned FileNo = 1;
22782285
unsigned Discriminator = 0;
@@ -2286,7 +2293,7 @@ static void recordSourceLine(AsmPrinter &Asm, unsigned Line, unsigned Col,
22862293
.getOrCreateSourceID(Scope->getFile());
22872294
}
22882295
Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2289-
Discriminator, Fn);
2296+
Discriminator, Fn, Comment);
22902297
}
22912298

22922299
const MachineInstr *
@@ -2617,10 +2624,10 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
26172624
// Register a source line with debug info. Returns the unique label that was
26182625
// emitted and which provides correspondence to the source line list.
26192626
void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,
2620-
unsigned Flags) {
2627+
unsigned Flags, StringRef Location) {
26212628
::recordSourceLine(*Asm, Line, Col, S, Flags,
26222629
Asm->OutStreamer->getContext().getDwarfCompileUnitID(),
2623-
getDwarfVersion(), getUnits());
2630+
getDwarfVersion(), getUnits(), Location);
26242631
}
26252632

26262633
//===----------------------------------------------------------------------===//

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ class DwarfDebug : public DebugHandlerBase {
679679
/// label that was emitted and which provides correspondence to the
680680
/// source line list.
681681
void recordSourceLine(unsigned Line, unsigned Col, const MDNode *Scope,
682-
unsigned Flags);
682+
unsigned Flags, StringRef Location = {});
683683

684684
/// Populate LexicalScope entries with variables' info.
685685
void collectEntityInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP,

llvm/lib/MC/MCAsmStreamer.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,8 @@ class MCAsmStreamer final : public MCStreamer {
303303
unsigned CUID = 0) override;
304304
void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
305305
unsigned Flags, unsigned Isa,
306-
unsigned Discriminator,
307-
StringRef FileName) override;
306+
unsigned Discriminator, StringRef FileName,
307+
StringRef Location = {}) override;
308308
virtual void emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) override;
309309

310310
MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
@@ -1739,15 +1739,16 @@ void MCAsmStreamer::emitDwarfFile0Directive(
17391739
void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
17401740
unsigned Column, unsigned Flags,
17411741
unsigned Isa, unsigned Discriminator,
1742-
StringRef FileName) {
1742+
StringRef FileName,
1743+
StringRef Comment) {
17431744
// If target doesn't support .loc/.file directive, we need to record the lines
17441745
// same way like we do in object mode.
17451746
if (MAI->isAIX()) {
17461747
// In case we see two .loc directives in a row, make sure the
17471748
// first one gets a line entry.
17481749
MCDwarfLineEntry::make(this, getCurrentSectionOnly());
17491750
this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
1750-
Discriminator, FileName);
1751+
Discriminator, FileName, Comment);
17511752
return;
17521753
}
17531754

@@ -1778,12 +1779,15 @@ void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
17781779

17791780
if (IsVerboseAsm) {
17801781
OS.PadToColumn(MAI->getCommentColumn());
1781-
OS << MAI->getCommentString() << ' ' << FileName << ':'
1782-
<< Line << ':' << Column;
1782+
OS << MAI->getCommentString() << ' ';
1783+
if (Comment.empty())
1784+
OS << FileName << ':' << Line << ':' << Column;
1785+
else
1786+
OS << Comment;
17831787
}
17841788
EmitEOL();
17851789
this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
1786-
Discriminator, FileName);
1790+
Discriminator, FileName, Comment);
17871791
}
17881792

17891793
void MCAsmStreamer::emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) {

llvm/lib/MC/MCObjectStreamer.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,13 +418,14 @@ void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
418418
unsigned Column, unsigned Flags,
419419
unsigned Isa,
420420
unsigned Discriminator,
421-
StringRef FileName) {
421+
StringRef FileName,
422+
StringRef Comment) {
422423
// In case we see two .loc directives in a row, make sure the
423424
// first one gets a line entry.
424425
MCDwarfLineEntry::make(this, getCurrentSectionOnly());
425426

426427
this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
427-
Discriminator, FileName);
428+
Discriminator, FileName, Comment);
428429
}
429430

430431
static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,

llvm/lib/MC/MCStreamer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ void MCStreamer::emitCFIMTETaggedFrame() {
262262
void MCStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
263263
unsigned Column, unsigned Flags,
264264
unsigned Isa, unsigned Discriminator,
265-
StringRef FileName) {
265+
StringRef FileName, StringRef Comment) {
266266
getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
267267
Discriminator);
268268
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
2+
; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 < %s | FileCheck %s
3+
4+
define amdgpu_kernel void @_Z3fooPiiii(ptr addrspace(1) nocapture noundef writeonly %c.coerce, i32 noundef %a, i32 noundef %b, i32 noundef %d) !dbg !9 {
5+
; CHECK-LABEL: _Z3fooPiiii:
6+
; CHECK: .Lfunc_begin0:
7+
; CHECK-NEXT: .file 0 "test" "a.hip" md5 0x004a28df8cfd98cdd2c71d5d814d9c6b
8+
; CHECK-NEXT: .cfi_sections .debug_frame
9+
; CHECK-NEXT: .cfi_startproc
10+
; CHECK-NEXT: ; %bb.0: ; %entry
11+
; CHECK-NEXT: .file 1 "." "a.h"
12+
; CHECK-NEXT: .loc 1 5 12 prologue_end ; ./a.h:5:12 @[ a.hip:12:8 ]
13+
; CHECK-NEXT: s_load_dwordx4 s[0:3], s[8:9], 0x8
14+
; CHECK-NEXT: s_load_dwordx2 s[4:5], s[8:9], 0x0
15+
; CHECK-NEXT: v_mov_b32_e32 v0, 0
16+
; CHECK-NEXT: s_waitcnt lgkmcnt(0)
17+
; CHECK-NEXT: s_add_i32 s1, s1, s0
18+
; CHECK-NEXT: .Ltmp0:
19+
; CHECK-NEXT: .loc 1 5 12 is_stmt 0 ; ./a.h:5:12 @[ a.hip:13:9 ]
20+
; CHECK-NEXT: s_add_i32 s0, s2, s0
21+
; CHECK-NEXT: .Ltmp1:
22+
; CHECK-NEXT: .file 2 "a.hip"
23+
; CHECK-NEXT: .loc 2 13 6 is_stmt 1 ; a.hip:13:6
24+
; CHECK-NEXT: s_mul_i32 s0, s0, s1
25+
; CHECK-NEXT: v_mov_b32_e32 v1, s0
26+
; CHECK-NEXT: global_store_dword v0, v1, s[4:5]
27+
; CHECK-NEXT: .loc 2 14 1 ; a.hip:14:1
28+
; CHECK-NEXT: s_endpgm
29+
; CHECK-NEXT: .Ltmp2:
30+
entry:
31+
%add.i = add nsw i32 %b, %a, !dbg !13
32+
%add.i3 = add nsw i32 %d, %a, !dbg !17
33+
%mul = mul nsw i32 %add.i3, %add.i, !dbg !19
34+
store i32 %mul, ptr addrspace(1) %c.coerce, align 4, !dbg !19, !tbaa !20
35+
ret void, !dbg !24
36+
}
37+
38+
!llvm.dbg.cu = !{!0}
39+
!llvm.module.flags = !{!2, !3, !4, !5, !6, !7}
40+
!llvm.ident = !{!8}
41+
42+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 20.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, splitDebugInlining: false, nameTableKind: None)
43+
!1 = !DIFile(filename: "a.hip", directory: "test", checksumkind: CSK_MD5, checksum: "004a28df8cfd98cdd2c71d5d814d9c6b")
44+
!2 = !{i32 1, !"amdhsa_code_object_version", i32 500}
45+
!3 = !{i32 1, !"amdgpu_printf_kind", !"hostcall"}
46+
!4 = !{i32 7, !"Dwarf Version", i32 5}
47+
!5 = !{i32 2, !"Debug Info Version", i32 3}
48+
!6 = !{i32 1, !"wchar_size", i32 4}
49+
!7 = !{i32 8, !"PIC Level", i32 2}
50+
!8 = !{!"clang version 20.0.0"}
51+
!9 = distinct !DISubprogram(name: "foo", scope: !10, file: !10, line: 11, type: !11, scopeLine: 11, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
52+
!10 = !DIFile(filename: "a.hip", directory: "test")
53+
!11 = !DISubroutineType(types: !12)
54+
!12 = !{}
55+
!13 = !DILocation(line: 5, column: 12, scope: !14, inlinedAt: !16)
56+
!14 = distinct !DISubprogram(name: "bar", scope: !15, file: !15, line: 4, type: !11, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
57+
!15 = !DIFile(filename: "./a.h", directory: "test")
58+
!16 = distinct !DILocation(line: 12, column: 8, scope: !9)
59+
!17 = !DILocation(line: 5, column: 12, scope: !14, inlinedAt: !18)
60+
!18 = distinct !DILocation(line: 13, column: 9, scope: !9)
61+
!19 = !DILocation(line: 13, column: 6, scope: !9)
62+
!20 = !{!21, !21, i64 0}
63+
!21 = !{!"int", !22, i64 0}
64+
!22 = !{!"omnipotent char", !23, i64 0}
65+
!23 = !{!"Simple C++ TBAA"}
66+
!24 = !DILocation(line: 14, column: 1, scope: !9)

llvm/test/CodeGen/XCore/dwarf_debug.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
; CHECK-LABEL: f
77
; CHECK: entsp [[S:[0-9]+]]
88
; ...the prologue...
9-
; CHECK: .loc 1 2 0 prologue_end # test.c:2:0
9+
; CHECK: .loc 1 2 0 prologue_end # test.c:2
1010
; CHECK: add r0, r0, 1
1111
; CHECK: retsp [[S]]
1212
define i32 @f(i32 %a) !dbg !4 {

llvm/test/DebugInfo/X86/inline-seldag-test.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
; Make sure the condition test is attributed to the inline function, not the
1919
; location of the test's operands within the caller.
2020

21-
; ASM: # inline-seldag-test.c:2:0
22-
; ASM-NOT: .loc
21+
; ASM: # inline-seldag-test.c:4:0
22+
; ASM: .loc 1 2 0 # inline-seldag-test.c:2 @[ inline-seldag-test.c:6:7 ]
2323
; ASM: testl
2424

2525
; Function Attrs: nounwind uwtable

0 commit comments

Comments
 (0)