Skip to content

Commit a195d1f

Browse files
[DebugInfo] Implement TAG_label entries for debug_names (#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.
1 parent 4488f49 commit a195d1f

File tree

2 files changed

+67
-5
lines changed

2 files changed

+67
-5
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,9 +1422,18 @@ void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {
14221422
llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel.");
14231423
}
14241424

1425-
if (Label)
1426-
if (const auto *Sym = Label->getSymbol())
1427-
addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym);
1425+
if (!Label)
1426+
return;
1427+
1428+
const auto *Sym = Label->getSymbol();
1429+
if (!Sym)
1430+
return;
1431+
1432+
addLabelAddress(*Die, dwarf::DW_AT_low_pc, Sym);
1433+
1434+
// A TAG_label with a name and an AT_low_pc must be placed in debug_names.
1435+
if (StringRef Name = Label->getName(); !Name.empty())
1436+
getDwarfDebug().addAccelName(*CUNode, Name, *Die);
14281437
}
14291438

14301439
DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) {

llvm/test/DebugInfo/X86/debug-names-dwarf64.ll

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
; CHECK-NEXT: DW_AT_name ("foo")
1111
; CHECK: [[TYPEDIE:.+]]: DW_TAG_base_type
1212
; CHECK-NEXT: DW_AT_name ("int")
13+
; CHECK: [[SPDIE:.+]]: DW_TAG_subprogram
14+
; CHECK: DW_AT_name ("func")
15+
; CHECK: [[LABELDIE:.+]]: DW_TAG_label
16+
; CHECK-NEXT: DW_AT_name ("MyLabel")
1317

1418
; CHECK: .debug_names contents:
1519
; CHECK-NEXT: Name Index @ 0x0 {
@@ -19,8 +23,8 @@
1923
; CHECK-NEXT: CU count: 1
2024
; CHECK-NEXT: Local TU count: 0
2125
; CHECK-NEXT: Foreign TU count: 0
22-
; CHECK-NEXT: Bucket count: 2
23-
; CHECK-NEXT: Name count: 2
26+
; CHECK-NEXT: Bucket count: 4
27+
; CHECK-NEXT: Name count: 4
2428
; CHECK: }
2529
; CHECK-NEXT: Compilation Unit offsets [
2630
; CHECK-NEXT: CU[0]: 0x00000000
@@ -30,6 +34,14 @@
3034
; CHECK-NEXT: Tag: DW_TAG_variable
3135
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
3236
; CHECK-NEXT: }
37+
; CHECK-NEXT: Abbreviation [[ABBREV_SP:0x[0-9a-f]*]] {
38+
; CHECK-NEXT: Tag: DW_TAG_subprogram
39+
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
40+
; CHECK-NEXT: }
41+
; CHECK-NEXT: Abbreviation [[ABBREV_LABEL:0x[0-9a-f]*]] {
42+
; CHECK-NEXT: Tag: DW_TAG_label
43+
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
44+
; CHECK-NEXT: }
3345
; CHECK-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] {
3446
; CHECK-NEXT: Tag: DW_TAG_base_type
3547
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
@@ -56,6 +68,29 @@
5668
; CHECK-NEXT: DW_IDX_die_offset: [[VARDIE]]
5769
; CHECK-NEXT: }
5870
; CHECK-NEXT: }
71+
; CHECK-NEXT: Name 3 {
72+
; CHECK-NEXT: Hash: 0x7C96FE71
73+
; CHECK-NEXT: String: {{.+}} "func"
74+
; CHECK-NEXT: Entry @ {{.+}} {
75+
; CHECK-NEXT: Abbrev: [[ABBREV_SP]]
76+
; CHECK-NEXT: Tag: DW_TAG_subprogram
77+
; CHECK-NEXT: DW_IDX_die_offset: [[SPDIE]]
78+
; CHECK-NEXT: }
79+
; CHECK-NEXT: }
80+
; CHECK-NEXT: ]
81+
; CHECK-NEXT: Bucket 2 [
82+
; CHECK-NEXT: EMPTY
83+
; CHECK-NEXT: ]
84+
; CHECK-NEXT: Bucket 3 [
85+
; CHECK-NEXT: Name 4 {
86+
; CHECK-NEXT: Hash: 0xEC64E52B
87+
; CHECK-NEXT: String: {{.+}} "MyLabel"
88+
; CHECK-NEXT: Entry @ {{.+}} {
89+
; CHECK-NEXT: Abbrev: [[ABBREV_LABEL]]
90+
; CHECK-NEXT: Tag: DW_TAG_label
91+
; CHECK-NEXT: DW_IDX_die_offset: [[LABELDIE]]
92+
; CHECK-NEXT: }
93+
; CHECK-NEXT: }
5994
; CHECK-NEXT: ]
6095
; CHECK-NEXT: }
6196

@@ -64,12 +99,25 @@
6499
; IR generated and reduced from:
65100
; $ cat foo.c
66101
; int foo;
102+
; void func() {
103+
; goto MyLabel;
104+
;
105+
; MyLabel:
106+
; return 1;
107+
; }
67108
; $ clang -g -gpubnames -S -emit-llvm foo.c -o foo.ll
68109

69110
target triple = "x86_64-unknown-linux-gnu"
70111

71112
@foo = dso_local global i32 0, align 4, !dbg !0
72113

114+
define void @func() !dbg !11 {
115+
call void @llvm.dbg.label(metadata !15), !dbg !14
116+
ret void, !dbg !14
117+
}
118+
119+
declare void @llvm.dbg.label(metadata)
120+
73121
!llvm.dbg.cu = !{!2}
74122
!llvm.module.flags = !{!7, !8, !9}
75123
!llvm.ident = !{!10}
@@ -85,3 +133,8 @@ target triple = "x86_64-unknown-linux-gnu"
85133
!8 = !{i32 2, !"Debug Info Version", i32 3}
86134
!9 = !{i32 1, !"wchar_size", i32 4}
87135
!10 = !{!"clang version 12.0.0"}
136+
!11 = distinct !DISubprogram(name: "func", linkageName: "func", scope: !3, file: !3, line: 2, type: !12, unit: !2)
137+
!12 = !DISubroutineType(types: !13)
138+
!13 = !{null}
139+
!14 = !DILocation(line: 2, column: 13, scope: !11)
140+
!15 = !DILabel(scope: !11, name: "MyLabel", file: !3, line: 5)

0 commit comments

Comments
 (0)