]> granicus.if.org Git - llvm/commitdiff
Refactor the DIExpression fragment query interface (NFC)
authorAdrian Prantl <aprantl@apple.com>
Thu, 22 Dec 2016 05:27:12 +0000 (05:27 +0000)
committerAdrian Prantl <aprantl@apple.com>
Thu, 22 Dec 2016 05:27:12 +0000 (05:27 +0000)
... so it becomes available to DIExpressionCursor.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290322 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/DebugInfoMetadata.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
lib/CodeGen/AsmPrinter/DebugLocEntry.h
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/AsmPrinter/DwarfExpression.cpp
lib/IR/DebugInfoMetadata.cpp
lib/IR/Verifier.cpp
lib/Transforms/Scalar/SROA.cpp
lib/Transforms/Utils/Local.cpp

index 69ef2ea40c6dc60608e73f4b748b1c71d85e4f0e..f8f8ffd8c7412f6cb9a3d7beab105adee470e274 100644 (file)
@@ -1973,15 +1973,6 @@ public:
     return Elements[I];
   }
 
-  /// Return whether this is a piece of an aggregate variable.
-  bool isFragment() const;
-
-  /// Return the offset of this fragment in bits.
-  uint64_t getFragmentOffsetInBits() const;
-
-  /// Return the size of this fragment in bits.
-  uint64_t getFragmentSizeInBits() const;
-
   /// Determine whether this represents a standalone constant value.
   bool isConstant() const;
 
@@ -2085,6 +2076,24 @@ public:
   bool startsWithDeref() const {
     return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_deref;
   }
+
+  /// Holds the characteristics of one fragment of a larger variable.
+  struct FragmentInfo {
+    uint64_t SizeInBits;
+    uint64_t OffsetInBits;
+  };
+
+  /// Retrieve the details of this fragment expression.
+  static Optional<FragmentInfo> getFragmentInfo(expr_op_iterator Start,
+                                               expr_op_iterator End);
+
+  /// Retrieve the details of this fragment expression.
+  Optional<FragmentInfo> getFragmentInfo() const {
+    return getFragmentInfo(expr_op_begin(), expr_op_end());
+  }
+
+  /// Return whether this is a piece of an aggregate variable.
+  bool isFragment() const { return getFragmentInfo().hasValue(); }
 };
 
 /// Global variables.
index 7adac4cbf94425b3fc440cc5299a68920d9bc398..f0537e04165f9cf2d587013e93e0cbd6148422b2 100644 (file)
@@ -713,9 +713,10 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
   OS << V->getName();
 
   const DIExpression *Expr = MI->getDebugExpression();
-  if (Expr->isFragment())
-    OS << " [fragment offset=" << Expr->getFragmentOffsetInBits()
-       << " size=" << Expr->getFragmentSizeInBits() << "]";
+  auto Fragment = Expr->getFragmentInfo();
+  if (Fragment)
+    OS << " [fragment offset=" << Fragment->OffsetInBits
+       << " size=" << Fragment->SizeInBits << "]";
   OS << " <- ";
 
   // The second operand is only an offset if it's an immediate.
