Emit dwarf variable info communicated by code generator through DBG_VALUE machine instructions.

This is a work in progress.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98556 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel 2010-03-15 18:33:46 +00:00
parent fc6e69bcb2
commit 90a48adf9c
4 changed files with 107 additions and 14 deletions

View File

@ -1309,6 +1309,8 @@ void AsmPrinter::processDebugLoc(const MachineInstr *MI,
if (!MAI || !DW || !MAI->doesSupportDebugInformation() if (!MAI || !DW || !MAI->doesSupportDebugInformation()
|| !DW->ShouldEmitDwarfDebug()) || !DW->ShouldEmitDwarfDebug())
return; return;
if (MI->getOpcode() == TargetOpcode::DBG_VALUE)
return;
DebugLoc DL = MI->getDebugLoc(); DebugLoc DL = MI->getDebugLoc();
if (DL.isUnknown()) if (DL.isUnknown())
return; return;

View File

@ -148,16 +148,21 @@ public:
class DbgVariable { 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
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), AbstractVar(AbsVar), TheDIE(0) {} : Var(V), FrameIndex(I), DbgValueMInsn(0), AbstractVar(AbsVar), TheDIE(0) {}
DbgVariable(DIVariable V, const MachineInstr *MI, DbgVariable *AbsVar)
: Var(V), FrameIndex(0), DbgValueMInsn(MI), 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; }
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; }
@ -1493,6 +1498,29 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
// Add variable address. // Add variable address.
if (!Scope->isAbstractScope()) { if (!Scope->isAbstractScope()) {
// Check if variable is described by DBG_VALUE instruction.
if (const MachineInstr *DbgValueInsn = DV->getDbgValue()) {
if (DbgValueInsn->getNumOperands() == 3) {
// FIXME : Handle getNumOperands != 3
if (DbgValueInsn->getOperand(0).getType()
== MachineOperand::MO_Register
&& DbgValueInsn->getOperand(0).getReg()) {
MachineLocation Location;
Location.set(DbgValueInsn->getOperand(0).getReg());
addAddress(VariableDie, dwarf::DW_AT_location, Location);
} 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);
} else {
//FIXME : Handle other operand types.
delete VariableDie;
return NULL;
}
}
} else {
MachineLocation Location; MachineLocation Location;
unsigned FrameReg; unsigned FrameReg;
int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(), FrameReg); int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(), FrameReg);
@ -1505,6 +1533,7 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
else else
addAddress(VariableDie, dwarf::DW_AT_location, Location); addAddress(VariableDie, dwarf::DW_AT_location, Location);
} }
}
if (Tag == dwarf::DW_TAG_formal_parameter && VD.getType().isArtificial()) if (Tag == dwarf::DW_TAG_formal_parameter && VD.getType().isArtificial())
addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
@ -1928,6 +1957,27 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
return AbsDbgVariable; return AbsDbgVariable;
} }
/// findAbstractVariable - Find abstract variable, if any, associated with Var.
/// FIXME : Refactor findAbstractVariable.
DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
const MachineInstr *MI,
DILocation &ScopeLoc) {
DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var.getNode());
if (AbsDbgVariable)
return AbsDbgVariable;
DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope().getNode());
if (!Scope)
return NULL;
AbsDbgVariable = new DbgVariable(Var, MI,
NULL /* No more-abstract variable*/);
Scope->addVariable(AbsDbgVariable);
AbstractVariables[Var.getNode()] = AbsDbgVariable;
return AbsDbgVariable;
}
/// collectVariableInfo - Populate DbgScope entries with variables' info. /// collectVariableInfo - Populate DbgScope entries with variables' info.
void DwarfDebug::collectVariableInfo() { void DwarfDebug::collectVariableInfo() {
if (!MMI) return; if (!MMI) return;
@ -1953,6 +2003,43 @@ void DwarfDebug::collectVariableInfo() {
DbgVariable *RegVar = new DbgVariable(DV, VP.first, AbsDbgVariable); DbgVariable *RegVar = new DbgVariable(DV, VP.first, AbsDbgVariable);
Scope->addVariable(RegVar); Scope->addVariable(RegVar);
} }
// Collect variable information from DBG_VALUE machine instructions;
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
I != E; ++I) {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
const MachineInstr *MInsn = II;
if (MInsn->getOpcode() != TargetOpcode::DBG_VALUE)
continue;
// FIXME : Lift this restriction.
if (MInsn->getNumOperands() != 3)
continue;
DIVariable DV((MDNode*)(MInsn->getOperand(MInsn->getNumOperands() - 1).getMetadata()));
if (DV.getTag() == dwarf::DW_TAG_arg_variable) {
// FIXME Handle inlined subroutine arguments.
DbgVariable *ArgVar = new DbgVariable(DV, MInsn, NULL);
CurrentFnDbgScope->addVariable(ArgVar);
continue;
}
DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) continue;
DILocation ScopeLoc = MF->getDILocation(DL);
DbgScope *Scope =
ConcreteScopes.lookup(ScopeLoc.getOrigLocation().getNode());
if (!Scope)
Scope = DbgScopeMap.lookup(ScopeLoc.getScope().getNode());
// If variable scope is not found then skip this variable.
if (!Scope)
continue;
DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn,
ScopeLoc);
DbgVariable *RegVar = new DbgVariable(DV, MInsn, AbsDbgVariable);
Scope->addVariable(RegVar);
}
}
} }
/// beginScope - Process beginning of a scope starting at Label. /// beginScope - Process beginning of a scope starting at Label.
@ -2022,6 +2109,8 @@ bool DwarfDebug::extractScopeInformation() {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) { II != IE; ++II) {
const MachineInstr *MInsn = II; const MachineInstr *MInsn = II;
// FIXME : Remove DBG_VALUE check.
if (MInsn->getOpcode() == TargetOpcode::DBG_VALUE) continue;
MIIndexMap[MInsn] = MIIndex++; MIIndexMap[MInsn] = MIIndex++;
DebugLoc DL = MInsn->getDebugLoc(); DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) continue; if (DL.isUnknown()) continue;
@ -2042,6 +2131,8 @@ bool DwarfDebug::extractScopeInformation() {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) { II != IE; ++II) {
const MachineInstr *MInsn = II; const MachineInstr *MInsn = II;
// FIXME : Remove DBG_VALUE check.
if (MInsn->getOpcode() == TargetOpcode::DBG_VALUE) continue;
DebugLoc DL = MInsn->getDebugLoc(); DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) continue; if (DL.isUnknown()) continue;
DILocation DLT = MF->getDILocation(DL); DILocation DLT = MF->getDILocation(DL);

