[llvm] [MC] output inlined-at debug info (PR #106230)
Yaxun Liu via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 28 06:49:12 PDT 2024
https://github.com/yxsamliu updated https://github.com/llvm/llvm-project/pull/106230
>From 3a87fa7ebe2079f0abf4ad4a7bce6e3539ca4735 Mon Sep 17 00:00:00 2001
From: "Yaxun (Sam) Liu" <yaxun.liu at amd.com>
Date: Tue, 27 Aug 2024 09:39:47 -0400
Subject: [PATCH] [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.
---
llvm/include/llvm/MC/MCObjectStreamer.h | 4 +-
llvm/include/llvm/MC/MCStreamer.h | 3 +-
llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 23 ++++---
llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 2 +-
llvm/lib/MC/MCAsmStreamer.cpp | 18 +++--
llvm/lib/MC/MCObjectStreamer.cpp | 5 +-
llvm/lib/MC/MCStreamer.cpp | 2 +-
.../test/CodeGen/AMDGPU/dbg-info-inline-at.ll | 66 +++++++++++++++++++
llvm/test/CodeGen/XCore/dwarf_debug.ll | 2 +-
llvm/test/DebugInfo/X86/inline-seldag-test.ll | 4 +-
10 files changed, 104 insertions(+), 25 deletions(-)
create mode 100644 llvm/test/CodeGen/AMDGPU/dbg-info-inline-at.ll
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 bd6e8f03edf454..0347ce7cf9864d 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/CodeGen/XCore/dwarf_debug.ll b/llvm/test/CodeGen/XCore/dwarf_debug.ll
index 43851130c08f4e..084d0fca863205 100644
--- a/llvm/test/CodeGen/XCore/dwarf_debug.ll
+++ b/llvm/test/CodeGen/XCore/dwarf_debug.ll
@@ -6,7 +6,7 @@
; CHECK-LABEL: f
; CHECK: entsp [[S:[0-9]+]]
; ...the prologue...
-; CHECK: .loc 1 2 0 prologue_end # test.c:2:0
+; CHECK: .loc 1 2 0 prologue_end # test.c:2
; CHECK: add r0, r0, 1
; CHECK: retsp [[S]]
define i32 @f(i32 %a) !dbg !4 {
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
More information about the llvm-commits
mailing list