Identify when a lexical scope is split in to multiple instruction ranges. Emit such ranges using DW_AT_ranges.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102004 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel 2010-04-21 16:32:19 +00:00
parent a560fd28c0
commit 9cdb4109d5
2 changed files with 322 additions and 192 deletions

View File

@ -32,6 +32,7 @@
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ValueHandle.h"
@ -40,6 +41,9 @@
#include "llvm/System/Path.h"
using namespace llvm;
static cl::opt<bool> PrintDbgScope("print-dbgscope", cl::Hidden,
cl::desc("Print DbgScope information for each machine instruction"));
namespace {
const char *DWARFGroupName = "DWARF Emission";
const char *DbgTimerName = "DWARF Debug Writer";
@ -184,6 +188,12 @@ public:
DIE *getDIE() const { return TheDIE; }
};
//===----------------------------------------------------------------------===//
/// 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.
///
@ -195,17 +205,19 @@ class DbgScope {
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, MDNode *I = 0)
: Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(false),
LastInsn(0), FirstInsn(0), IndentLevel(0) {}
LastInsn(0), FirstInsn(0),
DFSIn(0), DFSOut(0), IndentLevel(0) {}
virtual ~DbgScope();
// Accessors.
@ -216,12 +228,55 @@ public:
MDNode *getScopeNode() const { return Desc.getNode(); }
const SmallVector<DbgScope *, 4> &getScopes() { return Scopes; }
const SmallVector<DbgVariable *, 8> &getVariables() { return Variables; }
void setLastInsn(const MachineInstr *MI) { LastInsn = MI; }
const MachineInstr *getLastInsn() { return LastInsn; }
void setFirstInsn(const MachineInstr *MI) { FirstInsn = MI; }
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; }
const MachineInstr *getFirstInsn() { return FirstInsn; }
// Depth First Search support to walk and mainpluate 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.
///
@ -231,48 +286,11 @@ public:
///
void addVariable(DbgVariable *V) { Variables.push_back(V); }
void fixInstructionMarkers(DenseMap<const MachineInstr *,
unsigned> &MIIndexMap) {
assert(getFirstInsn() && "First instruction is missing!");
// Use the end of last child scope as end of this scope.
const SmallVector<DbgScope *, 4> &Scopes = getScopes();
const MachineInstr *LastInsn = getFirstInsn();
unsigned LIndex = 0;
if (Scopes.empty()) {
assert(getLastInsn() && "Inner most scope does not have last insn!");
return;
}
for (SmallVector<DbgScope *, 4>::const_iterator SI = Scopes.begin(),
SE = Scopes.end(); SI != SE; ++SI) {
DbgScope *DS = *SI;
DS->fixInstructionMarkers(MIIndexMap);
const MachineInstr *DSLastInsn = DS->getLastInsn();
unsigned DSI = MIIndexMap[DSLastInsn];
if (DSI > LIndex) {
LastInsn = DSLastInsn;
LIndex = DSI;
}
}
unsigned CurrentLastInsnIndex = 0;
if (const MachineInstr *CL = getLastInsn())
CurrentLastInsnIndex = MIIndexMap[CL];
unsigned FIndex = MIIndexMap[getFirstInsn()];
// Set LastInsn as the last instruction for this scope only if
// it follows
// 1) this scope's first instruction and
// 2) current last instruction for this scope, if any.
if (LIndex >= CurrentLastInsnIndex && LIndex >= FIndex)
setLastInsn(LastInsn);
}
#ifndef NDEBUG
void dump() const;
#endif
};
} // end llvm namespace
#ifndef NDEBUG
@ -308,7 +326,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
DwarfFrameSectionSym = DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0;
DwarfStrSectionSym = TextSectionSym = 0;
DwarfDebugRangeSectionSym = 0;
if (TimePassesIsEnabled) {
NamedRegionTimer T(DbgTimerName, DWARFGroupName);
beginModule(M);
@ -1257,56 +1275,6 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
return SPDie;
}
/// getUpdatedDbgScope - Find DbgScope assicated with the instruction.
/// Update scope hierarchy. Create abstract scope if required.
DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI,
MDNode *InlinedAt) {
assert(N && "Invalid Scope encoding!");
assert(MI && "Missing machine instruction!");
bool isAConcreteScope = InlinedAt != 0;
DbgScope *NScope = NULL;
if (InlinedAt)
NScope = DbgScopeMap.lookup(InlinedAt);
else
NScope = DbgScopeMap.lookup(N);
assert(NScope && "Unable to find working scope!");
if (NScope->getFirstInsn())
return NScope;
DbgScope *Parent = NULL;
if (isAConcreteScope) {
DILocation IL(InlinedAt);
Parent = getUpdatedDbgScope(IL.getScope().getNode(), MI,
IL.getOrigLocation().getNode());
assert(Parent && "Unable to find Parent scope!");
NScope->setParent(Parent);
Parent->addScope(NScope);
} else if (DIDescriptor(N).isLexicalBlock()) {
DILexicalBlock DB(N);
Parent = getUpdatedDbgScope(DB.getContext().getNode(), MI, InlinedAt);
NScope->setParent(Parent);
Parent->addScope(NScope);
}
NScope->setFirstInsn(MI);
if (!Parent && !InlinedAt) {
StringRef SPName = DISubprogram(N).getLinkageName();
if (SPName == Asm->MF->getFunction()->getName())
CurrentFnDbgScope = NScope;
}
if (isAConcreteScope) {
ConcreteScopes[InlinedAt] = NScope;
getOrCreateAbstractScope(N);
}
return NScope;
}
DbgScope *DwarfDebug::getOrCreateAbstractScope(MDNode *N) {
assert(N && "Invalid Scope encoding!");
@ -1403,18 +1371,40 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(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) {
MCSymbol *Start = InsnBeforeLabelMap.lookup(Scope->getFirstInsn());
MCSymbol *End = InsnAfterLabelMap.lookup(Scope->getLastInsn());
DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block);
if (Scope->isAbstractScope())
return ScopeDIE;
const SmallVector<DbgRange, 4> &Ranges = Scope->getRanges();
if (Ranges.empty())
return 0;
SmallVector<DbgRange, 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.
addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
DebugRangeSymbols.size() * Asm->getTargetData().getPointerSize());
for (SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(),
RE = Ranges.end(); RI != RE; ++RI) {
DebugRangeSymbols.push_back(InsnBeforeLabelMap.lookup(RI->first));
DebugRangeSymbols.push_back(InsnAfterLabelMap.lookup(RI->second));
}
DebugRangeSymbols.push_back(NULL);
DebugRangeSymbols.push_back(NULL);
return ScopeDIE;
}
MCSymbol *Start = InsnBeforeLabelMap.lookup(RI->first);
MCSymbol *End = InsnAfterLabelMap.lookup(RI->second);
if (Start == 0 || End == 0) return 0;
assert(Start->isDefined() && "Invalid starting label for an inlined scope!");
assert(End->isDefined() && "Invalid end label for an inlined scope!");
DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block);
if (Scope->isAbstractScope())
return ScopeDIE;
addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
Start ? Start : Asm->GetTempSymbol("func_begin",
Asm->getFunctionNumber()));
@ -1428,14 +1418,28 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
/// a function. Construct DIE to represent this concrete inlined copy
/// of the function.
DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
MCSymbol *StartLabel = InsnBeforeLabelMap.lookup(Scope->getFirstInsn());
MCSymbol *EndLabel = InsnAfterLabelMap.lookup(Scope->getLastInsn());
if (StartLabel == 0 || EndLabel == 0) return 0;
const SmallVector<DbgRange, 4> &Ranges = Scope->getRanges();
assert (Ranges.empty() == false
&& "DbgScope does not have instruction markers!");
// FIXME : .debug_inlined section specification does not clearly state how
// to emit inlined scope that is split into multiple instruction ranges.
// For now, use first instruction range and emit low_pc/high_pc pair and
// corresponding .debug_inlined section entry for this pair.
SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin();
MCSymbol *StartLabel = InsnBeforeLabelMap.lookup(RI->first);
MCSymbol *EndLabel = InsnAfterLabelMap.lookup(RI->second);
if (StartLabel == 0 || EndLabel == 0) {
assert (0 && "Unexpected Start and End labels for a inlined scope!");
return 0;
}
assert(StartLabel->isDefined() &&
"Invalid starting label for an inlined scope!");
assert(EndLabel->isDefined() &&
"Invalid end label for an inlined scope!");
if (!Scope->getScopeNode())
return NULL;
DIScope DS(Scope->getScopeNode());
@ -2111,10 +2115,6 @@ void DwarfDebug::beginScope(const MachineInstr *MI) {
if (DL.isUnknown())
return;
// Check and update last known location info.
if (DL == PrevInstLoc)
return;
MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
// FIXME: Should only verify each scope once!
@ -2126,17 +2126,29 @@ void DwarfDebug::beginScope(const MachineInstr *MI) {
DenseMap<const MachineInstr *, DbgVariable *>::iterator DI
= DbgValueStartMap.find(MI);
if (DI != DbgValueStartMap.end()) {
MCSymbol *Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
PrevInstLoc = DL;
MCSymbol *Label = NULL;
if (DL == PrevInstLoc)
Label = PrevLabel;
else {
Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
PrevInstLoc = DL;
PrevLabel = Label;
}
DI->second->setDbgValueLabel(Label);
}
return;
}
// Emit a label to indicate location change. This is used for line
// table even if this instruction does start a new scope.
MCSymbol *Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
PrevInstLoc = DL;
// table even if this instruction does not start a new scope.
MCSymbol *Label = NULL;
if (DL == PrevInstLoc)
Label = PrevLabel;
else {
Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
PrevInstLoc = DL;
PrevLabel = Label;
}
// If this instruction begins a scope then note down corresponding label.
if (InsnsBeginScopeSet.count(MI) != 0)
@ -2145,15 +2157,6 @@ void DwarfDebug::beginScope(const MachineInstr *MI) {
/// endScope - Process end of a scope.
void DwarfDebug::endScope(const MachineInstr *MI) {
// Ignore DBG_VALUE instruction.
if (MI->isDebugValue())
return;
// Check location.
DebugLoc DL = MI->getDebugLoc();
if (DL.isUnknown())
return;
if (InsnsEndScopeSet.count(MI) != 0) {
// Emit a label if this instruction ends a scope.
MCSymbol *Label = MMI->getContext().CreateTempSymbol();
@ -2162,29 +2165,135 @@ void DwarfDebug::endScope(const MachineInstr *MI) {
}
}
/// createDbgScope - Create DbgScope for the scope.
void DwarfDebug::createDbgScope(MDNode *Scope, MDNode *InlinedAt) {
/// getOrCreateDbgScope - Create DbgScope for the scope.
DbgScope *DwarfDebug::getOrCreateDbgScope(MDNode *Scope, MDNode *InlinedAt) {
if (!InlinedAt) {
DbgScope *WScope = DbgScopeMap.lookup(Scope);
if (WScope)
return;
return WScope;
WScope = new DbgScope(NULL, DIDescriptor(Scope), NULL);
DbgScopeMap.insert(std::make_pair(Scope, WScope));
if (DIDescriptor(Scope).isLexicalBlock())
createDbgScope(DILexicalBlock(Scope).getContext().getNode(), NULL);
return;
if (DIDescriptor(Scope).isLexicalBlock()) {
DbgScope *Parent =
getOrCreateDbgScope(DILexicalBlock(Scope).getContext().getNode(), NULL);
WScope->setParent(Parent);
Parent->addScope(WScope);
}
if (!WScope->getParent()) {
StringRef SPName = DISubprogram(Scope).getLinkageName();
if (SPName == Asm->MF->getFunction()->getName())
CurrentFnDbgScope = WScope;
}
return WScope;
}
DbgScope *WScope = DbgScopeMap.lookup(InlinedAt);
if (WScope)
return;
return WScope;
WScope = new DbgScope(NULL, DIDescriptor(Scope), InlinedAt);
DbgScopeMap.insert(std::make_pair(InlinedAt, WScope));
DILocation DL(InlinedAt);
createDbgScope(DL.getScope().getNode(), DL.getOrigLocation().getNode());
DbgScope *Parent =
getOrCreateDbgScope(DL.getScope().getNode(), DL.getOrigLocation().getNode());
WScope->setParent(Parent);
Parent->addScope(WScope);
ConcreteScopes[InlinedAt] = WScope;
getOrCreateAbstractScope(Scope);
return WScope;
}
/// hasValidLocation - Return true if debug location entry attached with
/// machine instruction encodes valid location info.
static bool hasValidLocation(LLVMContext &Ctx,
const MachineInstr *MInsn,
MDNode *&Scope, MDNode *&InlinedAt) {
if (MInsn->isDebugValue())
return false;
DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) return false;
MDNode *S = DL.getScope(Ctx);
// There is no need to create another DIE for compile unit. For all
// other scopes, create one DbgScope now. This will be translated
// into a scope DIE at the end.
if (DIScope(S).isCompileUnit()) return false;
Scope = S;
InlinedAt = DL.getInlinedAt(Ctx);
return true;
}
/// 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);
break;
}
}
if (!visitedChildren) {
WorkStack.pop_back();
WS->setDFSOut(++Counter);
}
}
}
/// printDbgScopeInfo - Print DbgScope info for each machine instruction.
static
void printDbgScopeInfo(LLVMContext &Ctx, const MachineFunction *MF,
DenseMap<const MachineInstr *, DbgScope *> &MI2ScopeMap)
{
#ifndef NDEBUG
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.
if (hasValidLocation(Ctx, MInsn, Scope, InlinedAt)) {
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() {
@ -2193,80 +2302,100 @@ bool DwarfDebug::extractScopeInformation() {
if (!DbgScopeMap.empty())
return false;
DenseMap<const MachineInstr *, unsigned> MIIndexMap;
unsigned MIIndex = 0;
LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
// Scan each instruction and create scopes. First build working set of scopes.
LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
SmallVector<DbgRange, 4> MIRanges;
DenseMap<const MachineInstr *, DbgScope *> MI2ScopeMap;
MDNode *PrevScope = NULL;
MDNode *PrevInlinedAt = NULL;
const MachineInstr *RangeBeginMI = NULL;
const MachineInstr *PrevMI = NULL;
for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
I != E; ++I) {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
const MachineInstr *MInsn = II;
// FIXME : Remove DBG_VALUE check.
if (MInsn->isDebugValue()) continue;
MIIndexMap[MInsn] = MIIndex++;
MDNode *Scope = NULL;
MDNode *InlinedAt = NULL;
// Check if instruction has valid location information.
if (!hasValidLocation(Ctx, MInsn, Scope, InlinedAt)) {
PrevMI = MInsn;
continue;
}
DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) continue;
// If scope has not changed then skip this instruction.
if (Scope == PrevScope && PrevInlinedAt == InlinedAt) {
PrevMI = MInsn;
continue;
}
if (RangeBeginMI) {
// If we have alread seen a beginning of a instruction range and
// current instruction scope does not match scope of first instruction
// in this range then create a new instruction range.
DbgRange R(RangeBeginMI, PrevMI);
MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevScope, PrevInlinedAt);
MIRanges.push_back(R);
}
// This is a beginning of a new instruction range.
RangeBeginMI = MInsn;
MDNode *Scope = DL.getScope(Ctx);
// There is no need to create another DIE for compile unit. For all
// other scopes, create one DbgScope now. This will be translated
// into a scope DIE at the end.
if (DIScope(Scope).isCompileUnit()) continue;
createDbgScope(Scope, DL.getInlinedAt(Ctx));
// Reset previous markers.
PrevMI = MInsn;
PrevScope = Scope;
PrevInlinedAt = InlinedAt;
}
}
// Build scope hierarchy using working set of scopes.
for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
I != E; ++I) {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
const MachineInstr *MInsn = II;
// FIXME : Remove DBG_VALUE check.
if (MInsn->isDebugValue()) continue;
DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) continue;
MDNode *Scope = DL.getScope(Ctx);
if (Scope == 0) continue;
// There is no need to create another DIE for compile unit. For all
// other scopes, create one DbgScope now. This will be translated
// into a scope DIE at the end.
if (DIScope(Scope).isCompileUnit()) continue;
DbgScope *DScope = getUpdatedDbgScope(Scope, MInsn, DL.getInlinedAt(Ctx));
DScope->setLastInsn(MInsn);
}
// Create last instruction range.
if (RangeBeginMI && PrevMI && PrevScope) {
DbgRange R(RangeBeginMI, PrevMI);
MIRanges.push_back(R);
MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevScope, PrevInlinedAt);
}
if (!CurrentFnDbgScope)
return false;
CurrentFnDbgScope->fixInstructionMarkers(MIIndexMap);
calculateDominanceGraph(CurrentFnDbgScope);
if (PrintDbgScope)
printDbgScopeInfo(Ctx, 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() - Indentify instructions that are marking
/// beginning of or end of a scope.
/// identifyScopeMarkers() -
/// Each DbgScope 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() {
// Each scope 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.
SmallVector<DbgScope *, 4> WorkList;
WorkList.push_back(CurrentFnDbgScope);
while (!WorkList.empty()) {
DbgScope *S = WorkList.pop_back_val();
const SmallVector<DbgScope *, 4> &Children = S->getScopes();
if (!Children.empty())
for (SmallVector<DbgScope *, 4>::const_iterator SI = Children.begin(),
@ -2275,11 +2404,17 @@ void DwarfDebug::identifyScopeMarkers() {
if (S->isAbstractScope())
continue;
assert(S->getFirstInsn() && "DbgScope does not have first instruction!");
InsnsBeginScopeSet.insert(S->getFirstInsn());
assert(S->getLastInsn() && "DbgScope does not have last instruction!");
InsnsEndScopeSet.insert(S->getLastInsn());
const SmallVector<DbgRange, 4> &Ranges = S->getRanges();
if (Ranges.empty())
continue;
for (SmallVector<DbgRange, 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!");
InsnsBeginScopeSet.insert(RI->first);
InsnsEndScopeSet.insert(RI->second);
}
}
}

View File

@ -368,13 +368,8 @@ private:
/// createSubprogramDIE - Create new DIE using SP.
DIE *createSubprogramDIE(const DISubprogram &SP, bool MakeDecl = false);
/// getUpdatedDbgScope - Find or create DbgScope assicated with
/// the instruction. Initialize scope and update scope hierarchy.
DbgScope *getUpdatedDbgScope(MDNode *N, const MachineInstr *MI,
MDNode *InlinedAt);
/// createDbgScope - Create DbgScope for the scope.
void createDbgScope(MDNode *Scope, MDNode *InlinedAt);
/// getOrCreateDbgScope - Create DbgScope for the scope.
DbgScope *getOrCreateDbgScope(MDNode *Scope, MDNode *InlinedAt);
DbgScope *getOrCreateAbstractScope(MDNode *N);