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
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 0122d87..0e2e39e 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -855,7 +855,8 @@
/// 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 @@
}
}
- 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 @@
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 @@
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 @@
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 @@
I = DbgConcreteScopeMap.find(GV);
if (I == DbgConcreteScopeMap.end()) {
+ // FIXME: Can this situation actually happen? And if so, should it?
if (TimePassesIsEnabled)
DebugTimer->stopTimer();