From 30436451e28a92642b1d4f56afc9e7df575b7756 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Wed, 21 May 2014 22:41:17 +0000 Subject: [PATCH] DebugInfo: Ensure concrete out of line variables from inlined functions reference their abstract origins. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209327 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 45 ++++++++++++---------- lib/CodeGen/AsmPrinter/DwarfDebug.h | 3 +- test/DebugInfo/X86/concrete_out_of_line.ll | 3 ++ 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index cb5824b3572..e4170f026bd 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1024,6 +1024,7 @@ void DwarfDebug::endModule() { // clean up. SPMap.clear(); + AbstractVariables.clear(); // Reset these for the next Module if we have one. FirstCU = nullptr; @@ -1032,21 +1033,25 @@ void DwarfDebug::endModule() { // Find abstract variable, if any, associated with Var. DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV, DebugLoc ScopeLoc) { + return findAbstractVariable(DV, ScopeLoc.getScope(DV->getContext())); +} + +DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV, + const MDNode *ScopeNode) { LLVMContext &Ctx = DV->getContext(); // More then one inlined variable corresponds to one abstract variable. DIVariable Var = cleanseInlinedVariable(DV, Ctx); - DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var); - if (AbsDbgVariable) - return AbsDbgVariable; + auto I = AbstractVariables.find(Var); + if (I != AbstractVariables.end()) + return I->second.get(); - LexicalScope *Scope = LScopes.findAbstractScope(ScopeLoc.getScope(Ctx)); + LexicalScope *Scope = LScopes.findAbstractScope(ScopeNode); if (!Scope) return nullptr; - AbsDbgVariable = new DbgVariable(Var, nullptr, this); - addScopeVariable(Scope, AbsDbgVariable); - AbstractVariables[Var] = AbsDbgVariable; - return AbsDbgVariable; + auto AbsDbgVariable = make_unique(Var, nullptr, this); + addScopeVariable(Scope, AbsDbgVariable.get()); + return (AbstractVariables[Var] = std::move(AbsDbgVariable)).get(); } // If Var is a current function argument then add it to CurrentFnArguments list. @@ -1226,7 +1231,10 @@ DwarfDebug::collectVariableInfo(SmallPtrSet &Processed) { if (!Processed.insert(DV)) continue; if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext())) - addScopeVariable(Scope, new DbgVariable(DV, nullptr, this)); + addScopeVariable( + Scope, + new DbgVariable(DV, findAbstractVariable(DV, Scope->getScopeNode()), + this)); } } @@ -1516,14 +1524,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { assert(DV && DV.isVariable()); if (!ProcessedVars.insert(DV)) continue; - // Check that DbgVariable for DV wasn't created earlier, when - // findAbstractVariable() was called for inlined instance of DV. - LLVMContext &Ctx = DV->getContext(); - DIVariable CleanDV = cleanseInlinedVariable(DV, Ctx); - if (AbstractVariables.lookup(CleanDV)) - continue; - if (LexicalScope *Scope = LScopes.findAbstractScope(DV.getContext())) - addScopeVariable(Scope, new DbgVariable(DV, nullptr, this)); + findAbstractVariable(DV, DV.getContext()); } constructAbstractSubprogramScopeDIE(TheCU, AScope); } @@ -1539,12 +1540,16 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { PrevCU = &TheCU; // Clear debug info - for (auto &I : ScopeVariables) - DeleteContainerPointers(I.second); + // Ownership of DbgVariables is a bit subtle - ScopeVariables owns all the + // DbgVariables except those that are also in AbstractVariables (since they + // can be used cross-function) + for (const auto &I : ScopeVariables) + for (const auto *Var : I.second) + if (!AbstractVariables.count(Var->getVariable()) || Var->getAbstractVariable()) + delete Var; ScopeVariables.clear(); DeleteContainerPointers(CurrentFnArguments); DbgValues.clear(); - AbstractVariables.clear(); LabelsBeforeInsn.clear(); LabelsAfterInsn.clear(); PrevLabel = nullptr; diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index b2e16074f51..aa18e7c3456 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -199,7 +199,7 @@ class DwarfDebug : public AsmPrinterHandler { ScopeVariablesMap ScopeVariables; // Collection of abstract variables. - DenseMap AbstractVariables; + DenseMap> AbstractVariables; // Collection of DebugLocEntry. Stored in a linked list so that DIELocLists // can refer to them in spite of insertions into this list. @@ -336,6 +336,7 @@ class DwarfDebug : public AsmPrinterHandler { /// \brief Find abstract variable associated with Var. DbgVariable *findAbstractVariable(DIVariable &Var, DebugLoc Loc); + DbgVariable *findAbstractVariable(DIVariable &Var, const MDNode *Scope); /// \brief Find DIE for the given subprogram and attach appropriate /// DW_AT_low_pc and DW_AT_high_pc attributes. If there are global diff --git a/test/DebugInfo/X86/concrete_out_of_line.ll b/test/DebugInfo/X86/concrete_out_of_line.ll index baa819de85d..ad9d3b66696 100644 --- a/test/DebugInfo/X86/concrete_out_of_line.ll +++ b/test/DebugInfo/X86/concrete_out_of_line.ll @@ -39,6 +39,8 @@ ; CHECK-NEXT: DW_AT_specification {{.*}} {[[DTOR_DECL]]} ; CHECK-NEXT: DW_AT_inline ; CHECK-NOT: DW_AT_inline +; CHECK-NOT: DW_TAG +; CHECK: [[D1_THIS_ABS:0x........]]: DW_TAG_formal_parameter ; CHECK: [[D2_ABS]]: DW_TAG_subprogram ; CHECK-NEXT: DW_AT_{{.*}}linkage_name ; CHECK-NEXT: DW_AT_specification {{.*}} {[[DTOR_DECL]]} @@ -52,6 +54,7 @@ ; CHECK: DW_TAG_subprogram ; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D1_ABS]]} ; CHECK: DW_TAG_formal_parameter +; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D1_THIS_ABS]]} ; CHECK: DW_TAG_inlined_subroutine ; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D2_ABS]]} -- 2.34.1