From: Adrian Prantl Date: Tue, 10 Feb 2015 23:18:28 +0000 (+0000) Subject: Debug Info: Support variables that are described by more than one MMI X-Git-Tag: llvmorg-3.7.0-rc1~12509 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ca7e4702211a8cd6c65785089f6f782901323a0b;p=platform%2Fupstream%2Fllvm.git Debug Info: Support variables that are described by more than one MMI table entry. This happens when SROA splits up an alloca and the resulting allocas cannot be lowered to SSA values because their address is passed to a function. Fixes PR22502. llvm-svn: 228764 --- diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 7e147e8..6a8c9b5 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -516,15 +516,21 @@ DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, } // .. else use frame index. - int FI = DV.getFrameIndex(); - if (FI != ~0) { + if (DV.getFrameIndex().back() == ~0) + return VariableDie; + + auto Expr = DV.getExpression().begin(); + DIELoc *Loc = new (DIEValueAllocator) DIELoc(); + DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); + for (auto FI : DV.getFrameIndex()) { unsigned FrameReg = 0; const TargetFrameLowering *TFI = Asm->TM.getSubtargetImpl()->getFrameLowering(); int Offset = TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg); - MachineLocation Location(FrameReg, Offset); - addVariableAddress(DV, *VariableDie, Location); + DwarfExpr.AddMachineRegIndirect(FrameReg, Offset); + DwarfExpr.AddExpression(*(Expr++)); } + addBlock(*VariableDie, dwarf::DW_AT_location, Loc); return VariableDie; } @@ -767,7 +773,8 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, const MachineLocation &Location) { DIELoc *Loc = new (DIEValueAllocator) DIELoc(); DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); - DIExpression Expr = DV.getExpression(); + assert(DV.getExpression().size() == 1); + DIExpression Expr = DV.getExpression().back(); bool ValidReg; if (Location.getOffset()) { ValidReg = DwarfExpr.AddMachineRegIndirect(Location.getReg(), diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 8cb033a..3b6f461 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -783,10 +783,9 @@ void DwarfDebug::collectVariableInfoFromMMITable( DIVariable DV(VI.Var); DIExpression Expr(VI.Expr); ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); - ConcreteVariables.push_back(make_unique(DV, Expr, this)); - DbgVariable *RegVar = ConcreteVariables.back().get(); - RegVar->setFrameIndex(VI.Slot); - InfoHolder.addScopeVariable(Scope, RegVar); + auto RegVar = make_unique(DV, Expr, this, VI.Slot); + if (InfoHolder.addScopeVariable(Scope, RegVar.get())) + ConcreteVariables.push_back(std::move(RegVar)); } } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index a1a9426..4755c9c 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -67,41 +67,66 @@ public: //===----------------------------------------------------------------------===// /// \brief This class is used to track local variable information. +/// +/// - Variables whose location changes over time have a DotDebugLocOffset and the +/// other fields are not used. +/// +/// - Variables that are described by multiple MMI table entries have multiple +/// expressions and frame indices. class DbgVariable { - DIVariable Var; // Variable Descriptor. - DIExpression Expr; // Complex address location expression. - DIE *TheDIE; // Variable DIE. - unsigned DotDebugLocOffset; // Offset in DotDebugLocEntries. - const MachineInstr *MInsn; // DBG_VALUE instruction of the variable. - int FrameIndex; + DIVariable Var; /// Variable Descriptor. + SmallVector Expr; /// Complex address location expression. + DIE *TheDIE; /// Variable DIE. + unsigned DotDebugLocOffset; /// Offset in DotDebugLocEntries. + const MachineInstr *MInsn; /// DBG_VALUE instruction of the variable. + SmallVector FrameIndex; /// Frame index of the variable. DwarfDebug *DD; public: /// Construct a DbgVariable from a DIVariable. - DbgVariable(DIVariable V, DIExpression E, DwarfDebug *DD) - : Var(V), Expr(E), TheDIE(nullptr), DotDebugLocOffset(~0U), - MInsn(nullptr), FrameIndex(~0), DD(DD) { - assert(Var.Verify() && Expr.Verify()); + DbgVariable(DIVariable V, DIExpression E, DwarfDebug *DD, int FI = ~0) + : Var(V), Expr(1, E), TheDIE(nullptr), DotDebugLocOffset(~0U), + MInsn(nullptr), DD(DD) { + FrameIndex.push_back(FI); + assert(Var.Verify() && E.Verify()); } /// Construct a DbgVariable from a DEBUG_VALUE. /// AbstractVar may be NULL. DbgVariable(const MachineInstr *DbgValue, DwarfDebug *DD) - : Var(DbgValue->getDebugVariable()), Expr(DbgValue->getDebugExpression()), - TheDIE(nullptr), DotDebugLocOffset(~0U), MInsn(DbgValue), - FrameIndex(~0), DD(DD) {} + : Var(DbgValue->getDebugVariable()), Expr(1, DbgValue->getDebugExpression()), + TheDIE(nullptr), DotDebugLocOffset(~0U), MInsn(DbgValue), DD(DD) { + FrameIndex.push_back(~0); + } // Accessors. DIVariable getVariable() const { return Var; } - DIExpression getExpression() const { return Expr; } + const ArrayRef getExpression() const { return Expr; } void setDIE(DIE &D) { TheDIE = &D; } DIE *getDIE() const { return TheDIE; } void setDotDebugLocOffset(unsigned O) { DotDebugLocOffset = O; } unsigned getDotDebugLocOffset() const { return DotDebugLocOffset; } StringRef getName() const { return Var.getName(); } const MachineInstr *getMInsn() const { return MInsn; } - int getFrameIndex() const { return FrameIndex; } - void setFrameIndex(int FI) { FrameIndex = FI; } + const ArrayRef getFrameIndex() const { return FrameIndex; } + + void addMMIEntry(const DbgVariable &V) { + assert( DotDebugLocOffset == ~0U && !MInsn && "not an MMI entry"); + assert(V.DotDebugLocOffset == ~0U && !V.MInsn && "not an MMI entry"); + assert(V.Var == Var && "conflicting DIVariable"); + + if (V.getFrameIndex().back() != ~0) { + auto E = V.getExpression(); + auto FI = V.getFrameIndex(); + Expr.append(E.begin(), E.end()); + FrameIndex.append(FI.begin(), FI.end()); + } + assert(Expr.size() > 1 + ? std::all_of(Expr.begin(), Expr.end(), + [](DIExpression &E) { return E.isBitPiece(); }) + : (true && "conflicting locations for variable")); + } + // Translate tag to proper Dwarf tag. dwarf::Tag getTag() const { if (Var.getTag() == dwarf::DW_TAG_arg_variable) @@ -128,14 +153,11 @@ public: bool variableHasComplexAddress() const { assert(Var.isVariable() && "Invalid complex DbgVariable!"); - return Expr.getNumElements() > 0; + assert(Expr.size() == 1 && + "variableHasComplexAddress() invoked on multi-FI variable"); + return Expr.back().getNumElements() > 0; } bool isBlockByrefVariable() const; - unsigned getNumAddrElements() const { - assert(Var.isVariable() && "Invalid complex DbgVariable!"); - return Expr.getNumElements(); - } - uint64_t getAddrElement(unsigned i) const { return Expr.getElement(i); } DIType getType() const; private: diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp index 408f683..3988f0d 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp @@ -146,7 +146,7 @@ void DwarfFile::emitStrings(const MCSection *StrSection, StrPool.emit(*Asm, StrSection, OffsetSection); } -void DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { +bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { SmallVectorImpl &Vars = ScopeVariables[LS]; DIVariable DV = Var->getVariable(); // Variables with positive arg numbers are parameters. @@ -168,13 +168,17 @@ void DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { // A later indexed parameter has been found, insert immediately before it. if (CurNum > ArgNum) break; - assert(CurNum != ArgNum && "Duplicate argument"); + if (CurNum == ArgNum) { + (*I)->addMMIEntry(*Var); + return false; + } ++I; } Vars.insert(I, Var); - return; + return true; } Vars.push_back(Var); + return true; } } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h index f14d673..35bf33a 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h @@ -95,7 +95,8 @@ public: /// \brief Returns the string pool. DwarfStringPool &getStringPool() { return StrPool; } - void addScopeVariable(LexicalScope *LS, DbgVariable *Var); + /// \returns false if the variable was merged with a previous one. + bool addScopeVariable(LexicalScope *LS, DbgVariable *Var); DenseMap> &getScopeVariables() { return ScopeVariables;