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"
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.

View File

@ -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);