From 15552c46a0f3307e5e363dcce33638aa489fe928 Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Tue, 14 Apr 2015 01:12:42 +0000 Subject: [PATCH] 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). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234832 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/DebugInfo.h | 30 +++++++------------------- include/llvm/IR/DebugInfoMetadata.h | 6 ++++++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 6 +++--- lib/CodeGen/AsmPrinter/DebugLocEntry.h | 9 ++++---- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 20 ++++++++--------- lib/CodeGen/AsmPrinter/DwarfDebug.h | 8 +++---- lib/Transforms/Scalar/SROA.cpp | 8 +++---- lib/Transforms/Utils/Local.cpp | 3 +-- 8 files changed, 40 insertions(+), 50 deletions(-) diff --git a/include/llvm/IR/DebugInfo.h b/include/llvm/IR/DebugInfo.h index d467b5abe0e..d7aebeecdcb 100644 --- a/include/llvm/IR/DebugInfo.h +++ b/include/llvm/IR/DebugInfo.h @@ -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 { -public: - DIExpression() = default; - DIExpression(const MDExpression *N) : DIDescriptor(N) {} +class DIExpression { + MDExpression *N; - MDExpression *get() const { - return cast_or_null(DIDescriptor::get()); - } - operator MDExpression *() const { return get(); } - MDExpression *operator->() const { return get(); } - MDExpression &operator*() const { return *get(); } +public: + DIExpression(const MDExpression *N = nullptr) + : N(const_cast(N)) {} - 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. diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 9e6117c9521..2c2b5807c5c 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -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. diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 10e399530d6..99081ef2c38 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -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. diff --git a/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/lib/CodeGen/AsmPrinter/DebugLocEntry.h index f50ebae7ba6..dd7f806e029 100644 --- a/lib/CodeGen/AsmPrinter/DebugLocEntry.h +++ b/lib/CodeGen/AsmPrinter/DebugLocEntry.h @@ -76,7 +76,7 @@ public: MachineLocation getLoc() const { return Loc; } const MDNode *getVariableNode() const { return Variable; } DIVariable getVariable() const { return cast(Variable); } - bool isBitPiece() const { return getExpression().isBitPiece(); } + bool isBitPiece() const { return getExpression()->isBitPiece(); } DIExpression getExpression() const { return cast_or_null(Expression); } @@ -108,8 +108,7 @@ public: DIExpression NextExpr = cast_or_null(Next.Values[0].Expression); DIVariable NextVar = cast_or_null(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(); } } diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 2998d1fbf30..4e349f280c3 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -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 &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. diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index ee7a8239ff0..74ff4db3bd6 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -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; diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index cecd29b1341..e8310d7f53e 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -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; diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index cba77452061..a8f4c211009 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -1121,8 +1121,7 @@ bool llvm::replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress, SmallVector 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); } -- 2.34.1