From 8832992df56dd51f58bf8fc386dec9cbf99054c9 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Fri, 27 Jun 2014 05:31:49 +0000 Subject: [PATCH] Revert "Revert "PR20038: DebugInfo: Inlined call sites where the caller has debug info but the call itself has no debug location."" This reverts commit r211724. llvm-svn: 211871 --- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 3 +- llvm/lib/CodeGen/LexicalScopes.cpp | 9 +- llvm/lib/IR/DebugInfo.cpp | 26 +++++ llvm/test/DebugInfo/PR20038.ll | 114 ++++++++++++--------- 4 files changed, 102 insertions(+), 50 deletions(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index f78ca2c03b4e..5aa2659fb6c5 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -786,8 +786,7 @@ void DwarfDebug::finishVariableDefinitions() { for (const auto &Var : ConcreteVariables) { DIE *VariableDie = Var->getDIE(); // FIXME: There shouldn't be any variables without DIEs. - if (!VariableDie) - continue; + assert(VariableDie); // FIXME: Consider the time-space tradeoff of just storing the unit pointer // in the ConcreteVariables list, rather than looking it up again here. // DIE::getUnit isn't simple - it walks parent pointers, etc. diff --git a/llvm/lib/CodeGen/LexicalScopes.cpp b/llvm/lib/CodeGen/LexicalScopes.cpp index d12c234bf3b2..f67c717d4e41 100644 --- a/llvm/lib/CodeGen/LexicalScopes.cpp +++ b/llvm/lib/CodeGen/LexicalScopes.cpp @@ -137,6 +137,8 @@ LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) { /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If /// not available then create new lexical scope. LexicalScope *LexicalScopes::getOrCreateLexicalScope(DebugLoc DL) { + if (DL.isUnknown()) + return nullptr; MDNode *Scope = nullptr; MDNode *InlinedAt = nullptr; DL.getScopeAndInlinedAt(Scope, InlinedAt, MF->getFunction()->getContext()); @@ -172,9 +174,12 @@ LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) { std::make_tuple(Parent, DIDescriptor(Scope), nullptr, false)).first; - if (!Parent && DIDescriptor(Scope).isSubprogram() && - DISubprogram(Scope).describes(MF->getFunction())) + if (!Parent) { + assert(DIDescriptor(Scope).isSubprogram()); + assert(DISubprogram(Scope).describes(MF->getFunction())); + assert(!CurrentFnLexicalScope); CurrentFnLexicalScope = &I->second; + } return &I->second; } diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index db9e56defa12..2023be313bda 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -532,6 +532,32 @@ bool DISubprogram::Verify() const { if (isLValueReference() && isRValueReference()) return false; + if (auto *F = getFunction()) { + LLVMContext &Ctxt = F->getContext(); + for (auto &BB : *F) { + for (auto &I : BB) { + DebugLoc DL = I.getDebugLoc(); + if (DL.isUnknown()) + continue; + + MDNode *Scope = nullptr; + MDNode *IA = nullptr; + // walk the inlined-at scopes + while (DL.getScopeAndInlinedAt(Scope, IA, F->getContext()), IA) + DL = DebugLoc::getFromDILocation(IA); + DL.getScopeAndInlinedAt(Scope, IA, Ctxt); + assert(!IA); + while (!DIDescriptor(Scope).isSubprogram()) { + DILexicalBlockFile D(Scope); + Scope = D.isLexicalBlockFile() + ? D.getScope() + : DebugLoc::getFromDILexicalBlock(Scope).getScope(Ctxt); + } + if (!DISubprogram(Scope).describes(F)) + return false; + } + } + } return DbgNode->getNumOperands() == 20; } diff --git a/llvm/test/DebugInfo/PR20038.ll b/llvm/test/DebugInfo/PR20038.ll index a9fb3ff3b604..61145e5c8441 100644 --- a/llvm/test/DebugInfo/PR20038.ll +++ b/llvm/test/DebugInfo/PR20038.ll @@ -18,26 +18,38 @@ ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name {{.*}} "~C" +; CHECK: [[D1_ABS:.*]]: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_ZN1CD1Ev" +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: [[D1_THIS_ABS:.*]]: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "this" + ; CHECK: DW_TAG_subprogram ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name {{.*}} "fun4" - -; FIXME: The dtor is inlined into fun4 and should have an inlined_subroutine -; entry. (it may be necessary to put some non-trivial instruction, such as an -; assignment to a global, in the dtor just to ensure its emission/inlining) - -; CHECK-NOT: DW_TAG_inlined_subroutine - -; CHECK: DW_TAG_subprogram +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_lexical_block +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_inlined_subroutine ; CHECK-NOT: DW_TAG -; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_ZN1CD1Ev" +; CHECK: DW_AT_abstract_origin {{.*}} {[[D1_ABS]]} +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_abstract_origin {{.*}} {[[D1_THIS_ABS]]} -; FIXME: But I think where the real issue is for PR20038 is that the D1 ctor, ; -; calling and inlining D2, doesn't end up with an inlined_subroutine. Though this -; might be more the result of a lack of any actual work in D2 (again, could use -; an assignment to global, etc) +; FIXME: D2 is actually inlined into D1 but doesn't show up here, possibly due +; to there being no work in D2 (calling another member function from the dtor +; causes D2 to show up, calling a free function doesn't). -; CHECK-NOT: DW_TAG_inlined_subroutine +; CHECK-NOT: DW_TAG +; CHECK: NULL +; CHECK-NOT: DW_TAG +; CHECK: NULL +; CHECK-NOT: DW_TAG +; CHECK: NULL %struct.C = type { i8 } @@ -47,48 +59,48 @@ define void @_Z4fun4v() #0 { entry: %this.addr.i.i = alloca %struct.C*, align 8, !dbg !21 - %this.addr.i = alloca %struct.C*, align 8 + %this.addr.i = alloca %struct.C*, align 8, !dbg !22 %agg.tmp.ensured = alloca %struct.C, align 1 %cleanup.cond = alloca i1 - %0 = load i8* @b, align 1, !dbg !22 - %tobool = trunc i8 %0 to i1, !dbg !22 + %0 = load i8* @b, align 1, !dbg !24 + %tobool = trunc i8 %0 to i1, !dbg !24 store i1 false, i1* %cleanup.cond - br i1 %tobool, label %land.rhs, label %land.end, !dbg !22 + br i1 %tobool, label %land.rhs, label %land.end, !dbg !24 land.rhs: ; preds = %entry - store i1 true, i1* %cleanup.cond, !dbg !23 + store i1 true, i1* %cleanup.cond, !dbg !25 br label %land.end land.end: ; preds = %land.rhs, %entry %1 = phi i1 [ false, %entry ], [ true, %land.rhs ] - %cleanup.is_active = load i1* %cleanup.cond - br i1 %cleanup.is_active, label %cleanup.action, label %cleanup.done + %cleanup.is_active = load i1* %cleanup.cond, !dbg !27 + br i1 %cleanup.is_active, label %cleanup.action, label %cleanup.done, !dbg !27 cleanup.action: ; preds = %land.end - store %struct.C* %agg.tmp.ensured, %struct.C** %this.addr.i, align 8 - call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr.i}, metadata !25), !dbg !27 - %this1.i = load %struct.C** %this.addr.i + store %struct.C* %agg.tmp.ensured, %struct.C** %this.addr.i, align 8, !dbg !22 + call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr.i}, metadata !29), !dbg !31 + %this1.i = load %struct.C** %this.addr.i, !dbg !22 store %struct.C* %this1.i, %struct.C** %this.addr.i.i, align 8, !dbg !21 - call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr.i.i}, metadata !28), !dbg !29 + call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr.i.i}, metadata !32), !dbg !33 %this1.i.i = load %struct.C** %this.addr.i.i, !dbg !21 - br label %cleanup.done + br label %cleanup.done, !dbg !22 cleanup.done: ; preds = %cleanup.action, %land.end - ret void, !dbg !22 + ret void, !dbg !34 } ; Function Attrs: alwaysinline nounwind define void @_ZN1CD1Ev(%struct.C* %this) unnamed_addr #1 align 2 { entry: - %this.addr.i = alloca %struct.C*, align 8, !dbg !21 + %this.addr.i = alloca %struct.C*, align 8, !dbg !37 %this.addr = alloca %struct.C*, align 8 store %struct.C* %this, %struct.C** %this.addr, align 8 - call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr}, metadata !25), !dbg !27 + call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr}, metadata !29), !dbg !38 %this1 = load %struct.C** %this.addr - store %struct.C* %this1, %struct.C** %this.addr.i, align 8, !dbg !21 - call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr.i}, metadata !28), !dbg !29 - %this1.i = load %struct.C** %this.addr.i, !dbg !21 - ret void, !dbg !21 + store %struct.C* %this1, %struct.C** %this.addr.i, align 8, !dbg !37 + call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr.i}, metadata !32), !dbg !39 + %this1.i = load %struct.C** %this.addr.i, !dbg !37 + ret void, !dbg !37 } ; Function Attrs: alwaysinline nounwind @@ -96,9 +108,9 @@ define void @_ZN1CD2Ev(%struct.C* %this) unnamed_addr #1 align 2 { entry: %this.addr = alloca %struct.C*, align 8 store %struct.C* %this, %struct.C** %this.addr, align 8 - call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr}, metadata !28), !dbg !30 + call void @llvm.dbg.declare(metadata !{%struct.C** %this.addr}, metadata !32), !dbg !40 %this1 = load %struct.C** %this.addr - ret void, !dbg !31 + ret void, !dbg !41 } ; Function Attrs: nounwind readnone @@ -133,14 +145,24 @@ attributes #2 = { nounwind readnone } !18 = metadata !{i32 2, metadata !"Dwarf Version", i32 4} !19 = metadata !{i32 2, metadata !"Debug Info Version", i32 1} !20 = metadata !{metadata !"clang version 3.5.0 "} -!21 = metadata !{i32 6, i32 0, metadata !17, null} -!22 = metadata !{i32 5, i32 0, metadata !12, null} -!23 = metadata !{i32 5, i32 0, metadata !24, null} -!24 = metadata !{i32 786443, metadata !5, metadata !12, i32 5, i32 0, i32 1, i32 1} ; [ DW_TAG_lexical_block ] [/tmp/dbginfo/PR20038.cpp] -!25 = metadata !{i32 786689, metadata !17, metadata !"this", null, i32 16777216, metadata !26, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 0] -!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] -!27 = metadata !{i32 0, i32 0, metadata !17, null} -!28 = metadata !{i32 786689, metadata !16, metadata !"this", null, i32 16777216, metadata !26, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 0] -!29 = metadata !{i32 0, i32 0, metadata !16, metadata !21} -!30 = metadata !{i32 0, i32 0, metadata !16, null} -!31 = metadata !{i32 6, i32 0, metadata !16, null} +!21 = metadata !{i32 6, i32 0, metadata !17, metadata !22} +!22 = metadata !{i32 5, i32 0, metadata !23, null} +!23 = metadata !{i32 786443, metadata !5, metadata !12, i32 5, i32 0, i32 3, i32 3} ; [ DW_TAG_lexical_block ] [/tmp/dbginfo/PR20038.cpp] +!24 = metadata !{i32 5, i32 0, metadata !12, null} +!25 = metadata !{i32 5, i32 0, metadata !26, null} +!26 = metadata !{i32 786443, metadata !5, metadata !12, i32 5, i32 0, i32 1, i32 1} ; [ DW_TAG_lexical_block ] [/tmp/dbginfo/PR20038.cpp] +!27 = metadata !{i32 5, i32 0, metadata !28, null} +!28 = metadata !{i32 786443, metadata !5, metadata !12, i32 5, i32 0, i32 2, i32 2} ; [ DW_TAG_lexical_block ] [/tmp/dbginfo/PR20038.cpp] +!29 = metadata !{i32 786689, metadata !17, metadata !"this", null, i32 16777216, metadata !30, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 0] +!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] +!31 = metadata !{i32 0, i32 0, metadata !17, metadata !22} +!32 = metadata !{i32 786689, metadata !16, metadata !"this", null, i32 16777216, metadata !30, i32 1088, i32 0} ; [ DW_TAG_arg_variable ] [this] [line 0] +!33 = metadata !{i32 0, i32 0, metadata !16, metadata !21} +!34 = metadata !{i32 5, i32 0, metadata !35, null} +!35 = metadata !{i32 786443, metadata !5, metadata !36, i32 5, i32 0, i32 5, i32 5} ; [ DW_TAG_lexical_block ] [/tmp/dbginfo/PR20038.cpp] +!36 = metadata !{i32 786443, metadata !5, metadata !12, i32 5, i32 0, i32 4, i32 4} ; [ DW_TAG_lexical_block ] [/tmp/dbginfo/PR20038.cpp] +!37 = metadata !{i32 6, i32 0, metadata !17, null} +!38 = metadata !{i32 0, i32 0, metadata !17, null} +!39 = metadata !{i32 0, i32 0, metadata !16, metadata !37} +!40 = metadata !{i32 0, i32 0, metadata !16, null} +!41 = metadata !{i32 6, i32 0, metadata !16, null}