[llvm-commits] [llvm] r61908 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp

Evan Cheng echeng at apple.com
Thu Jan 8 13:38:45 PST 2009


On Jan 7, 2009, at 6:33 PM, Devang Patel wrote:

> Author: dpatel
> Date: Wed Jan  7 20:33:41 2009
> New Revision: 61908
>
> URL: http://llvm.org/viewvc/llvm-project?rev=61908&view=rev
> Log:
> Add APIs to manage scope using DebugInfo interface.
> This is a shameless copy of similar APIs from MachineModuleInfo. The  
> copy from MMI will be deleted in near future.
>
> Modified:
>    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=61908&r1=61907&r2=61908&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Wed Jan  7  
> 20:33:41 2009
> @@ -1193,6 +1193,60 @@
> };
>
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +/// DbgVariable - This class is used to track local variable  
> information.
> +///
> +class DbgVariable {
> +private:
> +  DIVariable *Var;                   // Variable Descriptor.
> +  unsigned FrameIndex;               // Variable frame index.
> +
> +public:
> +  DbgVariable(DIVariable *V, unsigned I) : Var(V), FrameIndex(I)  {}
> +
> +  // Accessors.
> +  DIVariable *getVariable()  const { return Var; }
> +  unsigned getFrameIndex() const { return FrameIndex; }
> +};
> +
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +/// DbgScope - This class is used to track scope information.
> +///
> +class DbgScope {
> +private:
> +  DbgScope *Parent;                   // Parent to this scope.
> +  DIDescriptor *Desc;                 // Debug info descriptor for  
> scope.
> +                                      // Either subprogram or block.
> +  unsigned StartLabelID;              // Label ID of the beginning  
> of scope.
> +  unsigned EndLabelID;                // Label ID of the end of  
> scope.
> +  SmallVector<DbgScope *, 8> Scopes;     // Scopes defined in scope.
> +  SmallVector<DbgVariable *, 32> Variables;// Variables declared in  
> scope.

32 seems a bit excessive, no?

Evan

>
> +
> +public:
> +  DbgScope(DbgScope *P, DIDescriptor *D)
> +  : Parent(P), Desc(D), StartLabelID(0), EndLabelID(0), Scopes(),  
> Variables()
> +  {}
> +  ~DbgScope();
> +
> +  // Accessors.
> +  DbgScope *getParent()        const { return Parent; }
> +  DIDescriptor *getDesc()       const { return Desc; }
> +  unsigned getStartLabelID()     const { return StartLabelID; }
> +  unsigned getEndLabelID()       const { return EndLabelID; }
> +  SmallVector<DbgScope *, 8> &getScopes() { return Scopes; }
> +  SmallVector<DbgVariable *, 32> &getVariables() { return  
> Variables; }

Return SmallVectorImpl instead?


Evan

>
> +  void setStartLabelID(unsigned S) { StartLabelID = S; }
> +  void setEndLabelID(unsigned E)   { EndLabelID = E; }
> +
> +  /// 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); }
> +};
> +
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> /// DwarfDebug - Emits Dwarf debug directives.
> ///
> class DwarfDebug : public Dwarf {
> @@ -1253,6 +1307,44 @@
>   ///
>   bool shouldEmit;
>
> +  // RootScope - Top level scope for the current function.
> +  //
> +  DbgScope *RootDbgScope;
> +
> +  // DbgScopeMap - Tracks the scopes in the current function.
> +  DenseMap<GlobalVariable *, DbgScope *> DbgScopeMap;
> +
> +  // DbgLabelIDList - One entry per assigned label.  Normally the  
> entry is equal to
> +  // the list index(+1).  If the entry is zero then the label has  
> been deleted.
> +  // Any other value indicates the label has been deleted by is  
> mapped to
> +  // another label.
> +  SmallVector<unsigned, 32> DbgLabelIDList;
> +
> +  /// NextLabelID - Return the next unique label id.
> +  ///
> +  unsigned NextLabelID() {
> +    unsigned ID = (unsigned)DbgLabelIDList.size() + 1;
> +    DbgLabelIDList.push_back(ID);
> +    return ID;
> +  }
> +
> +  /// RemapLabel - Indicate that a label has been merged into  
> another.
> +  ///
> +  void RemapLabel(unsigned OldLabelID, unsigned NewLabelID) {
> +    assert(0 < OldLabelID && OldLabelID <= DbgLabelIDList.size() &&
> +          "Old label ID out of range.");
> +    assert(NewLabelID <= DbgLabelIDList.size() &&
> +          "New label ID out of range.");
> +    DbgLabelIDList[OldLabelID - 1] = NewLabelID;
> +  }
> +
> +  /// MappedLabel - Find out the label's final ID.  Zero indicates  
> deletion.
> +  /// ID != Mapped ID indicates that the label was folded into  
> another label.
> +  unsigned MappedLabel(unsigned LabelID) const {
> +    assert(LabelID <= DbgLabelIDList.size() && "Debug label ID out  
> of range.");
> +    return LabelID ? DbgLabelIDList[LabelID - 1] : 0;
> +  }
> +
>   struct FunctionDebugFrameInfo {
>     unsigned Number;
>     std::vector<MachineMove> Moves;
> @@ -1494,6 +1586,25 @@
>
>   /// AddSourceLine - Add location information to specified debug  
> information
>   /// entry.
> +  void AddSourceLine(DIE *Die, DIVariable *V) {
> +    unsigned FileID = 0;
> +    unsigned Line = V->getLineNumber();
> +    if (V->getVersion() < DIDescriptor::Version7) {
> +      // Version6 or earlier. Use compile unit info to get file id.
> +      CompileUnit *Unit = FindCompileUnit(V->getCompileUnit());
> +      FileID = Unit->getID();
> +    } else {
> +      // Version7 or newer, use filename and directory info from  
> DIVariable
> +      // directly.
> +      unsigned DID = Directories.idFor(V->getDirectory());
> +      FileID = SrcFiles.idFor(SrcFileInfo(DID, V->getFilename()));
> +    }
> +    AddUInt(Die, DW_AT_decl_file, 0, FileID);
> +    AddUInt(Die, DW_AT_decl_line, 0, Line);
> +  }
> +
> +  /// AddSourceLine - Add location information to specified debug  
> information
> +  /// entry.
>   void AddSourceLine(DIE *Die, DIGlobal *G) {
>     unsigned FileID = 0;
>     unsigned Line = G->getLineNumber();
> @@ -2393,6 +2504,191 @@
>     return VariableDie;
>   }
>
> +  /// NewScopeVariable - Create a new scope variable.
> +  ///
> +  DIE *NewDbgScopeVariable(DbgVariable *DV, CompileUnit *Unit) {
> +    // Get the descriptor.
> +    DIVariable *VD = DV->getVariable();
> +
> +    // Translate tag to proper Dwarf tag.  The result variable is  
> dropped for
> +    // now.
> +    unsigned Tag;
> +    switch (VD->getTag()) {
> +    case DW_TAG_return_variable:  return NULL;
> +    case DW_TAG_arg_variable:     Tag = DW_TAG_formal_parameter;  
> break;
> +    case DW_TAG_auto_variable:    // fall thru
> +    default:                      Tag = DW_TAG_variable; break;
> +    }
> +
> +    // Define variable debug information entry.
> +    DIE *VariableDie = new DIE(Tag);
> +    AddString(VariableDie, DW_AT_name, DW_FORM_string, VD- 
> >getName());
> +
> +    // Add source line info if available.
> +    AddSourceLine(VariableDie, VD);
> +
> +    // Add variable type.
> +    AddType(Unit, VariableDie, VD->getType());
> +
> +    // Add variable address.
> +    MachineLocation Location;
> +    Location.set(RI->getFrameRegister(*MF),
> +                 RI->getFrameIndexOffset(*MF, DV->getFrameIndex()));
> +    AddAddress(VariableDie, DW_AT_location, Location);
> +
> +    return VariableDie;
> +  }
> +
> +
> +  /// getOrCreateScope - Returns the scope associated with the  
> given descriptor.
> +  ///
> +  DbgScope *getOrCreateScope(GlobalVariable *V) {
> +    DbgScope *&Slot = DbgScopeMap[V];
> +    if (!Slot) {
> +      // FIXME - breaks down when the context is an inlined function.
> +      DIDescriptor ParentDesc;
> +      DIBlock *DB = new DIBlock(V);
> +      if (DIBlock *Block = dyn_cast<DIBlock>(DB)) {
> +        ParentDesc = Block->getContext();
> +      }
> +      DbgScope *Parent = ParentDesc.isNull() ?
> +        getOrCreateScope(ParentDesc.getGV()) : NULL;
> +      Slot = new DbgScope(Parent, DB);
> +      if (Parent) {
> +        Parent->AddScope(Slot);
> +      } else if (RootDbgScope) {
> +        // FIXME - Add inlined function scopes to the root so we  
> can delete
> +        // them later.  Long term, handle inlined functions properly.
> +        RootDbgScope->AddScope(Slot);
> +      } else {
> +        // First function is top level function.
> +        RootDbgScope = Slot;
> +      }
> +    }
> +    return Slot;
> +  }
> +
> +  /// ConstructDbgScope - Construct the components of a scope.
> +  ///
> +  void ConstructDbgScope(DbgScope *ParentScope,
> +                         unsigned ParentStartID, unsigned  
> ParentEndID,
> +                         DIE *ParentDie, CompileUnit *Unit) {
> +    // Add variables to scope.
> +    SmallVector<DbgVariable *, 32> &Variables = ParentScope- 
> >getVariables();
> +    for (unsigned i = 0, N = Variables.size(); i < N; ++i) {
> +      DIE *VariableDie = NewDbgScopeVariable(Variables[i], Unit);
> +      if (VariableDie) ParentDie->AddChild(VariableDie);
> +    }
> +
> +    // Add nested scopes.
> +    SmallVector<DbgScope *, 8> &Scopes = ParentScope->getScopes();
> +    for (unsigned j = 0, M = Scopes.size(); j < M; ++j) {
> +      // Define the Scope debug information entry.
> +      DbgScope *Scope = Scopes[j];
> +      // FIXME - Ignore inlined functions for the time being.
> +      if (!Scope->getParent()) continue;
> +
> +      unsigned StartID = MappedLabel(Scope->getStartLabelID());
> +      unsigned EndID = MappedLabel(Scope->getEndLabelID());
> +
> +      // Ignore empty scopes.
> +      if (StartID == EndID && StartID != 0) continue;
> +      if (Scope->getScopes().empty() && Scope- 
> >getVariables().empty()) continue;
> +
> +      if (StartID == ParentStartID && EndID == ParentEndID) {
> +        // Just add stuff to the parent scope.
> +        ConstructDbgScope(Scope, ParentStartID, ParentEndID,  
> ParentDie, Unit);
> +      } else {
> +        DIE *ScopeDie = new DIE(DW_TAG_lexical_block);
> +
> +        // Add the scope bounds.
> +        if (StartID) {
> +          AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr,
> +                             DWLabel("label", StartID));
> +        } else {
> +          AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr,
> +                             DWLabel("func_begin", SubprogramCount));
> +        }
> +        if (EndID) {
> +          AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr,
> +                             DWLabel("label", EndID));
> +        } else {
> +          AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr,
> +                             DWLabel("func_end", SubprogramCount));
> +        }
> +
> +        // Add the scope contents.
> +        ConstructDbgScope(Scope, StartID, EndID, ScopeDie, Unit);
> +        ParentDie->AddChild(ScopeDie);
> +      }
> +    }
> +  }
> +
> +  /// ConstructRootDbgScope - Construct the scope for the subprogram.
> +  ///
> +  void ConstructRootDbgScope(DbgScope *RootScope) {
> +    // Exit if there is no root scope.
> +    if (!RootScope) return;
> +
> +    // Get the subprogram debug information entry.
> +    DISubprogram *SPD = cast<DISubprogram>(RootScope->getDesc());
> +
> +    // Get the compile unit context.
> +    CompileUnit *Unit = FindCompileUnit(SPD->getCompileUnit());
> +
> +    // Get the subprogram die.
> +    DIE *SPDie = Unit->getDieMapSlotFor(SPD->getGV());
> +    assert(SPDie && "Missing subprogram descriptor");
> +
> +    // Add the function bounds.
> +    AddLabel(SPDie, DW_AT_low_pc, DW_FORM_addr,
> +                    DWLabel("func_begin", SubprogramCount));
> +    AddLabel(SPDie, DW_AT_high_pc, DW_FORM_addr,
> +                    DWLabel("func_end", SubprogramCount));
> +    MachineLocation Location(RI->getFrameRegister(*MF));
> +    AddAddress(SPDie, DW_AT_frame_base, Location);
> +
> +    ConstructDbgScope(RootScope, 0, 0, SPDie, Unit);
> +  }
> +
> +  /// ConstructDefaultDbgScope - Construct a default scope for the  
> subprogram.
> +  ///
> +  void ConstructDefaultDbgScope(MachineFunction *MF) {
> +    // Find the correct subprogram descriptor.
> +    std::string SPName = "llvm.dbg.subprograms";
> +    std::vector<GlobalVariable*> Result;
> +    getGlobalVariablesUsing(*M, SPName, Result);
> +    for (std::vector<GlobalVariable *>::iterator I = Result.begin(),
> +           E = Result.end(); I != E; ++I) {
> +
> +      DISubprogram *SPD = new DISubprogram(*I);
> +
> +      if (SPD->getName() == MF->getFunction()->getName()) {
> +        // Get the compile unit context.
> +        CompileUnit *Unit = FindCompileUnit(SPD->getCompileUnit());
> +
> +        // Get the subprogram die.
> +        DIE *SPDie = Unit->getDieMapSlotFor(SPD->getGV());
> +        assert(SPDie && "Missing subprogram descriptor");
> +
> +        // Add the function bounds.
> +        AddLabel(SPDie, DW_AT_low_pc, DW_FORM_addr,
> +                 DWLabel("func_begin", SubprogramCount));
> +        AddLabel(SPDie, DW_AT_high_pc, DW_FORM_addr,
> +                 DWLabel("func_end", SubprogramCount));
> +
> +        MachineLocation Location(RI->getFrameRegister(*MF));
> +        AddAddress(SPDie, DW_AT_frame_base, Location);
> +        return;
> +      }
> +    }
> +#if 0
> +    // FIXME: This is causing an abort because C++ mangled names  
> are compared
> +    // with their unmangled counterparts. See PR2885. Don't do this  
> assert.
> +    assert(0 && "Couldn't find DIE for machine function!");
> +#endif
> +  }
> +
>   /// ConstructScope - Construct the components of a scope.
>   ///
>   void ConstructScope(DebugScope *ParentScope,
> @@ -3282,6 +3578,7 @@
>   , SectionSourceLines()
>   , didInitial(false)
>   , shouldEmit(false)
> +  , RootDbgScope(NULL)
>   {
>   }
>   virtual ~DwarfDebug() {
>
>
> _______________________________________________
> 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