Start using LexicalScopes utility. No intetional functionality change.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137246 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel
2011-08-10 20:55:27 +00:00
parent 53642c5335
commit bf47fdb91c
2 changed files with 113 additions and 526 deletions

View File

@ -45,9 +45,6 @@
#include "llvm/Support/Path.h" #include "llvm/Support/Path.h"
using namespace llvm; using namespace llvm;
static cl::opt<bool> PrintDbgScope("print-dbgscope", cl::Hidden,
cl::desc("Print DbgScope information for each machine instruction"));
static cl::opt<bool> DisableDebugInfoPrinting("disable-debug-info-print", static cl::opt<bool> DisableDebugInfoPrinting("disable-debug-info-print",
cl::Hidden, cl::Hidden,
cl::desc("Disable debug info printing")); cl::desc("Disable debug info printing"));
@ -120,143 +117,12 @@ DIType DbgVariable::getType() const {
return Ty; return Ty;
} }
//===----------------------------------------------------------------------===//
/// DbgRange - This is used to track range of instructions with identical
/// debug info scope.
///
typedef std::pair<const MachineInstr *, const MachineInstr *> DbgRange;
//===----------------------------------------------------------------------===//
/// DbgScope - This class is used to track scope information.
///
class DbgScope {
DbgScope *Parent; // Parent to this scope.
DIDescriptor Desc; // Debug info descriptor for scope.
// Location at which this scope is inlined.
AssertingVH<const MDNode> InlinedAtLocation;
bool AbstractScope; // Abstract Scope
const MachineInstr *LastInsn; // Last instruction of this scope.
const MachineInstr *FirstInsn; // First instruction of this scope.
unsigned DFSIn, DFSOut;
// Scopes defined in scope. Contents not owned.
SmallVector<DbgScope *, 4> Scopes;
// Variables declared in scope. Contents owned.
SmallVector<DbgVariable *, 8> Variables;
SmallVector<DbgRange, 4> Ranges;
// Private state for dump()
mutable unsigned IndentLevel;
public:
DbgScope(DbgScope *P, DIDescriptor D, const MDNode *I = 0)
: Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(false),
LastInsn(0), FirstInsn(0),
DFSIn(0), DFSOut(0), IndentLevel(0) {
if (Parent)
Parent->addScope(this);
}
virtual ~DbgScope();
// Accessors.
DbgScope *getParent() const { return Parent; }
DIDescriptor getDesc() const { return Desc; }
const MDNode *getInlinedAt() const { return InlinedAtLocation; }
const MDNode *getScopeNode() const { return Desc; }
const SmallVector<DbgScope *, 4> &getScopes() { return Scopes; }
const SmallVector<DbgVariable *, 8> &getDbgVariables() { return Variables; }
const SmallVector<DbgRange, 4> &getRanges() { return Ranges; }
/// openInsnRange - This scope covers instruction range starting from MI.
void openInsnRange(const MachineInstr *MI) {
if (!FirstInsn)
FirstInsn = MI;
if (Parent)
Parent->openInsnRange(MI);
}
/// extendInsnRange - Extend the current instruction range covered by
/// this scope.
void extendInsnRange(const MachineInstr *MI) {
assert (FirstInsn && "MI Range is not open!");
LastInsn = MI;
if (Parent)
Parent->extendInsnRange(MI);
}
/// closeInsnRange - Create a range based on FirstInsn and LastInsn collected
/// until now. This is used when a new scope is encountered while walking
/// machine instructions.
void closeInsnRange(DbgScope *NewScope = NULL) {
assert (LastInsn && "Last insn missing!");
Ranges.push_back(DbgRange(FirstInsn, LastInsn));
FirstInsn = NULL;
LastInsn = NULL;
// If Parent dominates NewScope then do not close Parent's instruction
// range.
if (Parent && (!NewScope || !Parent->dominates(NewScope)))
Parent->closeInsnRange(NewScope);
}
void setAbstractScope() { AbstractScope = true; }
bool isAbstractScope() const { return AbstractScope; }
// Depth First Search support to walk and manipulate DbgScope hierarchy.
unsigned getDFSOut() const { return DFSOut; }
void setDFSOut(unsigned O) { DFSOut = O; }
unsigned getDFSIn() const { return DFSIn; }
void setDFSIn(unsigned I) { DFSIn = I; }
bool dominates(const DbgScope *S) {
if (S == this)
return true;
if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut())
return true;
return false;
}
/// addScope - Add a scope to the scope.
///
void addScope(DbgScope *S) { Scopes.push_back(S); }
/// addVariable - Add a variable to the scope.
///
void addVariable(DbgVariable *V) { Variables.push_back(V); }
#ifndef NDEBUG
void dump() const;
#endif
};
} // end llvm namespace } // end llvm namespace
#ifndef NDEBUG
void DbgScope::dump() const {
raw_ostream &err = dbgs();
err.indent(IndentLevel);
err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n";
const MDNode *N = Desc;
N->dump();
if (AbstractScope)
err << "Abstract Scope\n";
IndentLevel += 2;
if (!Scopes.empty())
err << "Children ...\n";
for (unsigned i = 0, e = Scopes.size(); i != e; ++i)
if (Scopes[i] != this)
Scopes[i]->dump();
IndentLevel -= 2;
}
#endif
DbgScope::~DbgScope() {
for (unsigned j = 0, M = Variables.size(); j < M; ++j)
delete Variables[j];
}
DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
: Asm(A), MMI(Asm->MMI), FirstCU(0), : Asm(A), MMI(Asm->MMI), FirstCU(0),
AbbreviationsSet(InitAbbreviationsSetSize), AbbreviationsSet(InitAbbreviationsSetSize),
CurrentFnDbgScope(0), PrevLabel(NULL) { PrevLabel(NULL) {
NextStringPoolNumber = 0; NextStringPoolNumber = 0;
DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0; DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0;
@ -408,29 +274,6 @@ DIE *DwarfDebug::createSubprogramDIE(DISubprogram SP) {
return SPDie; return SPDie;
} }
DbgScope *DwarfDebug::getOrCreateAbstractScope(const MDNode *N) {
assert(N && "Invalid Scope encoding!");
DbgScope *AScope = AbstractScopes.lookup(N);
if (AScope)
return AScope;
DbgScope *Parent = NULL;
DIDescriptor Scope(N);
if (Scope.isLexicalBlock()) {
DILexicalBlock DB(N);
DIDescriptor ParentDesc = DB.getContext();
Parent = getOrCreateAbstractScope(ParentDesc);
}
AScope = new DbgScope(Parent, DIDescriptor(N), NULL);
AScope->setAbstractScope();
AbstractScopes[N] = AScope;
if (DIDescriptor(N).isSubprogram())
AbstractScopesList.push_back(AScope);
return AScope;
}
/// isSubprogramContext - Return true if Context is either a subprogram /// isSubprogramContext - Return true if Context is either a subprogram
/// or another context nested inside a subprogram. /// or another context nested inside a subprogram.
static bool isSubprogramContext(const MDNode *Context) { static bool isSubprogramContext(const MDNode *Context) {
@ -512,25 +355,25 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(const MDNode *SPNode) {
/// constructLexicalScope - Construct new DW_TAG_lexical_block /// constructLexicalScope - Construct new DW_TAG_lexical_block
/// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels. /// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels.
DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) { DIE *DwarfDebug::constructLexicalScopeDIE(LexicalScope *Scope) {
DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block); DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block);
if (Scope->isAbstractScope()) if (Scope->isAbstractScope())
return ScopeDIE; return ScopeDIE;
const SmallVector<DbgRange, 4> &Ranges = Scope->getRanges(); const SmallVector<InsnRange, 4> &Ranges = Scope->getRanges();
if (Ranges.empty()) if (Ranges.empty())
return 0; return 0;
CompileUnit *TheCU = getCompileUnit(Scope->getScopeNode()); CompileUnit *TheCU = getCompileUnit(Scope->getScopeNode());
SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(); SmallVector<InsnRange, 4>::const_iterator RI = Ranges.begin();
if (Ranges.size() > 1) { if (Ranges.size() > 1) {
// .debug_range section has not been laid out yet. Emit offset in // .debug_range section has not been laid out yet. Emit offset in
// .debug_range as a uint, size 4, for now. emitDIE will handle // .debug_range as a uint, size 4, for now. emitDIE will handle
// DW_AT_ranges appropriately. // DW_AT_ranges appropriately.
TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4, TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
DebugRangeSymbols.size() * Asm->getTargetData().getPointerSize()); DebugRangeSymbols.size() * Asm->getTargetData().getPointerSize());
for (SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(), for (SmallVector<InsnRange, 4>::const_iterator RI = Ranges.begin(),
RE = Ranges.end(); RI != RE; ++RI) { RE = Ranges.end(); RI != RE; ++RI) {
DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first)); DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first));
DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second)); DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second));
@ -557,11 +400,11 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
/// constructInlinedScopeDIE - This scope represents inlined body of /// constructInlinedScopeDIE - This scope represents inlined body of
/// a function. Construct DIE to represent this concrete inlined copy /// a function. Construct DIE to represent this concrete inlined copy
/// of the function. /// of the function.
DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) { DIE *DwarfDebug::constructInlinedScopeDIE(LexicalScope *Scope) {
const SmallVector<DbgRange, 4> &Ranges = Scope->getRanges(); const SmallVector<InsnRange, 4> &Ranges = Scope->getRanges();
assert (Ranges.empty() == false assert (Ranges.empty() == false
&& "DbgScope does not have instruction markers!"); && "LexicalScope does not have instruction markers!");
if (!Scope->getScopeNode()) if (!Scope->getScopeNode())
return NULL; return NULL;
@ -574,7 +417,7 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
return NULL; return NULL;
} }
SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(); SmallVector<InsnRange, 4>::const_iterator RI = Ranges.begin();
const MCSymbol *StartLabel = getLabelBeforeInsn(RI->first); const MCSymbol *StartLabel = getLabelBeforeInsn(RI->first);
const MCSymbol *EndLabel = getLabelAfterInsn(RI->second); const MCSymbol *EndLabel = getLabelAfterInsn(RI->second);
@ -597,7 +440,7 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
// DW_AT_ranges appropriately. // DW_AT_ranges appropriately.
TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4, TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
DebugRangeSymbols.size() * Asm->getTargetData().getPointerSize()); DebugRangeSymbols.size() * Asm->getTargetData().getPointerSize());
for (SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(), for (SmallVector<InsnRange, 4>::const_iterator RI = Ranges.begin(),
RE = Ranges.end(); RI != RE; ++RI) { RE = Ranges.end(); RI != RE; ++RI) {
DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first)); DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first));
DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second)); DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second));
@ -650,7 +493,7 @@ static bool isUnsignedDIType(DIType Ty) {
} }
/// constructVariableDIE - Construct a DIE for the given DbgVariable. /// constructVariableDIE - Construct a DIE for the given DbgVariable.
DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) { DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, LexicalScope *Scope) {
StringRef Name = DV->getName(); StringRef Name = DV->getName();
if (Name.empty()) if (Name.empty())
return NULL; return NULL;
@ -784,25 +627,25 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
} }
/// constructScopeDIE - Construct a DIE for this scope. /// constructScopeDIE - Construct a DIE for this scope.
DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) { DIE *DwarfDebug::constructScopeDIE(LexicalScope *Scope) {
if (!Scope || !Scope->getScopeNode()) if (!Scope || !Scope->getScopeNode())
return NULL; return NULL;
SmallVector <DIE *, 8> Children; SmallVector <DIE *, 8> Children;
// Collect arguments for current function. // Collect arguments for current function.
if (Scope == CurrentFnDbgScope) if (LScopes.isCurrentFunctionScope(Scope))
for (unsigned i = 0, N = CurrentFnArguments.size(); i < N; ++i) for (unsigned i = 0, N = CurrentFnArguments.size(); i < N; ++i)
if (DbgVariable *ArgDV = CurrentFnArguments[i]) if (DbgVariable *ArgDV = CurrentFnArguments[i])
if (DIE *Arg = constructVariableDIE(ArgDV, Scope)) if (DIE *Arg = constructVariableDIE(ArgDV, Scope))
Children.push_back(Arg); Children.push_back(Arg);
// Collect lexical scope childrens first. // Collect lexical scope childrens first.
const SmallVector<DbgVariable *, 8> &Variables = Scope->getDbgVariables(); const SmallVector<DbgVariable *, 8> &Variables = ScopeVariables.lookup(Scope);
for (unsigned i = 0, N = Variables.size(); i < N; ++i) for (unsigned i = 0, N = Variables.size(); i < N; ++i)
if (DIE *Variable = constructVariableDIE(Variables[i], Scope)) if (DIE *Variable = constructVariableDIE(Variables[i], Scope))
Children.push_back(Variable); Children.push_back(Variable);
const SmallVector<DbgScope *, 4> &Scopes = Scope->getScopes(); const SmallVector<LexicalScope *, 4> &Scopes = Scope->getChildren();
for (unsigned j = 0, M = Scopes.size(); j < M; ++j) for (unsigned j = 0, M = Scopes.size(); j < M; ++j)
if (DIE *Nested = constructScopeDIE(Scopes[j])) if (DIE *Nested = constructScopeDIE(Scopes[j]))
Children.push_back(Nested); Children.push_back(Nested);
@ -1176,7 +1019,7 @@ void DwarfDebug::beginModule(Module *M) {
void DwarfDebug::endModule() { void DwarfDebug::endModule() {
if (!FirstCU) return; if (!FirstCU) return;
const Module *M = MMI->getModule(); const Module *M = MMI->getModule();
DenseMap<const MDNode *, DbgScope *> DeadFnScopeMap; DenseMap<const MDNode *, LexicalScope *> DeadFnScopeMap;
if (NamedMDNode *AllSPs = M->getNamedMetadata("llvm.dbg.sp")) { if (NamedMDNode *AllSPs = M->getNamedMetadata("llvm.dbg.sp")) {
for (unsigned SI = 0, SE = AllSPs->getNumOperands(); SI != SE; ++SI) { for (unsigned SI = 0, SE = AllSPs->getNumOperands(); SI != SE; ++SI) {
if (ProcessedSPNodes.count(AllSPs->getOperand(SI)) != 0) continue; if (ProcessedSPNodes.count(AllSPs->getOperand(SI)) != 0) continue;
@ -1192,21 +1035,20 @@ void DwarfDebug::endModule() {
if (!NMD) continue; if (!NMD) continue;
unsigned E = NMD->getNumOperands(); unsigned E = NMD->getNumOperands();
if (!E) continue; if (!E) continue;
DbgScope *Scope = new DbgScope(NULL, DIDescriptor(SP), NULL); LexicalScope *Scope = new LexicalScope(NULL, DIDescriptor(SP), NULL, false);
DeadFnScopeMap[SP] = Scope; DeadFnScopeMap[SP] = Scope;
SmallVector<DbgVariable *, 8> Variables;
for (unsigned I = 0; I != E; ++I) { for (unsigned I = 0; I != E; ++I) {
DIVariable DV(NMD->getOperand(I)); DIVariable DV(NMD->getOperand(I));
if (!DV.Verify()) continue; if (!DV.Verify()) continue;
Scope->addVariable(new DbgVariable(DV)); Variables.push_back(new DbgVariable(DV));
} }
// Construct subprogram DIE and add variables DIEs. // Construct subprogram DIE and add variables DIEs.
constructSubprogramDIE(SP); constructSubprogramDIE(SP);
DIE *ScopeDIE = getCompileUnit(SP)->getDIE(SP); DIE *ScopeDIE = getCompileUnit(SP)->getDIE(SP);
const SmallVector<DbgVariable *, 8> &Variables = Scope->getDbgVariables();
for (unsigned i = 0, N = Variables.size(); i < N; ++i) { for (unsigned i = 0, N = Variables.size(); i < N; ++i) {
DIE *VariableDIE = constructVariableDIE(Variables[i], Scope); if (DIE *VariableDIE = constructVariableDIE(Variables[i], Scope))
if (VariableDIE)
ScopeDIE->addChild(VariableDIE); ScopeDIE->addChild(VariableDIE);
} }
} }
@ -1284,20 +1126,23 @@ void DwarfDebug::endModule() {
} }
/// findAbstractVariable - Find abstract variable, if any, associated with Var. /// findAbstractVariable - Find abstract variable, if any, associated with Var.
DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var, DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV,
DebugLoc ScopeLoc) { DebugLoc ScopeLoc) {
LLVMContext &Ctx = DV->getContext();
// More then one inlined variable corresponds to one abstract variable.
DIVariable Var = cleanseInlinedVariable(DV, Ctx);
DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var); DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var);
if (AbsDbgVariable) if (AbsDbgVariable)
return AbsDbgVariable; return AbsDbgVariable;
LLVMContext &Ctx = Var->getContext(); LexicalScope *Scope = LScopes.findAbstractScope(ScopeLoc.getScope(Ctx));
DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope(Ctx));
if (!Scope) if (!Scope)
return NULL; return NULL;
AbsDbgVariable = new DbgVariable(Var); AbsDbgVariable = new DbgVariable(Var);
Scope->addVariable(AbsDbgVariable); addScopeVariable(Scope, AbsDbgVariable);
AbstractVariables[Var] = AbsDbgVariable; AbstractVariables[Var] = AbsDbgVariable;
return AbsDbgVariable; return AbsDbgVariable;
} }
@ -1305,8 +1150,8 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
/// addCurrentFnArgument - If Var is a current function argument then add /// addCurrentFnArgument - If Var is a current function argument then add
/// it to CurrentFnArguments list. /// it to CurrentFnArguments list.
bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF, bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF,
DbgVariable *Var, DbgScope *Scope) { DbgVariable *Var, LexicalScope *Scope) {
if (Scope != CurrentFnDbgScope) if (!LScopes.isCurrentFunctionScope(Scope))
return false; return false;
DIVariable DV = Var->getVariable(); DIVariable DV = Var->getVariable();
if (DV.getTag() != dwarf::DW_TAG_arg_variable) if (DV.getTag() != dwarf::DW_TAG_arg_variable)
@ -1340,7 +1185,7 @@ DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction *MF,
DIVariable DV(Var); DIVariable DV(Var);
const std::pair<unsigned, DebugLoc> &VP = VI->second; const std::pair<unsigned, DebugLoc> &VP = VI->second;
DbgScope *Scope = findDbgScope(VP.second); LexicalScope *Scope = LScopes.findLexicalScope(VP.second);
// If variable scope is not found then skip this variable. // If variable scope is not found then skip this variable.
if (Scope == 0) if (Scope == 0)
@ -1350,7 +1195,7 @@ DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction *MF,
DbgVariable *RegVar = new DbgVariable(DV); DbgVariable *RegVar = new DbgVariable(DV);
recordVariableFrameIndex(RegVar, VP.first); recordVariableFrameIndex(RegVar, VP.first);
if (!addCurrentFnArgument(MF, RegVar, Scope)) if (!addCurrentFnArgument(MF, RegVar, Scope))
Scope->addVariable(RegVar); addScopeVariable(Scope, RegVar);
if (AbsDbgVariable) { if (AbsDbgVariable) {
recordVariableFrameIndex(AbsDbgVariable, VP.first); recordVariableFrameIndex(AbsDbgVariable, VP.first);
VarToAbstractVarMap[RegVar] = AbsDbgVariable; VarToAbstractVarMap[RegVar] = AbsDbgVariable;
@ -1395,7 +1240,7 @@ static DotDebugLocEntry getDebugLocEntry(AsmPrinter *Asm,
return DotDebugLocEntry(); return DotDebugLocEntry();
} }
/// collectVariableInfo - Populate DbgScope entries with variables' info. /// collectVariableInfo - Find variables for each lexical scope.
void void
DwarfDebug::collectVariableInfo(const MachineFunction *MF, DwarfDebug::collectVariableInfo(const MachineFunction *MF,
SmallPtrSet<const MDNode *, 16> &Processed) { SmallPtrSet<const MDNode *, 16> &Processed) {
@ -1418,18 +1263,18 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
const MachineInstr *MInsn = History.front(); const MachineInstr *MInsn = History.front();
DIVariable DV(Var); DIVariable DV(Var);
DbgScope *Scope = NULL; LexicalScope *Scope = NULL;
if (DV.getTag() == dwarf::DW_TAG_arg_variable && if (DV.getTag() == dwarf::DW_TAG_arg_variable &&
DISubprogram(DV.getContext()).describes(MF->getFunction())) DISubprogram(DV.getContext()).describes(MF->getFunction()))
Scope = CurrentFnDbgScope; Scope = LScopes.getCurrentFunctionScope();
else { else {
if (DV.getVersion() <= LLVMDebugVersion9) if (DV.getVersion() <= LLVMDebugVersion9)
Scope = findDbgScope(MInsn->getDebugLoc()); Scope = LScopes.findLexicalScope(MInsn->getDebugLoc());
else { else {
if (MDNode *IA = DV.getInlinedAt()) if (MDNode *IA = DV.getInlinedAt())
Scope = InlinedDbgScopeMap.lookup(DebugLoc::getFromDILocation(IA)); Scope = LScopes.findInlinedScope(DebugLoc::getFromDILocation(IA));
else else
Scope = DbgScopeMap.lookup(cast<MDNode>(DV->getOperand(1))); Scope = LScopes.findLexicalScope(cast<MDNode>(DV->getOperand(1)));
} }
} }
// If variable scope is not found then skip this variable. // If variable scope is not found then skip this variable.
@ -1440,7 +1285,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
assert(MInsn->isDebugValue() && "History must begin with debug value"); assert(MInsn->isDebugValue() && "History must begin with debug value");
DbgVariable *RegVar = new DbgVariable(DV); DbgVariable *RegVar = new DbgVariable(DV);
if (!addCurrentFnArgument(MF, RegVar, Scope)) if (!addCurrentFnArgument(MF, RegVar, Scope))
Scope->addVariable(RegVar); addScopeVariable(Scope, RegVar);
if (DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc())) { if (DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc())) {
DbgVariableToDbgInstMap[AbsVar] = MInsn; DbgVariableToDbgInstMap[AbsVar] = MInsn;
VarToAbstractVarMap[RegVar] = AbsVar; VarToAbstractVarMap[RegVar] = AbsVar;
@ -1501,9 +1346,8 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
DIVariable DV(cast<MDNode>(NMD->getOperand(i))); DIVariable DV(cast<MDNode>(NMD->getOperand(i)));
if (!DV || !Processed.insert(DV)) if (!DV || !Processed.insert(DV))
continue; continue;
DbgScope *Scope = DbgScopeMap.lookup(DV.getContext()); if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext()))
if (Scope) addScopeVariable(Scope, new DbgVariable(DV));
Scope->addVariable(new DbgVariable(DV));
} }
} }
} }
@ -1585,253 +1429,33 @@ void DwarfDebug::endInstruction(const MachineInstr *MI) {
I->second = PrevLabel; I->second = PrevLabel;
} }
/// getOrCreateRegularScope - Create regular DbgScope.
DbgScope *DwarfDebug::getOrCreateRegularScope(MDNode *Scope) {
DbgScope *WScope = DbgScopeMap.lookup(Scope);
if (WScope)
return WScope;
DbgScope *Parent = NULL;
if (DIDescriptor(Scope).isLexicalBlock())
Parent = getOrCreateDbgScope(DebugLoc::getFromDILexicalBlock(Scope));
WScope = new DbgScope(Parent, DIDescriptor(Scope), NULL);
DbgScopeMap.insert(std::make_pair(Scope, WScope));
if (!Parent && DIDescriptor(Scope).isSubprogram()
&& DISubprogram(Scope).describes(Asm->MF->getFunction()))
CurrentFnDbgScope = WScope;
return WScope;
}
/// getOrCreateInlinedScope - Create inlined scope.
DbgScope *DwarfDebug::getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt){
DbgScope *InlinedScope = DbgScopeMap.lookup(InlinedAt);
if (InlinedScope)
return InlinedScope;
DebugLoc InlinedLoc = DebugLoc::getFromDILocation(InlinedAt);
InlinedScope = new DbgScope(getOrCreateDbgScope(InlinedLoc),
DIDescriptor(Scope), InlinedAt);
InlinedDbgScopeMap[InlinedLoc] = InlinedScope;
DbgScopeMap[InlinedAt] = InlinedScope;
return InlinedScope;
}
/// getOrCreateDbgScope - Create DbgScope for the scope.
DbgScope *DwarfDebug::getOrCreateDbgScope(DebugLoc DL) {
LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
MDNode *Scope = NULL;
MDNode *InlinedAt = NULL;
DL.getScopeAndInlinedAt(Scope, InlinedAt, Ctx);
if (!InlinedAt)
return getOrCreateRegularScope(Scope);
// Create an abstract scope for inlined function.
getOrCreateAbstractScope(Scope);
// Create an inlined scope for inlined function.
return getOrCreateInlinedScope(Scope, InlinedAt);
}
/// calculateDominanceGraph - Calculate dominance graph for DbgScope
/// hierarchy.
static void calculateDominanceGraph(DbgScope *Scope) {
assert (Scope && "Unable to calculate scop edominance graph!");
SmallVector<DbgScope *, 4> WorkStack;
WorkStack.push_back(Scope);
unsigned Counter = 0;
while (!WorkStack.empty()) {
DbgScope *WS = WorkStack.back();
const SmallVector<DbgScope *, 4> &Children = WS->getScopes();
bool visitedChildren = false;
for (SmallVector<DbgScope *, 4>::const_iterator SI = Children.begin(),
SE = Children.end(); SI != SE; ++SI) {
DbgScope *ChildScope = *SI;
if (!ChildScope->getDFSOut()) {
WorkStack.push_back(ChildScope);
visitedChildren = true;
ChildScope->setDFSIn(++Counter);
#ifndef NDEBUG
if (PrintDbgScope)
dbgs() << "calculate dbgscope dom: In " << Counter << "\n";
#endif
break;
}
}
if (!visitedChildren) {
WorkStack.pop_back();
WS->setDFSOut(++Counter);
#ifndef NDEBUG
if (PrintDbgScope)
dbgs() << "calculate dbgscope dom: In " << WS->getDFSIn()
<< " Out " << Counter << "\n";
#endif
}
}
}
/// printDbgScopeInfo - Print DbgScope info for each machine instruction.
static
void printDbgScopeInfo(const MachineFunction *MF,
DenseMap<const MachineInstr *, DbgScope *> &MI2ScopeMap)
{
#ifndef NDEBUG
LLVMContext &Ctx = MF->getFunction()->getContext();
unsigned PrevDFSIn = 0;
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;
MDNode *Scope = NULL;
MDNode *InlinedAt = NULL;
// Check if instruction has valid location information.
DebugLoc MIDL = MInsn->getDebugLoc();
if (!MIDL.isUnknown()) {
MIDL.getScopeAndInlinedAt(Scope, InlinedAt, Ctx);
dbgs() << " [ ";
if (InlinedAt)
dbgs() << "*";
DenseMap<const MachineInstr *, DbgScope *>::iterator DI =
MI2ScopeMap.find(MInsn);
if (DI != MI2ScopeMap.end()) {
DbgScope *S = DI->second;
dbgs() << S->getDFSIn();
PrevDFSIn = S->getDFSIn();
} else
dbgs() << PrevDFSIn;
} else
dbgs() << " [ x" << PrevDFSIn;
dbgs() << " ]";
MInsn->dump();
}
dbgs() << "\n";
}
#endif
}
/// extractScopeInformation - Scan machine instructions in this function
/// and collect DbgScopes. Return true, if at least one scope was found.
bool DwarfDebug::extractScopeInformation() {
// If scope information was extracted using .dbg intrinsics then there is not
// any need to extract these information by scanning each instruction.
if (!DbgScopeMap.empty())
return false;
// Scan each instruction and create scopes. First build working set of scopes.
SmallVector<DbgRange, 4> MIRanges;
DenseMap<const MachineInstr *, DbgScope *> MI2ScopeMap;
for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
I != E; ++I) {
const MachineInstr *RangeBeginMI = NULL;
const MachineInstr *PrevMI = NULL;
DebugLoc PrevDL;
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
const MachineInstr *MInsn = II;
// Check if instruction has valid location information.
const DebugLoc MIDL = MInsn->getDebugLoc();
if (MIDL.isUnknown()) {
PrevMI = MInsn;
continue;
}
// If scope has not changed then skip this instruction.
if (MIDL == PrevDL) {
PrevMI = MInsn;
continue;
}
// Ignore DBG_VALUE. It does not contribute to any instruction in output.
if (MInsn->isDebugValue())
continue;
if (RangeBeginMI) {
// If we have already seen a beginning of an instruction range and
// current instruction scope does not match scope of first instruction
// in this range then create a new instruction range.
DEBUG(dbgs() << "Creating new instruction range :\n");
DEBUG(dbgs() << "Begin Range at " << *RangeBeginMI);
DEBUG(dbgs() << "End Range at " << *PrevMI);
DEBUG(dbgs() << "Next Range starting at " << *MInsn);
DEBUG(dbgs() << "------------------------\n");
DbgRange R(RangeBeginMI, PrevMI);
MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevDL);
MIRanges.push_back(R);
}
// This is a beginning of a new instruction range.
RangeBeginMI = MInsn;
// Reset previous markers.
PrevMI = MInsn;
PrevDL = MIDL;
}
// Create last instruction range.
if (RangeBeginMI && PrevMI && !PrevDL.isUnknown()) {
DbgRange R(RangeBeginMI, PrevMI);
MIRanges.push_back(R);
MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevDL);
}
}
if (!CurrentFnDbgScope)
return false;
calculateDominanceGraph(CurrentFnDbgScope);
if (PrintDbgScope)
printDbgScopeInfo(Asm->MF, MI2ScopeMap);
// Find ranges of instructions covered by each DbgScope;
DbgScope *PrevDbgScope = NULL;
for (SmallVector<DbgRange, 4>::const_iterator RI = MIRanges.begin(),
RE = MIRanges.end(); RI != RE; ++RI) {
const DbgRange &R = *RI;
DbgScope *S = MI2ScopeMap.lookup(R.first);
assert (S && "Lost DbgScope for a machine instruction!");
if (PrevDbgScope && !PrevDbgScope->dominates(S))
PrevDbgScope->closeInsnRange(S);
S->openInsnRange(R.first);
S->extendInsnRange(R.second);
PrevDbgScope = S;
}
if (PrevDbgScope)
PrevDbgScope->closeInsnRange();
identifyScopeMarkers();
return !DbgScopeMap.empty();
}
/// identifyScopeMarkers() - /// identifyScopeMarkers() -
/// Each DbgScope has first instruction and last instruction to mark beginning /// Each LexicalScope has first instruction and last instruction to mark beginning
/// and end of a scope respectively. Create an inverse map that list scopes /// and end of a scope respectively. Create an inverse map that list scopes
/// starts (and ends) with an instruction. One instruction may start (or end) /// starts (and ends) with an instruction. One instruction may start (or end)
/// multiple scopes. Ignore scopes that are not reachable. /// multiple scopes. Ignore scopes that are not reachable.
void DwarfDebug::identifyScopeMarkers() { void DwarfDebug::identifyScopeMarkers() {
SmallVector<DbgScope *, 4> WorkList; SmallVector<LexicalScope *, 4> WorkList;
WorkList.push_back(CurrentFnDbgScope); WorkList.push_back(LScopes.getCurrentFunctionScope());
while (!WorkList.empty()) { while (!WorkList.empty()) {
DbgScope *S = WorkList.pop_back_val(); LexicalScope *S = WorkList.pop_back_val();
const SmallVector<DbgScope *, 4> &Children = S->getScopes(); const SmallVector<LexicalScope *, 4> &Children = S->getChildren();
if (!Children.empty()) if (!Children.empty())
for (SmallVector<DbgScope *, 4>::const_iterator SI = Children.begin(), for (SmallVector<LexicalScope *, 4>::const_iterator SI = Children.begin(),
SE = Children.end(); SI != SE; ++SI) SE = Children.end(); SI != SE; ++SI)
WorkList.push_back(*SI); WorkList.push_back(*SI);
if (S->isAbstractScope()) if (S->isAbstractScope())
continue; continue;
const SmallVector<DbgRange, 4> &Ranges = S->getRanges(); const SmallVector<InsnRange, 4> &Ranges = S->getRanges();
if (Ranges.empty()) if (Ranges.empty())
continue; continue;
for (SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(), for (SmallVector<InsnRange, 4>::const_iterator RI = Ranges.begin(),
RE = Ranges.end(); RI != RE; ++RI) { RE = Ranges.end(); RI != RE; ++RI) {
assert(RI->first && "DbgRange does not have first instruction!"); assert(RI->first && "InsnRange does not have first instruction!");
assert(RI->second && "DbgRange does not have second instruction!"); assert(RI->second && "InsnRange does not have second instruction!");
requestLabelBeforeInsn(RI->first); requestLabelBeforeInsn(RI->first);
requestLabelAfterInsn(RI->second); requestLabelAfterInsn(RI->second);
} }
@ -1859,7 +1483,9 @@ static DebugLoc getFnDebugLoc(DebugLoc DL, const LLVMContext &Ctx) {
/// emitted immediately after the function entry point. /// emitted immediately after the function entry point.
void DwarfDebug::beginFunction(const MachineFunction *MF) { void DwarfDebug::beginFunction(const MachineFunction *MF) {
if (!MMI->hasDebugInfo()) return; if (!MMI->hasDebugInfo()) return;
if (!extractScopeInformation()) return; LScopes.initialize(*MF);
if (LScopes.empty()) return;
identifyScopeMarkers();
FunctionBeginSym = Asm->GetTempSymbol("func_begin", FunctionBeginSym = Asm->GetTempSymbol("func_begin",
Asm->getFunctionNumber()); Asm->getFunctionNumber());
@ -2025,12 +1651,16 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
} }
} }
void DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
// SmallVector<DbgVariable *, 8> &Vars = ScopeVariables.lookup(LS);
ScopeVariables[LS].push_back(Var);
// Vars.push_back(Var);
}
/// endFunction - Gather and emit post-function debug information. /// endFunction - Gather and emit post-function debug information.
/// ///
void DwarfDebug::endFunction(const MachineFunction *MF) { void DwarfDebug::endFunction(const MachineFunction *MF) {
if (!MMI->hasDebugInfo() || DbgScopeMap.empty()) return; if (!MMI->hasDebugInfo() || LScopes.empty()) return;
if (CurrentFnDbgScope) {
// Define end label for subprogram. // Define end label for subprogram.
FunctionEndSym = Asm->GetTempSymbol("func_end", FunctionEndSym = Asm->GetTempSymbol("func_end",
@ -2042,8 +1672,9 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
collectVariableInfo(MF, ProcessedVars); collectVariableInfo(MF, ProcessedVars);
// Construct abstract scopes. // Construct abstract scopes.
for (SmallVector<DbgScope *, 4>::iterator AI = AbstractScopesList.begin(), SmallVector<LexicalScope *, 4> &AList = LScopes.getAbstractScopesList();
AE = AbstractScopesList.end(); AI != AE; ++AI) { for (SmallVector<LexicalScope *, 4>::iterator AI = AList.begin(),
AE = AList.end(); AI != AE; ++AI) {
DISubprogram SP((*AI)->getScopeNode()); DISubprogram SP((*AI)->getScopeNode());
if (SP.Verify()) { if (SP.Verify()) {
// Collect info for variables that were optimized out. // Collect info for variables that were optimized out.
@ -2056,9 +1687,8 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
DIVariable DV(cast<MDNode>(NMD->getOperand(i))); DIVariable DV(cast<MDNode>(NMD->getOperand(i)));
if (!DV || !ProcessedVars.insert(DV)) if (!DV || !ProcessedVars.insert(DV))
continue; continue;
DbgScope *Scope = AbstractScopes.lookup(DV.getContext()); if (LexicalScope *Scope = LScopes.findAbstractScope(DV.getContext()))
if (Scope) addScopeVariable(Scope, new DbgVariable(DV));
Scope->addVariable(new DbgVariable(DV));
} }
} }
} }
@ -2066,30 +1696,28 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
constructScopeDIE(*AI); constructScopeDIE(*AI);
} }
DIE *CurFnDIE = constructScopeDIE(CurrentFnDbgScope); DIE *CurFnDIE = constructScopeDIE(LScopes.getCurrentFunctionScope());
if (!DisableFramePointerElim(*MF)) if (!DisableFramePointerElim(*MF)) {
getCompileUnit(CurrentFnDbgScope->getScopeNode())->addUInt(CurFnDIE, LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
getCompileUnit(FnScope->getScopeNode())->addUInt(CurFnDIE,
dwarf::DW_AT_APPLE_omit_frame_ptr, dwarf::DW_AT_APPLE_omit_frame_ptr,
dwarf::DW_FORM_flag, 1); dwarf::DW_FORM_flag, 1);
}
DebugFrames.push_back(FunctionDebugFrameInfo(Asm->getFunctionNumber(), DebugFrames.push_back(FunctionDebugFrameInfo(Asm->getFunctionNumber(),
MMI->getFrameMoves())); MMI->getFrameMoves()));
}
// Clear debug info // Clear debug info
CurrentFnDbgScope = NULL; for (DenseMap<LexicalScope *, SmallVector<DbgVariable *, 8> >::iterator
I = ScopeVariables.begin(), E = ScopeVariables.end(); I != E; ++I)
DeleteContainerPointers(I->second);
ScopeVariables.clear();
DeleteContainerPointers(CurrentFnArguments); DeleteContainerPointers(CurrentFnArguments);
DbgVariableToFrameIndexMap.clear(); DbgVariableToFrameIndexMap.clear();
VarToAbstractVarMap.clear(); VarToAbstractVarMap.clear();
DbgVariableToDbgInstMap.clear(); DbgVariableToDbgInstMap.clear();
InlinedDbgScopeMap.clear();
DeleteContainerSeconds(DbgScopeMap);
UserVariables.clear(); UserVariables.clear();
DbgValues.clear(); DbgValues.clear();
DeleteContainerSeconds(AbstractScopes);
AbstractScopesList.clear();
AbstractVariables.clear(); AbstractVariables.clear();
LabelsBeforeInsn.clear(); LabelsBeforeInsn.clear();
LabelsAfterInsn.clear(); LabelsAfterInsn.clear();
@ -2114,21 +1742,6 @@ bool DwarfDebug::findVariableFrameIndex(const DbgVariable *V, int *FI) {
return true; return true;
} }
/// findDbgScope - Find DbgScope for the debug loc.
DbgScope *DwarfDebug::findDbgScope(DebugLoc DL) {
if (DL.isUnknown())
return NULL;
DbgScope *Scope = NULL;
LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
if (MDNode *IA = DL.getInlinedAt(Ctx))
Scope = InlinedDbgScopeMap.lookup(DebugLoc::getFromDILocation(IA));
else
Scope = DbgScopeMap.lookup(DL.getScope(Ctx));
return Scope;
}
/// recordSourceLine - Register a source line with debug info. Returns the /// recordSourceLine - Register a source line with debug info. Returns the
/// unique label that was emitted and which provides correspondence to /// unique label that was emitted and which provides correspondence to
/// the source line list. /// the source line list.

View File

@ -15,6 +15,7 @@
#define CODEGEN_ASMPRINTER_DWARFDEBUG_H__ #define CODEGEN_ASMPRINTER_DWARFDEBUG_H__
#include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/MC/MachineLocation.h" #include "llvm/MC/MachineLocation.h"
#include "llvm/Analysis/DebugInfo.h" #include "llvm/Analysis/DebugInfo.h"
#include "DIE.h" #include "DIE.h"
@ -30,7 +31,6 @@ namespace llvm {
class CompileUnit; class CompileUnit;
class DbgConcreteScope; class DbgConcreteScope;
class DbgScope;
class DbgVariable; class DbgVariable;
class MachineFrameInfo; class MachineFrameInfo;
class MachineModuleInfo; class MachineModuleInfo;
@ -192,33 +192,18 @@ class DwarfDebug {
/// ///
UniqueVector<const MCSection*> SectionMap; UniqueVector<const MCSection*> SectionMap;
/// CurrentFnDbgScope - Top level scope for the current function.
///
DbgScope *CurrentFnDbgScope;
/// CurrentFnArguments - List of Arguments (DbgValues) for current function. /// CurrentFnArguments - List of Arguments (DbgValues) for current function.
SmallVector<DbgVariable *, 8> CurrentFnArguments; SmallVector<DbgVariable *, 8> CurrentFnArguments;
/// DbgScopeMap - Tracks the scopes in the current function. Owns the LexicalScopes LScopes;
/// contained DbgScope*s.
DenseMap<const MDNode *, DbgScope *> DbgScopeMap;
/// InlinedDbgScopeMap - Tracks inlined function scopes in current function.
DenseMap<DebugLoc, DbgScope *> InlinedDbgScopeMap;
/// AbstractScopes - Tracks the abstract scopes a module. These scopes are
/// not included DbgScopeMap. AbstractScopes owns its DbgScope*s.
DenseMap<const MDNode *, DbgScope *> AbstractScopes;
/// AbstractSPDies - Collection of abstract subprogram DIEs. /// AbstractSPDies - Collection of abstract subprogram DIEs.
DenseMap<const MDNode *, DIE *> AbstractSPDies; DenseMap<const MDNode *, DIE *> AbstractSPDies;
/// AbstractScopesList - Tracks abstract scopes constructed while processing /// ScopeVariables - Collection of dbg variables of a scope.
/// a function. This list is cleared during endFunction(). DenseMap<LexicalScope *, SmallVector<DbgVariable *, 8> > ScopeVariables;
SmallVector<DbgScope *, 4>AbstractScopesList;
/// AbstractVariables - Collection on abstract variables. Owned by the /// AbstractVariables - Collection on abstract variables.
/// DbgScopes in AbstractScopes.
DenseMap<const MDNode *, DbgVariable *> AbstractVariables; DenseMap<const MDNode *, DbgVariable *> AbstractVariables;
/// DbgVariableToFrameIndexMap - Tracks frame index used to find /// DbgVariableToFrameIndexMap - Tracks frame index used to find
@ -316,11 +301,7 @@ private:
/// ///
void assignAbbrevNumber(DIEAbbrev &Abbrev); void assignAbbrevNumber(DIEAbbrev &Abbrev);
/// getOrCreateDbgScope - Create DbgScope for the scope. void addScopeVariable(LexicalScope *LS, DbgVariable *Var);
DbgScope *getOrCreateDbgScope(DebugLoc DL);
DbgScope *getOrCreateRegularScope(MDNode *Scope);
DbgScope *getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt);
DbgScope *getOrCreateAbstractScope(const MDNode *N);
/// findAbstractVariable - Find abstract variable associated with Var. /// findAbstractVariable - Find abstract variable associated with Var.
DbgVariable *findAbstractVariable(DIVariable &Var, DebugLoc Loc); DbgVariable *findAbstractVariable(DIVariable &Var, DebugLoc Loc);
@ -333,18 +314,18 @@ private:
/// constructLexicalScope - Construct new DW_TAG_lexical_block /// constructLexicalScope - Construct new DW_TAG_lexical_block
/// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels. /// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels.
DIE *constructLexicalScopeDIE(DbgScope *Scope); DIE *constructLexicalScopeDIE(LexicalScope *Scope);
/// constructInlinedScopeDIE - This scope represents inlined body of /// constructInlinedScopeDIE - This scope represents inlined body of
/// a function. Construct DIE to represent this concrete inlined copy /// a function. Construct DIE to represent this concrete inlined copy
/// of the function. /// of the function.
DIE *constructInlinedScopeDIE(DbgScope *Scope); DIE *constructInlinedScopeDIE(LexicalScope *Scope);
/// constructVariableDIE - Construct a DIE for the given DbgVariable. /// constructVariableDIE - Construct a DIE for the given DbgVariable.
DIE *constructVariableDIE(DbgVariable *DV, DbgScope *S); DIE *constructVariableDIE(DbgVariable *DV, LexicalScope *S);
/// constructScopeDIE - Construct a DIE for this scope. /// constructScopeDIE - Construct a DIE for this scope.
DIE *constructScopeDIE(DbgScope *Scope); DIE *constructScopeDIE(LexicalScope *Scope);
/// EmitSectionLabels - Emit initial Dwarf sections with a label at /// EmitSectionLabels - Emit initial Dwarf sections with a label at
/// the start of each one. /// the start of each one.
@ -449,23 +430,16 @@ private:
/// is found. Update FI to hold value of the index. /// is found. Update FI to hold value of the index.
bool findVariableFrameIndex(const DbgVariable *V, int *FI); bool findVariableFrameIndex(const DbgVariable *V, int *FI);
/// findDbgScope - Find DbgScope for the debug loc.
DbgScope *findDbgScope(DebugLoc DL);
/// identifyScopeMarkers() - Indentify instructions that are marking /// identifyScopeMarkers() - Indentify instructions that are marking
/// beginning of or end of a scope. /// beginning of or end of a scope.
void identifyScopeMarkers(); void identifyScopeMarkers();
/// extractScopeInformation - Scan machine instructions in this function
/// and collect DbgScopes. Return true, if atleast one scope was found.
bool extractScopeInformation();
/// addCurrentFnArgument - If Var is an current function argument that add /// addCurrentFnArgument - If Var is an current function argument that add
/// it in CurrentFnArguments list. /// it in CurrentFnArguments list.
bool addCurrentFnArgument(const MachineFunction *MF, bool addCurrentFnArgument(const MachineFunction *MF,
DbgVariable *Var, DbgScope *Scope); DbgVariable *Var, LexicalScope *Scope);
/// collectVariableInfo - Populate DbgScope entries with variables' info. /// collectVariableInfo - Populate LexicalScope entries with variables' info.
void collectVariableInfo(const MachineFunction *, void collectVariableInfo(const MachineFunction *,
SmallPtrSet<const MDNode *, 16> &ProcessedVars); SmallPtrSet<const MDNode *, 16> &ProcessedVars);