tzh
2024-08-22 c7d0944258c7d0943aa7b2211498fd612971ce27
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
# RUN: llc -mtriple=x86_64-linux-gnu -start-before greedy -stop-after virtregrewriter -o - %s | FileCheck %s
 
--- |
  ; ModuleID = '<stdin>'
  source_filename = "test/DebugInfo/X86/dbg-value-inlined-parameter.ll"
  target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
  target triple = "x86_64-apple-darwin"
 
  %struct.S1 = type { float*, i32 }
 
  @p = common global %struct.S1 zeroinitializer, align 8, !dbg !0
 
  ; Function Attrs: nounwind optsize ssp
  define void @foobar() !dbg !15 {
  entry:
    tail call void @llvm.dbg.value(metadata %struct.S1* @p, metadata !18, metadata !DIExpression()) , !dbg !25
    ret void, !dbg !32
  }
 
  ; Function Attrs: nounwind readnone speculatable
  declare void @llvm.dbg.value(metadata, metadata, metadata) #2
 
  !llvm.dbg.cu = !{!2}
  !llvm.module.flags = !{!14}
 
  !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
  !1 = !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 14, type: !6, isLocal: false, isDefinition: true)
  !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 2.9 (trunk 125693)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !5, imports: !4)
  !3 = !DIFile(filename: "nm2.c", directory: "/private/tmp")
  !4 = !{}
  !5 = !{!0}
  !6 = !DIDerivedType(tag: DW_TAG_typedef, name: "S1", scope: !2, file: !3, line: 4, baseType: !7)
  !7 = !DICompositeType(tag: DW_TAG_structure_type, name: "S1", scope: !2, file: !3, line: 1, size: 128, align: 64, elements: !8)
  !8 = !{!9, !12}
  !9 = !DIDerivedType(tag: DW_TAG_member, name: "m", scope: !3, file: !3, line: 2, baseType: !10, size: 64, align: 64)
  !10 = !DIDerivedType(tag: DW_TAG_pointer_type, scope: !2, baseType: !11, size: 64, align: 64)
  !11 = !DIBasicType(name: "float", size: 32, align: 32, encoding: DW_ATE_float)
  !12 = !DIDerivedType(tag: DW_TAG_member, name: "nums", scope: !3, file: !3, line: 3, baseType: !13, size: 32, align: 32, offset: 64)
  !13 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
  !14 = !{i32 1, !"Debug Info Version", i32 3}
  !15 = distinct !DISubprogram(name: "foobar", scope: !3, file: !3, line: 15, type: !16, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: true, unit: !2)
  !16 = !DISubroutineType(types: !17)
  !17 = !{null}
  !18 = !DILocalVariable(name: "sp", arg: 1, scope: !19, file: !3, line: 7, type: !24)
  !19 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 8, type: !20, isLocal: false, isDefinition: true, scopeLine: 8, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !22)
  !20 = !DISubroutineType(types: !21)
  !21 = !{!13}
  !22 = !{!18, !23}
  !23 = !DILocalVariable(name: "nums", arg: 2, scope: !19, file: !3, line: 7, type: !13)
  !24 = !DIDerivedType(tag: DW_TAG_pointer_type, scope: !2, baseType: !6, size: 64, align: 64)
  !25 = !DILocation(line: 7, column: 13, scope: !19, inlinedAt: !26)
  !26 = !DILocation(line: 16, column: 3, scope: !27)
  !27 = distinct !DILexicalBlock(scope: !15, file: !3, line: 15, column: 15)
  !32 = !DILocation(line: 17, column: 1, scope: !27)
 
