diff options
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 39 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 9 | 
2 files changed, 39 insertions, 9 deletions
| diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 0122d87a9f3..0e2e39eea23 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -855,7 +855,8 @@ DIE *DwarfDebug::CreateMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT){  /// CreateSubprogramDIE - Create new DIE using SP.  DIE *DwarfDebug::CreateSubprogramDIE(CompileUnit *DW_Unit,                                       const DISubprogram &SP, -                                     bool IsConstructor) { +                                     bool IsConstructor, +                                     bool IsInlined) {    DIE *SPDie = new DIE(dwarf::DW_TAG_subprogram);    std::string Name; @@ -903,7 +904,7 @@ DIE *DwarfDebug::CreateSubprogramDIE(CompileUnit *DW_Unit,        }    } -  if (!SP.isLocalToUnit()) +  if (!SP.isLocalToUnit() && !IsInlined)      AddUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);    // DW_TAG_inlined_subroutine may refer to this DIE. @@ -2425,7 +2426,7 @@ unsigned DwarfDebug::RecordRegionEnd(GlobalVariable *V) {    return ID;  } -/// RecordVariable - Indicate the declaration of  a local variable. +/// RecordVariable - Indicate the declaration of a local variable.  void DwarfDebug::RecordVariable(GlobalVariable *GV, unsigned FrameIndex,                                  const MachineInstr *MI) {    if (TimePassesIsEnabled) @@ -2453,12 +2454,33 @@ void DwarfDebug::RecordVariable(GlobalVariable *GV, unsigned FrameIndex,        DenseMap<const GlobalVariable *, DbgScope *>::iterator          AI = AbstractInstanceRootMap.find(V); -      if (AI != AbstractInstanceRootMap.end()) +      if (AI != AbstractInstanceRootMap.end()) { +        // This method is called each time a DECLARE node is encountered. For an +        // inlined function, this could be many, many times. We don't want to +        // re-add variables to that DIE for each time. We just want to add them +        // once. Check to make sure that we haven't added them already. +        DenseMap<const GlobalVariable *, +          SmallSet<const GlobalVariable *, 32> >::iterator +          IP = InlinedParamMap.find(V); + +        if (IP != InlinedParamMap.end()) { +          SmallSet<const GlobalVariable*, 32> &S = IP->second; + +          if (S.count(GV) > 0) { +            if (TimePassesIsEnabled) +              DebugTimer->stopTimer(); +            return; +          } + +        } +          // or GV is an inlined local variable.          Scope = AI->second; -      else +        InlinedParamMap[V].insert(GV); +      } else {          // or GV is a local variable.          Scope = getOrCreateScope(V); +      }      }    } @@ -2494,13 +2516,13 @@ unsigned DwarfDebug::RecordInlinedFnStart(DISubprogram &SP, DICompileUnit CU,      CompileUnit *Unit = &FindCompileUnit(SP.getCompileUnit());      DIE *SPDie = Unit->getDieMapSlotFor(GV);      if (!SPDie) -      SPDie = CreateSubprogramDIE(Unit, SP); +      SPDie = CreateSubprogramDIE(Unit, SP, false, true);      // Mark as being inlined. This makes this subprogram entry an abstract      // instance root.      // FIXME: Our debugger doesn't care about the value of DW_AT_inline, only -    // that it's defined. It probably won't change in the future, but this -    // could be more elegant. +    // that it's defined. That probably won't change in the future. However, +    // this could be more elegant.      AddUInt(SPDie, dwarf::DW_AT_inline, 0, dwarf::DW_INL_declared_not_inlined);      // Keep track of the abstract scope for this function. @@ -2566,6 +2588,7 @@ unsigned DwarfDebug::RecordInlinedFnEnd(DISubprogram &SP) {      I = DbgConcreteScopeMap.find(GV);    if (I == DbgConcreteScopeMap.end()) { +    // FIXME: Can this situation actually happen? And if so, should it?      if (TimePassesIsEnabled)        DebugTimer->stopTimer(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 18afbdaab3a..a997199bed0 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -22,6 +22,7 @@  #include "llvm/Support/raw_ostream.h"  #include "llvm/ADT/DenseMap.h"  #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/SmallSet.h"  #include "llvm/ADT/StringMap.h"  #include "llvm/ADT/UniqueVector.h"  #include <string> @@ -163,6 +164,11 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf {    /// attribute.    DenseMap<const GlobalVariable *, DbgScope *> AbstractInstanceRootMap; +  /// InlinedParamMap - A map keeping track of which parameters are assigned to +  /// which abstract instance. +  DenseMap<const GlobalVariable *, +    SmallSet<const GlobalVariable *, 32> > InlinedParamMap; +    /// AbstractInstanceRootList - List of abstract instance roots of inlined    /// functions. These are subroutine entries that contain a DW_AT_inline    /// attribute. @@ -333,7 +339,8 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf {    /// CreateSubprogramDIE - Create new DIE using SP.    DIE *CreateSubprogramDIE(CompileUnit *DW_Unit,                             const DISubprogram &SP, -                           bool IsConstructor = false); +                           bool IsConstructor = false, +                           bool IsInlined = false);    /// FindCompileUnit - Get the compile unit for the given descriptor.     /// | 

