[llvm] [DebugInfo] Implement TAG_label entries for debug_names (PR #71724)

Felipe de Azevedo Piovezan via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 8 10:58:18 PST 2023


https://github.com/felipepiovezan created https://github.com/llvm/llvm-project/pull/71724

The DWARF 5 specification says that:

> The name index must contain an entry for each debugging information entry that
> defines a named [...] label [...].

The verifier currently verifies this, but the AsmPrinter does not add entries for TAG_labels in debug_names. This patch addresses the issue by ensuring we add labels in the accelerator tables once we have a fully completed DIE for the TAG_label entry.

We also respect the spec as follows:
> DW_TAG_label debugging information entries without an address attribute
> (DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, or DW_AT_entry_pc) are excluded.

The effect of this on the size of accelerator tables is minimal, as TAG_labels are usually created by C/C++ labels (see example in test), which are typically paired with "goto" statements.

>From a2f6fc5d44b791a2c7842a570620fa429d52ce5e Mon Sep 17 00:00:00 2001
From: Felipe de Azevedo Piovezan <fpiovezan at apple.com>
Date: Tue, 7 Nov 2023 17:10:25 -0800
Subject: [PATCH] [DebugInfo] Implement TAG_label entries for debug_names

The DWARF 5 specification says that:

> The name index must contain an entry for each debugging information entry that
> defines a named [...] label [...].

The verifier currently verifies this, but the AsmPrinter does not add entries
for TAG_labels in debug_names. This patch addresses the issue by ensuring we add
labels in the accelerator tables once we have a fully completed DIE for the
TAG_label entry.

We also respect the spec as follows:
> DW_TAG_label debugging information entries without an address attribute
> (DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, or DW_AT_entry_pc) are excluded.

The effect of this on the size of accelerator tables is minimal, as TAG_labels
are usually created by C/C++ labels (see example in test), which are typically
paired with "goto" statements.
---
 .../CodeGen/AsmPrinter/DwarfCompileUnit.cpp   | 15 ++++-
 .../test/DebugInfo/X86/debug-names-dwarf64.ll | 57 ++++++++++++++++++-
 2 files changed, 67 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 42bf755737506b4..feb5ab665a17d8c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -1422,9 +1422,18 @@ void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {
       llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel.");
   }
 
-  if (Label)
-    if (const auto *Sym = Label->getSymbol())
-      addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym);
+  if (!Label)
+    return;
+
+  const auto *Sym = Label->getSymbol();
+  if (!Sym)
+    return;
+
+  addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym);
+
+  // A TAG_label with a name and an AT_low_pc must be placed in debug_names.
+  if (StringRef Name = Label->getName(); !Name.empty())
+    getDwarfDebug().addAccelName(*CUNode, Name, *Die);
 }
 
 DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) {
diff --git a/llvm/test/DebugInfo/X86/debug-names-dwarf64.ll b/llvm/test/DebugInfo/X86/debug-names-dwarf64.ll
index 8cd1f0c18292093..e5fd6be033ca767 100644
--- a/llvm/test/DebugInfo/X86/debug-names-dwarf64.ll
+++ b/llvm/test/DebugInfo/X86/debug-names-dwarf64.ll
@@ -10,6 +10,10 @@
 ; CHECK-NEXT:                   DW_AT_name ("foo")
 ; CHECK:      [[TYPEDIE:.+]]: DW_TAG_base_type
 ; CHECK-NEXT:                   DW_AT_name ("int")
+; CHECK:      [[SPDIE:.+]]:   DW_TAG_subprogram
+; CHECK:                        DW_AT_name ("func")
+; CHECK:      [[LABELDIE:.+]]: DW_TAG_label
+; CHECK-NEXT:                   DW_AT_name ("MyLabel")
 
 ; CHECK:      .debug_names contents:
 ; CHECK-NEXT: Name Index @ 0x0 {
@@ -19,8 +23,8 @@
 ; CHECK-NEXT:     CU count: 1
 ; CHECK-NEXT:     Local TU count: 0
 ; CHECK-NEXT:     Foreign TU count: 0
-; CHECK-NEXT:     Bucket count: 2
-; CHECK-NEXT:     Name count: 2
+; CHECK-NEXT:     Bucket count: 4
+; CHECK-NEXT:     Name count: 4
 ; CHECK:        }
 ; CHECK-NEXT:   Compilation Unit offsets [
 ; CHECK-NEXT:     CU[0]: 0x00000000
@@ -30,6 +34,14 @@
 ; CHECK-NEXT:       Tag: DW_TAG_variable
 ; CHECK-NEXT:       DW_IDX_die_offset: DW_FORM_ref4
 ; CHECK-NEXT:     }
+; CHECK-NEXT:     Abbreviation [[ABBREV_SP:0x[0-9a-f]*]] {
+; CHECK-NEXT:       Tag: DW_TAG_subprogram
+; CHECK-NEXT:       DW_IDX_die_offset: DW_FORM_ref4
+; CHECK-NEXT:     }
+; CHECK-NEXT:     Abbreviation [[ABBREV_LABEL:0x[0-9a-f]*]] {
+; CHECK-NEXT:       Tag: DW_TAG_label
+; CHECK-NEXT:       DW_IDX_die_offset: DW_FORM_ref4
+; CHECK-NEXT:     }
 ; CHECK-NEXT:     Abbreviation [[ABBREV:0x[0-9a-f]*]] {
 ; CHECK-NEXT:       Tag: DW_TAG_base_type
 ; CHECK-NEXT:       DW_IDX_die_offset: DW_FORM_ref4
@@ -56,6 +68,29 @@
 ; CHECK-NEXT:         DW_IDX_die_offset: [[VARDIE]]
 ; CHECK-NEXT:       }
 ; CHECK-NEXT:     }
