mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-10-11 23:25:15 +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:
parent
94c9cd17de
commit
6679ee4e80
@ -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.
|
||||||
@ -2453,14 +2454,35 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert(Scope && "Unable to find the variable's scope");
|
assert(Scope && "Unable to find the variable's scope");
|
||||||
DbgVariable *DV = new DbgVariable(DIVariable(GV), FrameIndex);
|
DbgVariable *DV = new DbgVariable(DIVariable(GV), FrameIndex);
|
||||||
@ -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.
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user