Use value semantics to manage DbgVariables rather than dynamic allocation/pointers.

Requires switching some vectors to lists to maintain pointer validity.
These could be changed to forward_lists (singly linked) with a bit more
work - I've left comments to that effect.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206780 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Blaikie
2014-04-21 20:13:09 +00:00
parent c5b286bc41
commit d0da5af325
2 changed files with 57 additions and 54 deletions

View File

@ -563,14 +563,13 @@ DIE *DwarfDebug::createScopeChildrenDIE(DwarfCompileUnit *TheCU,
// Collect arguments for current function. // Collect arguments for current function.
if (LScopes.isCurrentFunctionScope(Scope)) { if (LScopes.isCurrentFunctionScope(Scope)) {
for (DbgVariable *ArgDV : CurrentFnArguments) for (DbgVariable &ArgDV : CurrentFnArguments)
if (ArgDV) if (ArgDV.getVariable()) {
if (DIE *Arg = DIE *Arg = TheCU->constructVariableDIE(ArgDV, Scope->isAbstractScope());
TheCU->constructVariableDIE(*ArgDV, Scope->isAbstractScope())) { Children.push_back(Arg);
Children.push_back(Arg); if (ArgDV.isObjectPointer())
if (ArgDV->isObjectPointer()) ObjectPointer = Arg;
ObjectPointer = Arg; }
}
// If this is a variadic function, add an unspecified parameter. // If this is a variadic function, add an unspecified parameter.
DISubprogram SP(Scope->getScopeNode()); DISubprogram SP(Scope->getScopeNode());
@ -583,11 +582,11 @@ DIE *DwarfDebug::createScopeChildrenDIE(DwarfCompileUnit *TheCU,
} }
// Collect lexical scope children first. // Collect lexical scope children first.
for (DbgVariable *DV : ScopeVariables.lookup(Scope)) for (DbgVariable &DV : ScopeVariables.lookup(Scope))
if (DIE *Variable = TheCU->constructVariableDIE(*DV, if (DIE *Variable = TheCU->constructVariableDIE(DV,
Scope->isAbstractScope())) { Scope->isAbstractScope())) {
Children.push_back(Variable); Children.push_back(Variable);
if (DV->isObjectPointer()) if (DV.isObjectPointer())
ObjectPointer = Variable; ObjectPointer = Variable;
} }
for (LexicalScope *LS : Scope->getChildren()) for (LexicalScope *LS : Scope->getChildren())
@ -1120,32 +1119,33 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV,
if (!Scope) if (!Scope)
return NULL; return NULL;
AbsDbgVariable = new DbgVariable(Var, NULL, this); AbsDbgVariable = &addScopeVariable(Scope, DbgVariable(Var, NULL, this));
addScopeVariable(Scope, AbsDbgVariable);
AbstractVariables[Var] = AbsDbgVariable; AbstractVariables[Var] = AbsDbgVariable;
return AbsDbgVariable; return AbsDbgVariable;
} }
// If Var is a current function argument then add it to CurrentFnArguments list. // If Var is a current function argument then add it to CurrentFnArguments list.
bool DwarfDebug::addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope) { DbgVariable *DwarfDebug::addCurrentFnArgument(DbgVariable &Var, LexicalScope *Scope) {
if (!LScopes.isCurrentFunctionScope(Scope)) if (!LScopes.isCurrentFunctionScope(Scope))
return false; return nullptr;
DIVariable DV = Var->getVariable(); DIVariable DV = Var.getVariable();
if (DV.getTag() != dwarf::DW_TAG_arg_variable) if (DV.getTag() != dwarf::DW_TAG_arg_variable)
return false; return nullptr;
unsigned ArgNo = DV.getArgNumber(); unsigned ArgNo = DV.getArgNumber();
if (ArgNo == 0) if (ArgNo == 0)
return false; return nullptr;
size_t Size = CurrentFnArguments.size(); auto I = CurrentFnArguments.begin();
if (Size == 0) for (; I != CurrentFnArguments.end(); ++I)
CurrentFnArguments.resize(CurFn->getFunction()->arg_size()); if (ArgNo < I->getVariable().getArgNumber())
// llvm::Function argument size is not good indicator of how many break;
// arguments does the function have at source level. return &*CurrentFnArguments.insert(I, std::move(Var));
if (ArgNo > Size) }
CurrentFnArguments.resize(ArgNo * 2);
CurrentFnArguments[ArgNo - 1] = Var; DbgVariable &DwarfDebug::addVariable(DbgVariable Var, LexicalScope *Scope) {
return true; if (DbgVariable *Res = addCurrentFnArgument(Var, Scope))
return *Res;
return addScopeVariable(Scope, std::move(Var));
} }
// Collect variable information from side table maintained by MMI. // Collect variable information from side table maintained by MMI.
@ -1163,10 +1163,9 @@ void DwarfDebug::collectVariableInfoFromMMITable(
continue; continue;
DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VI.Loc); DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VI.Loc);
DbgVariable *RegVar = new DbgVariable(DV, AbsDbgVariable, this); DbgVariable RegVar(DV, AbsDbgVariable, this);
RegVar->setFrameIndex(VI.Slot); RegVar.setFrameIndex(VI.Slot);
if (!addCurrentFnArgument(RegVar, Scope)) addVariable(std::move(RegVar), Scope);
addScopeVariable(Scope, RegVar);
if (AbsDbgVariable) if (AbsDbgVariable)
AbsDbgVariable->setFrameIndex(VI.Slot); AbsDbgVariable->setFrameIndex(VI.Slot);
} }
@ -1247,21 +1246,19 @@ DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
Processed.insert(DV); Processed.insert(DV);
assert(MInsn->isDebugValue() && "History must begin with debug value"); assert(MInsn->isDebugValue() && "History must begin with debug value");
DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc()); DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc());
DbgVariable *RegVar = new DbgVariable(DV, AbsVar, this); DbgVariable &RegVar = addVariable(DbgVariable(DV, AbsVar, this), Scope);
if (!addCurrentFnArgument(RegVar, Scope))
addScopeVariable(Scope, RegVar);
if (AbsVar) if (AbsVar)
AbsVar->setMInsn(MInsn); AbsVar->setMInsn(MInsn);
// Simplify ranges that are fully coalesced. // Simplify ranges that are fully coalesced.
if (History.size() <= 1 || if (History.size() <= 1 ||
(History.size() == 2 && MInsn->isIdenticalTo(History.back()))) { (History.size() == 2 && MInsn->isIdenticalTo(History.back()))) {
RegVar->setMInsn(MInsn); RegVar.setMInsn(MInsn);
continue; continue;
} }
// Handle multiple DBG_VALUE instructions describing one variable. // Handle multiple DBG_VALUE instructions describing one variable.
RegVar->setDotDebugLocOffset(DotDebugLocEntries.size()); RegVar.setDotDebugLocOffset(DotDebugLocEntries.size());
DotDebugLocEntries.resize(DotDebugLocEntries.size() + 1); DotDebugLocEntries.resize(DotDebugLocEntries.size() + 1);
DebugLocList &LocList = DotDebugLocEntries.back(); DebugLocList &LocList = DotDebugLocEntries.back();
@ -1319,7 +1316,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
if (!DV || !DV.isVariable() || !Processed.insert(DV)) if (!DV || !DV.isVariable() || !Processed.insert(DV))
continue; continue;
if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext())) if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext()))
addScopeVariable(Scope, new DbgVariable(DV, NULL, this)); addScopeVariable(Scope, DbgVariable(DV, NULL, this));
} }
} }
@ -1626,9 +1623,9 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
} }
} }
void DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { DbgVariable &DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable Var) {
SmallVectorImpl<DbgVariable *> &Vars = ScopeVariables[LS]; auto &Vars = ScopeVariables[LS];
DIVariable DV = Var->getVariable(); DIVariable DV = Var.getVariable();
// Variables with positive arg numbers are parameters. // Variables with positive arg numbers are parameters.
if (unsigned ArgNum = DV.getArgNumber()) { if (unsigned ArgNum = DV.getArgNumber()) {
// Keep all parameters in order at the start of the variable list to ensure // Keep all parameters in order at the start of the variable list to ensure
@ -1638,9 +1635,9 @@ void DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
// builds have the right order to begin with), searching from the back (this // builds have the right order to begin with), searching from the back (this
// would catch the unoptimized case quickly), or doing a binary search // would catch the unoptimized case quickly), or doing a binary search
// rather than linear search. // rather than linear search.
SmallVectorImpl<DbgVariable *>::iterator I = Vars.begin(); auto I = Vars.begin();
while (I != Vars.end()) { while (I != Vars.end()) {
unsigned CurNum = (*I)->getVariable().getArgNumber(); unsigned CurNum = I->getVariable().getArgNumber();
// A local (non-parameter) variable has been found, insert immediately // A local (non-parameter) variable has been found, insert immediately
// before it. // before it.
if (CurNum == 0) if (CurNum == 0)
@ -1650,11 +1647,11 @@ void DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
break; break;
++I; ++I;
} }
Vars.insert(I, Var); return *Vars.insert(I, std::move(Var));
return;
} }
Vars.push_back(Var); Vars.push_back(std::move(Var));
return Vars.back();
} }
// Gather and emit post-function debug information. // Gather and emit post-function debug information.
@ -1710,7 +1707,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
if (AbstractVariables.lookup(CleanDV)) if (AbstractVariables.lookup(CleanDV))
continue; continue;
if (LexicalScope *Scope = LScopes.findAbstractScope(DV.getContext())) if (LexicalScope *Scope = LScopes.findAbstractScope(DV.getContext()))
addScopeVariable(Scope, new DbgVariable(DV, NULL, this)); addScopeVariable(Scope, DbgVariable(DV, NULL, this));
} }
} }
if (ProcessedSPNodes.count(AScope->getScopeNode()) == 0) if (ProcessedSPNodes.count(AScope->getScopeNode()) == 0)
@ -1728,10 +1725,8 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
PrevCU = TheCU; PrevCU = TheCU;
// Clear debug info // Clear debug info
for (auto &I : ScopeVariables)
DeleteContainerPointers(I.second);
ScopeVariables.clear(); ScopeVariables.clear();
DeleteContainerPointers(CurrentFnArguments); CurrentFnArguments.clear();
UserVariables.clear(); UserVariables.clear();
DbgValues.clear(); DbgValues.clear();
AbstractVariables.clear(); AbstractVariables.clear();
@ -2470,7 +2465,7 @@ void DwarfDebug::emitDebugARanges() {
// Build a set of address spans, sorted by CU. // Build a set of address spans, sorted by CU.
for (const MCSection *Section : Sections) { for (const MCSection *Section : Sections) {
SmallVector<SymbolCU, 8> &List = SectionMap[Section]; auto &List = SectionMap[Section];
if (List.size() < 2) if (List.size() < 2)
continue; continue;

View File

@ -30,6 +30,8 @@
#include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCDwarf.h"
#include "llvm/Support/Allocator.h" #include "llvm/Support/Allocator.h"
#include <list>
namespace llvm { namespace llvm {
class AsmPrinter; class AsmPrinter;
@ -274,7 +276,9 @@ class DwarfDebug : public AsmPrinterHandler {
SectionMapType SectionMap; SectionMapType SectionMap;
// List of arguments for current function. // List of arguments for current function.
SmallVector<DbgVariable *, 8> CurrentFnArguments; // Linked list use to maintain pointer validity. Singly linked list could
// suffice with some contortions to addCurrentFnArgument.
std::list<DbgVariable> CurrentFnArguments;
LexicalScopes LScopes; LexicalScopes LScopes;
@ -282,7 +286,9 @@ class DwarfDebug : public AsmPrinterHandler {
DenseMap<const MDNode *, DIE *> AbstractSPDies; DenseMap<const MDNode *, DIE *> AbstractSPDies;
// Collection of dbg variables of a scope. // Collection of dbg variables of a scope.
typedef DenseMap<LexicalScope *, SmallVector<DbgVariable *, 8> > // Linked list use to maintain pointer validity. Singly linked list could
// suffice with some contortions to addScopeVariable.
typedef DenseMap<LexicalScope *, std::list<DbgVariable>>
ScopeVariablesMap; ScopeVariablesMap;
ScopeVariablesMap ScopeVariables; ScopeVariablesMap ScopeVariables;
@ -413,7 +419,7 @@ class DwarfDebug : public AsmPrinterHandler {
MCDwarfDwoLineTable *getDwoLineTable(const DwarfCompileUnit &); MCDwarfDwoLineTable *getDwoLineTable(const DwarfCompileUnit &);
void addScopeVariable(LexicalScope *LS, DbgVariable *Var); DbgVariable &addScopeVariable(LexicalScope *LS, DbgVariable Var);
const SmallVectorImpl<DwarfUnit *> &getUnits() { const SmallVectorImpl<DwarfUnit *> &getUnits() {
return InfoHolder.getUnits(); return InfoHolder.getUnits();
@ -591,7 +597,9 @@ class DwarfDebug : public AsmPrinterHandler {
/// \brief If Var is an current function argument that add it in /// \brief If Var is an current function argument that add it in
/// CurrentFnArguments list. /// CurrentFnArguments list.
bool addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope); DbgVariable *addCurrentFnArgument(DbgVariable &Var, LexicalScope *Scope);
DbgVariable &addVariable(DbgVariable Var, LexicalScope *Scope);
/// \brief Populate LexicalScope entries with variables' info. /// \brief Populate LexicalScope entries with variables' info.
void collectVariableInfo(SmallPtrSet<const MDNode *, 16> &ProcessedVars); void collectVariableInfo(SmallPtrSet<const MDNode *, 16> &ProcessedVars);