Skip to content

Commit 5ab3e9f

Browse files
committed
[KeyInstr] Use DISubprogram's is-key-instructions-on flag at DWARF emission
A non-key-instructions function inlined into a key-instructions function uses non-key-instructions is_stmt placement (without `findForceIsStmtInstrs`). A key-instructions function inlined into a non-key-instructions function currently results in falling back to non-key-instructions for the inlined scope too. Both of these consessions (not using `findForceIsStmtInstrs` in the 1st case, and not using Key Instructions for the inlined scope in the 2nd) are for performance reasons; to do the right thing we'd need to run both `findForceIsStmtInstrs` and `computeKeyInstructions` - in case that's controversial I've got a seperate PR for that. <link to PR>
1 parent ebd7f75 commit 5ab3e9f

File tree

2 files changed

+120
-5
lines changed

2 files changed

+120
-5
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,10 @@ static cl::opt<DwarfDebug::MinimizeAddrInV5> MinimizeAddrInV5Option(
169169
"Stuff")),
170170
cl::init(DwarfDebug::MinimizeAddrInV5::Default));
171171

172-
static cl::opt<bool> KeyInstructionsAreStmts("dwarf-use-key-instructions",
173-
cl::Hidden, cl::init(false));
172+
/// Set to false to ignore Key Instructions metadata.
173+
static cl::opt<bool> KeyInstructionsAreStmts(
174+
"dwarf-use-key-instructions", cl::Hidden, cl::init(true),
175+
cl::desc("Set to false to ignore Key Instructions metadata"));
174176

175177
static constexpr unsigned ULEB128PadSize = 4;
176178

@@ -2077,8 +2079,17 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
20772079
unsigned LastAsmLine =
20782080
Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
20792081

2082+
// Not-Key-Instructions functions inlined into Key Instructions functions
2083+
// should use default is_stmt handling. Key Instructions functions inlined
2084+
// into not-key-instructions functions currently fall back to not-key
2085+
// handling to avoid having to run computeKeyInstructions for all functions
2086+
// (which will impact non-key-instructions builds).
2087+
// TODO: Investigate the performance impact of doing that.
2088+
bool ScopeUsesKeyInstructions =
2089+
KeyInstructionsAreStmts && DL && SP->getKeyInstructionsEnabled();
2090+
20802091
bool IsKey = false;
2081-
if (KeyInstructionsAreStmts && DL && DL.getLine())
2092+
if (ScopeUsesKeyInstructions && DL && DL.getLine())
20822093
IsKey = KeyInstructions.contains(MI);
20832094

20842095
if (!DL && MI == PrologEndLoc) {
@@ -2158,7 +2169,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
21582169
PrologEndLoc = nullptr;
21592170
}
21602171

