From 314bf7cbbf7e27b47faa4e78d321ea16057ae6a0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 23 Apr 2010 01:18:53 +0000 Subject: [PATCH] Revert 102135, 102129, 102127, 102106, 102104, 102102, 102012, 102004, because 102004 causes codegen to emit invalid assembly on at least x86_64-unknown-gnu-linux. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102155 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 562 +++++++++----------------- lib/CodeGen/AsmPrinter/DwarfDebug.h | 26 +- 2 files changed, 212 insertions(+), 376 deletions(-) diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 06782423fe3..c31aec17590 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -32,7 +32,6 @@ #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" @@ -41,12 +40,6 @@ #include "llvm/System/Path.h" using namespace llvm; -static cl::opt PrintDbgScope("print-dbgscope", cl::Hidden, - cl::desc("Print DbgScope information for each machine instruction")); - -static cl::opt DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden, - cl::desc("Disable debug info printing")); - namespace { const char *DWARFGroupName = "DWARF Emission"; const char *DbgTimerName = "DWARF Debug Writer"; @@ -191,12 +184,6 @@ public: DIE *getDIE() const { return TheDIE; } }; -//===----------------------------------------------------------------------===// -/// DbgRange - This is used to track range of instructions with identical -/// debug info scope. -/// -typedef std::pair DbgRange; - //===----------------------------------------------------------------------===// /// DbgScope - This class is used to track scope information. /// @@ -208,19 +195,17 @@ 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 Scopes; // Variables declared in scope. Contents owned. SmallVector Variables; - SmallVector 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), - DFSIn(0), DFSOut(0), IndentLevel(0) {} + LastInsn(0), FirstInsn(0), IndentLevel(0) {} virtual ~DbgScope(); // Accessors. @@ -231,55 +216,12 @@ public: MDNode *getScopeNode() const { return Desc.getNode(); } const SmallVector &getScopes() { return Scopes; } const SmallVector &getVariables() { return Variables; } - const SmallVector &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 setLastInsn(const MachineInstr *MI) { LastInsn = MI; } + const MachineInstr *getLastInsn() { return LastInsn; } + void setFirstInsn(const MachineInstr *MI) { FirstInsn = MI; } void setAbstractScope() { AbstractScope = true; } bool isAbstractScope() const { return AbstractScope; } - - // 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; - } + const MachineInstr *getFirstInsn() { return FirstInsn; } /// addScope - Add a scope to the scope. /// @@ -289,11 +231,48 @@ public: /// void addVariable(DbgVariable *V) { Variables.push_back(V); } + void fixInstructionMarkers(DenseMap &MIIndexMap) { + assert(getFirstInsn() && "First instruction is missing!"); + + // Use the end of last child scope as end of this scope. + const SmallVector &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::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 @@ -329,8 +308,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) DwarfFrameSectionSym = DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0; DwarfStrSectionSym = TextSectionSym = 0; - DwarfDebugRangeSectionSym = 0; - FunctionBeginSym = 0; + if (TimePassesIsEnabled) { NamedRegionTimer T(DbgTimerName, DWARFGroupName); beginModule(M); @@ -1279,6 +1257,56 @@ 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!"); @@ -1375,54 +1403,23 @@ 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) { - - DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block); - if (Scope->isAbstractScope()) - return ScopeDIE; - - const SmallVector &Ranges = Scope->getRanges(); - if (Ranges.empty()) - return 0; - - bool MarkFunctionBegin = false; - if (FunctionBeginSym && - Asm->MF->getFunction()->isWeakForLinker()) - MarkFunctionBegin = true; - - SmallVector::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::const_iterator RI = Ranges.begin(), - RE = Ranges.end(); RI != RE; ++RI) { - MCSymbol *Sym = LabelsBeforeInsn.lookup(RI->first); - if (MarkFunctionBegin) - WeakDebugRangeSymbols.insert(std::make_pair(Sym, FunctionBeginSym)); - DebugRangeSymbols.push_back(Sym); - - Sym = LabelsAfterInsn.lookup(RI->second); - if (MarkFunctionBegin) - WeakDebugRangeSymbols.insert(std::make_pair(Sym, FunctionBeginSym)); - DebugRangeSymbols.push_back(Sym); - } - DebugRangeSymbols.push_back(NULL); - DebugRangeSymbols.push_back(NULL); - return ScopeDIE; - } - - MCSymbol *Start = LabelsBeforeInsn.lookup(RI->first); - MCSymbol *End = LabelsAfterInsn.lookup(RI->second); - + + MCSymbol *Start = InsnBeforeLabelMap.lookup(Scope->getFirstInsn()); + MCSymbol *End = InsnAfterLabelMap.lookup(Scope->getLastInsn()); 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!"); - addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, Start); - addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, End); + 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())); + addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, + End ? End : Asm->GetTempSymbol("func_end",Asm->getFunctionNumber())); return ScopeDIE; } @@ -1431,28 +1428,14 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) { /// a function. Construct DIE to represent this concrete inlined copy /// of the function. DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) { - - const SmallVector &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::const_iterator RI = Ranges.begin(); - MCSymbol *StartLabel = LabelsBeforeInsn.lookup(RI->first); - MCSymbol *EndLabel = LabelsAfterInsn.lookup(RI->second); - - if (StartLabel == 0 || EndLabel == 0) { - assert (0 && "Unexpected Start and End labels for a inlined scope!"); - return 0; - } + MCSymbol *StartLabel = InsnBeforeLabelMap.lookup(Scope->getFirstInsn()); + MCSymbol *EndLabel = InsnAfterLabelMap.lookup(Scope->getLastInsn()); + if (StartLabel == 0 || EndLabel == 0) 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()); @@ -1866,9 +1849,6 @@ void DwarfDebug::constructSubprogramDIE(MDNode *N) { /// content. Create global DIEs and emit initial debug info sections. /// This is inovked by the target AsmPrinter. void DwarfDebug::beginModule(Module *M) { - if (DisableDebugInfoPrinting) - return; - DebugInfoFinder DbgFinder; DbgFinder.processModule(*M); @@ -2131,6 +2111,10 @@ 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! @@ -2142,174 +2126,65 @@ void DwarfDebug::beginScope(const MachineInstr *MI) { DenseMap::iterator DI = DbgValueStartMap.find(MI); if (DI != DbgValueStartMap.end()) { - MCSymbol *Label = NULL; - if (DL == PrevInstLoc) - Label = PrevLabel; - else { - Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope); - PrevInstLoc = DL; - PrevLabel = Label; - } + MCSymbol *Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope); + PrevInstLoc = DL; DI->second->setDbgValueLabel(Label); } return; } // Emit a label to indicate location change. This is used for line - // 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; - } + // table even if this instruction does start a new scope. + MCSymbol *Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope); + PrevInstLoc = DL; // If this instruction begins a scope then note down corresponding label. if (InsnsBeginScopeSet.count(MI) != 0) - LabelsBeforeInsn[MI] = Label; + InsnBeforeLabelMap[MI] = Label; } /// 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(); Asm->OutStreamer.EmitLabel(Label); - LabelsAfterInsn[MI] = Label; + InsnAfterLabelMap[MI] = Label; } } -/// getOrCreateDbgScope - Create DbgScope for the scope. -DbgScope *DwarfDebug::getOrCreateDbgScope(MDNode *Scope, MDNode *InlinedAt) { +/// createDbgScope - Create DbgScope for the scope. +void DwarfDebug::createDbgScope(MDNode *Scope, MDNode *InlinedAt) { if (!InlinedAt) { DbgScope *WScope = DbgScopeMap.lookup(Scope); if (WScope) - return WScope; + return; WScope = new DbgScope(NULL, DIDescriptor(Scope), NULL); DbgScopeMap.insert(std::make_pair(Scope, WScope)); - 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; + if (DIDescriptor(Scope).isLexicalBlock()) + createDbgScope(DILexicalBlock(Scope).getContext().getNode(), NULL); + return; } DbgScope *WScope = DbgScopeMap.lookup(InlinedAt); if (WScope) - return WScope; + return; WScope = new DbgScope(NULL, DIDescriptor(Scope), InlinedAt); DbgScopeMap.insert(std::make_pair(InlinedAt, WScope)); DILocation DL(InlinedAt); - DbgScope *Parent = - getOrCreateDbgScope(DL.getScope().getNode(), DL.getOrigLocation().getNode()); - WScope->setParent(Parent); - Parent->addScope(WScope); - - ConcreteScopes[InlinedAt] = WScope; - getOrCreateAbstractScope(Scope); - - return WScope; + createDbgScope(DL.getScope().getNode(), DL.getOrigLocation().getNode()); } -/// 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 WorkStack; - WorkStack.push_back(Scope); - unsigned Counter = 0; - while (!WorkStack.empty()) { - DbgScope *WS = WorkStack.back(); - const SmallVector &Children = WS->getScopes(); - bool visitedChildren = false; - for (SmallVector::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 &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::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() { @@ -2318,100 +2193,80 @@ bool DwarfDebug::extractScopeInformation() { if (!DbgScopeMap.empty()) return false; - // Scan each instruction and create scopes. First build working set of scopes. + DenseMap MIIndexMap; + unsigned MIIndex = 0; LLVMContext &Ctx = Asm->MF->getFunction()->getContext(); - SmallVector MIRanges; - DenseMap MI2ScopeMap; - MDNode *PrevScope = NULL; - MDNode *PrevInlinedAt = NULL; - const MachineInstr *RangeBeginMI = NULL; - const MachineInstr *PrevMI = NULL; + + // Scan each instruction and create scopes. First build 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; - MDNode *Scope = NULL; - MDNode *InlinedAt = NULL; - - // Check if instruction has valid location information. - if (!hasValidLocation(Ctx, MInsn, Scope, InlinedAt)) { - PrevMI = MInsn; - continue; - } + // FIXME : Remove DBG_VALUE check. + if (MInsn->isDebugValue()) continue; + MIIndexMap[MInsn] = MIIndex++; - // 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; + DebugLoc DL = MInsn->getDebugLoc(); + if (DL.isUnknown()) continue; - // Reset previous markers. - PrevMI = MInsn; - PrevScope = Scope; - PrevInlinedAt = InlinedAt; + 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)); } } - // Create last instruction range. - if (RangeBeginMI && PrevMI && PrevScope) { - DbgRange R(RangeBeginMI, PrevMI); - MIRanges.push_back(R); - MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevScope, PrevInlinedAt); + + // 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); + } } - + if (!CurrentFnDbgScope) return false; - calculateDominanceGraph(CurrentFnDbgScope); - if (PrintDbgScope) - printDbgScopeInfo(Ctx, Asm->MF, MI2ScopeMap); - - // Find ranges of instructions covered by each DbgScope; - DbgScope *PrevDbgScope = NULL; - for (SmallVector::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(); + CurrentFnDbgScope->fixInstructionMarkers(MIIndexMap); identifyScopeMarkers(); return !DbgScopeMap.empty(); } -/// 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. +/// identifyScopeMarkers() - Indentify instructions that are marking +/// beginning of or end of a scope. 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 WorkList; WorkList.push_back(CurrentFnDbgScope); while (!WorkList.empty()) { DbgScope *S = WorkList.pop_back_val(); - + const SmallVector &Children = S->getScopes(); if (!Children.empty()) for (SmallVector::const_iterator SI = Children.begin(), @@ -2420,17 +2275,11 @@ void DwarfDebug::identifyScopeMarkers() { if (S->isAbstractScope()) continue; - - const SmallVector &Ranges = S->getRanges(); - if (Ranges.empty()) - continue; - for (SmallVector::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); - } + 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()); } } @@ -2457,10 +2306,9 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { collectVariableInfo(); - FunctionBeginSym = Asm->GetTempSymbol("func_begin", - Asm->getFunctionNumber()); // Assumes in correct section after the entry point. - Asm->OutStreamer.EmitLabel(FunctionBeginSym); + Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_begin", + Asm->getFunctionNumber())); // Emit label for the implicitly defined dbg.stoppoint at the start of the // function. @@ -2524,8 +2372,8 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { DeleteContainerSeconds(AbstractScopes); AbstractScopesList.clear(); AbstractVariables.clear(); - LabelsBeforeInsn.clear(); - LabelsAfterInsn.clear(); + InsnBeforeLabelMap.clear(); + InsnAfterLabelMap.clear(); Lines.clear(); PrevLabel = NULL; } @@ -3240,21 +3088,11 @@ void DwarfDebug::emitDebugRanges() { // Start the dwarf ranges section. Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfRangesSection()); - for (SmallVector::const_iterator - I = DebugRangeSymbols.begin(), E = DebugRangeSymbols.end(); - I != E; ++I) { - if (*I) { - const MCSymbol *Begin = TextSectionSym; - // If this symbol is inside linkonce section then use appropriate begin - // marker; - DenseMap::iterator WI - = WeakDebugRangeSymbols.find(*I); - if (WI != WeakDebugRangeSymbols.end()) - Begin = WI->second; - - Asm->EmitLabelDifference(*I, Begin, + for (SmallVector::const_iterator I = DebugRangeSymbols.begin(), + E = DebugRangeSymbols.end(); I != E; ++I) { + if (*I) + Asm->EmitLabelDifference(*I, TextSectionSym, Asm->getTargetData().getPointerSize()); - } else Asm->OutStreamer.EmitIntValue(0, Asm->getTargetData().getPointerSize(), /*addrspace*/0); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 16d41370535..bfd6f48d2e3 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -188,22 +188,16 @@ class DwarfDebug { DenseMap > InlineInfo; SmallVector InlinedSPNodes; - /// LabelsBeforeInsn - Maps instruction with label emitted before + /// InsnBeforeLabelMap - Maps instruction with label emitted before /// instruction. - DenseMap LabelsBeforeInsn; + DenseMap InsnBeforeLabelMap; - /// LabelsAfterInsn - Maps instruction with label emitted after + /// InsnAfterLabelMap - Maps instruction with label emitted after /// instruction. - DenseMap LabelsAfterInsn; + DenseMap InsnAfterLabelMap; SmallVector DebugRangeSymbols; - /// weakDebugRangeSymbols - In cases where function bodies is not emitted - /// into .text section, use function begin marker as anchor for debug range - /// offsets. This map keeps track of such symbols and corresponding - /// function begin marker symbols. - DenseMap WeakDebugRangeSymbols; - /// Previous instruction's location information. This is used to determine /// label location to indicate scope boundries in dwarf debug info. DebugLoc PrevInstLoc; @@ -224,8 +218,7 @@ class DwarfDebug { // section offsets and are created by EmitSectionLabels. MCSymbol *DwarfFrameSectionSym, *DwarfInfoSectionSym, *DwarfAbbrevSectionSym; MCSymbol *DwarfStrSectionSym, *TextSectionSym, *DwarfDebugRangeSectionSym; - - MCSymbol *FunctionBeginSym; + private: /// getSourceDirectoryAndFileIds - Return the directory and file ids that @@ -375,8 +368,13 @@ private: /// createSubprogramDIE - Create new DIE using SP. DIE *createSubprogramDIE(const DISubprogram &SP, bool MakeDecl = false); - /// getOrCreateDbgScope - Create DbgScope for the scope. - DbgScope *getOrCreateDbgScope(MDNode *Scope, MDNode *InlinedAt); + /// 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); DbgScope *getOrCreateAbstractScope(MDNode *N);