mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Debug Info: Support variables that are described by more than one MMI
table entry. This happens when SROA splits up an alloca and the resulting allocas cannot be lowered to SSA values because their address is passed to a function. Fixes PR22502. llvm-svn: 228764
This commit is contained in:
parent
7f72d35a3f
commit
988ec9ddfa
@ -516,15 +516,21 @@ DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
|
||||
}
|
||||
|
||||
// .. else use frame index.
|
||||
int FI = DV.getFrameIndex();
|
||||
if (FI != ~0) {
|
||||
if (DV.getFrameIndex().back() == ~0)
|
||||
return VariableDie;
|
||||
|
||||
auto Expr = DV.getExpression().begin();
|
||||
DIELoc *Loc = new (DIEValueAllocator) DIELoc();
|
||||
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
|
||||
for (auto FI : DV.getFrameIndex()) {
|
||||
unsigned FrameReg = 0;
|
||||
const TargetFrameLowering *TFI =
|
||||
Asm->TM.getSubtargetImpl()->getFrameLowering();
|
||||
int Offset = TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg);
|
||||
MachineLocation Location(FrameReg, Offset);
|
||||
addVariableAddress(DV, *VariableDie, Location);
|
||||
DwarfExpr.AddMachineRegIndirect(FrameReg, Offset);
|
||||
DwarfExpr.AddExpression(*(Expr++));
|
||||
}
|
||||
addBlock(*VariableDie, dwarf::DW_AT_location, Loc);
|
||||
|
||||
return VariableDie;
|
||||
}
|
||||
@ -767,7 +773,8 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
|
||||
const MachineLocation &Location) {
|
||||
DIELoc *Loc = new (DIEValueAllocator) DIELoc();
|
||||
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
|
||||
DIExpression Expr = DV.getExpression();
|
||||
assert(DV.getExpression().size() == 1);
|
||||
DIExpression Expr = DV.getExpression().back();
|
||||
bool ValidReg;
|
||||
if (Location.getOffset()) {
|
||||
ValidReg = DwarfExpr.AddMachineRegIndirect(Location.getReg(),
|
||||
|
@ -783,10 +783,9 @@ void DwarfDebug::collectVariableInfoFromMMITable(
|
||||
DIVariable DV(VI.Var);
|
||||
DIExpression Expr(VI.Expr);
|
||||
ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode());
|
||||
ConcreteVariables.push_back(make_unique<DbgVariable>(DV, Expr, this));
|
||||
DbgVariable *RegVar = ConcreteVariables.back().get();
|
||||
RegVar->setFrameIndex(VI.Slot);
|
||||
InfoHolder.addScopeVariable(Scope, RegVar);
|
||||
auto RegVar = make_unique<DbgVariable>(DV, Expr, this, VI.Slot);
|
||||
if (InfoHolder.addScopeVariable(Scope, RegVar.get()))
|
||||
ConcreteVariables.push_back(std::move(RegVar));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,41 +67,66 @@ public:
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// \brief This class is used to track local variable information.
|
||||
///
|
||||
/// - Variables whose location changes over time have a DotDebugLocOffset and the
|
||||
/// other fields are not used.
|
||||
///
|
||||
/// - Variables that are described by multiple MMI table entries have multiple
|
||||
/// expressions and frame indices.
|
||||
class DbgVariable {
|
||||
DIVariable Var; // Variable Descriptor.
|
||||
DIExpression Expr; // Complex address location expression.
|
||||
DIE *TheDIE; // Variable DIE.
|
||||
unsigned DotDebugLocOffset; // Offset in DotDebugLocEntries.
|
||||
const MachineInstr *MInsn; // DBG_VALUE instruction of the variable.
|
||||
int FrameIndex;
|
||||
DIVariable Var; /// Variable Descriptor.
|
||||
SmallVector<DIExpression, 1> Expr; /// Complex address location expression.
|
||||
DIE *TheDIE; /// Variable DIE.
|
||||
unsigned DotDebugLocOffset; /// Offset in DotDebugLocEntries.
|
||||
const MachineInstr *MInsn; /// DBG_VALUE instruction of the variable.
|
||||
SmallVector<int, 1> FrameIndex; /// Frame index of the variable.
|
||||
DwarfDebug *DD;
|
||||
|
||||
public:
|
||||
/// Construct a DbgVariable from a DIVariable.
|
||||
DbgVariable(DIVariable V, DIExpression E, DwarfDebug *DD)
|
||||
: Var(V), Expr(E), TheDIE(nullptr), DotDebugLocOffset(~0U),
|
||||
MInsn(nullptr), FrameIndex(~0), DD(DD) {
|
||||
assert(Var.Verify() && Expr.Verify());
|
||||
DbgVariable(DIVariable V, DIExpression E, DwarfDebug *DD, int FI = ~0)
|
||||
: Var(V), Expr(1, E), TheDIE(nullptr), DotDebugLocOffset(~0U),
|
||||
MInsn(nullptr), DD(DD) {
|
||||
FrameIndex.push_back(FI);
|
||||
assert(Var.Verify() && E.Verify());
|
||||
}
|
||||
|
||||
/// Construct a DbgVariable from a DEBUG_VALUE.
|
||||
/// AbstractVar may be NULL.
|
||||
DbgVariable(const MachineInstr *DbgValue, DwarfDebug *DD)
|
||||
: Var(DbgValue->getDebugVariable()), Expr(DbgValue->getDebugExpression()),
|
||||
TheDIE(nullptr), DotDebugLocOffset(~0U), MInsn(DbgValue),
|
||||
FrameIndex(~0), DD(DD) {}
|
||||
: Var(DbgValue->getDebugVariable()), Expr(1, DbgValue->getDebugExpression()),
|
||||
TheDIE(nullptr), DotDebugLocOffset(~0U), MInsn(DbgValue), DD(DD) {
|
||||
FrameIndex.push_back(~0);
|
||||
}
|
||||
|
||||
// Accessors.
|
||||
DIVariable getVariable() const { return Var; }
|
||||
DIExpression getExpression() const { return Expr; }
|
||||
const ArrayRef<DIExpression> getExpression() const { return Expr; }
|
||||
void setDIE(DIE &D) { TheDIE = &D; }
|
||||
DIE *getDIE() const { return TheDIE; }
|
||||
void setDotDebugLocOffset(unsigned O) { DotDebugLocOffset = O; }
|
||||
unsigned getDotDebugLocOffset() const { return DotDebugLocOffset; }
|
||||
StringRef getName() const { return Var.getName(); }
|
||||
const MachineInstr *getMInsn() const { return MInsn; }
|
||||
int getFrameIndex() const { return FrameIndex; }
|
||||
void setFrameIndex(int FI) { FrameIndex = FI; }
|
||||
const ArrayRef<int> getFrameIndex() const { return FrameIndex; }
|
||||
|
||||
void addMMIEntry(const DbgVariable &V) {
|
||||
assert( DotDebugLocOffset == ~0U && !MInsn && "not an MMI entry");
|
||||
assert(V.DotDebugLocOffset == ~0U && !V.MInsn && "not an MMI entry");
|
||||
assert(V.Var == Var && "conflicting DIVariable");
|
||||
|
||||
if (V.getFrameIndex().back() != ~0) {
|
||||
auto E = V.getExpression();
|
||||
auto FI = V.getFrameIndex();
|
||||
Expr.append(E.begin(), E.end());
|
||||
FrameIndex.append(FI.begin(), FI.end());
|
||||
}
|
||||
assert(Expr.size() > 1
|
||||
? std::all_of(Expr.begin(), Expr.end(),
|
||||
[](DIExpression &E) { return E.isBitPiece(); })
|
||||
: (true && "conflicting locations for variable"));
|
||||
}
|
||||
|
||||
// Translate tag to proper Dwarf tag.
|
||||
dwarf::Tag getTag() const {
|
||||
if (Var.getTag() == dwarf::DW_TAG_arg_variable)
|
||||
@ -128,14 +153,11 @@ public:
|
||||
|
||||
bool variableHasComplexAddress() const {
|
||||
assert(Var.isVariable() && "Invalid complex DbgVariable!");
|
||||
return Expr.getNumElements() > 0;
|
||||
assert(Expr.size() == 1 &&
|
||||
"variableHasComplexAddress() invoked on multi-FI variable");
|
||||
return Expr.back().getNumElements() > 0;
|
||||
}
|
||||
bool isBlockByrefVariable() const;
|
||||
unsigned getNumAddrElements() const {
|
||||
assert(Var.isVariable() && "Invalid complex DbgVariable!");
|
||||
return Expr.getNumElements();
|
||||
}
|
||||
uint64_t getAddrElement(unsigned i) const { return Expr.getElement(i); }
|
||||
DIType getType() const;
|
||||
|
||||
private:
|
||||
|
@ -146,7 +146,7 @@ void DwarfFile::emitStrings(const MCSection *StrSection,
|
||||
StrPool.emit(*Asm, StrSection, OffsetSection);
|
||||
}
|
||||
|
||||
void DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
|
||||
bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
|
||||
SmallVectorImpl<DbgVariable *> &Vars = ScopeVariables[LS];
|
||||
DIVariable DV = Var->getVariable();
|
||||
// Variables with positive arg numbers are parameters.
|
||||
@ -168,13 +168,17 @@ void DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
|
||||
// A later indexed parameter has been found, insert immediately before it.
|
||||
if (CurNum > ArgNum)
|
||||
break;
|
||||
assert(CurNum != ArgNum && "Duplicate argument");
|
||||
if (CurNum == ArgNum) {
|
||||
(*I)->addMMIEntry(*Var);
|
||||
return false;
|
||||
}
|
||||
++I;
|
||||
}
|
||||
Vars.insert(I, Var);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
Vars.push_back(Var);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,8 @@ public:
|
||||
/// \brief Returns the string pool.
|
||||
DwarfStringPool &getStringPool() { return StrPool; }
|
||||
|
||||
void addScopeVariable(LexicalScope *LS, DbgVariable *Var);
|
||||
/// \returns false if the variable was merged with a previous one.
|
||||
bool addScopeVariable(LexicalScope *LS, DbgVariable *Var);
|
||||
|
||||
DenseMap<LexicalScope *, SmallVector<DbgVariable *, 8>> &getScopeVariables() {
|
||||
return ScopeVariables;
|
||||
|
Loading…
Reference in New Issue
Block a user