From aead63c0337ed24053b8bdde8918aacdc66d8231 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Mon, 29 Mar 2010 22:59:58 +0000 Subject: [PATCH] Encode start location of debug value, communicated through DBG_VALUE machine instruction, in a variable's DIE. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99845 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 52 +++++++++++++++++++-------- lib/CodeGen/AsmPrinter/DwarfDebug.h | 6 ++++ 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 2f23ca0e441..d76de693dff 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -149,20 +149,26 @@ class DbgVariable { DIVariable Var; // Variable Descriptor. unsigned FrameIndex; // Variable frame index. const MachineInstr *DbgValueMInsn; // DBG_VALUE + // DbgValueLabel - DBG_VALUE is effective from this label. + MCSymbol *DbgValueLabel; DbgVariable *const AbstractVar; // Abstract variable for this variable. DIE *TheDIE; public: // AbsVar may be NULL. DbgVariable(DIVariable V, unsigned I, DbgVariable *AbsVar) - : Var(V), FrameIndex(I), DbgValueMInsn(0), AbstractVar(AbsVar), TheDIE(0) {} + : Var(V), FrameIndex(I), DbgValueMInsn(0), + DbgValueLabel(0), AbstractVar(AbsVar), TheDIE(0) {} DbgVariable(DIVariable V, const MachineInstr *MI, DbgVariable *AbsVar) - : Var(V), FrameIndex(0), DbgValueMInsn(MI), AbstractVar(AbsVar), TheDIE(0) + : Var(V), FrameIndex(0), DbgValueMInsn(MI), DbgValueLabel(0), + AbstractVar(AbsVar), TheDIE(0) {} // Accessors. DIVariable getVariable() const { return Var; } unsigned getFrameIndex() const { return FrameIndex; } const MachineInstr *getDbgValue() const { return DbgValueMInsn; } + MCSymbol *getDbgValueLabel() const { return DbgValueLabel; } + void setDbgValueLabel(MCSymbol *L) { DbgValueLabel = L; } DbgVariable *getAbstractVariable() const { return AbstractVar; } void setDIE(DIE *D) { TheDIE = D; } DIE *getDIE() const { return TheDIE; } @@ -1367,7 +1373,7 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) { DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) { MCSymbol *Start = Scope->getStartLabel(); MCSymbol *End = Scope->getEndLabel(); - if (Start == 0) return 0; + if (Start == 0 || End == 0) return 0; assert(Start->isDefined() && "Invalid starting label for an inlined scope!"); assert(End->isDefined() && "Invalid end label for an inlined scope!"); @@ -1390,7 +1396,7 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) { DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) { MCSymbol *StartLabel = Scope->getStartLabel(); MCSymbol *EndLabel = Scope->getEndLabel(); - if (StartLabel == 0) return 0; + if (StartLabel == 0 || EndLabel == 0) return 0; assert(StartLabel->isDefined() && "Invalid starting label for an inlined scope!"); @@ -1498,12 +1504,18 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) { MachineLocation Location; Location.set(DbgValueInsn->getOperand(0).getReg()); addAddress(VariableDie, dwarf::DW_AT_location, Location); + if (MCSymbol *VS = DV->getDbgValueLabel()) + addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr, + VS); } else if (DbgValueInsn->getOperand(0).getType() == MachineOperand::MO_Immediate) { DIEBlock *Block = new DIEBlock(); unsigned Imm = DbgValueInsn->getOperand(0).getImm(); addUInt(Block, 0, dwarf::DW_FORM_udata, Imm); addBlock(VariableDie, dwarf::DW_AT_const_value, 0, Block); + if (MCSymbol *VS = DV->getDbgValueLabel()) + addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr, + VS); } else { //FIXME : Handle other operand types. delete VariableDie; @@ -1566,10 +1578,9 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) { else ScopeDIE = updateSubprogramScopeDIE(DS.getNode()); } - else { + else ScopeDIE = constructLexicalScopeDIE(Scope); - if (!ScopeDIE) return NULL; - } + if (!ScopeDIE) return NULL; // Add variables to scope. const SmallVector &Variables = Scope->getVariables(); @@ -1957,10 +1968,11 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var, if (!Scope) return NULL; - AbsDbgVariable = new DbgVariable(Var, MI, + AbsDbgVariable = new DbgVariable(Var, MI, NULL /* No more-abstract variable*/); Scope->addVariable(AbsDbgVariable); AbstractVariables[Var.getNode()] = AbsDbgVariable; + DbgValueStartMap[MI] = AbsDbgVariable; return AbsDbgVariable; } @@ -1998,6 +2010,7 @@ void DwarfDebug::collectVariableInfo() { const MachineInstr *MInsn = II; if (MInsn->getOpcode() != TargetOpcode::DBG_VALUE) continue; + // FIXME : Lift this restriction. if (MInsn->getNumOperands() != 3) continue; @@ -2006,6 +2019,7 @@ void DwarfDebug::collectVariableInfo() { // FIXME Handle inlined subroutine arguments. DbgVariable *ArgVar = new DbgVariable(DV, MInsn, NULL); CurrentFnDbgScope->addVariable(ArgVar); + DbgValueStartMap[MInsn] = ArgVar; continue; } @@ -2020,9 +2034,9 @@ void DwarfDebug::collectVariableInfo() { if (!Scope) continue; - DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn, - ScopeLoc); + DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn, ScopeLoc); DbgVariable *RegVar = new DbgVariable(DV, MInsn, AbsDbgVariable); + DbgValueStartMap[MInsn] = RegVar; Scope->addVariable(RegVar); } } @@ -2030,10 +2044,6 @@ void DwarfDebug::collectVariableInfo() { /// beginScope - Process beginning of a scope. void DwarfDebug::beginScope(const MachineInstr *MI) { - // Ignore DBG_VALUE instructions. - if (MI->getOpcode() == TargetOpcode::DBG_VALUE) - return; - // Check location. DebugLoc DL = MI->getDebugLoc(); if (DL.isUnknown()) @@ -2047,6 +2057,18 @@ void DwarfDebug::beginScope(const MachineInstr *MI) { return; PrevDILoc = DILoc.getNode(); + // DBG_VALUE instruction establishes new value. + if (MI->getOpcode() == TargetOpcode::DBG_VALUE) { + DenseMap::iterator DI + = DbgValueStartMap.find(MI); + if (DI != DbgValueStartMap.end()) { + MCSymbol *Label = recordSourceLine(DILoc.getLineNumber(), + DILoc.getColumnNumber(), + DILoc.getScope().getNode()); + DI->second->setDbgValueLabel(Label); + } + } + // Emit a label to indicate location change. This is used for line // table even if this instruction does start a new scope. MCSymbol *Label = recordSourceLine(DILoc.getLineNumber(), @@ -2062,7 +2084,6 @@ void DwarfDebug::beginScope(const MachineInstr *MI) { for (ScopeVector::iterator SDI = SD.begin(), SDE = SD.end(); SDI != SDE; ++SDI) (*SDI)->setStartLabel(Label); - } /// endScope - Process end of a scope. @@ -2289,6 +2310,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { DeleteContainerSeconds(DbgScopeMap); DbgScopeBeginMap.clear(); DbgScopeEndMap.clear(); + DbgValueStartMap.clear(); ConcreteScopes.clear(); DeleteContainerSeconds(AbstractScopes); AbstractScopesList.clear(); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 4a29091128a..5ab2a0cf2be 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -150,6 +150,12 @@ class DwarfDebug : public DwarfPrinter { /// DbgScopes in AbstractScopes. DenseMap AbstractVariables; + /// DbgValueStartMap - Tracks starting scope of variable DIEs. + /// If the scope of an object begins sometime after the low pc value for the + /// scope most closely enclosing the object, the object entry may have a + /// DW_AT_start_scope attribute. + DenseMap DbgValueStartMap; + /// InliendSubprogramDIEs - Collection of subprgram DIEs that are marked /// (at the end of the module) as DW_AT_inline. SmallPtrSet InlinedSubprogramDIEs; -- 2.34.1