Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit a422113

Browse files
committed
DebugInfo: Ensure that all debug location scope chains from instructions within a function, lead to the function itself.
Originally committed in r211723, reverted in r211724 due to failure cases found and fixed (ArgumentPromotion: r211872, Inlining: r212065), committed again in r212085 and reverted again in r212089 after fixing some other cases, such as debug info subprogram lists not keeping track of the function they represent (r212128) and then short-circuiting things like LiveDebugVariables that build LexicalScopes for functions that might not have full debug info. And again, I believe the invariant actually holds for some reasonable amount of code (but I'll keep an eye on the buildbots and see what happens... ). Original commit message: PR20038: DebugInfo: Inlined call sites where the caller has debug info but the call itself has no debug location. This situation does bad things when inlined, so I've fixed Clang not to produce inlinable call sites without locations when the caller has debug info (in the one case where I could find that this occurred). This updates the PR20038 test case to be what clang now produces, and readds the assertion that had to be removed due to this bug. I've also beefed up the debug info verifier to help diagnose these issues in the future, and I hope to add checks to the inliner to just assert-fail if it encounters this situation. If, in the future, we decide we have to cope with this situation, the right thing to do is probably to just remove all the DebugLocs from the inlined instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212205 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 5599fde commit a422113

File tree

4 files changed

+102
-50
lines changed

4 files changed

+102
-50
lines changed

lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -788,8 +788,7 @@ void DwarfDebug::finishVariableDefinitions() {
788788
for (const auto &Var : ConcreteVariables) {
789789
DIE *VariableDie = Var->getDIE();
790790
// FIXME: There shouldn't be any variables without DIEs.
791-
if (!VariableDie)
792-
continue;
791+
assert(VariableDie);
793792
// FIXME: Consider the time-space tradeoff of just storing the unit pointer
794793
// in the ConcreteVariables list, rather than looking it up again here.
795794
// DIE::getUnit isn't simple - it walks parent pointers, etc.

lib/CodeGen/LexicalScopes.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) {
137137
/// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
138138
/// not available then create new lexical scope.
139139
LexicalScope *LexicalScopes::getOrCreateLexicalScope(DebugLoc DL) {
140+
if (DL.isUnknown())
141+
return nullptr;
140142
MDNode *Scope = nullptr;
141143
MDNode *InlinedAt = nullptr;
142144
DL.getScopeAndInlinedAt(Scope, InlinedAt, MF->getFunction()->getContext());
@@ -172,9 +174,12 @@ LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) {
172174
std::make_tuple(Parent, DIDescriptor(Scope),
173175
nullptr, false)).first;
174176

175-
if (!Parent && DIDescriptor(Scope).isSubprogram() &&
176-
DISubprogram(Scope).describes(MF->getFunction()))
177+
if (!Parent) {
178+
assert(DIDescriptor(Scope).isSubprogram());
179+
assert(DISubprogram(Scope).describes(MF->getFunction()));
180+
assert(!CurrentFnLexicalScope);
177181
CurrentFnLexicalScope = &I->second;
182+
}
178183

179184
return &I->second;
180185
}

lib/IR/DebugInfo.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,32 @@ bool DISubprogram::Verify() const {
538538
if (isLValueReference() && isRValueReference())
539539
return false;
540540

541+
if (auto *F = getFunction()) {
542+
LLVMContext &Ctxt = F->getContext();
543+
for (auto &BB : *F) {
544+
for (auto &I : BB) {
545+
DebugLoc DL = I.getDebugLoc();
546+
if (DL.isUnknown())
547+
continue;
548+
549+
MDNode *Scope = nullptr;
550+
MDNode *IA = nullptr;
551+
// walk the inlined-at scopes
552+
while (DL.getScopeAndInlinedAt(Scope, IA, F->getContext()), IA)
553+
DL = DebugLoc::getFromDILocation(IA);
554+
DL.getScopeAndInlinedAt(Scope, IA, Ctxt);
555+
assert(!IA);
556+
while (!DIDescriptor(Scope).isSubprogram()) {
557+
DILexicalBlockFile D(Scope);
558+
Scope = D.isLexicalBlockFile()
559+
? D.getScope()
560+
: DebugLoc::getFromDILexicalBlock(Scope).getScope(Ctxt);
561+
}
562+
if (!DISubprogram(Scope).describes(F))
563+
return false;
564+
}
565+
}
566+
}
541567
return DbgNode->getNumOperands() == 20;
542568
}
543569

test/DebugInfo/PR20038.ll

Lines changed: 68 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,38 @@
1818
; CHECK-NOT: DW_TAG
1919
; CHECK: DW_AT_name {{.*}} "~C"
2020

21-
; CHECK: DW_TAG_subprogram
21+
; CHECK: [[D1_ABS:.*]]: DW_TAG_subprogram
2222
; CHECK-NOT: DW_TAG
23-
; CHECK: DW_AT_name {{.*}} "fun4"
24-
25-
; FIXME: The dtor is inlined into fun4 and should have an inlined_subroutine
26-
; entry. (it may be necessary to put some non-trivial instruction, such as an
27-
; assignment to a global, in the dtor just to ensure its emission/inlining)
28-
29-
; CHECK-NOT: DW_TAG_inlined_subroutine
23+
; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_ZN1CD1Ev"
24+
; CHECK-NOT: {{DW_TAG|NULL}}
25+
; CHECK: [[D1_THIS_ABS:.*]]: DW_TAG_formal_parameter
26+
; CHECK-NOT: DW_TAG
27+
; CHECK: DW_AT_name {{.*}} "this"
3028

3129
; CHECK: DW_TAG_subprogram
3230
; CHECK-NOT: DW_TAG
33-
; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_ZN1CD1Ev"
31+
; CHECK: DW_AT_name {{.*}} "fun4"
32+
; CHECK-NOT: {{DW_TAG|NULL}}
33+
; CHECK: DW_TAG_lexical_block
34+
; CHECK-NOT: {{DW_TAG|NULL}}
35+
; CHECK: DW_TAG_inlined_subroutine
36+
; CHECK-NOT: DW_TAG
37+
; CHECK: DW_AT_abstract_origin {{.*}} {[[D1_ABS]]}
38+
; CHECK-NOT: {{DW_TAG|NULL}}
39+
; CHECK: DW_TAG_formal_parameter
40+
; CHECK-NOT: DW_TAG
41+
; CHECK: DW_AT_abstract_origin {{.*}} {[[D1_THIS_ABS]]}
3442

35-
; FIXME: But I think where the real issue is for PR20038 is that the D1 ctor, ;
36-
; calling and inlining D2, doesn't end up with an inlined_subroutine. Though this
37-
; might be more the result of a lack of any actual work in D2 (again, could use
38-
; an assignment to global, etc)
43+
; FIXME: D2 is actually inlined into D1 but doesn't show up here, possibly due
44+
; to there being no work in D2 (calling another member function from the dtor
45+
; causes D2 to show up, calling a free function doesn't).
3946

40-
; CHECK-NOT: DW_TAG_inlined_subroutine
47+
; CHECK-NOT: DW_TAG
48+
; CHECK: NULL
49+
; CHECK-NOT: DW_TAG
50+
; CHECK: NULL
51+
; CHECK-NOT: DW_TAG
52+
; CHECK: NULL
4153

4254
%struct.C = type { i8 }
4355

@@ -47,58 +59,58 @@
4759
define void @_Z4fun4v() #0 {
4860
entry:
4961
%this.addr.i.i = alloca %struct.C*, align 8, !dbg !21
50-
%this.addr.i = alloca %struct.C*, align 8
62+
%this.addr.i = alloca %struct.C*, align 8, !dbg !22
5163
%agg.tmp.ensured = alloca %struct.C, align 1
5264
%cleanup.cond = alloca i1
53-
%0 = load i8* @b, align 1, !dbg !22
54-
%tobool = trunc i8 %0 to i1, !dbg !22
65+
%0 = load i8* @b, align 1, !dbg !24
66+
%tobool = trunc i8 %0 to i1, !dbg !24
5567
store i1 false, i1* %cleanup.cond
56-
br i1 %tobool, label %land.rhs, label %land.end, !dbg !22
68+
br i1 %tobool, label %land.rhs, label %land.end, !dbg !24
5769

5870
land.rhs: ; preds = %entry
59-
store i1 true, i1* %cleanup.cond, !dbg !23
71+
store i1 true, i1* %cleanup.cond, !dbg !25
6072
br label %land.end
6173

6274
land.end: ; preds = %land.rhs, %entry
6375
%1 = phi i1 [ false, %entry ], [ true, %land.rhs ]
64-
%cleanup.is_active = load i1* %cleanup.cond
65-
br i1 %cleanup.is_active, label %cleanup.action, label %cleanup.done
76+
%cleanup.is_active = load i1* %cleanup.cond, !dbg !27
77+
br i1 %cleanup.is_active, label %cleanup.action, label %cleanup.done, !dbg !27
6678

6779
cleanup.action: ; preds = %land.end
68-
store %struct.C* %agg.tmp.ensured, %struct.C** %this.addr.i, align 8
69-
call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr.i}, metadata !25), !dbg !27
70-
%this1.i = load %struct.C** %this.addr.i
80+
store %struct.C* %agg.tmp.ensured, %struct.C** %this.addr.i, align 8, !dbg !22
81+
call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr.i}, metadata !29), !dbg !31
82+
%this1.i = load %struct.C** %this.addr.i, !dbg !22
7183
store %struct.C* %this1.i, %struct.C** %this.addr.i.i, align 8, !dbg !21
72-
call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr.i.i}, metadata !28), !dbg !29
84+
call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr.i.i}, metadata !32), !dbg !33
7385
%this1.i.i = load %struct.C** %this.addr.i.i, !dbg !21
74-
br label %cleanup.done
86+
br label %cleanup.done, !dbg !22
7587