...
---
name:            foobar
tracksRegLiveness: true
body:             |
  bb.0:
    %1:gr64 = IMPLICIT_DEF
    %2:gr64 = IMPLICIT_DEF
 
  bb.1:
    ; This DBG_VALUE will be discarded (use before def of %0).
    DBG_VALUE debug-use %0, debug-use $noreg, !18, !DIExpression(), debug-location !25
    %0:gr64 = IMPLICIT_DEF
    %0:gr64 = IMPLICIT_DEF
    %0:gr64 = IMPLICIT_DEF
    %0:gr64 = IMPLICIT_DEF
 
  bb.2:
    ; This DBG_VALUE will be discarded (%1 is defined earlier, but it is not live in, so we do not know where %1 is stored).
    DBG_VALUE debug-use %1, debug-use $noreg, !18, !DIExpression(), debug-location !25
    %1:gr64 = IMPLICIT_DEF
    %1:gr64 = IMPLICIT_DEF
    %1:gr64 = IMPLICIT_DEF
    %1:gr64 = IMPLICIT_DEF
    ; This DBG_VALUE is kept, even if %1 is dead, it was defined in the prev instruction,
    ; so the value should be available for as long as the register allocated to %1 is live.
    DBG_VALUE debug-use %1, debug-use $noreg, !18, !DIExpression(), debug-location !25
 
  bb.3:
    %1:gr64 = IMPLICIT_DEF
    DBG_VALUE 0, debug-use $noreg, !23, !DIExpression(), debug-location !25
    ; This DBG_VALUE is kept, even if %1 is dead, it was defined in the prev non-dbg instruction,
    ; so the value should be available for as long as the register allocated to %1 is live.
    DBG_VALUE debug-use %1, debug-use $noreg, !18, !DIExpression(), debug-location !25
 
  bb.4:
    ; All DBG_VALUEs here should survive. %2 is livein as it was defined in bb.0, and it has use/def in the BTS64rr instruction.
    DBG_VALUE debug-use %2, debug-use $noreg, !18, !DIExpression(), debug-location !25
    %2:gr64 = BTS64rr %2, 0, implicit-def $eflags
    DBG_VALUE 0, debug-use $noreg, !23, !DIExpression(), debug-location !25
    DBG_VALUE debug-use %2, debug-use $noreg, !18, !DIExpression(), debug-location !25
    %2:gr64 = BTS64rr %2, 0, implicit-def $eflags
    DBG_VALUE debug-use %2, debug-use $noreg, !18, !DIExpression(), debug-location !25
    %2:gr64 = BTS64rr %2, 0, implicit-def $eflags
    DBG_VALUE debug-use %2, debug-use $noreg, !18, !DIExpression(), debug-location !25
 
  bb.5:
    RET 0, debug-location !32
...
 
# CHECK-LABEL: name: foobar
 
# CHECK-LABEL: bb.1:
# CHECK:        DBG_VALUE debug-use $noreg
 
# CHECK-LABEL: bb.2:
# CHECK:        DBG_VALUE debug-use $noreg
# CHECK-NEXT:   dead renamable $rcx = IMPLICIT_DEF
# CHECK-NEXT:   dead renamable $rcx = IMPLICIT_DEF
# CHECK-NEXT:   dead renamable $rcx = IMPLICIT_DEF
# CHECK-NEXT:   dead renamable $rcx = IMPLICIT_DEF
# CHECK-NEXT:   DBG_VALUE debug-use $rcx, debug-use $noreg, !18, !DIExpression()
 
# CHECK-LABEL: bb.3:
# CHECK:        dead renamable $rcx = IMPLICIT_DEF
# CHECK-NEXT:   DBG_VALUE 0, debug-use $noreg, !23, !DIExpression()
# CHECK-NEXT:   DBG_VALUE debug-use $rcx, debug-use $noreg, !18, !DIExpression()
 
# CHECK-LABEL: bb.4:
# CHECK:        liveins: $rax
# CHECK:        DBG_VALUE debug-use $rax, debug-use $noreg, !18, !DIExpression()
# CHECK-NEXT:   renamable $rax = BTS64rr killed renamable $rax, 0, implicit-def $eflags
# CHECK-NEXT:   DBG_VALUE 0, debug-use $noreg, !23, !DIExpression()
# CHECK-NEXT:   DBG_VALUE debug-use $rax, debug-use $noreg, !18, !DIExpression()
# CHECK-NEXT:   renamable $rax = BTS64rr killed renamable $rax, 0, implicit-def $eflags
# CHECK-NEXT:   DBG_VALUE debug-use $rax, debug-use $noreg, !18, !DIExpression()
# CHECK-NEXT:   dead renamable $rax = BTS64rr killed renamable $rax, 0, implicit-def $eflags
 
# CHECK-LABEL: bb.5:
# CHECK-NEXT:   RET 0