DebugInfo: Gut DIExpression
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Tue, 14 Apr 2015 01:12:42 +0000 (01:12 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Tue, 14 Apr 2015 01:12:42 +0000 (01:12 +0000)
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
include/llvm/IR/DebugInfoMetadata.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/AsmPrinter/DebugLocEntry.h
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.h
lib/Transforms/Scalar/SROA.cpp
lib/Transforms/Utils/Local.cpp

index d467b5abe0ea20e15c39c9492d22c33b59226f0e..d7aebeecdcb07500834d8db6b9a55bf769d9e334 100644 (file)
@@ -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<MDExpression>(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<MDExpression *>(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.
index 9e6117c9521440808eb42c30e903082e71c5b2d1..2c2b5807c5c3627cdc8f9952299cd093d7754364 100644 (file)
@@ -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.
index 10e399530d6bf55158d2a3fc9be1d1b974f00385..99081ef2c38bff1894c2954f6304aa1eb3c78bf1 100644 (file)
@@ -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.
index f50ebae7ba6effe7183df09c8f72eb6b53c169b1..dd7f806e0297f46e2d8f7fff7d16465f177270a9 100644 (file)
@@ -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();
 }
 
 }
index 2998d1fbf30b7b34d38638b83690f75a1c73d0db..4e349f280c312b9e7138ff373855ef75fbab83cf 100644 (file)
@@ -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.
index ee7a8239ff086cb6dacdefce583daec4f95aeac5..74ff4db3bd6bb431276359fc51e6b1eac140cc80 100644 (file)
@@ -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;
index cecd29b13410f2c1f8974a7bdf876f163f3f68a9..e8310d7f53ee485f273a5b183434236a7c72aadd 100644 (file)
@@ -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;
index cba7745206160534b9ee0f0afd8f66e5d8073303..a8f4c211009b84f994c2310d8451626844961bea 100644 (file)
@@ -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);
   }