[llvm] r298388 - DwarfExpression: Defer emitting DWARF register operations

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 21 09:37:36 PDT 2017


Author: adrian
Date: Tue Mar 21 11:37:35 2017
New Revision: 298388

URL: http://llvm.org/viewvc/llvm-project?rev=298388&view=rev
Log:
DwarfExpression: Defer emitting DWARF register operations
until the rest of the expression is known.

This is still an NFC refactoring in preparation of a subsequent bugfix.

Modified:
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp?rev=298388&r1=298387&r2=298388&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp Tue Mar 21 11:37:35 2017
@@ -98,7 +98,7 @@ bool DwarfExpression::addMachineReg(cons
 
   // If this is a valid register number, emit it.
   if (Reg >= 0) {
-    addReg(Reg);
+    DwarfRegs.push_back({Reg, 0, nullptr});
     return true;
   }
 
@@ -110,7 +110,7 @@ bool DwarfExpression::addMachineReg(cons
       unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg);
       unsigned Size = TRI.getSubRegIdxSize(Idx);
       unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
-      addReg(Reg, "super-register");
+      DwarfRegs.push_back({Reg, 0, "super-register"});
       // Use a DW_OP_bit_piece to describe the sub-register.
       setSubRegisterPiece(Size, RegOffset);
       return true;
@@ -140,17 +140,17 @@ bool DwarfExpression::addMachineReg(cons
     // If this sub-register has a DWARF number and we haven't covered
     // its range, emit a DWARF piece for it.
     if (Reg >= 0 && Intersection.any()) {
-      addReg(Reg, "sub-register");
+      // Emit a piece for any gap in the coverage.
+      if (Offset > CurPos)
+        DwarfRegs.push_back({-1, Offset - CurPos, "missing"});
+      DwarfRegs.push_back(
+          {Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"});
       if (Offset >= MaxSize)
 	break;
-      // emit a piece for the any gap in the coverage.
-      if (Offset > CurPos)
-        addOpPiece(Offset - CurPos);
-      addOpPiece(std::min<unsigned>(Size, MaxSize - Offset));
-      CurPos = Offset + Size;
 
       // Mark it as emitted.
       Coverage.set(Offset, Offset + Size);
+      CurPos = Offset + Size;
     }
   }
 
@@ -194,18 +194,33 @@ bool DwarfExpression::addMachineRegExpre
                                               DIExpressionCursor &ExprCursor,
                                               unsigned MachineReg,
                                               unsigned FragmentOffsetInBits) {
-  if (!ExprCursor)
-    return addMachineReg(TRI, MachineReg);
+  auto Fragment = ExprCursor.getFragmentInfo();
+  if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U))
+    return false;
+
+  bool HasComplexExpression = false;
+  auto Op = ExprCursor.peek();
+  if (Op && Op->getOp() != dwarf::DW_OP_LLVM_fragment)
+    HasComplexExpression = true;
+
+  if (!HasComplexExpression) {
+    for (auto &Reg : DwarfRegs) {
+      if (Reg.DwarfRegNo >= 0)
+        addReg(Reg.DwarfRegNo, Reg.Comment);
+      addOpPiece(Reg.Size);
+    }
+    DwarfRegs.clear();
+    return true;
+  }
 
   // Pattern-match combinations for which more efficient representations exist
   // first.
-  bool ValidReg = false;
-  auto Op = ExprCursor.peek();
+  assert(DwarfRegs.size() == 1);
+  auto Reg = DwarfRegs[0];
+  assert(Reg.Size == 0 && "subregister has same size as superregister");
   switch (Op->getOp()) {
   default: {
-    auto Fragment = ExprCursor.getFragmentInfo();
-    ValidReg = addMachineReg(TRI, MachineReg,
-			     Fragment ? Fragment->SizeInBits : ~1U);
+    addReg(Reg.DwarfRegNo, 0);
     break;
   }
   case dwarf::DW_OP_plus:
@@ -214,22 +229,28 @@ bool DwarfExpression::addMachineRegExpre
     // [DW_OP_reg,Offset,DW_OP_minus,DW_OP_deref] --> [DW_OP_breg,-Offset].
     auto N = ExprCursor.peekNext();
     if (N && N->getOp() == dwarf::DW_OP_deref) {
-      unsigned Offset = Op->getArg(0);
-      ValidReg = addMachineRegIndirect(
-          TRI, MachineReg, Op->getOp() == dwarf::DW_OP_plus ? Offset : -Offset);
+      int Offset = Op->getArg(0);
+      int SignedOffset = (Op->getOp() == dwarf::DW_OP_plus) ? Offset : -Offset;
+      if (isFrameRegister(TRI, MachineReg)) {
+        // If variable offset is based in frame register then use fbreg.
+        emitOp(dwarf::DW_OP_fbreg);
+        emitSigned(SignedOffset);
+      } else
+        addRegIndirect(Reg.DwarfRegNo, SignedOffset);
       ExprCursor.consume(2);
-    } else
-      ValidReg = addMachineReg(TRI, MachineReg);
+      break;
+    }
+    addReg(Reg.DwarfRegNo, 0);
     break;
   }
   case dwarf::DW_OP_deref:
     // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg].
-    ValidReg = addMachineRegIndirect(TRI, MachineReg);
+    addRegIndirect(Reg.DwarfRegNo, 0);
     ExprCursor.take();
     break;
   }
-
-  return ValidReg;
+  DwarfRegs.clear();
+  return true;
 }
 
 void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
@@ -308,6 +329,7 @@ void DwarfExpression::maskSubRegister()
 
 
 void DwarfExpression::finalize() {
+  assert(DwarfRegs.size() == 0 && "dwarf registers not emitted");
   // Emit any outstanding DW_OP_piece operations to mask out subregisters.
   if (SubRegisterSizeInBits == 0)
     return;

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h?rev=298388&r1=298387&r2=298388&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h Tue Mar 21 11:37:35 2017
@@ -84,6 +84,16 @@ public:
 /// entry.
 class DwarfExpression {
 protected:
+  /// Holds information about all subregisters comprising a register location.
+  struct Register {
+    int DwarfRegNo;
+    unsigned Size;
+    const char *Comment;
+  };
+
+  /// The register location, if any.
+  SmallVector<Register, 2> DwarfRegs;
+
   /// Current Fragment Offset in Bits.
   uint64_t OffsetInBits = 0;
   unsigned DwarfVersion;




More information about the llvm-commits mailing list