View File

@ -361,6 +361,8 @@ class DwarfDebug : public DwarfPrinter {
/// findAbstractVariable - Find abstract variable associated with Var. /// findAbstractVariable - Find abstract variable associated with Var.
DbgVariable *findAbstractVariable(DIVariable &Var, unsigned FrameIdx, DbgVariable *findAbstractVariable(DIVariable &Var, unsigned FrameIdx,
DILocation &Loc); DILocation &Loc);
DbgVariable *findAbstractVariable(DIVariable &Var, const MachineInstr *MI,
DILocation &Loc);
/// updateSubprogramScopeDIE - Find DIE for the given subprogram and /// updateSubprogramScopeDIE - Find DIE for the given subprogram and
/// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes. /// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes.

View File

@ -368,8 +368,6 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
static void SetDebugLoc(unsigned MDDbgKind, Instruction *I, static void SetDebugLoc(unsigned MDDbgKind, Instruction *I,
SelectionDAGBuilder *SDB, SelectionDAGBuilder *SDB,
FastISel *FastIS, MachineFunction *MF) { FastISel *FastIS, MachineFunction *MF) {
if (isa<DbgInfoIntrinsic>(I)) return;
if (MDNode *Dbg = I->getMetadata(MDDbgKind)) { if (MDNode *Dbg = I->getMetadata(MDDbgKind)) {
DILocation DILoc(Dbg); DILocation DILoc(Dbg);
DebugLoc Loc = ExtractDebugLocation(DILoc, MF->getDebugLocInfo()); DebugLoc Loc = ExtractDebugLocation(DILoc, MF->getDebugLocInfo());