+; CHECK-NEXT:     Name 3 {
+; CHECK-NEXT:       Hash: 0x7C96FE71
+; CHECK-NEXT:       String: {{.+}} "func"
+; CHECK-NEXT:       Entry @ {{.+}} {
+; CHECK-NEXT:         Abbrev: [[ABBREV_SP]]
+; CHECK-NEXT:         Tag: DW_TAG_subprogram
+; CHECK-NEXT:         DW_IDX_die_offset: [[SPDIE]]
+; CHECK-NEXT:       }
+; CHECK-NEXT:     }
+; CHECK-NEXT:   ]
+; CHECK-NEXT:   Bucket 2 [
+; CHECK-NEXT:     EMPTY
+; CHECK-NEXT:   ]
+; CHECK-NEXT:   Bucket 3 [
+; CHECK-NEXT:     Name 4 {
+; CHECK-NEXT:       Hash: 0xEC64E52B
+; CHECK-NEXT:       String: {{.+}} "MyLabel"
+; CHECK-NEXT:       Entry @ {{.+}} {
+; CHECK-NEXT:         Abbrev: [[ABBREV_LABEL]]
+; CHECK-NEXT:         Tag: DW_TAG_label
+; CHECK-NEXT:         DW_IDX_die_offset: [[LABELDIE]]
+; CHECK-NEXT:       }
+; CHECK-NEXT:     }
 ; CHECK-NEXT:   ]
 ; CHECK-NEXT: }
 
@@ -64,12 +99,25 @@
 ; IR generated and reduced from:
 ; $ cat foo.c
 ; int foo;
+; void func() {
+;   goto MyLabel;
+;
+; MyLabel:
+;   return 1;
+; }
 ; $ clang -g -gpubnames -S -emit-llvm foo.c -o foo.ll
 
 target triple = "x86_64-unknown-linux-gnu"
 
 @foo = dso_local global i32 0, align 4, !dbg !0
 
+define void @func() !dbg !11 {
+  call void @llvm.dbg.label(metadata !15), !dbg !14
+  ret void, !dbg !14
+}
+
+declare void @llvm.dbg.label(metadata)
+
 !llvm.dbg.cu = !{!2}
 !llvm.module.flags = !{!7, !8, !9}
 !llvm.ident = !{!10}
@@ -85,3 +133,8 @@ target triple = "x86_64-unknown-linux-gnu"
 !8 = !{i32 2, !"Debug Info Version", i32 3}
 !9 = !{i32 1, !"wchar_size", i32 4}
 !10 = !{!"clang version 12.0.0"}
+!11 = distinct !DISubprogram(name: "func", linkageName: "func", scope: !3, file: !3, line: 2, type: !12,  unit: !2)
+!12 = !DISubroutineType(types: !13)
+!13 = !{null}
+!14 = !DILocation(line: 2, column: 13, scope: !11)
+!15 = !DILabel(scope: !11, name: "MyLabel", file: !3, line: 5)



More information about the llvm-commits mailing list