mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
DebugInfo: Gut DIExpression
Completely gut `DIExpression`, turning it into a simple wrapper around `MDExpression *`. There are two bits of magic left: - It's constructed from `const MDExpression*` but convertible to `MDExpression*`. - It's default-constructed to `nullptr`. Otherwise, it should behave quite like a raw pointer. Once I've done the same to the rest of the `DIDescriptor` subclasses, I'll come back to delete them entirely (and update call sites as necessary to deal with the missing magic). llvm-svn: 234832
This commit is contained in:
parent
129325cc57
commit
2e9424982a
@ -651,30 +651,16 @@ public:
|
||||
void printExtendedName(raw_ostream &OS) const;
|
||||
};
|
||||
|
||||
/// \brief A complex location expression in postfix notation.
|
||||
///
|
||||
/// This is (almost) a DWARF expression that modifies the location of a
|
||||
/// variable or (or the location of a single piece of a variable).
|
||||
///
|
||||
/// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const
|
||||
/// and have DW_OP_plus consume the topmost elements on the stack.
|
||||
class DIExpression : public DIDescriptor {
|
||||
class DIExpression {
|
||||
MDExpression *N;
|
||||
|
||||
public:
|
||||
DIExpression() = default;
|
||||
DIExpression(const MDExpression *N) : DIDescriptor(N) {}
|
||||
DIExpression(const MDExpression *N = nullptr)
|
||||
: N(const_cast<MDExpression *>(N)) {}
|
||||
|
||||
MDExpression *get() const {
|
||||
return cast_or_null<MDExpression>(DIDescriptor::get());
|
||||
}
|
||||
operator MDExpression *() const { return get(); }
|
||||
MDExpression *operator->() const { return get(); }
|
||||
MDExpression &operator*() const { return *get(); }
|
||||
|
||||
unsigned getNumElements() const { return get()->getNumElements(); }
|
||||
uint64_t getElement(unsigned I) const { return get()->getElement(I); }
|
||||
bool isBitPiece() const { return get()->isBitPiece(); }
|
||||
uint64_t getBitPieceOffset() const { return get()->getBitPieceOffset(); }
|
||||
uint64_t getBitPieceSize() const { return get()->getBitPieceSize(); }
|
||||
operator MDExpression *() const { return N; }
|
||||
MDExpression *operator->() const { return N; }
|
||||
MDExpression &operator*() const { return *N; }
|
||||
};
|
||||
|
||||
/// \brief This object holds location information.
|
||||
|
@ -1934,6 +1934,12 @@ public:
|
||||
|
||||
/// \brief DWARF expression.
|
||||
///
|
||||
/// This is (almost) a DWARF expression that modifies the location of a
|
||||
/// variable or (or the location of a single piece of a variable).
|
||||
///
|
||||
/// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const
|
||||
/// and have DW_OP_plus consume the topmost elements on the stack.
|
||||
///
|
||||
/// TODO: Co-allocate the expression elements.
|
||||
/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
|
||||
/// storage types.
|
||||
|
@ -679,9 +679,9 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
|
||||
OS << V.getName();
|
||||
|
||||
DIExpression Expr = MI->getDebugExpression();
|
||||
if (Expr.isBitPiece())
|
||||
OS << " [bit_piece offset=" << Expr.getBitPieceOffset()
|
||||
<< " size=" << Expr.getBitPieceSize() << "]";
|
||||
if (Expr->isBitPiece())
|
||||
OS << " [bit_piece offset=" << Expr->getBitPieceOffset()
|
||||
<< " size=" << Expr->getBitPieceSize() << "]";
|
||||
OS << " <- ";
|
||||
|
||||
// The second operand is only an offset if it's an immediate.
|
||||
|
@ -76,7 +76,7 @@ public:
|
||||
MachineLocation getLoc() const { return Loc; }
|
||||
const MDNode *getVariableNode() const { return Variable; }
|
||||
DIVariable getVariable() const { return cast<MDLocalVariable>(Variable); }
|
||||
bool isBitPiece() const { return getExpression().isBitPiece(); }
|
||||
bool isBitPiece() const { return getExpression()->isBitPiece(); }
|
||||
DIExpression getExpression() const {
|
||||
return cast_or_null<MDExpression>(Expression);
|
||||
}
|
||||
@ -108,8 +108,7 @@ public:
|
||||
DIExpression NextExpr =
|
||||
cast_or_null<MDExpression>(Next.Values[0].Expression);
|
||||
DIVariable NextVar = cast_or_null<MDLocalVariable>(Next.Values[0].Variable);
|
||||
if (Var == NextVar && Expr.isBitPiece() &&
|
||||
NextExpr.isBitPiece()) {
|
||||
if (Var == NextVar && Expr->isBitPiece() && NextExpr->isBitPiece()) {
|
||||
addValues(Next.Values);
|
||||
End = Next.End;
|
||||
return true;
|
||||
@ -192,8 +191,8 @@ inline bool operator==(const DebugLocEntry::Value &A,
|
||||
/// \brief Compare two pieces based on their offset.
|
||||
inline bool operator<(const DebugLocEntry::Value &A,
|
||||
const DebugLocEntry::Value &B) {
|
||||
return A.getExpression().getBitPieceOffset() <
|
||||
B.getExpression().getBitPieceOffset();
|
||||
return A.getExpression()->getBitPieceOffset() <
|
||||
B.getExpression()->getBitPieceOffset();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -759,12 +759,12 @@ static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {
|
||||
|
||||
/// Determine whether two variable pieces overlap.
|
||||
static bool piecesOverlap(DIExpression P1, DIExpression P2) {
|
||||
if (!P1.isBitPiece() || !P2.isBitPiece())
|
||||
if (!P1->isBitPiece() || !P2->isBitPiece())
|
||||
return true;
|
||||
unsigned l1 = P1.getBitPieceOffset();
|
||||
unsigned l2 = P2.getBitPieceOffset();
|
||||
unsigned r1 = l1 + P1.getBitPieceSize();
|
||||
unsigned r2 = l2 + P2.getBitPieceSize();
|
||||
unsigned l1 = P1->getBitPieceOffset();
|
||||
unsigned l2 = P2->getBitPieceOffset();
|
||||
unsigned r1 = l1 + P1->getBitPieceSize();
|
||||
unsigned r2 = l2 + P2->getBitPieceSize();
|
||||
// True where [l1,r1[ and [r1,r2[ overlap.
|
||||
return (l1 < r2) && (l2 < r1);
|
||||
}
|
||||
@ -836,7 +836,7 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
|
||||
bool couldMerge = false;
|
||||
|
||||
// If this is a piece, it may belong to the current DebugLocEntry.
|
||||
if (DIExpr.isBitPiece()) {
|
||||
if (DIExpr->isBitPiece()) {
|
||||
// Add this value to the list of open ranges.
|
||||
OpenRanges.push_back(Value);
|
||||
|
||||
@ -1129,7 +1129,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
|
||||
if (DIVar.getTag() == dwarf::DW_TAG_arg_variable &&
|
||||
getDISubprogram(DIVar.getContext()).describes(MF->getFunction())) {
|
||||
LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin();
|
||||
if (Ranges.front().first->getDebugExpression().isBitPiece()) {
|
||||
if (Ranges.front().first->getDebugExpression()->isBitPiece()) {
|
||||
// Mark all non-overlapping initial pieces.
|
||||
for (auto I = Ranges.begin(); I != Ranges.end(); ++I) {
|
||||
DIExpression Piece = I->first->getDebugExpression();
|
||||
@ -1488,7 +1488,7 @@ static void emitDebugLocValue(const AsmPrinter &AP,
|
||||
} else if (Value.isLocation()) {
|
||||
MachineLocation Loc = Value.getLoc();
|
||||
DIExpression Expr = Value.getExpression();
|
||||
if (!Expr || (Expr.getNumElements() == 0))
|
||||
if (!Expr || !Expr->getNumElements())
|
||||
// Regular entry.
|
||||
AP.EmitDwarfRegOp(Streamer, Loc);
|
||||
else {
|
||||
@ -1523,8 +1523,8 @@ void DebugLocEntry::finalize(const AsmPrinter &AP,
|
||||
unsigned Offset = 0;
|
||||
for (auto Piece : Values) {
|
||||
DIExpression Expr = Piece.getExpression();
|
||||
unsigned PieceOffset = Expr.getBitPieceOffset();
|
||||
unsigned PieceSize = Expr.getBitPieceSize();
|
||||
unsigned PieceOffset = Expr->getBitPieceOffset();
|
||||
unsigned PieceSize = Expr->getBitPieceSize();
|
||||
assert(Offset <= PieceOffset && "overlapping or duplicate pieces");
|
||||
if (Offset < PieceOffset) {
|
||||
// The DWARF spec seriously mandates pieces with no locations for gaps.
|
||||
|
@ -123,9 +123,9 @@ public:
|
||||
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"));
|
||||
? std::all_of(Expr.begin(), Expr.end(),
|
||||
[](DIExpression &E) { return E->isBitPiece(); })
|
||||
: (true && "conflicting locations for variable"));
|
||||
}
|
||||
|
||||
// Translate tag to proper Dwarf tag.
|
||||
@ -156,7 +156,7 @@ public:
|
||||
assert(Var && "Invalid complex DbgVariable!");
|
||||
assert(Expr.size() == 1 &&
|
||||
"variableHasComplexAddress() invoked on multi-FI variable");
|
||||
return Expr.back().getNumElements() > 0;
|
||||
return Expr.back()->getNumElements() > 0;
|
||||
}
|
||||
bool isBlockByrefVariable() const;
|
||||
DIType getType() const;
|
||||
|
@ -4191,14 +4191,14 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
|
||||
// Create a piece expression describing the new partition or reuse AI's
|
||||
// expression if there is only one partition.
|
||||
DIExpression PieceExpr = Expr;
|
||||
if (IsSplit || Expr.isBitPiece()) {
|
||||
if (IsSplit || Expr->isBitPiece()) {
|
||||
// If this alloca is already a scalar replacement of a larger aggregate,
|
||||
// Piece.Offset describes the offset inside the scalar.
|
||||
uint64_t Offset = Expr.isBitPiece() ? Expr.getBitPieceOffset() : 0;
|
||||
uint64_t Offset = Expr->isBitPiece() ? Expr->getBitPieceOffset() : 0;
|
||||
uint64_t Start = Offset + Piece.Offset;
|
||||
uint64_t Size = Piece.Size;
|
||||
if (Expr.isBitPiece()) {
|
||||
uint64_t AbsEnd = Expr.getBitPieceOffset() + Expr.getBitPieceSize();
|
||||
if (Expr->isBitPiece()) {
|
||||
uint64_t AbsEnd = Expr->getBitPieceOffset() + Expr->getBitPieceSize();
|
||||
if (Start >= AbsEnd)
|
||||
// No need to describe a SROAed padding.
|
||||
continue;
|
||||
|
@ -1121,8 +1121,7 @@ bool llvm::replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
|
||||
SmallVector<uint64_t, 4> NewDIExpr;
|
||||
NewDIExpr.push_back(dwarf::DW_OP_deref);
|
||||
if (DIExpr)
|
||||
for (unsigned i = 0, n = DIExpr.getNumElements(); i < n; ++i)
|
||||
NewDIExpr.push_back(DIExpr.getElement(i));
|
||||
NewDIExpr.append(DIExpr->elements_begin(), DIExpr->elements_end());
|
||||
DIExpr = Builder.createExpression(NewDIExpr);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user