7688
cleanup.done: ; preds = %cleanup.action, %land.end
77-
ret void, !dbg !22
89+
ret void, !dbg !34
7890
}
7991

8092
; Function Attrs: alwaysinline nounwind
8193
define void @_ZN1CD1Ev(%struct.C* %this) unnamed_addr #1 align 2 {
8294
entry:
83-
%this.addr.i = alloca %struct.C*, align 8, !dbg !21
95+
%this.addr.i = alloca %struct.C*, align 8, !dbg !37
8496
%this.addr = alloca %struct.C*, align 8
8597
store %struct.C* %this, %struct.C** %this.addr, align 8
86-
call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr}, metadata !25), !dbg !27
98+
call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr}, metadata !29), !dbg !38
8799
%this1 = load %struct.C** %this.addr
88-
store %struct.C* %this1, %struct.C** %this.addr.i, align 8, !dbg !21
89-
call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr.i}, metadata !28), !dbg !29
90-
%this1.i = load %struct.C** %this.addr.i, !dbg !21
91-
ret void, !dbg !21
100+
store %struct.C* %this1, %struct.C** %this.addr.i, align 8, !dbg !37
101+
call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr.i}, metadata !32), !dbg !39
102+
%this1.i = load %struct.C** %this.addr.i, !dbg !37
103+
ret void, !dbg !37
92104
}
93105