2161-
if (KeyInstructionsAreStmts) {
2172+
if (ScopeUsesKeyInstructions) {
21622173
if (IsKey)
21632174
Flags |= DWARF2_FLAG_IS_STMT;
21642175
} else {
@@ -2651,7 +2662,13 @@ void DwarfDebug::beginFunctionImpl(const MachineFunction *MF) {
26512662
PrologEndLoc = emitInitialLocDirective(
26522663
*MF, Asm->OutStreamer->getContext().getDwarfCompileUnitID());
26532664

2654-
if (KeyInstructionsAreStmts)
2665+
// If this function wasn't built with Key Instructions but has a function
2666+
// inlined into it that was, we treat the inlined instance as if it wasn't
2667+
// built with Key Instructions. If this function was built with Key
2668+
// Instructions but a function inlined into it wasn't then we continue to use
2669+
// Key Instructions for this function and fall back to non-key behaviour for
2670+
// the inlined function (except it doesn't beneit from findForceIsStmtInstrs).
2671+
if (KeyInstructionsAreStmts && SP->getKeyInstructionsEnabled())
26552672
computeKeyInstructions(MF);
26562673
else
26572674
findForceIsStmtInstrs(MF);
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# RUN: llc %s --start-after=livedebugvalues --dwarf-use-key-instructions --filetype=obj -o - \
2+
# RUN: | llvm-objdump -d - --no-show-raw-insn \
3+
# RUN: | FileCheck %s --check-prefix=OBJ
4+
5+
# RUN: llc %s --start-after=livedebugvalues --dwarf-use-key-instructions --filetype=obj -o - \
6+
# RUN: | llvm-dwarfdump - --debug-line \
7+
# RUN: | FileCheck %s --check-prefix=DBG
8+
9+
10+
11+
--- |
12+
target triple = "x86_64-unknown-linux-gnu"
13+
14+
define hidden noundef i32 @key() local_unnamed_addr !dbg !5 {
15+
entry:
16+
ret i32 0
17+
}
18+
19+
define hidden noundef i32 @not_key() local_unnamed_addr !dbg !9 {
20+
entry:
21+
ret i32 0
22+
}
23+
24+
!llvm.dbg.cu = !{!0}
25+
!llvm.module.flags = !{!2, !3}
26+
!llvm.ident = !{!4}
27+
28+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_17, file: !1, producer: "clang version 21.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, splitDebugInlining: false, nameTableKind: None)
29+
!1 = !DIFile(filename: "test.cpp", directory: "/")
30+
!2 = !{i32 7, !"Dwarf Version", i32 5}
31+
!3 = !{i32 2, !"Debug Info Version", i32 3}
32+
!4 = !{!"clang version 21.0.0"}
33+
!5 = distinct !DISubprogram(name: "key", scope: !1, file: !1, line: 1, type: !6, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: true)
34+
!6 = !DISubroutineType(types: !7)
35+
!7 = !{}
36+
!9 = distinct !DISubprogram(name: "not_key", scope: !1, file: !1, line: 1, type: !6, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, keyInstructions: false)
37+
!10 = distinct !DILocation(line: 5, scope: !5)
38+
!11 = distinct !DILocation(line: 9, scope: !9)
39+
...
40+
---
41+
name: key
42+
alignment: 16
43+
body: |
44+
bb.0.entry:
45+
46+
; OBJ: 0000000000000000 <key>:
47+
; OBJ-NEXT: 0: movl $0x1, %eax
48+
; OBJ-NEXT: 5: movl $0x2, %eax
49+
; OBJ-NEXT: a: movl $0x3, %eax
50+
; OBJ-NEXT: f: movl $0x4, %eax
51+
; OBJ-NEXT: 14: movl $0x5, %eax
52+
; OBJ-NEXT: 19: retq
53+
;
54+
; DBG: Address Line Column File ISA Discriminator OpIndex Flags
55+
; DBG-NEXT: ------------------ ------ ------ ------ --- ------------- ------- -------------
56+
; DBG-NEXT: 0x0000000000000000 1 0 0 0 0 0 is_stmt prologue_end
57+
; DBG-NEXT: 0x0000000000000005 2 0 0 0 0 0 is_stmt
58+
; DBG-NEXT: 0x000000000000000a 2 0 0 0 0 0
59+
; DBG-NEXT: 0x000000000000000f 3 0 0 0 0 0 is_stmt
60+
; DBG-NEXT: 0x0000000000000014 3 0 0 0 0 0
61+
;
62+
$eax = MOV32ri 1, debug-location !DILocation(line: 1, scope: !5) ; is_stmt (prologue_end)
63+
$eax = MOV32ri 2, debug-location !DILocation(line: 2, scope: !5, atomGroup: 1, atomRank: 1) ; is_stmt (key)
64+
$eax = MOV32ri 3, debug-location !DILocation(line: 2, scope: !9, inlinedAt: !10)
65+
$eax = MOV32ri 4, debug-location !DILocation(line: 3, scope: !9, inlinedAt: !10) ; is_stmt (not_key)
66+
$eax = MOV32ri 5, debug-location !DILocation(line: 3, scope: !5, atomGroup: 1, atomRank: 2) ; is_stmt (key)
67+
RET64 $eax, debug-location !DILocation(line: 3, scope: !5, atomGroup: 1, atomRank: 1)
68+
...
69+
---
70+
name: not_key
71+
alignment: 16
72+
body: |
73+
bb.0.entry:
74+
75+
; OBJ: 0000000000000020 <not_key>:
76+
; OBJ-NEXT: 20: movl $0x1, %eax
77+
; OBJ-NEXT: 25: movl $0x2, %eax
78+
; OBJ-NEXT: 2a: movl $0x3, %eax
79+
; OBJ-NEXT: 2f: retq
80+
;
81+
; TODO: Currently key inlined into not-key is treated as not-key. Investigate
82+
; performance implications of honouring the flag in this scenario.
83+
;
84+
; Address Line Column File ISA Discriminator OpIndex Flags
85+
; ------------------ ------ ------ ------ --- ------------- ------- -------------
86+
; DBG-NEXT: 0x0000000000000020 1 0 0 0 0 0 is_stmt prologue_end
87+
; DBG-NEXT: 0x0000000000000025 2 0 0 0 0 0 is_stmt
88+
; DBG-NEXT: 0x000000000000002a 3 0 0 0 0 0 is_stmt
89+
; DBG-NEXT: 0x000000000000002f 3 0 0 0 0 0
90+
;
91+
; NOTE: The `is_stmt` comments at the end of the lines reflects what we want
92+
; to see if the TODO above is resolved.
93+
;
94+
$eax = MOV32ri 1, debug-location !DILocation(line: 1, scope: !9) ; is_stmt (prologue_end)
95+
$eax = MOV32ri 2, debug-location !DILocation(line: 2, scope: !5, inlinedAt: !11, atomGroup: 1, atomRank: 2)
96+
$eax = MOV32ri 3, debug-location !DILocation(line: 3, scope: !5, inlinedAt: !11, atomGroup: 1, atomRank: 1) ; is_stmt (key)
97+
RET64 $eax, debug-location !DILocation(line: 3, scope: !9)
98+
...

0 commit comments

Comments
 (0)