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
This commit is contained in:
Devang Patel 2010-03-29 22:59:58 +00:00
parent f8df3e011c
commit aead63c033
2 changed files with 43 additions and 15 deletions

View File

@ -149,20 +149,26 @@ class DbgVariable {
DIVariable Var; // Variable Descriptor. DIVariable Var; // Variable Descriptor.
unsigned FrameIndex; // Variable frame index. unsigned FrameIndex; // Variable frame index.
const MachineInstr *DbgValueMInsn; // DBG_VALUE const MachineInstr *DbgValueMInsn; // DBG_VALUE
// DbgValueLabel - DBG_VALUE is effective from this label.
MCSymbol *DbgValueLabel;
DbgVariable *const AbstractVar; // Abstract variable for this variable. DbgVariable *const AbstractVar; // Abstract variable for this variable.
DIE *TheDIE; DIE *TheDIE;
public: public:
// AbsVar may be NULL. // AbsVar may be NULL.
DbgVariable(DIVariable V, unsigned I, DbgVariable *AbsVar) 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) 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. // Accessors.
DIVariable getVariable() const { return Var; } DIVariable getVariable() const { return Var; }
unsigned getFrameIndex() const { return FrameIndex; } unsigned getFrameIndex() const { return FrameIndex; }
const MachineInstr *getDbgValue() const { return DbgValueMInsn; } const MachineInstr *getDbgValue() const { return DbgValueMInsn; }
MCSymbol *getDbgValueLabel() const { return DbgValueLabel; }
void setDbgValueLabel(MCSymbol *L) { DbgValueLabel = L; }
DbgVariable *getAbstractVariable() const { return AbstractVar; } DbgVariable *getAbstractVariable() const { return AbstractVar; }
void setDIE(DIE *D) { TheDIE = D; } void setDIE(DIE *D) { TheDIE = D; }
DIE *getDIE() const { return TheDIE; } DIE *getDIE() const { return TheDIE; }
@ -1367,7 +1373,7 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) { DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
MCSymbol *Start = Scope->getStartLabel(); MCSymbol *Start = Scope->getStartLabel();
MCSymbol *End = Scope->getEndLabel(); 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(Start->isDefined() && "Invalid starting label for an inlined scope!");
assert(End->isDefined() && "Invalid end 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) { DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
MCSymbol *StartLabel = Scope->getStartLabel(); MCSymbol *StartLabel = Scope->getStartLabel();
MCSymbol *EndLabel = Scope->getEndLabel(); MCSymbol *EndLabel = Scope->getEndLabel();
if (StartLabel == 0) return 0; if (StartLabel == 0 || EndLabel == 0) return 0;
assert(StartLabel->isDefined() && assert(StartLabel->isDefined() &&
"Invalid starting label for an inlined scope!"); "Invalid starting label for an inlined scope!");
@ -1498,12 +1504,18 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
MachineLocation Location; MachineLocation Location;
Location.set(DbgValueInsn->getOperand(0).getReg()); Location.set(DbgValueInsn->getOperand(0).getReg());
addAddress(VariableDie, dwarf::DW_AT_location, Location); 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() == } else if (DbgValueInsn->getOperand(0).getType() ==
MachineOperand::MO_Immediate) { MachineOperand::MO_Immediate) {
DIEBlock *Block = new DIEBlock(); DIEBlock *Block = new DIEBlock();
unsigned Imm = DbgValueInsn->getOperand(0).getImm(); unsigned Imm = DbgValueInsn->getOperand(0).getImm();
addUInt(Block, 0, dwarf::DW_FORM_udata, Imm); addUInt(Block, 0, dwarf::DW_FORM_udata, Imm);
addBlock(VariableDie, dwarf::DW_AT_const_value, 0, Block); 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 { } else {
//FIXME : Handle other operand types. //FIXME : Handle other operand types.
delete VariableDie; delete VariableDie;
@ -1566,10 +1578,9 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
else else
ScopeDIE = updateSubprogramScopeDIE(DS.getNode()); ScopeDIE = updateSubprogramScopeDIE(DS.getNode());
} }
else { else
ScopeDIE = constructLexicalScopeDIE(Scope); ScopeDIE = constructLexicalScopeDIE(Scope);
if (!ScopeDIE) return NULL; if (!ScopeDIE) return NULL;
}
// Add variables to scope. // Add variables to scope.
const SmallVector<DbgVariable *, 8> &Variables = Scope->getVariables(); const SmallVector<DbgVariable *, 8> &Variables = Scope->getVariables();
@ -1961,6 +1972,7 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
NULL /* No more-abstract variable*/); NULL /* No more-abstract variable*/);
Scope->addVariable(AbsDbgVariable); Scope->addVariable(AbsDbgVariable);
AbstractVariables[Var.getNode()] = AbsDbgVariable; AbstractVariables[Var.getNode()] = AbsDbgVariable;
DbgValueStartMap[MI] = AbsDbgVariable;
return AbsDbgVariable; return AbsDbgVariable;
} }
@ -1998,6 +2010,7 @@ void DwarfDebug::collectVariableInfo() {
const MachineInstr *MInsn = II; const MachineInstr *MInsn = II;
if (MInsn->getOpcode() != TargetOpcode::DBG_VALUE) if (MInsn->getOpcode() != TargetOpcode::DBG_VALUE)
continue; continue;
// FIXME : Lift this restriction. // FIXME : Lift this restriction.
if (MInsn->getNumOperands() != 3) if (MInsn->getNumOperands() != 3)
continue; continue;
@ -2006,6 +2019,7 @@ void DwarfDebug::collectVariableInfo() {
// FIXME Handle inlined subroutine arguments. // FIXME Handle inlined subroutine arguments.
DbgVariable *ArgVar = new DbgVariable(DV, MInsn, NULL); DbgVariable *ArgVar = new DbgVariable(DV, MInsn, NULL);
CurrentFnDbgScope->addVariable(ArgVar); CurrentFnDbgScope->addVariable(ArgVar);
DbgValueStartMap[MInsn] = ArgVar;
continue; continue;
} }
@ -2020,9 +2034,9 @@ void DwarfDebug::collectVariableInfo() {
if (!Scope) if (!Scope)
continue; continue;
DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn, DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn, ScopeLoc);
ScopeLoc);
DbgVariable *RegVar = new DbgVariable(DV, MInsn, AbsDbgVariable); DbgVariable *RegVar = new DbgVariable(DV, MInsn, AbsDbgVariable);
DbgValueStartMap[MInsn] = RegVar;
Scope->addVariable(RegVar); Scope->addVariable(RegVar);
} }
} }
@ -2030,10 +2044,6 @@ void DwarfDebug::collectVariableInfo() {
/// beginScope - Process beginning of a scope. /// beginScope - Process beginning of a scope.
void DwarfDebug::beginScope(const MachineInstr *MI) { void DwarfDebug::beginScope(const MachineInstr *MI) {
// Ignore DBG_VALUE instructions.
if (MI->getOpcode() == TargetOpcode::DBG_VALUE)
return;
// Check location. // Check location.
DebugLoc DL = MI->getDebugLoc(); DebugLoc DL = MI->getDebugLoc();
if (DL.isUnknown()) if (DL.isUnknown())
@ -2047,6 +2057,18 @@ void DwarfDebug::beginScope(const MachineInstr *MI) {
return; return;
PrevDILoc = DILoc.getNode(); PrevDILoc = DILoc.getNode();
// DBG_VALUE instruction establishes new value.
if (MI->getOpcode() == TargetOpcode::DBG_VALUE) {
DenseMap<const MachineInstr *, DbgVariable *>::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 // Emit a label to indicate location change. This is used for line
// table even if this instruction does start a new scope. // table even if this instruction does start a new scope.
MCSymbol *Label = recordSourceLine(DILoc.getLineNumber(), MCSymbol *Label = recordSourceLine(DILoc.getLineNumber(),
@ -2062,7 +2084,6 @@ void DwarfDebug::beginScope(const MachineInstr *MI) {
for (ScopeVector::iterator SDI = SD.begin(), SDE = SD.end(); for (ScopeVector::iterator SDI = SD.begin(), SDE = SD.end();
SDI != SDE; ++SDI) SDI != SDE; ++SDI)
(*SDI)->setStartLabel(Label); (*SDI)->setStartLabel(Label);
} }
/// endScope - Process end of a scope. /// endScope - Process end of a scope.
@ -2289,6 +2310,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
DeleteContainerSeconds(DbgScopeMap); DeleteContainerSeconds(DbgScopeMap);
DbgScopeBeginMap.clear(); DbgScopeBeginMap.clear();
DbgScopeEndMap.clear(); DbgScopeEndMap.clear();
DbgValueStartMap.clear();
ConcreteScopes.clear(); ConcreteScopes.clear();
DeleteContainerSeconds(AbstractScopes); DeleteContainerSeconds(AbstractScopes);
AbstractScopesList.clear(); AbstractScopesList.clear();

View File

@ -150,6 +150,12 @@ class DwarfDebug : public DwarfPrinter {
/// DbgScopes in AbstractScopes. /// DbgScopes in AbstractScopes.
DenseMap<MDNode *, DbgVariable *> AbstractVariables; DenseMap<MDNode *, DbgVariable *> 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<const MachineInstr *, DbgVariable *> DbgValueStartMap;
/// InliendSubprogramDIEs - Collection of subprgram DIEs that are marked /// InliendSubprogramDIEs - Collection of subprgram DIEs that are marked
/// (at the end of the module) as DW_AT_inline. /// (at the end of the module) as DW_AT_inline.
SmallPtrSet<DIE *, 4> InlinedSubprogramDIEs; SmallPtrSet<DIE *, 4> InlinedSubprogramDIEs;