94106
; Function Attrs: alwaysinline nounwind
95107
define void @_ZN1CD2Ev(%struct.C* %this) unnamed_addr #1 align 2 {
96108
entry:
97109
%this.addr = alloca %struct.C*, align 8
98110
store %struct.C* %this, %struct.C** %this.addr, align 8
99-
call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr}, metadata !28), !dbg !30
111+
call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr}, metadata !32), !dbg !40
100112
%this1 = load %struct.C** %this.addr
101-
ret void, !dbg !31
113+
ret void, !dbg !41
102114
}
103115

104116
; Function Attrs: nounwind readnone
@@ -133,14 +145,24 @@ attributes #2 = { nounwind readnone }
133145
!18 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
134146
!19 = metadata !{i32 2, metadata !"Debug Info Version", i32 1}
135147
!20 = metadata !{metadata !"clang version 3.5.0 "}
136-
!21 = metadata !{i32 6, i32 0, metadata !17, null}
137-
!22 = metadata !{i32 5, i32 0, metadata !12, null}
138-
!23 = metadata !{i32 5, i32 0, metadata !24, null}
139-
!24 = metadata !{i32 786443, metadata !5, metadata !12, i32 5, i32 0, i32 1, i32 1} ; [ DW_TAG_lexical_block ] [/tmp/dbginfo/PR20038.cpp]
140-
!25 = metadata !{i32 786689, metadata !17, metadata !"this", null, i32 16777216, metadata !26, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 0]
141-
!26 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !"_ZTS1C"} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from _ZTS1C]
142-
!27 = metadata !{i32 0, i32 0, metadata !17, null}
143-
!28 = metadata !{i32 786689, metadata !16, metadata !"this", null, i32 16777216, metadata !26, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 0]
144-
!29 = metadata !{i32 0, i32 0, metadata !16, metadata !21}
145-
!30 = metadata !{i32 0, i32 0, metadata !16, null}
146-
!31 = metadata !{i32 6, i32 0, metadata !16, null}
148+
!21 = metadata !{i32 6, i32 0, metadata !17, metadata !22}
149+
!22 = metadata !{i32 5, i32 0, metadata !23, null}
150+
!23 = metadata !{i32 786443, metadata !5, metadata !12, i32 5, i32 0, i32 3, i32 3} ; [ DW_TAG_lexical_block ] [/tmp/dbginfo/PR20038.cpp]
151+
!24 = metadata !{i32 5, i32 0, metadata !12, null}
152+
!25 = metadata !{i32 5, i32 0, metadata !26, null}
153+
!26 = metadata !{i32 786443, metadata !5, metadata !12, i32 5, i32 0, i32 1, i32 1} ; [ DW_TAG_lexical_block ] [/tmp/dbginfo/PR20038.cpp]
154+
!27 = metadata !{i32 5, i32 0, metadata !28, null}
155+
!28 = metadata !{i32 786443, metadata !5, metadata !12, i32 5, i32 0, i32 2, i32 2} ; [ DW_TAG_lexical_block ] [/tmp/dbginfo/PR20038.cpp]
156+
!29 = metadata !{i32 786689, metadata !17, metadata !"this", null, i32 16777216, metadata !30, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 0]
157+
!30 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !"_ZTS1C"} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from _ZTS1C]
158+
!31 = metadata !{i32 0, i32 0, metadata !17, metadata !22}
159+
!32 = metadata !{i32 786689, metadata !16, metadata !"this", null, i32 16777216, metadata !30, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 0]
160+
!33 = metadata !{i32 0, i32 0, metadata !16, metadata !21}
161+
!34 = metadata !{i32 5, i32 0, metadata !35, null}
162+
!35 = metadata !{i32 786443, metadata !5, metadata !36, i32 5, i32 0, i32 5, i32 5} ; [ DW_TAG_lexical_block ] [/tmp/dbginfo/PR20038.cpp]
163+
!36 = metadata !{i32 786443, metadata !5, metadata !12, i32 5, i32 0, i32 4, i32 4} ; [ DW_TAG_lexical_block ] [/tmp/dbginfo/PR20038.cpp]
164+
!37 = metadata !{i32 6, i32 0, metadata !17, null}
165+
!38 = metadata !{i32 0, i32 0, metadata !17, null}
166+
!39 = metadata !{i32 0, i32 0, metadata !16, metadata !37}
167+
!40 = metadata !{i32 0, i32 0, metadata !16, null}
168+
!41 = metadata !{i32 6, i32 0, metadata !16, null}

0 commit comments

Comments
 (0)