livedebugvalues_many_loop_heads.mir
6.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
--- |
; RUN: llc %s -march=x86-64 -run-pass=livedebugvalues -o - -experimental-debug-variable-locations | FileCheck %s -implicit-check-not=DBG_VALUE
; The MIR below represents a pathalogical case for value-tracking
; LiveDebugValues. The code structure is eight nested loops, with loop heads
; from bb.1 to bb.8, a central block bb.9 that does nothing, and loop ends
; from bb.10 to bb.17. The CMP's and jumps might be broken; the only
; important part is that it looks like nested loops to LiveDebugValues.
;
; The variable location is always $rsi, which enters the function live.
; There's also a def of $rsi in bb.14, in a loop tail, half way into the
; loop nest.s.
;
; This presents a serious problem: the outer four loops each implicitly have
; a PHI value for $rsi, because the block could be entered on a path straight
; from entry, or from bb.14 where $rsi is def'd. While the innermost four
; loops have a value of $rsi that is live-through each loop from bb.5
; onwards.
;
; Value-tracking LiveDebugValues _must_ correctly identify each PHI value.
; Observe the DBG_VALUE in bb.2: this variable location musn't be propagated
; any further, because there's a path to either successor that goes through
; bb.14 where the value is overwritten.Value tracking needs to identify the
; PHI value on entry to the block; and that each successor has a different
; PHI value in that register.
;
; Likewise, we mustn't identify values as PHIs which aren't. Entering bb.5
; has a PHI value (from bb.4) in $rsi. There are no paths to bb.5 that pass
; through the clobbering bb.14, which don't also pass through bb.4: thus
; that value is live-through the innermost four loops. If we
; over-approximated where PHIs happened, we would lose variable location
; coverage here, by not propagating the variable location through the inner
; loops.
;
; Getting this right requires the lattice descent (described in the
; implementation) to search loop head PHI values, until one is found that is
; live-through a loop.
; This location in bb.2 should not be propagated further,
; CHECK-LABEL: bb.2:
; CHECK: DBG_VALUE $rsi, $noreg
; This location should be live through the inner loops, til bb.14
; CHECK-LABEL: bb.5:
; CHECK: DBG_VALUE $rsi, $noreg
; CHECK-LABEL: bb.6:
; CHECK: DBG_VALUE $rsi, $noreg
; CHECK-LABEL: bb.7:
; CHECK: DBG_VALUE $rsi, $noreg
; CHECK-LABEL: bb.8:
; CHECK: DBG_VALUE $rsi, $noreg
; CHECK-LABEL: bb.9:
; CHECK: DBG_VALUE $rsi, $noreg
; CHECK-LABEL: bb.10:
; CHECK: DBG_VALUE $rsi, $noreg
; CHECK-LABEL: bb.11:
; CHECK: DBG_VALUE $rsi, $noreg
; CHECK-LABEL: bb.12:
; CHECK: DBG_VALUE $rsi, $noreg
; CHECK-LABEL: bb.13:
; CHECK: DBG_VALUE $rsi, $noreg
declare i64 @bees(i64 %arg);
define i32 @chiasm(i64 %arg) local_unnamed_addr !dbg !12 {
entry:
br label %bb1, !dbg !17
bb1:
br label %bb2, !dbg !17
bb2:
br label %bb3, !dbg !17
bb3:
ret i32 0, !dbg !17
}
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!7, !8, !9, !10}
!llvm.ident = !{!11}
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 10.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3, debugInfoForProfiling: true, nameTableKind: None)
!1 = !DIFile(filename: "main.cpp", directory: "F:\")
!2 = !{}
!3 = !{!4}
!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression())
!5 = distinct !DIGlobalVariable(name: "start", scope: !0, file: !1, line: 4, type: !6, isLocal: false, isDefinition: true)
!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!7 = !{i32 2, !"Dwarf Version", i32 4}
!8 = !{i32 2, !"Debug Info Version", i32 3}
!9 = !{i32 1, !"wchar_size", i32 2}
!10 = !{i32 7, !"PIC Level", i32 2}
!11 = !{!"clang version 10.0.0"}
!12 = distinct !DISubprogram(name: "bb_to_bb", linkageName: "bb_to_bb", scope: !1, file: !1, line: 6, type: !13, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !15)
!13 = !DISubroutineType(types: !14)
!14 = !{!6, !6}
!15 = !{!16}
!16 = !DILocalVariable(name: "myVar", scope: !12, file: !1, line: 7, type: !6)
!17 = !DILocation(line: 10, scope: !12)
...
---
name: chiasm
tracksRegLiveness: true
liveins:
- { reg: '$rdi', virtual-reg: '' }
stack:
- { id: 0, name: '', type: spill-slot, offset: -8, size: 8, alignment: 8,
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
body: |
bb.0.entry:
liveins: $rdi, $rsi
bb.1:
liveins: $rsi, $rdi
CMP64ri8 renamable $rdi, 1, implicit-def $eflags, debug-location !17
JCC_1 %bb.17, 4, implicit $eflags, debug-location !17
bb.2:
liveins: $rsi, $rdi
DBG_VALUE $rsi, $noreg, !16, !DIExpression(), debug-location !17
CMP64ri8 renamable $rdi, 2, implicit-def $eflags, debug-location !17
JCC_1 %bb.16, 4, implicit $eflags, debug-location !17
bb.3:
liveins: $rsi, $rdi
CMP64ri8 renamable $rdi, 3, implicit-def $eflags, debug-location !17
JCC_1 %bb.15, 4, implicit $eflags, debug-location !17
bb.4:
liveins: $rsi, $rdi
CMP64ri8 renamable $rdi, 4, implicit-def $eflags, debug-location !17
JCC_1 %bb.14, 4, implicit $eflags, debug-location !17
bb.5:
liveins: $rsi, $rdi
DBG_VALUE $rsi, $noreg, !16, !DIExpression(), debug-location !17
CMP64ri8 renamable $rdi, 4, implicit-def $eflags, debug-location !17
JCC_1 %bb.13, 4, implicit $eflags, debug-location !17
bb.6:
liveins: $rsi, $rdi
CMP64ri8 renamable $rdi, 4, implicit-def $eflags, debug-location !17
JCC_1 %bb.12, 4, implicit $eflags, debug-location !17
bb.7:
liveins: $rsi, $rdi
CMP64ri8 renamable $rdi, 4, implicit-def $eflags, debug-location !17
JCC_1 %bb.11, 4, implicit $eflags, debug-location !17
bb.8:
liveins: $rsi, $rdi
CMP64ri8 renamable $rdi, 4, implicit-def $eflags, debug-location !17
JCC_1 %bb.10, 4, implicit $eflags, debug-location !17
bb.9:
liveins: $rsi, $rdi, $eflags
;$rsi = MOV64ri 0, debug-location !17
;JMP_1 %bb.1, debug-location !17
bb.10:
liveins: $rsi, $rdi, $eflags
JCC_1 %bb.8, 4, implicit $eflags, debug-location !17
bb.11:
liveins: $rsi, $rdi, $eflags
JCC_1 %bb.7, 4, implicit $eflags, debug-location !17
bb.12:
liveins: $rsi, $rdi, $eflags
JCC_1 %bb.6, 4, implicit $eflags, debug-location !17
bb.13:
liveins: $rsi, $rdi, $eflags
JCC_1 %bb.5, 4, implicit $eflags, debug-location !17
bb.14:
liveins: $rsi, $rdi, $eflags
$rsi = MOV64ri 0, debug-location !17
JCC_1 %bb.4, 4, implicit $eflags, debug-location !17
bb.15:
liveins: $rsi, $rdi, $eflags
JCC_1 %bb.3, 4, implicit $eflags, debug-location !17
bb.16:
liveins: $rsi, $rdi, $eflags
JCC_1 %bb.2, 4, implicit $eflags, debug-location !17
bb.17:
liveins: $rsi, $rdi, $eflags
JCC_1 %bb.1, 4, implicit $eflags, debug-location !17
bb.18:
liveins: $rsi, $rdi, $eflags
RETQ
...