[llvm-commits] [llvm] r102004 - in /llvm/trunk/lib/CodeGen/AsmPrinter: DwarfDebug.cpp DwarfDebug.h
Dan Gohman
gohman at apple.com
Thu Apr 22 17:15:55 PDT 2010
Hi Devang,
This commit is breaking the llvm-gcc build on x86_64-unknown-linux-gnu systems, with
error messages from the assembler like this:
t.s:4675: Error: invalid sections for operation on `.Ltmp49' and `.Ltext_begin' setting `.Lset88'
t.s:4675: Error: invalid sections for operation on `.Ltmp60' and `.Ltext_begin' setting `.Lset89'
t.s:4675: Error: invalid sections for operation on `.Ltmp62' and `.Ltext_begin' setting `.Lset90'
Attached is a testcase in t.ll, which is reduced from compiling eh_alloc.cc for libsupc++.
Compile it with
llc -relocation-model=pic --ffunction-sections t.ll
I've also attached t.s, the assembly file this produces, and errors.txt, the errors
from the assembler trying to assemble it.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: t.ll
Type: application/octet-stream
Size: 90273 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20100422/84310c00/attachment.obj>
-------------- next part --------------
-------------- next part --------------
A non-text attachment was scrubbed...
Name: t.s
Type: application/octet-stream
Size: 208200 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20100422/84310c00/attachment-0001.obj>
-------------- next part --------------
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: errors.txt
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20100422/84310c00/attachment.txt>
-------------- next part --------------
Can you investigate this?
Thanks,
Dan
On Apr 21, 2010, at 9:32 AM, Devang Patel wrote:
> Author: dpatel
> Date: Wed Apr 21 11:32:19 2010
> New Revision: 102004
>
> URL: http://llvm.org/viewvc/llvm-project?rev=102004&view=rev
> Log:
> Identify when a lexical scope is split in to multiple instruction ranges. Emit such ranges using DW_AT_ranges.
>
> Modified:
> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=102004&r1=102003&r2=102004&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Wed Apr 21 11:32:19 2010
> @@ -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";
> @@ -185,6 +189,12 @@
> };
>
> //===----------------------------------------------------------------------===//
> +/// 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 {
> @@ -195,17 +205,19 @@
> 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 @@
> 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 @@
> ///
> 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 @@
>
> DwarfFrameSectionSym = DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0;
> DwarfStrSectionSym = TextSectionSym = 0;
> -
> + DwarfDebugRangeSectionSym = 0;
> if (TimePassesIsEnabled) {
> NamedRegionTimer T(DbgTimerName, DWARFGroupName);
> beginModule(M);
> @@ -1257,56 +1275,6 @@
> 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 @@
> /// 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());
> - 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;
>
> + 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!");
> +
> addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
> Start ? Start : Asm->GetTempSymbol("func_begin",
> Asm->getFunctionNumber()));
> @@ -1428,14 +1418,28 @@
> /// 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 @@
> 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 @@
> 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 @@
>
> /// 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 @@
> }
> }
>
> -/// 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 @@
> 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++;
> -
> - DebugLoc DL = MInsn->getDebugLoc();
> - if (DL.isUnknown()) continue;
> -
> - 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));
> - }
> - }
> + MDNode *Scope = NULL;
> + MDNode *InlinedAt = NULL;
>
> + // Check if instruction has valid location information.
> + if (!hasValidLocation(Ctx, MInsn, Scope, InlinedAt)) {
> + PrevMI = MInsn;
> + continue;
> + }
> +
> + // If scope has not changed then skip this instruction.
> + if (Scope == PrevScope && PrevInlinedAt == InlinedAt) {
> + PrevMI = MInsn;
> + continue;
> + }
>
> - // 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;
> + 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);
> + }
>
> - MDNode *Scope = DL.getScope(Ctx);
> - if (Scope == 0) continue;
> + // This is a beginning of a new instruction range.
> + RangeBeginMI = MInsn;
>
> - // 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);
> + // Reset previous markers.
> + PrevMI = MInsn;
> + PrevScope = Scope;
> + PrevInlinedAt = InlinedAt;
> }
> }
>
> + // 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 @@
>
> 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);
> + }
> }
> }
>
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=102004&r1=102003&r2=102004&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Wed Apr 21 11:32:19 2010
> @@ -368,13 +368,8 @@
> /// 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);
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list