index 3d0ae1a93992f96c65de77fc93cf8a4b401ce2dc..8dde4a1031b05f6f6625c9accaad02e85a3b9cdb 100644 (file)
@@ -944,9 +944,10 @@ void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {
       unsigned StructOffset = 0;
 
       // Handle fragments.
-      if (DIExpr && DIExpr->isFragment()) {
+      auto Fragment = DIExpr->getFragmentInfo();
+      if (DIExpr && Fragment) {
         IsSubfield = true;
-        StructOffset = DIExpr->getFragmentOffsetInBits() / 8;
+        StructOffset = Fragment->OffsetInBits / 8;
       } else if (DIExpr && DIExpr->getNumElements() > 0) {
         continue; // Ignore unrecognized exprs.
       }
index aa71449b2c082279ec340bdd97dde4e3609a8435..94190981e88ec3f25fe4279c546b8a2e7dd9a140 100644 (file)
@@ -65,10 +65,12 @@ MCSymbol *DebugHandlerBase::getLabelAfterInsn(const MachineInstr *MI) {
 
 int DebugHandlerBase::fragmentCmp(const DIExpression *P1,
                                   const DIExpression *P2) {
-  unsigned l1 = P1->getFragmentOffsetInBits();
-  unsigned l2 = P2->getFragmentOffsetInBits();
-  unsigned r1 = l1 + P1->getFragmentSizeInBits();
-  unsigned r2 = l2 + P2->getFragmentSizeInBits();
+  auto Fragment1 = *P1->getFragmentInfo();
+  auto Fragment2 = *P2->getFragmentInfo();
+  unsigned l1 = Fragment1.OffsetInBits;
+  unsigned l2 = Fragment2.OffsetInBits;
+  unsigned r1 = l1 + Fragment1.SizeInBits;
+  unsigned r2 = l2 + Fragment2.SizeInBits;
   if (r1 <= l2)
     return -1;
   else if (r2 <= l1)
index 9444fad048f37ea7baf91cdf42cc700dae69a07e..36fb1507ddc657aac1302e59b17d7a25298a7273 100644 (file)
@@ -175,8 +175,8 @@ inline bool operator==(const DebugLocEntry::Value &A,
 /// Compare two fragments based on their offset.
 inline bool operator<(const DebugLocEntry::Value &A,
                       const DebugLocEntry::Value &B) {
-  return A.getExpression()->getFragmentOffsetInBits() <
-         B.getExpression()->getFragmentOffsetInBits();
+  return A.getExpression()->getFragmentInfo()->OffsetInBits <
+         B.getExpression()->getFragmentInfo()->OffsetInBits;
 }
 
 }
index 45d6e38aea7f31f0e157dacfb78db125c3e48bf4..b465b98f368a6d0e1be4498cbe2817590f4058e9 100644 (file)
@@ -469,10 +469,12 @@ static SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &
 sortGlobalExprs(SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &GVEs) {
   std::sort(GVEs.begin(), GVEs.end(),
             [](DwarfCompileUnit::GlobalExpr A, DwarfCompileUnit::GlobalExpr B) {
-              if (A.Expr != B.Expr && A.Expr && B.Expr &&
-                  A.Expr->isFragment() && B.Expr->isFragment())
-                return A.Expr->getFragmentOffsetInBits() <
-                       B.Expr->getFragmentOffsetInBits();
+              if (A.Expr != B.Expr && A.Expr && B.Expr) {
+               auto FragmentA = A.Expr->getFragmentInfo();
+               auto FragmentB = B.Expr->getFragmentInfo();
+               if (FragmentA && FragmentB)
+                 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
+             }
               return false;
             });
   GVEs.erase(std::unique(GVEs.begin(), GVEs.end(),
index a17776f2ce9cab766e3f0647cc07d2f0f17673df..5419a10f4f9a3f743c9543f777eedd836856a8d5 100644 (file)
@@ -285,7 +285,7 @@ void DwarfExpression::addFragmentOffset(const DIExpression *Expr) {
   if (!Expr || !Expr->isFragment())
     return;
 
-  uint64_t FragmentOffset = Expr->getFragmentOffsetInBits();
+  uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits;
   assert(FragmentOffset >= OffsetInBits &&
          "overlapping or duplicate fragments");
   if (FragmentOffset > OffsetInBits)
index 75c397e134564d6ab4daefef63c99cd43725f400..1003093760fe893b8d1ed4fe56b4c5c3ce0e1437 100644 (file)
@@ -601,22 +601,14 @@ bool DIExpression::isValid() const {
   return true;
 }
 
-bool DIExpression::isFragment() const {
-  assert(isValid() && "Expected valid expression");
-  if (unsigned N = getNumElements())
-    if (N >= 3)
-      return getElement(N - 3) == dwarf::DW_OP_LLVM_fragment;
-  return false;
-}
-
-uint64_t DIExpression::getFragmentOffsetInBits() const {
-  assert(isFragment() && "Expected fragment");
-  return getElement(getNumElements() - 2);
-}
-
-uint64_t DIExpression::getFragmentSizeInBits() const {
-  assert(isFragment() && "Expected fragment");
-  return getElement(getNumElements() - 1);
+Optional<DIExpression::FragmentInfo>
+DIExpression::getFragmentInfo(expr_op_iterator Start, expr_op_iterator End) {
+  for (auto I = Start; I != End; ++I)
+    if (I->getOp() == dwarf::DW_OP_LLVM_fragment) {
+      DIExpression::FragmentInfo Info = {I->getArg(1), I->getArg(0)};
+      return Info;
+    }
+  return None;
 }
 
 bool DIExpression::isConstant() const {
index 2b9dfcea2fb6dcb379650a69f1d589c572e2782c..9a19354e2558d1a02d89bfd3972c5f0251156cc7 100644 (file)
@@ -4344,7 +4344,8 @@ void Verifier::verifyFragmentExpression(const DbgInfoIntrinsic &I) {
     return;
 
   // Nothing to do if this isn't a bit piece expression.
-  if (!E->isFragment())
+  auto Fragment = E->getFragmentInfo();
+  if (!Fragment)
     return;
 
   // The frontend helps out GDB by emitting the members of local anonymous
@@ -4362,8 +4363,8 @@ void Verifier::verifyFragmentExpression(const DbgInfoIntrinsic &I) {
   if (!VarSize)
     return;
 
-  unsigned FragSize = E->getFragmentSizeInBits();
-  unsigned FragOffset = E->getFragmentOffsetInBits();
+  unsigned FragSize = Fragment->SizeInBits;
+  unsigned FragOffset = Fragment->OffsetInBits;
   AssertDI(FragSize + FragOffset <= VarSize,
          "fragment is larger than or outside of variable", &I, V, E);
   AssertDI(FragSize != VarSize, "fragment covers entire variable", &I, V, E);
index 887818bfdde9437bf88cc50da6c715ac4019d586..bfcb15530ef531d0a63dc9fcb427093b4e8c23bb 100644 (file)
@@ -4026,13 +4026,13 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
       if (Fragment.Size < AllocaSize || Expr->isFragment()) {
         // If this alloca is already a scalar replacement of a larger aggregate,
         // Fragment.Offset describes the offset inside the scalar.
-        uint64_t Offset =
-            Expr->isFragment() ? Expr->getFragmentOffsetInBits() : 0;
+        auto ExprFragment = Expr->getFragmentInfo();
+        uint64_t Offset = ExprFragment ? ExprFragment->OffsetInBits : 0;
         uint64_t Start = Offset + Fragment.Offset;
         uint64_t Size = Fragment.Size;
-        if (Expr->isFragment()) {
+        if (ExprFragment) {
           uint64_t AbsEnd =
-              Expr->getFragmentOffsetInBits() + Expr->getFragmentSizeInBits();
+           ExprFragment->OffsetInBits + ExprFragment->SizeInBits;
           if (Start >= AbsEnd)
             // No need to describe a SROAed padding.
             continue;
index 6de0f34e94cd8327568e026acf068c9422cddb7f..6e4174aa0cda144c6947c1fd92b6c27c1ac5f51a 100644 (file)
@@ -1112,9 +1112,10 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
     unsigned FragmentOffset = 0;
     // If this already is a bit fragment, we drop the bit fragment from the
     // expression and record the offset.
-    if (DIExpr->isFragment()) {
+    auto Fragment = DIExpr->getFragmentInfo();
+    if (Fragment) {
       Ops.append(DIExpr->elements_begin(), DIExpr->elements_end()-3);
-      FragmentOffset = DIExpr->getFragmentOffsetInBits();
+      FragmentOffset = Fragment->OffsetInBits;
     } else {
       Ops.append(DIExpr->elements_begin(), DIExpr->elements_end());
     }