[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