mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-17 06:33:21 +00:00
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:
parent
53642c5335
commit
bf47fdb91c
@ -45,9 +45,6 @@
|
||||
#include "llvm/Support/Path.h"
|
||||
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",
|
||||
cl::Hidden,
|
||||
cl::desc("Disable debug info printing"));
|
||||
@ -120,143 +117,12 @@ DIType DbgVariable::getType() const {
|
||||
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
|
||||
|
||||
#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)
|
||||
: Asm(A), MMI(Asm->MMI), FirstCU(0),
|
||||
AbbreviationsSet(InitAbbreviationsSetSize),
|
||||
CurrentFnDbgScope(0), PrevLabel(NULL) {
|
||||
PrevLabel(NULL) {
|
||||
NextStringPoolNumber = 0;
|
||||
|
||||
DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0;
|
||||
@ -408,29 +274,6 @@ DIE *DwarfDebug::createSubprogramDIE(DISubprogram SP) {
|
||||
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
|
||||
/// or another context nested inside a subprogram.
|
||||
static bool isSubprogramContext(const MDNode *Context) {
|
||||
@ -512,25 +355,25 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(const MDNode *SPNode) {
|
||||
|
||||
/// constructLexicalScope - Construct new DW_TAG_lexical_block
|
||||
/// 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);
|
||||
if (Scope->isAbstractScope())
|
||||
return ScopeDIE;
|
||||
|
||||
const SmallVector<DbgRange, 4> &Ranges = Scope->getRanges();
|
||||
const SmallVector<InsnRange, 4> &Ranges = Scope->getRanges();
|
||||
if (Ranges.empty())
|
||||
return 0;
|
||||
|
||||
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) {
|
||||
// .debug_range section has not been laid out yet. Emit offset in
|
||||
// .debug_range as a uint, size 4, for now. emitDIE will handle
|
||||
// DW_AT_ranges appropriately.
|
||||
TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
|
||||
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) {
|
||||
DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first));
|
||||
DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second));
|
||||
@ -557,11 +400,11 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
|
||||
/// constructInlinedScopeDIE - This scope represents inlined body of
|
||||
/// a function. Construct DIE to represent this concrete inlined copy
|
||||
/// 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
|
||||
&& "DbgScope does not have instruction markers!");
|
||||
&& "LexicalScope does not have instruction markers!");
|
||||
|
||||
if (!Scope->getScopeNode())
|
||||
return NULL;
|
||||
@ -574,7 +417,7 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
|
||||
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 *EndLabel = getLabelAfterInsn(RI->second);
|
||||
|
||||
@ -597,7 +440,7 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
|
||||
// DW_AT_ranges appropriately.
|
||||
TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
|
||||
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) {
|
||||
DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first));
|
||||
DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second));
|
||||
@ -650,7 +493,7 @@ static bool isUnsignedDIType(DIType Ty) {
|
||||
}
|
||||
|
||||
/// 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();
|
||||
if (Name.empty())
|
||||
return NULL;
|
||||
@ -784,25 +627,25 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
|
||||
}
|
||||
|
||||
/// constructScopeDIE - Construct a DIE for this scope.
|
||||
DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
|
||||
DIE *DwarfDebug::constructScopeDIE(LexicalScope *Scope) {
|
||||
if (!Scope || !Scope->getScopeNode())
|
||||
return NULL;
|
||||
|
||||
SmallVector <DIE *, 8> Children;
|
||||
|
||||
// Collect arguments for current function.
|
||||
if (Scope == CurrentFnDbgScope)
|
||||
if (LScopes.isCurrentFunctionScope(Scope))
|
||||
for (unsigned i = 0, N = CurrentFnArguments.size(); i < N; ++i)
|
||||
if (DbgVariable *ArgDV = CurrentFnArguments[i])
|
||||
if (DIE *Arg = constructVariableDIE(ArgDV, Scope))
|
||||
Children.push_back(Arg);
|
||||
|
||||
// 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)
|
||||
if (DIE *Variable = constructVariableDIE(Variables[i], Scope))
|
||||
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)
|
||||
if (DIE *Nested = constructScopeDIE(Scopes[j]))
|
||||
Children.push_back(Nested);
|
||||
@ -1176,7 +1019,7 @@ void DwarfDebug::beginModule(Module *M) {
|
||||
void DwarfDebug::endModule() {
|
||||
if (!FirstCU) return;
|
||||
const Module *M = MMI->getModule();
|
||||
DenseMap<const MDNode *, DbgScope *> DeadFnScopeMap;
|
||||
DenseMap<const MDNode *, LexicalScope *> DeadFnScopeMap;
|
||||
if (NamedMDNode *AllSPs = M->getNamedMetadata("llvm.dbg.sp")) {
|
||||
for (unsigned SI = 0, SE = AllSPs->getNumOperands(); SI != SE; ++SI) {
|
||||
if (ProcessedSPNodes.count(AllSPs->getOperand(SI)) != 0) continue;
|
||||
@ -1192,21 +1035,20 @@ void DwarfDebug::endModule() {
|
||||
if (!NMD) continue;
|
||||
unsigned E = NMD->getNumOperands();
|
||||
if (!E) continue;
|
||||
DbgScope *Scope = new DbgScope(NULL, DIDescriptor(SP), NULL);
|
||||
LexicalScope *Scope = new LexicalScope(NULL, DIDescriptor(SP), NULL, false);
|
||||
DeadFnScopeMap[SP] = Scope;
|
||||
SmallVector<DbgVariable *, 8> Variables;
|
||||
for (unsigned I = 0; I != E; ++I) {
|
||||
DIVariable DV(NMD->getOperand(I));
|
||||
if (!DV.Verify()) continue;
|
||||
Scope->addVariable(new DbgVariable(DV));
|
||||
Variables.push_back(new DbgVariable(DV));
|
||||
}
|
||||
|
||||
// Construct subprogram DIE and add variables DIEs.
|
||||
constructSubprogramDIE(SP);
|
||||
DIE *ScopeDIE = getCompileUnit(SP)->getDIE(SP);
|
||||
const SmallVector<DbgVariable *, 8> &Variables = Scope->getDbgVariables();
|
||||
for (unsigned i = 0, N = Variables.size(); i < N; ++i) {
|
||||
DIE *VariableDIE = constructVariableDIE(Variables[i], Scope);
|
||||
if (VariableDIE)
|
||||
if (DIE *VariableDIE = constructVariableDIE(Variables[i], Scope))
|
||||
ScopeDIE->addChild(VariableDIE);
|
||||
}
|
||||
}
|
||||
@ -1284,20 +1126,23 @@ void DwarfDebug::endModule() {
|
||||
}
|
||||
|
||||
/// findAbstractVariable - Find abstract variable, if any, associated with Var.
|
||||
DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
|
||||
DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV,
|
||||
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);
|
||||
if (AbsDbgVariable)
|
||||
return AbsDbgVariable;
|
||||
|
||||
LLVMContext &Ctx = Var->getContext();
|
||||
DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope(Ctx));
|
||||
LexicalScope *Scope = LScopes.findAbstractScope(ScopeLoc.getScope(Ctx));
|
||||
if (!Scope)
|
||||
return NULL;
|
||||
|
||||
AbsDbgVariable = new DbgVariable(Var);
|
||||
Scope->addVariable(AbsDbgVariable);
|
||||
addScopeVariable(Scope, AbsDbgVariable);
|
||||
AbstractVariables[Var] = AbsDbgVariable;
|
||||
return AbsDbgVariable;
|
||||
}
|
||||
@ -1305,8 +1150,8 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
|
||||
/// addCurrentFnArgument - If Var is a current function argument then add
|
||||
/// it to CurrentFnArguments list.
|
||||
bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF,
|
||||
DbgVariable *Var, DbgScope *Scope) {
|
||||
if (Scope != CurrentFnDbgScope)
|
||||
DbgVariable *Var, LexicalScope *Scope) {
|
||||
if (!LScopes.isCurrentFunctionScope(Scope))
|
||||
return false;
|
||||
DIVariable DV = Var->getVariable();
|
||||
if (DV.getTag() != dwarf::DW_TAG_arg_variable)
|
||||
@ -1340,7 +1185,7 @@ DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction *MF,
|
||||
DIVariable DV(Var);
|
||||
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 (Scope == 0)
|
||||
@ -1350,7 +1195,7 @@ DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction *MF,
|
||||
DbgVariable *RegVar = new DbgVariable(DV);
|
||||
recordVariableFrameIndex(RegVar, VP.first);
|
||||
if (!addCurrentFnArgument(MF, RegVar, Scope))
|
||||
Scope->addVariable(RegVar);
|
||||
addScopeVariable(Scope, RegVar);
|
||||
if (AbsDbgVariable) {
|
||||
recordVariableFrameIndex(AbsDbgVariable, VP.first);
|
||||
VarToAbstractVarMap[RegVar] = AbsDbgVariable;
|
||||
@ -1395,7 +1240,7 @@ static DotDebugLocEntry getDebugLocEntry(AsmPrinter *Asm,
|
||||
return DotDebugLocEntry();
|
||||
}
|
||||
|
||||
/// collectVariableInfo - Populate DbgScope entries with variables' info.
|
||||
/// collectVariableInfo - Find variables for each lexical scope.
|
||||
void
|
||||
DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
SmallPtrSet<const MDNode *, 16> &Processed) {
|
||||
@ -1418,18 +1263,18 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
const MachineInstr *MInsn = History.front();
|
||||
|
||||
DIVariable DV(Var);
|
||||
DbgScope *Scope = NULL;
|
||||
LexicalScope *Scope = NULL;
|
||||
if (DV.getTag() == dwarf::DW_TAG_arg_variable &&
|
||||
DISubprogram(DV.getContext()).describes(MF->getFunction()))
|
||||
Scope = CurrentFnDbgScope;
|
||||
Scope = LScopes.getCurrentFunctionScope();
|
||||
else {
|
||||
if (DV.getVersion() <= LLVMDebugVersion9)
|
||||
Scope = findDbgScope(MInsn->getDebugLoc());
|
||||
Scope = LScopes.findLexicalScope(MInsn->getDebugLoc());
|
||||
else {
|
||||
if (MDNode *IA = DV.getInlinedAt())
|
||||
Scope = InlinedDbgScopeMap.lookup(DebugLoc::getFromDILocation(IA));
|
||||
Scope = LScopes.findInlinedScope(DebugLoc::getFromDILocation(IA));
|
||||
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.
|
||||
@ -1440,7 +1285,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
assert(MInsn->isDebugValue() && "History must begin with debug value");
|
||||
DbgVariable *RegVar = new DbgVariable(DV);
|
||||
if (!addCurrentFnArgument(MF, RegVar, Scope))
|
||||
Scope->addVariable(RegVar);
|
||||
addScopeVariable(Scope, RegVar);
|
||||
if (DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc())) {
|
||||
DbgVariableToDbgInstMap[AbsVar] = MInsn;
|
||||
VarToAbstractVarMap[RegVar] = AbsVar;
|
||||
@ -1501,9 +1346,8 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
|
||||
DIVariable DV(cast<MDNode>(NMD->getOperand(i)));
|
||||
if (!DV || !Processed.insert(DV))
|
||||
continue;
|
||||
DbgScope *Scope = DbgScopeMap.lookup(DV.getContext());
|
||||
if (Scope)
|
||||
Scope->addVariable(new DbgVariable(DV));
|
||||
if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext()))
|
||||
addScopeVariable(Scope, new DbgVariable(DV));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1585,253 +1429,33 @@ void DwarfDebug::endInstruction(const MachineInstr *MI) {
|
||||
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() -
|
||||
/// 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
|
||||
/// starts (and ends) with an instruction. One instruction may start (or end)
|
||||
/// multiple scopes. Ignore scopes that are not reachable.
|
||||
void DwarfDebug::identifyScopeMarkers() {
|
||||
SmallVector<DbgScope *, 4> WorkList;
|
||||
WorkList.push_back(CurrentFnDbgScope);
|
||||
SmallVector<LexicalScope *, 4> WorkList;
|
||||
WorkList.push_back(LScopes.getCurrentFunctionScope());
|
||||
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())
|
||||
for (SmallVector<DbgScope *, 4>::const_iterator SI = Children.begin(),
|
||||
for (SmallVector<LexicalScope *, 4>::const_iterator SI = Children.begin(),
|
||||
SE = Children.end(); SI != SE; ++SI)
|
||||
WorkList.push_back(*SI);
|
||||
|
||||
if (S->isAbstractScope())
|
||||
continue;
|
||||
|
||||
const SmallVector<DbgRange, 4> &Ranges = S->getRanges();
|
||||
const SmallVector<InsnRange, 4> &Ranges = S->getRanges();
|
||||
if (Ranges.empty())
|
||||
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) {
|
||||
assert(RI->first && "DbgRange does not have first instruction!");
|
||||
assert(RI->second && "DbgRange does not have second instruction!");
|
||||
assert(RI->first && "InsnRange does not have first instruction!");
|
||||
assert(RI->second && "InsnRange does not have second instruction!");
|
||||
requestLabelBeforeInsn(RI->first);
|
||||
requestLabelAfterInsn(RI->second);
|
||||
}
|
||||
@ -1859,7 +1483,9 @@ static DebugLoc getFnDebugLoc(DebugLoc DL, const LLVMContext &Ctx) {
|
||||
/// emitted immediately after the function entry point.
|
||||
void DwarfDebug::beginFunction(const MachineFunction *MF) {
|
||||
if (!MMI->hasDebugInfo()) return;
|
||||
if (!extractScopeInformation()) return;
|
||||
LScopes.initialize(*MF);
|
||||
if (LScopes.empty()) return;
|
||||
identifyScopeMarkers();
|
||||
|
||||
FunctionBeginSym = Asm->GetTempSymbol("func_begin",
|
||||
Asm->getFunctionNumber());
|
||||
@ -2025,71 +1651,73 @@ 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.
|
||||
///
|
||||
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.
|
||||
FunctionEndSym = Asm->GetTempSymbol("func_end",
|
||||
Asm->getFunctionNumber());
|
||||
// Assumes in correct section after the entry point.
|
||||
Asm->OutStreamer.EmitLabel(FunctionEndSym);
|
||||
|
||||
SmallPtrSet<const MDNode *, 16> ProcessedVars;
|
||||
collectVariableInfo(MF, ProcessedVars);
|
||||
|
||||
// Construct abstract scopes.
|
||||
for (SmallVector<DbgScope *, 4>::iterator AI = AbstractScopesList.begin(),
|
||||
AE = AbstractScopesList.end(); AI != AE; ++AI) {
|
||||
DISubprogram SP((*AI)->getScopeNode());
|
||||
if (SP.Verify()) {
|
||||
// Collect info for variables that were optimized out.
|
||||
StringRef FName = SP.getLinkageName();
|
||||
if (FName.empty())
|
||||
FName = SP.getName();
|
||||
if (NamedMDNode *NMD =
|
||||
getFnSpecificMDNode(*(MF->getFunction()->getParent()), FName)) {
|
||||
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
|
||||
// Define end label for subprogram.
|
||||
FunctionEndSym = Asm->GetTempSymbol("func_end",
|
||||
Asm->getFunctionNumber());
|
||||
// Assumes in correct section after the entry point.
|
||||
Asm->OutStreamer.EmitLabel(FunctionEndSym);
|
||||
|
||||
SmallPtrSet<const MDNode *, 16> ProcessedVars;
|
||||
collectVariableInfo(MF, ProcessedVars);
|
||||
|
||||
// Construct abstract scopes.
|
||||
SmallVector<LexicalScope *, 4> &AList = LScopes.getAbstractScopesList();
|
||||
for (SmallVector<LexicalScope *, 4>::iterator AI = AList.begin(),
|
||||
AE = AList.end(); AI != AE; ++AI) {
|
||||
DISubprogram SP((*AI)->getScopeNode());
|
||||
if (SP.Verify()) {
|
||||
// Collect info for variables that were optimized out.
|
||||
StringRef FName = SP.getLinkageName();
|
||||
if (FName.empty())
|
||||
FName = SP.getName();
|
||||
if (NamedMDNode *NMD =
|
||||
getFnSpecificMDNode(*(MF->getFunction()->getParent()), FName)) {
|
||||
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
|
||||
DIVariable DV(cast<MDNode>(NMD->getOperand(i)));
|
||||
if (!DV || !ProcessedVars.insert(DV))
|
||||
continue;
|
||||
DbgScope *Scope = AbstractScopes.lookup(DV.getContext());
|
||||
if (Scope)
|
||||
Scope->addVariable(new DbgVariable(DV));
|
||||
}
|
||||
if (LexicalScope *Scope = LScopes.findAbstractScope(DV.getContext()))
|
||||
addScopeVariable(Scope, new DbgVariable(DV));
|
||||
}
|
||||
}
|
||||
if (ProcessedSPNodes.count((*AI)->getScopeNode()) == 0)
|
||||
constructScopeDIE(*AI);
|
||||
}
|
||||
|
||||
DIE *CurFnDIE = constructScopeDIE(CurrentFnDbgScope);
|
||||
|
||||
if (!DisableFramePointerElim(*MF))
|
||||
getCompileUnit(CurrentFnDbgScope->getScopeNode())->addUInt(CurFnDIE,
|
||||
dwarf::DW_AT_APPLE_omit_frame_ptr,
|
||||
dwarf::DW_FORM_flag, 1);
|
||||
|
||||
|
||||
DebugFrames.push_back(FunctionDebugFrameInfo(Asm->getFunctionNumber(),
|
||||
MMI->getFrameMoves()));
|
||||
if (ProcessedSPNodes.count((*AI)->getScopeNode()) == 0)
|
||||
constructScopeDIE(*AI);
|
||||
}
|
||||
|
||||
DIE *CurFnDIE = constructScopeDIE(LScopes.getCurrentFunctionScope());
|
||||
|
||||
if (!DisableFramePointerElim(*MF)) {
|
||||
LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
|
||||
getCompileUnit(FnScope->getScopeNode())->addUInt(CurFnDIE,
|
||||
dwarf::DW_AT_APPLE_omit_frame_ptr,
|
||||
dwarf::DW_FORM_flag, 1);
|
||||
}
|
||||
DebugFrames.push_back(FunctionDebugFrameInfo(Asm->getFunctionNumber(),
|
||||
MMI->getFrameMoves()));
|
||||
|
||||
// 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);
|
||||
DbgVariableToFrameIndexMap.clear();
|
||||
VarToAbstractVarMap.clear();
|
||||
DbgVariableToDbgInstMap.clear();
|
||||
InlinedDbgScopeMap.clear();
|
||||
DeleteContainerSeconds(DbgScopeMap);
|
||||
UserVariables.clear();
|
||||
DbgValues.clear();
|
||||
DeleteContainerSeconds(AbstractScopes);
|
||||
AbstractScopesList.clear();
|
||||
AbstractVariables.clear();
|
||||
LabelsBeforeInsn.clear();
|
||||
LabelsAfterInsn.clear();
|
||||
@ -2114,21 +1742,6 @@ bool DwarfDebug::findVariableFrameIndex(const DbgVariable *V, int *FI) {
|
||||
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
|
||||
/// unique label that was emitted and which provides correspondence to
|
||||
/// the source line list.
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define CODEGEN_ASMPRINTER_DWARFDEBUG_H__
|
||||
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/CodeGen/LexicalScopes.h"
|
||||
#include "llvm/MC/MachineLocation.h"
|
||||
#include "llvm/Analysis/DebugInfo.h"
|
||||
#include "DIE.h"
|
||||
@ -30,7 +31,6 @@ namespace llvm {
|
||||
|
||||
class CompileUnit;
|
||||
class DbgConcreteScope;
|
||||
class DbgScope;
|
||||
class DbgVariable;
|
||||
class MachineFrameInfo;
|
||||
class MachineModuleInfo;
|
||||
@ -192,33 +192,18 @@ class DwarfDebug {
|
||||
///
|
||||
UniqueVector<const MCSection*> SectionMap;
|
||||
|
||||
/// CurrentFnDbgScope - Top level scope for the current function.
|
||||
///
|
||||
DbgScope *CurrentFnDbgScope;
|
||||
|
||||
/// CurrentFnArguments - List of Arguments (DbgValues) for current function.
|
||||
SmallVector<DbgVariable *, 8> CurrentFnArguments;
|
||||
|
||||
/// DbgScopeMap - Tracks the scopes in the current function. Owns the
|
||||
/// 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;
|
||||
LexicalScopes LScopes;
|
||||
|
||||
/// AbstractSPDies - Collection of abstract subprogram DIEs.
|
||||
DenseMap<const MDNode *, DIE *> AbstractSPDies;
|
||||
|
||||
/// AbstractScopesList - Tracks abstract scopes constructed while processing
|
||||
/// a function. This list is cleared during endFunction().
|
||||
SmallVector<DbgScope *, 4>AbstractScopesList;
|
||||
/// ScopeVariables - Collection of dbg variables of a scope.
|
||||
DenseMap<LexicalScope *, SmallVector<DbgVariable *, 8> > ScopeVariables;
|
||||
|
||||
/// AbstractVariables - Collection on abstract variables. Owned by the
|
||||
/// DbgScopes in AbstractScopes.
|
||||
/// AbstractVariables - Collection on abstract variables.
|
||||
DenseMap<const MDNode *, DbgVariable *> AbstractVariables;
|
||||
|
||||
/// DbgVariableToFrameIndexMap - Tracks frame index used to find
|
||||
@ -316,11 +301,7 @@ private:
|
||||
///
|
||||
void assignAbbrevNumber(DIEAbbrev &Abbrev);
|
||||
|
||||
/// getOrCreateDbgScope - Create DbgScope for the scope.
|
||||
DbgScope *getOrCreateDbgScope(DebugLoc DL);
|
||||
DbgScope *getOrCreateRegularScope(MDNode *Scope);
|
||||
DbgScope *getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt);
|
||||
DbgScope *getOrCreateAbstractScope(const MDNode *N);
|
||||
void addScopeVariable(LexicalScope *LS, DbgVariable *Var);
|
||||
|
||||
/// findAbstractVariable - Find abstract variable associated with Var.
|
||||
DbgVariable *findAbstractVariable(DIVariable &Var, DebugLoc Loc);
|
||||
@ -333,18 +314,18 @@ private:
|
||||
|
||||
/// constructLexicalScope - Construct new DW_TAG_lexical_block
|
||||
/// 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
|
||||
/// a function. Construct DIE to represent this concrete inlined copy
|
||||
/// of the function.
|
||||
DIE *constructInlinedScopeDIE(DbgScope *Scope);
|
||||
DIE *constructInlinedScopeDIE(LexicalScope *Scope);
|
||||
|
||||
/// 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.
|
||||
DIE *constructScopeDIE(DbgScope *Scope);
|
||||
DIE *constructScopeDIE(LexicalScope *Scope);
|
||||
|
||||
/// EmitSectionLabels - Emit initial Dwarf sections with a label at
|
||||
/// the start of each one.
|
||||
@ -449,23 +430,16 @@ private:
|
||||
/// is found. Update FI to hold value of the index.
|
||||
bool findVariableFrameIndex(const DbgVariable *V, int *FI);
|
||||
|
||||
/// findDbgScope - Find DbgScope for the debug loc.
|
||||
DbgScope *findDbgScope(DebugLoc DL);
|
||||
|
||||
/// identifyScopeMarkers() - Indentify instructions that are marking
|
||||
/// beginning of or end of a scope.
|
||||
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
|
||||
/// it in CurrentFnArguments list.
|
||||
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 *,
|
||||
SmallPtrSet<const MDNode *, 16> &ProcessedVars);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user