mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	RecordVariable 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72047 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -855,7 +855,8 @@ DIE *DwarfDebug::CreateMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT){ | |||||||
| /// CreateSubprogramDIE - Create new DIE using SP. | /// CreateSubprogramDIE - Create new DIE using SP. | ||||||
| DIE *DwarfDebug::CreateSubprogramDIE(CompileUnit *DW_Unit, | DIE *DwarfDebug::CreateSubprogramDIE(CompileUnit *DW_Unit, | ||||||
|                                      const DISubprogram &SP, |                                      const DISubprogram &SP, | ||||||
|                                      bool IsConstructor) { |                                      bool IsConstructor, | ||||||
|  |                                      bool IsInlined) { | ||||||
|   DIE *SPDie = new DIE(dwarf::DW_TAG_subprogram); |   DIE *SPDie = new DIE(dwarf::DW_TAG_subprogram); | ||||||
|  |  | ||||||
|   std::string Name; |   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); |     AddUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); | ||||||
|  |  | ||||||
|   // DW_TAG_inlined_subroutine may refer to this DIE. |   // DW_TAG_inlined_subroutine may refer to this DIE. | ||||||
| @@ -2425,7 +2426,7 @@ unsigned DwarfDebug::RecordRegionEnd(GlobalVariable *V) { | |||||||
|   return ID; |   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, | void DwarfDebug::RecordVariable(GlobalVariable *GV, unsigned FrameIndex, | ||||||
|                                 const MachineInstr *MI) { |                                 const MachineInstr *MI) { | ||||||
|   if (TimePassesIsEnabled) |   if (TimePassesIsEnabled) | ||||||
| @@ -2453,12 +2454,33 @@ void DwarfDebug::RecordVariable(GlobalVariable *GV, unsigned FrameIndex, | |||||||
|       DenseMap<const GlobalVariable *, DbgScope *>::iterator |       DenseMap<const GlobalVariable *, DbgScope *>::iterator | ||||||
|         AI = AbstractInstanceRootMap.find(V); |         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. |         // or GV is an inlined local variable. | ||||||
|         Scope = AI->second; |         Scope = AI->second; | ||||||
|       else |         InlinedParamMap[V].insert(GV); | ||||||
|  |       } else { | ||||||
|         // or GV is a local variable. |         // or GV is a local variable. | ||||||
|         Scope = getOrCreateScope(V); |         Scope = getOrCreateScope(V); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -2494,13 +2516,13 @@ unsigned DwarfDebug::RecordInlinedFnStart(DISubprogram &SP, DICompileUnit CU, | |||||||
|     CompileUnit *Unit = &FindCompileUnit(SP.getCompileUnit()); |     CompileUnit *Unit = &FindCompileUnit(SP.getCompileUnit()); | ||||||
|     DIE *SPDie = Unit->getDieMapSlotFor(GV); |     DIE *SPDie = Unit->getDieMapSlotFor(GV); | ||||||
|     if (!SPDie) |     if (!SPDie) | ||||||
|       SPDie = CreateSubprogramDIE(Unit, SP); |       SPDie = CreateSubprogramDIE(Unit, SP, false, true); | ||||||
|  |  | ||||||
|     // Mark as being inlined. This makes this subprogram entry an abstract |     // Mark as being inlined. This makes this subprogram entry an abstract | ||||||
|     // instance root. |     // instance root. | ||||||
|     // FIXME: Our debugger doesn't care about the value of DW_AT_inline, only |     // 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 |     // that it's defined. That probably won't change in the future. However, | ||||||
|     // could be more elegant. |     // this could be more elegant. | ||||||
|     AddUInt(SPDie, dwarf::DW_AT_inline, 0, dwarf::DW_INL_declared_not_inlined); |     AddUInt(SPDie, dwarf::DW_AT_inline, 0, dwarf::DW_INL_declared_not_inlined); | ||||||
|  |  | ||||||
|     // Keep track of the abstract scope for this function. |     // Keep track of the abstract scope for this function. | ||||||
| @@ -2566,6 +2588,7 @@ unsigned DwarfDebug::RecordInlinedFnEnd(DISubprogram &SP) { | |||||||
|     I = DbgConcreteScopeMap.find(GV); |     I = DbgConcreteScopeMap.find(GV); | ||||||
|  |  | ||||||
|   if (I == DbgConcreteScopeMap.end()) { |   if (I == DbgConcreteScopeMap.end()) { | ||||||
|  |     // FIXME: Can this situation actually happen? And if so, should it? | ||||||
|     if (TimePassesIsEnabled) |     if (TimePassesIsEnabled) | ||||||
|       DebugTimer->stopTimer(); |       DebugTimer->stopTimer(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ | |||||||
| #include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | ||||||
| #include "llvm/ADT/DenseMap.h" | #include "llvm/ADT/DenseMap.h" | ||||||
| #include "llvm/ADT/FoldingSet.h" | #include "llvm/ADT/FoldingSet.h" | ||||||
|  | #include "llvm/ADT/SmallSet.h" | ||||||
| #include "llvm/ADT/StringMap.h" | #include "llvm/ADT/StringMap.h" | ||||||
| #include "llvm/ADT/UniqueVector.h" | #include "llvm/ADT/UniqueVector.h" | ||||||
| #include <string> | #include <string> | ||||||
| @@ -163,6 +164,11 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf { | |||||||
|   /// attribute. |   /// attribute. | ||||||
|   DenseMap<const GlobalVariable *, DbgScope *> AbstractInstanceRootMap; |   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 |   /// AbstractInstanceRootList - List of abstract instance roots of inlined | ||||||
|   /// functions. These are subroutine entries that contain a DW_AT_inline |   /// functions. These are subroutine entries that contain a DW_AT_inline | ||||||
|   /// attribute. |   /// attribute. | ||||||
| @@ -333,7 +339,8 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf { | |||||||
|   /// CreateSubprogramDIE - Create new DIE using SP. |   /// CreateSubprogramDIE - Create new DIE using SP. | ||||||
|   DIE *CreateSubprogramDIE(CompileUnit *DW_Unit, |   DIE *CreateSubprogramDIE(CompileUnit *DW_Unit, | ||||||
|                            const DISubprogram &SP, |                            const DISubprogram &SP, | ||||||
|                            bool IsConstructor = false); |                            bool IsConstructor = false, | ||||||
|  |                            bool IsInlined = false); | ||||||
|  |  | ||||||
|   /// FindCompileUnit - Get the compile unit for the given descriptor.  |   /// FindCompileUnit - Get the compile unit for the given descriptor.  | ||||||
|   /// |   /// | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user