[llvm] [MC] output inlined-at debug info (PR #106230)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 27 07:25:10 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-debuginfo
@llvm/pr-subscribers-backend-amdgpu
Author: Yaxun (Sam) Liu (yxsamliu)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/106230.diff
9 Files Affected:
- (modified) llvm/include/llvm/MC/MCObjectStreamer.h (+2-2)
- (modified) llvm/include/llvm/MC/MCStreamer.h (+2-1)
- (modified) llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (+15-8)
- (modified) llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h (+1-1)
- (modified) llvm/lib/MC/MCAsmStreamer.cpp (+11-7)
- (modified) llvm/lib/MC/MCObjectStreamer.cpp (+3-2)
- (modified) llvm/lib/MC/MCStreamer.cpp (+1-1)
- (added) llvm/test/CodeGen/AMDGPU/dbg-info-inline-at.ll (+66)
- (modified) llvm/test/DebugInfo/X86/inline-seldag-test.ll (+2-2)
``````````diff
diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h
index 4241ec1e1881ba..b93eef5748553c 100644
--- a/llvm/include/llvm/MC/MCObjectStreamer.h
+++ b/llvm/include/llvm/MC/MCObjectStreamer.h
@@ -141,8 +141,8 @@ class MCObjectStreamer : public MCStreamer {
SMLoc Loc) override;
void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
unsigned Flags, unsigned Isa,
- unsigned Discriminator,
- StringRef FileName) override;
+ unsigned Discriminator, StringRef FileName,
+ StringRef Location = {}) override;
void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
const MCSymbol *Label,
unsigned PointerSize) override;
diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index 78aa12062102c2..9b4b5c8a33a285 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -910,7 +910,8 @@ class MCStreamer {
virtual void emitDwarfLocDirective(unsigned FileNo, unsigned Line,
unsigned Column, unsigned Flags,
unsigned Isa, unsigned Discriminator,
- StringRef FileName);
+ StringRef FileName,
+ StringRef Location = {});
/// Associate a filename with a specified logical file number, and also
/// specify that file's checksum information. This implements the '.cv_file 4
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index f111b4aea06f1b..9cc6d4b475ab55 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -2056,6 +2056,14 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
}
}
+ auto RecordSourceLine = [&](auto &DL, auto Flags) {
+ SmallString<128> LocationString;
+ raw_svector_ostream OS(LocationString);
+ DL.print(OS);
+
+ const MDNode *Scope = DL.getScope();
+ recordSourceLine(DL.getLine(), DL.getCol(), Scope, Flags, LocationString);
+ };
// When we emit a line-0 record, we don't update PrevInstLoc; so look at
// the last line number actually emitted, to see if it was line 0.
unsigned LastAsmLine =
@@ -2072,8 +2080,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
// But we might be coming back to it after a line 0 record.
if ((LastAsmLine == 0 && DL.getLine() != 0) || Flags) {
// Reinstate the source location but not marked as a statement.
- const MDNode *Scope = DL.getScope();
- recordSourceLine(DL.getLine(), DL.getCol(), Scope, Flags);
+ RecordSourceLine(DL, Flags);
}
return;
}
@@ -2124,8 +2131,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
if (DL.getLine() && DL.getLine() != OldLine)
Flags |= DWARF2_FLAG_IS_STMT;
- const MDNode *Scope = DL.getScope();
- recordSourceLine(DL.getLine(), DL.getCol(), Scope, Flags);
+ RecordSourceLine(DL, Flags);
// If we're not at line 0, remember this location.
if (DL.getLine())
@@ -2168,7 +2174,8 @@ static std::pair<DebugLoc, bool> findPrologueEndLoc(const MachineFunction *MF) {
static void recordSourceLine(AsmPrinter &Asm, unsigned Line, unsigned Col,
const MDNode *S, unsigned Flags, unsigned CUID,
uint16_t DwarfVersion,
- ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs) {
+ ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs,
+ StringRef Location = {}) {
StringRef Fn;
unsigned FileNo = 1;
unsigned Discriminator = 0;
@@ -2182,7 +2189,7 @@ static void recordSourceLine(AsmPrinter &Asm, unsigned Line, unsigned Col,
.getOrCreateSourceID(Scope->getFile());
}
Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
- Discriminator, Fn);
+ Discriminator, Fn, Location);
}
DebugLoc DwarfDebug::emitInitialLocDirective(const MachineFunction &MF,
@@ -2356,10 +2363,10 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
// Register a source line with debug info. Returns the unique label that was
// emitted and which provides correspondence to the source line list.
void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,
- unsigned Flags) {
+ unsigned Flags, StringRef Location) {
::recordSourceLine(*Asm, Line, Col, S, Flags,
Asm->OutStreamer->getContext().getDwarfCompileUnitID(),
- getDwarfVersion(), getUnits());
+ getDwarfVersion(), getUnits(), Location);
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 6e379396ea079e..ee85a7ccdd97bb 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -677,7 +677,7 @@ class DwarfDebug : public DebugHandlerBase {
/// label that was emitted and which provides correspondence to the
/// source line list.
void recordSourceLine(unsigned Line, unsigned Col, const MDNode *Scope,
- unsigned Flags);
+ unsigned Flags, StringRef Location = {});
/// Populate LexicalScope entries with variables' info.
void collectEntityInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP,
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 9309d5987dc949..c322e49803dce3 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -299,8 +299,8 @@ class MCAsmStreamer final : public MCStreamer {
unsigned CUID = 0) override;
void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
unsigned Flags, unsigned Isa,
- unsigned Discriminator,
- StringRef FileName) override;
+ unsigned Discriminator, StringRef FileName,
+ StringRef Location = {}) override;
MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
bool emitCVFileDirective(unsigned FileNo, StringRef Filename,
@@ -1720,7 +1720,8 @@ void MCAsmStreamer::emitDwarfFile0Directive(
void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
unsigned Column, unsigned Flags,
unsigned Isa, unsigned Discriminator,
- StringRef FileName) {
+ StringRef FileName,
+ StringRef Location) {
// If target doesn't support .loc/.file directive, we need to record the lines
// same way like we do in object mode.
if (!MAI->usesDwarfFileAndLocDirectives()) {
@@ -1728,7 +1729,7 @@ void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
// first one gets a line entry.
MCDwarfLineEntry::make(this, getCurrentSectionOnly());
this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
- Discriminator, FileName);
+ Discriminator, FileName, Location);
return;
}
@@ -1759,12 +1760,15 @@ void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
if (IsVerboseAsm) {
OS.PadToColumn(MAI->getCommentColumn());
- OS << MAI->getCommentString() << ' ' << FileName << ':'
- << Line << ':' << Column;
+ OS << MAI->getCommentString() << ' ';
+ if (Location.empty())
+ OS << FileName << ':' << Line << ':' << Column;
+ else
+ OS << Location;
}
EmitEOL();
this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
- Discriminator, FileName);
+ Discriminator, FileName, Location);
}
MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 9dc3974fd8f0d3..2ba086af549ffc 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -418,13 +418,14 @@ void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
unsigned Column, unsigned Flags,
unsigned Isa,
unsigned Discriminator,
- StringRef FileName) {
+ StringRef FileName,
+ StringRef Location) {
// In case we see two .loc directives in a row, make sure the
// first one gets a line entry.
MCDwarfLineEntry::make(this, getCurrentSectionOnly());
this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
- Discriminator, FileName);
+ Discriminator, FileName, Location);
}
static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 1594bd3231abe8..216c715c7a407a 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -262,7 +262,7 @@ void MCStreamer::emitCFIMTETaggedFrame() {
void MCStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
unsigned Column, unsigned Flags,
unsigned Isa, unsigned Discriminator,
- StringRef FileName) {
+ StringRef FileName, StringRef Location) {
getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
Discriminator);
}
diff --git a/llvm/test/CodeGen/AMDGPU/dbg-info-inline-at.ll b/llvm/test/CodeGen/AMDGPU/dbg-info-inline-at.ll
new file mode 100644
index 00000000000000..4148f8156d8846
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/dbg-info-inline-at.ll
@@ -0,0 +1,66 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 < %s | FileCheck %s
+
+define amdgpu_kernel void @_Z3fooPiiii(ptr addrspace(1) nocapture noundef writeonly %c.coerce, i32 noundef %a, i32 noundef %b, i32 noundef %d) !dbg !9 {
+; CHECK-LABEL: _Z3fooPiiii:
+; CHECK: .Lfunc_begin0:
+; CHECK-NEXT: .file 0 "test" "a.hip" md5 0x004a28df8cfd98cdd2c71d5d814d9c6b
+; CHECK-NEXT: .cfi_sections .debug_frame
+; CHECK-NEXT: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: .file 1 "." "a.h"
+; CHECK-NEXT: .loc 1 5 12 prologue_end ; ./a.h:5:12 @[ a.hip:12:8 ]
+; CHECK-NEXT: s_load_dwordx4 s[0:3], s[6:7], 0x8
+; CHECK-NEXT: s_load_dwordx2 s[4:5], s[6:7], 0x0
+; CHECK-NEXT: v_mov_b32_e32 v0, 0
+; CHECK-NEXT: s_waitcnt lgkmcnt(0)
+; CHECK-NEXT: s_add_i32 s1, s1, s0
+; CHECK-NEXT: .Ltmp0:
+; CHECK-NEXT: .loc 1 5 12 is_stmt 0 ; ./a.h:5:12 @[ a.hip:13:9 ]
+; CHECK-NEXT: s_add_i32 s0, s2, s0
+; CHECK-NEXT: .Ltmp1:
+; CHECK-NEXT: .file 2 "a.hip"
+; CHECK-NEXT: .loc 2 13 6 is_stmt 1 ; a.hip:13:6
+; CHECK-NEXT: s_mul_i32 s0, s0, s1
+; CHECK-NEXT: v_mov_b32_e32 v1, s0
+; CHECK-NEXT: global_store_dword v0, v1, s[4:5]
+; CHECK-NEXT: .loc 2 14 1 ; a.hip:14:1
+; CHECK-NEXT: s_endpgm
+; CHECK-NEXT: .Ltmp2:
+entry:
+ %add.i = add nsw i32 %b, %a, !dbg !13
+ %add.i3 = add nsw i32 %d, %a, !dbg !17
+ %mul = mul nsw i32 %add.i3, %add.i, !dbg !19
+ store i32 %mul, ptr addrspace(1) %c.coerce, align 4, !dbg !19, !tbaa !20
+ ret void, !dbg !24
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5, !6, !7}
+!llvm.ident = !{!8}
+
+!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)
+!1 = !DIFile(filename: "a.hip", directory: "test", checksumkind: CSK_MD5, checksum: "004a28df8cfd98cdd2c71d5d814d9c6b")
+!2 = !{i32 1, !"amdhsa_code_object_version", i32 500}
+!3 = !{i32 1, !"amdgpu_printf_kind", !"hostcall"}
+!4 = !{i32 7, !"Dwarf Version", i32 5}
+!5 = !{i32 2, !"Debug Info Version", i32 3}
+!6 = !{i32 1, !"wchar_size", i32 4}
+!7 = !{i32 8, !"PIC Level", i32 2}
+!8 = !{!"clang version 20.0.0"}
+!9 = distinct !DISubprogram(name: "foo", scope: !10, file: !10, line: 11, type: !11, scopeLine: 11, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
+!10 = !DIFile(filename: "a.hip", directory: "test")
+!11 = !DISubroutineType(types: !12)
+!12 = !{}
+!13 = !DILocation(line: 5, column: 12, scope: !14, inlinedAt: !16)
+!14 = distinct !DISubprogram(name: "bar", scope: !15, file: !15, line: 4, type: !11, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
+!15 = !DIFile(filename: "./a.h", directory: "test")
+!16 = distinct !DILocation(line: 12, column: 8, scope: !9)
+!17 = !DILocation(line: 5, column: 12, scope: !14, inlinedAt: !18)
+!18 = distinct !DILocation(line: 13, column: 9, scope: !9)
+!19 = !DILocation(line: 13, column: 6, scope: !9)
+!20 = !{!21, !21, i64 0}
+!21 = !{!"int", !22, i64 0}
+!22 = !{!"omnipotent char", !23, i64 0}
+!23 = !{!"Simple C++ TBAA"}
+!24 = !DILocation(line: 14, column: 1, scope: !9)
diff --git a/llvm/test/DebugInfo/X86/inline-seldag-test.ll b/llvm/test/DebugInfo/X86/inline-seldag-test.ll
index 6417612a545805..6a62d2bab884b1 100644
--- a/llvm/test/DebugInfo/X86/inline-seldag-test.ll
+++ b/llvm/test/DebugInfo/X86/inline-seldag-test.ll
@@ -18,8 +18,8 @@
; Make sure the condition test is attributed to the inline function, not the
; location of the test's operands within the caller.
-; ASM: # inline-seldag-test.c:2:0
-; ASM-NOT: .loc
+; ASM: # inline-seldag-test.c:4:0
+; ASM: .loc 1 2 0 # inline-seldag-test.c:2 @[ inline-seldag-test.c:6:7 ]
; ASM: testl
; Function Attrs: nounwind uwtable
``````````
</details>
https://github.com/llvm/llvm-project/pull/106230
More information about the llvm-commits
mailing list