diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/CodeGen/LexicalScopes.h | 6 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 43 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 5 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 8 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/missing-abstract-variable.ll | 23 |
5 files changed, 59 insertions, 26 deletions
diff --git a/llvm/include/llvm/CodeGen/LexicalScopes.h b/llvm/include/llvm/CodeGen/LexicalScopes.h index 31d68726741..036aea30a51 100644 --- a/llvm/include/llvm/CodeGen/LexicalScopes.h +++ b/llvm/include/llvm/CodeGen/LexicalScopes.h @@ -197,6 +197,9 @@ public: /// dump - Print data structures to dbgs(). void dump(); + /// getOrCreateAbstractScope - Find or create an abstract lexical scope. + LexicalScope *getOrCreateAbstractScope(const MDNode *N); + private: /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If /// not available then create new lexical scope. @@ -208,9 +211,6 @@ private: /// getOrCreateInlinedScope - Find or create an inlined lexical scope. LexicalScope *getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt); - /// getOrCreateAbstractScope - Find or create an abstract lexical scope. - LexicalScope *getOrCreateAbstractScope(const MDNode *N); - /// extractLexicalScopes - Extract instruction ranges for each lexical scopes /// for the given machine function. void extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges, diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 73496b0c382..4dd36830a44 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1052,24 +1052,49 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV, return findAbstractVariable(DV, ScopeLoc.getScope(DV->getContext())); } -DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV, - const MDNode *ScopeNode) { +DbgVariable *DwarfDebug::getExistingAbstractVariable(DIVariable &DV, + DIVariable &Cleansed) { LLVMContext &Ctx = DV->getContext(); // More then one inlined variable corresponds to one abstract variable. - DIVariable Var = cleanseInlinedVariable(DV, Ctx); - auto I = AbstractVariables.find(Var); + // FIXME: This duplication of variables when inlining should probably be + // removed. It's done to allow each DIVariable to describe its location + // because the DebugLoc on the dbg.value/declare isn't accurate. We should + // make it accurate then remove this duplication/cleansing stuff. + Cleansed = cleanseInlinedVariable(DV, Ctx); + auto I = AbstractVariables.find(Cleansed); if (I != AbstractVariables.end()) return I->second.get(); + return nullptr; +} - LexicalScope *Scope = LScopes.findAbstractScope(ScopeNode); - if (!Scope) - return nullptr; - +DbgVariable *DwarfDebug::createAbstractVariable(DIVariable &Var, + LexicalScope *Scope) { auto AbsDbgVariable = make_unique<DbgVariable>(Var, nullptr, this); addScopeVariable(Scope, AbsDbgVariable.get()); return (AbstractVariables[Var] = std::move(AbsDbgVariable)).get(); } +DbgVariable *DwarfDebug::getOrCreateAbstractVariable(DIVariable &DV, + const MDNode *ScopeNode) { + DIVariable Cleansed = DV; + if (DbgVariable *Var = getExistingAbstractVariable(DV, Cleansed)) + return Var; + + return createAbstractVariable(Cleansed, + LScopes.getOrCreateAbstractScope(ScopeNode)); +} + +DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV, + const MDNode *ScopeNode) { + DIVariable Cleansed = DV; + if (DbgVariable *Var = getExistingAbstractVariable(DV, Cleansed)) + return Var; + + if (LexicalScope *Scope = LScopes.findAbstractScope(ScopeNode)) + return createAbstractVariable(Cleansed, Scope); + return nullptr; +} + // If Var is a current function argument then add it to CurrentFnArguments list. bool DwarfDebug::addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope) { if (!LScopes.isCurrentFunctionScope(Scope)) @@ -1513,7 +1538,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { assert(DV && DV.isVariable()); if (!ProcessedVars.insert(DV)) continue; - findAbstractVariable(DV, DV.getContext()); + getOrCreateAbstractVariable(DV, DV.getContext()); } constructAbstractSubprogramScopeDIE(TheCU, AScope); } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 2d673791102..a3b0242fd5f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -343,6 +343,11 @@ class DwarfDebug : public AsmPrinterHandler { } /// \brief Find abstract variable associated with Var. + DbgVariable *getExistingAbstractVariable(DIVariable &DV, + DIVariable &Cleansed); + DbgVariable *createAbstractVariable(DIVariable &DV, LexicalScope *Scope); + DbgVariable *getOrCreateAbstractVariable(DIVariable &Var, + const MDNode *Scope); DbgVariable *findAbstractVariable(DIVariable &Var, DebugLoc Loc); DbgVariable *findAbstractVariable(DIVariable &Var, const MDNode *Scope); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 2325ab8444e..0bac3bec389 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1782,12 +1782,10 @@ std::unique_ptr<DIE> DwarfUnit::constructVariableDIEImpl(const DbgVariable &DV, // Define variable debug information entry. auto VariableDie = make_unique<DIE>(DV.getTag()); DbgVariable *AbsVar = DV.getAbstractVariable(); - // FIXME: any missing abstract variable missing a DIE will result in incorrect - // DWARF. More details in test/DebugInfo/missing-abstract-variable.ll for an - // example of why this is happening. - if (AbsVar && AbsVar->getDIE()) + if (AbsVar) { + assert(AbsVar->getDIE()); addDIEEntry(*VariableDie, dwarf::DW_AT_abstract_origin, *AbsVar->getDIE()); - else { + } else { if (!Name.empty()) addString(*VariableDie, dwarf::DW_AT_name, Name); addSourceLine(*VariableDie, DV.getVariable()); diff --git a/llvm/test/DebugInfo/missing-abstract-variable.ll b/llvm/test/DebugInfo/missing-abstract-variable.ll index d2bfae0bf2b..c09227a0a71 100644 --- a/llvm/test/DebugInfo/missing-abstract-variable.ll +++ b/llvm/test/DebugInfo/missing-abstract-variable.ll @@ -44,7 +44,14 @@ ; CHECK: [[ABS_B:.*]]: DW_TAG_formal_parameter ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name {{.*}} "b" -; FIXME: Missing 'x's local 's' variable. +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_lexical_block +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_TAG_lexical_block +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: [[ABS_S:.*]]: DW_TAG_variable +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "s" ; CHECK: DW_TAG_subprogram ; CHECK-NOT: DW_TAG @@ -75,14 +82,17 @@ ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_abstract_origin {{.*}} {[[ABS_X]]} ; CHECK-NOT: {{DW_TAG|NULL}} -; FIXME: This formal parameter goes missing at least at -O2, maybe before that. +; FIXME: This formal parameter goes missing at least at -O2 (& on +; mips/powerpc), maybe before that. Perhaps SelectionDAG is to blame (and +; fastisel succeeds). ; CHECK: DW_TAG_formal_parameter ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_abstract_origin {{.*}} {[[ABS_B]]} ; The two lexical blocks here are caused by the scope of the if that includes ; the condition variable, and the scope within the if's composite statement. I'm -; not sure we really need both of them. +; not sure we really need both of them since there's no variable declared in the +; outer of the two ; CHECK-NOT: {{DW_TAG|NULL}} ; CHECK: DW_TAG_lexical_block @@ -91,12 +101,7 @@ ; CHECK-NOT: {{DW_TAG|NULL}} ; CHECK: DW_TAG_variable ; CHECK-NOT: DW_TAG - -; FIXME: This shouldn't have a name here, it should use DW_AT_abstract_origin -; to reference an abstract variable definition instead - -; CHECK: DW_AT_name {{.*}} "s" - +; CHECK: DW_AT_abstract_origin {{.*}} {[[ABS_S]]} @t = external global i32 |

