mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-15 05:24:01 +00:00
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:
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Reference in New Issue
Block a user