diff options
author | Devang Patel <dpatel@apple.com> | 2011-08-10 20:55:27 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2011-08-10 20:55:27 +0000 |
commit | bf47fdb91c3bc7c26fb7eb6096ca3657c69bd26f (patch) | |
tree | a33cfba2017a0d70be4fc36ae6f6d7171c26f277 /lib/CodeGen/AsmPrinter/DwarfDebug.cpp | |
parent | 53642c533564c41d9a85ad28efe19b12fc2305ce (diff) | |
download | external_llvm-bf47fdb91c3bc7c26fb7eb6096ca3657c69bd26f.zip external_llvm-bf47fdb91c3bc7c26fb7eb6096ca3657c69bd26f.tar.gz external_llvm-bf47fdb91c3bc7c26fb7eb6096ca3657c69bd26f.tar.bz2 |
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
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfDebug.cpp')
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 589 |
1 files changed, 101 insertions, 488 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 20507f5..003cc8c 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -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 (CurrentFnDbgScope) { + if (!MMI->hasDebugInfo() || LScopes.empty()) return; - // 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. |