llvm.org GIT mirror llvm / 27b6b31
Handle inlined variables in SelectionDAGBuilder::EmitFuncArgumentDbgValue(). In 2010 a commit with no testcase and no further explanation explicitly disabled the handling of inlined variables in EmitFuncArgumentDbgValue(). I don't think there is a good reason for this any more and re-enabling this adds debug locations for variables associated with an LLVM function argument in functions that are inlined into the first basic block. The only downside of doing this is that we may insert a DBG_VALUE before the inlined scope, but (1) this could be filtered out later, and (2) LiveDebugValues will not propagate it into subsequent basic blocks if they don't dominate the variable's lexical scope, so this seems like a small price to pay. rdar://problem/26228128 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317702 91177308-0d34-0410-b5e6-96231b3b80d8 Adrian Prantl 2 years ago
3 changed file(s) with 143 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
48264826
48274827 MachineFunction &MF = DAG.getMachineFunction();
48284828 const TargetInstrInfo *TII = DAG.getSubtarget().getInstrInfo();
4829
4830 // Ignore inlined function arguments here.
4831 //
4832 // FIXME: Should we be checking DL->inlinedAt() to determine this?
4833 if (!Variable->getScope()->getSubprogram()->describes(MF.getFunction()))
4834 return false;
48354829
48364830 bool IsIndirect = false;
48374831 Optional Op;
0 ; RUN: llc -filetype=obj -o - %s | llvm-dwarfdump --name resource - | FileCheck %s
1 ; CHECK: DW_TAG_formal_parameter
2 ; CHECK: DW_TAG_formal_parameter
3 ; CHECK-NEXT: DW_AT_location (DW_OP_reg1 W1)
4 ; CHECK-NEXT: DW_AT_abstract_origin {{.*}}"resource"
5 ;
6 ; Generated from:
7 ; typedef struct t *t_t;
8 ; extern unsigned int enable;
9 ; struct t {
10 ; struct q {
11 ; struct q *next;
12 ; unsigned long long resource;
13 ; } * s;
14 ; } * tt;
15 ; static unsigned long find(t_t t, unsigned long long resource) {
16 ; struct q *q;
17 ; q = t->s;
18 ; while (q) {
19 ; if (q->resource == resource)
20 ; return q;
21 ; q = q->next;
22 ; }
23 ; }
24 ; int g(t_t t, unsigned long long r) {
25 ; struct q *q;
26 ; q = find(t, r);
27 ; if (!q)
28 ; if (__builtin_expect(enable, 0)) { }
29 ; }
30
31
32 source_filename = "test.i"
33 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
34 target triple = "arm64-apple-ios5.0.0"
35
36 %struct.t = type { %struct.q* }
37 %struct.q = type { %struct.q*, i64 }
38
39 @tt = local_unnamed_addr global %struct.t* null, align 8, !dbg !0
40
41 ; Function Attrs: noredzone nounwind readonly ssp
42 define i32 @g(%struct.t* nocapture readonly %t, i64 %r) local_unnamed_addr #0 !dbg !20 {
43 entry:
44 tail call void @llvm.dbg.value(metadata %struct.t* %t, metadata !26, metadata !DIExpression()), !dbg !29
45 tail call void @llvm.dbg.value(metadata i64 %r, metadata !27, metadata !DIExpression()), !dbg !30
46 tail call void @llvm.dbg.value(metadata %struct.t* %t, metadata !31, metadata !DIExpression()), !dbg !39
47 tail call void @llvm.dbg.value(metadata i64 %r, metadata !37, metadata !DIExpression()), !dbg !41
48 %s.i5 = bitcast %struct.t* %t to %struct.q**
49 tail call void @llvm.dbg.value(metadata %struct.q** %s.i5, metadata !38, metadata !DIExpression(DW_OP_deref)), !dbg !42
50 %q.06.i = load %struct.q*, %struct.q** %s.i5, align 8
51 tail call void @llvm.dbg.value(metadata %struct.q* %q.06.i, metadata !38, metadata !DIExpression()), !dbg !42
52 %tobool7.i = icmp eq %struct.q* %q.06.i, null, !dbg !43
53 br i1 %tobool7.i, label %find.exit, label %while.body.i.preheader, !dbg !43
54
55 while.body.i.preheader: ; preds = %entry
56 br label %while.body.i, !dbg !44
57
58 while.body.i: ; preds = %while.body.i.preheader, %if.end.i
59 %q.08.i = phi %struct.q* [ %q.0.i, %if.end.i ], [ %q.06.i, %while.body.i.preheader ]
60 %resource1.i = getelementptr inbounds %struct.q, %struct.q* %q.08.i, i64 0, i32 1, !dbg !44
61 %0 = load i64, i64* %resource1.i, align 8, !dbg !44
62 %cmp.i = icmp eq i64 %0, %r, !dbg !47
63 br i1 %cmp.i, label %find.exit, label %if.end.i, !dbg !48
64
65 if.end.i: ; preds = %while.body.i
66 %next.i6 = bitcast %struct.q* %q.08.i to %struct.q**
67 tail call void @llvm.dbg.value(metadata %struct.q** %next.i6, metadata !38, metadata !DIExpression(DW_OP_deref)), !dbg !42
68 %q.0.i = load %struct.q*, %struct.q** %next.i6, align 8
69 tail call void @llvm.dbg.value(metadata %struct.q* %q.0.i, metadata !38, metadata !DIExpression()), !dbg !42
70 %tobool.i = icmp eq %struct.q* %q.0.i, null, !dbg !43
71 br i1 %tobool.i, label %find.exit, label %while.body.i, !dbg !43, !llvm.loop !49
72
73 find.exit: ; preds = %while.body.i, %if.end.i, %entry
74 ret i32 undef, !dbg !52
75 }
76
77 ; Function Attrs: nounwind readnone speculatable
78 declare void @llvm.dbg.value(metadata, metadata, metadata) #1
79
80 attributes #0 = { noredzone nounwind readonly ssp }
81 attributes #1 = { nounwind readnone speculatable }
82
83 !llvm.dbg.cu = !{!2}
84 !llvm.module.flags = !{!16, !17, !18}
85 !llvm.ident = !{!19}
86
87 !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
88 !1 = distinct !DIGlobalVariable(name: "tt", scope: !2, file: !3, line: 8, type: !6, isLocal: false, isDefinition: true)
89 !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 6.0.0 (trunk 317516) (llvm/trunk 317518)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
90 !3 = !DIFile(filename: "test.i", directory: "/")
91 !4 = !{}
92 !5 = !{!0}
93 !6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64)
94 !7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: !3, line: 3, size: 64, elements: !8)
95 !8 = !{!9}
96 !9 = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: !7, file: !3, line: 7, baseType: !10, size: 64)
97 !10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64)
98 !11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "q", file: !3, line: 4, size: 128, elements: !12)
99 !12 = !{!13, !14}
100 !13 = !DIDerivedType(tag: DW_TAG_member, name: "next", scope: !11, file: !3, line: 5, baseType: !10, size: 64)
101 !14 = !DIDerivedType(tag: DW_TAG_member, name: "resource", scope: !11, file: !3, line: 6, baseType: !15, size: 64, offset: 64)
102 !15 = !DIBasicType(name: "long long unsigned int", size: 64, encoding: DW_ATE_unsigned)
103 !16 = !{i32 2, !"Dwarf Version", i32 2}
104 !17 = !{i32 2, !"Debug Info Version", i32 3}
105 !18 = !{i32 1, !"wchar_size", i32 4}
106 !19 = !{!"clang version 6.0.0 (trunk 317516) (llvm/trunk 317518)"}
107 !20 = distinct !DISubprogram(name: "g", scope: !3, file: !3, line: 18, type: !21, isLocal: false, isDefinition: true, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: true, unit: !2, variables: !25)
108 !21 = !DISubroutineType(types: !22)
109 !22 = !{!23, !24, !15}
110 !23 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
111 !24 = !DIDerivedType(tag: DW_TAG_typedef, name: "t_t", file: !3, line: 1, baseType: !6)
112 !25 = !{!26, !27, !28}
113 !26 = !DILocalVariable(name: "t", arg: 1, scope: !20, file: !3, line: 18, type: !24)
114 !27 = !DILocalVariable(name: "r", arg: 2, scope: !20, file: !3, line: 18, type: !15)
115 !28 = !DILocalVariable(name: "q", scope: !20, file: !3, line: 19, type: !10)
116 !29 = !DILocation(line: 18, column: 11, scope: !20)
117 !30 = !DILocation(line: 18, column: 33, scope: !20)
118 !31 = !DILocalVariable(name: "t", arg: 1, scope: !32, file: !3, line: 9, type: !24)
119 !32 = distinct !DISubprogram(name: "find", scope: !3, file: !3, line: 9, type: !33, isLocal: true, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: true, unit: !2, variables: !36)
120 !33 = !DISubroutineType(types: !34)
121 !34 = !{!35, !24, !15}
122 !35 = !DIBasicType(name: "long unsigned int", size: 64, encoding: DW_ATE_unsigned)
123 !36 = !{!31, !37, !38}
124 !37 = !DILocalVariable(name: "resource", arg: 2, scope: !32, file: !3, line: 9, type: !15)
125 !38 = !DILocalVariable(name: "q", scope: !32, file: !3, line: 10, type: !10)
126 !39 = !DILocation(line: 9, column: 31, scope: !32, inlinedAt: !40)
127 !40 = distinct !DILocation(line: 20, column: 7, scope: !20)
128 !41 = !DILocation(line: 9, column: 53, scope: !32, inlinedAt: !40)
129 !42 = !DILocation(line: 10, column: 13, scope: !32, inlinedAt: !40)
130 !43 = !DILocation(line: 12, column: 3, scope: !32, inlinedAt: !40)
131 !44 = !DILocation(line: 13, column: 12, scope: !45, inlinedAt: !40)
132 !45 = distinct !DILexicalBlock(scope: !46, file: !3, line: 13, column: 9)
133 !46 = distinct !DILexicalBlock(scope: !32, file: !3, line: 12, column: 13)
134 !47 = !DILocation(line: 13, column: 21, scope: !45, inlinedAt: !40)
135 !48 = !DILocation(line: 13, column: 9, scope: !46, inlinedAt: !40)
136 !49 = distinct !{!49, !50, !51}
137 !50 = !DILocation(line: 12, column: 3, scope: !32)
138 !51 = !DILocation(line: 16, column: 3, scope: !32)
139 !52 = !DILocation(line: 24, column: 1, scope: !20)
2323
2424 ; CHECK: .debug_loc contents:
2525 ; CHECK-NEXT: 0x00000000:
26 ; CHECK-NEXT: 0x000000000000001f - 0x000000000000003c: DW_OP_reg3 RBX
27 ; We should only have one entry
26 ; We currently emit an entry for the function prologue, too, which could be optimized away.
27 ; CHECK: 0x000000000000001f - 0x000000000000003c: DW_OP_reg3 RBX
28 ; We should only have one entry inside the function.
2829 ; CHECK-NOT: :
2930
3031 declare i32 @foobar(i32, i32, i32, i32, i32)