<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jan 12, 2015 at 2:19 PM, Adrian Prantl <span dir="ltr"><<a href="mailto:aprantl@apple.com" target="_blank">aprantl@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: adrian<br>
Date: Mon Jan 12 16:19:22 2015<br>
New Revision: 225706<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=225706&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=225706&view=rev</a><br>
Log:<br>
Debug info: Factor out the creation of DWARF expressions from AsmPrinter<br>
into a new class DwarfExpression that can be shared between AsmPrinter<br>
and DwarfUnit.<br>
<br>
This is the first step towards unifying the two entirely redundant<br>
implementations of dwarf expression emission in DwarfUnit and AsmPrinter.<br>
<br>
Almost no functional change — Testcases were updated because asm comments<br>
that used to be on two lines now appear on the same line, which is<br>
actually preferable.<br>
<br>
Added:<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h<br>
Modified:<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt<br>
    llvm/trunk/test/CodeGen/ARM/debug-info-qreg.ll<br>
    llvm/trunk/test/CodeGen/ARM/debug-info-s16-reg.ll<br>
    llvm/trunk/test/DebugInfo/X86/subreg.ll<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp?rev=225706&r1=225705&r2=225706&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp?rev=225706&r1=225705&r2=225706&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp Mon Jan 12 16:19:22 2015<br>
@@ -12,8 +12,8 @@<br>
 //===----------------------------------------------------------------------===//<br>
<br>
 #include "ByteStreamer.h"<br>
+#include "DwarfExpression.h"<br>
 #include "llvm/CodeGen/AsmPrinter.h"<br>
-#include "llvm/ADT/SmallBitVector.h"<br>
 #include "llvm/ADT/Twine.h"<br>
 #include "llvm/IR/DataLayout.h"<br>
 #include "llvm/MC/MCAsmInfo.h"<br>
@@ -32,6 +32,31 @@ using namespace llvm;<br>
<br>
 #define DEBUG_TYPE "asm-printer"<br>
<br>
+/// DwarfExpression implementation for .debug_loc entries.<br>
+class DebugLocDwarfExpression : public DwarfExpression {<br>
+  ByteStreamer &BS;<br>
+public:<br>
+  DebugLocDwarfExpression(TargetMachine &TM, ByteStreamer &BS)<br>
+    : DwarfExpression(TM), BS(BS) {}<br>
+<br>
+  void EmitOp(uint8_t Op, const char* Comment) override;<br>
+  void EmitSigned(int Value) override;<br>
+  void EmitUnsigned(unsigned Value) override;<br>
+};<br>
+<br>
+void DebugLocDwarfExpression::EmitOp(uint8_t Op, const char* Comment) {<br>
+  BS.EmitInt8(Op, Comment<br>
+    ? Twine(Comment)+Twine(" ")+Twine(dwarf::OperationEncodingString(Op))<br></blockquote><div><br>You shouldn't need to Twine every one of these, should you? Just Twining one element should provide an appropriate implicit conversion on the other arguments? (well, if you Twine either the first or second elements, anyway)<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    : dwarf::OperationEncodingString(Op));<br>
+}<br>
+void DebugLocDwarfExpression::EmitSigned(int Value) {<br>
+  BS.EmitSLEB128(Value, Twine(Value));<br>
+}<br>
+void DebugLocDwarfExpression::EmitUnsigned(unsigned Value) {<br>
+  BS.EmitULEB128(Value, Twine(Value));<br>
+}<br>
+<br>
+<br>
 //===----------------------------------------------------------------------===//<br>
 // Dwarf Emission Helper Routines<br>
 //===----------------------------------------------------------------------===//<br>
@@ -187,57 +212,6 @@ void AsmPrinter::EmitSectionOffset(const<br>
   EmitLabelDifference(Label, SectionLabel, 4);<br>
 }<br>
<br>
-/// Emit a dwarf register operation.<br>
-static void emitDwarfRegOp(ByteStreamer &Streamer, int Reg) {<br>
-  assert(Reg >= 0);<br>
-  if (Reg < 32) {<br>
-    Streamer.EmitInt8(dwarf::DW_OP_reg0 + Reg,<br>
-                      dwarf::OperationEncodingString(dwarf::DW_OP_reg0 + Reg));<br>
-  } else {<br>
-    Streamer.EmitInt8(dwarf::DW_OP_regx, "DW_OP_regx");<br>
-    Streamer.EmitULEB128(Reg, Twine(Reg));<br>
-  }<br>
-}<br>
-<br>
-/// Emit an (double-)indirect dwarf register operation.<br>
-static void emitDwarfRegOpIndirect(ByteStreamer &Streamer, int Reg, int Offset,<br>
-                                   bool Deref) {<br>
-  assert(Reg >= 0);<br>
-  if (Reg < 32) {<br>
-    Streamer.EmitInt8(dwarf::DW_OP_breg0 + Reg,<br>
-                      dwarf::OperationEncodingString(dwarf::DW_OP_breg0 + Reg));<br>
-  } else {<br>
-    Streamer.EmitInt8(dwarf::DW_OP_bregx, "DW_OP_bregx");<br>
-    Streamer.EmitULEB128(Reg, Twine(Reg));<br>
-  }<br>
-  Streamer.EmitSLEB128(Offset);<br>
-  if (Deref)<br>
-    Streamer.EmitInt8(dwarf::DW_OP_deref, "DW_OP_deref");<br>
-}<br>
-<br>
-void AsmPrinter::EmitDwarfOpPiece(ByteStreamer &Streamer, unsigned SizeInBits,<br>
-                                  unsigned OffsetInBits) const {<br>
-  assert(SizeInBits > 0 && "piece has size zero");<br>
-  const unsigned SizeOfByte = 8;<br>
-  if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {<br>
-    Streamer.EmitInt8(dwarf::DW_OP_bit_piece, "DW_OP_bit_piece");<br>
-    Streamer.EmitULEB128(SizeInBits, Twine(SizeInBits));<br>
-    Streamer.EmitULEB128(OffsetInBits, Twine(OffsetInBits));<br>
-  } else {<br>
-    Streamer.EmitInt8(dwarf::DW_OP_piece, "DW_OP_piece");<br>
-    unsigned ByteSize = SizeInBits / SizeOfByte;<br>
-    Streamer.EmitULEB128(ByteSize, Twine(ByteSize));<br>
-  }<br>
-}<br>
-<br>
-/// Emit a shift-right dwarf expression.<br>
-static void emitDwarfOpShr(ByteStreamer &Streamer,<br>
-                           unsigned ShiftBy) {<br>
-  Streamer.EmitInt8(dwarf::DW_OP_constu, "DW_OP_constu");<br>
-  Streamer.EmitULEB128(ShiftBy);<br>
-  Streamer.EmitInt8(dwarf::DW_OP_shr, "DW_OP_shr");<br>
-}<br>
-<br>
 // Some targets do not provide a DWARF register number for every<br>
 // register.  This function attempts to emit a DWARF register by<br>
 // emitting a piece of a super-register or by piecing together<br>
@@ -247,112 +221,44 @@ void AsmPrinter::EmitDwarfRegOpPiece(Byt<br>
                                      unsigned PieceSizeInBits,<br>
                                      unsigned PieceOffsetInBits) const {<br>
   assert(MLoc.isReg() && "MLoc must be a register");<br>
-  const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();<br>
-  int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);<br>
-<br>
-  // If this is a valid register number, emit it.<br>
-  if (Reg >= 0) {<br>
-    emitDwarfRegOp(Streamer, Reg);<br>
-    EmitDwarfOpPiece(Streamer, PieceSizeInBits, PieceOffsetInBits);<br>
-    return;<br>
-  }<br>
-<br>
-  // Walk up the super-register chain until we find a valid number.<br>
-  // For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0.<br>
-  for (MCSuperRegIterator SR(MLoc.getReg(), TRI); SR.isValid(); ++SR) {<br>
-    Reg = TRI->getDwarfRegNum(*SR, false);<br>
-    if (Reg >= 0) {<br>
-      unsigned Idx = TRI->getSubRegIndex(*SR, MLoc.getReg());<br>
-      unsigned Size = TRI->getSubRegIdxSize(Idx);<br>
-      unsigned RegOffset = TRI->getSubRegIdxOffset(Idx);<br>
-      OutStreamer.AddComment("super-register");<br>
-      emitDwarfRegOp(Streamer, Reg);<br>
-      if (PieceOffsetInBits == RegOffset) {<br>
-        EmitDwarfOpPiece(Streamer, Size, RegOffset);<br>
-      } else {<br>
-        // If this is part of a variable in a sub-register at a<br>
-        // non-zero offset, we need to manually shift the value into<br>
-        // place, since the DW_OP_piece describes the part of the<br>
-        // variable, not the position of the subregister.<br>
-        if (RegOffset)<br>
-          emitDwarfOpShr(Streamer, RegOffset);<br>
-        EmitDwarfOpPiece(Streamer, Size, PieceOffsetInBits);<br>
-      }<br>
-      return;<br>
-    }<br>
-  }<br>
-<br>
-  // Otherwise, attempt to find a covering set of sub-register numbers.<br>
-  // For example, Q0 on ARM is a composition of D0+D1.<br>
-  //<br>
-  // Keep track of the current position so we can emit the more<br>
-  // efficient DW_OP_piece.<br>
-  unsigned CurPos = PieceOffsetInBits;<br>
-  // The size of the register in bits, assuming 8 bits per byte.<br>
-  unsigned RegSize = TRI->getMinimalPhysRegClass(MLoc.getReg())->getSize() * 8;<br>
-  // Keep track of the bits in the register we already emitted, so we<br>
-  // can avoid emitting redundant aliasing subregs.<br>
-  SmallBitVector Coverage(RegSize, false);<br>
-  for (MCSubRegIterator SR(MLoc.getReg(), TRI); SR.isValid(); ++SR) {<br>
-    unsigned Idx = TRI->getSubRegIndex(MLoc.getReg(), *SR);<br>
-    unsigned Size = TRI->getSubRegIdxSize(Idx);<br>
-    unsigned Offset = TRI->getSubRegIdxOffset(Idx);<br>
-    Reg = TRI->getDwarfRegNum(*SR, false);<br>
-<br>
-    // Intersection between the bits we already emitted and the bits<br>
-    // covered by this subregister.<br>
-    SmallBitVector Intersection(RegSize, false);<br>
-    Intersection.set(Offset, Offset + Size);<br>
-    Intersection ^= Coverage;<br>
-<br>
-    // If this sub-register has a DWARF number and we haven't covered<br>
-    // its range, emit a DWARF piece for it.<br>
-    if (Reg >= 0 && Intersection.any()) {<br>
-      OutStreamer.AddComment("sub-register");<br>
-      emitDwarfRegOp(Streamer, Reg);<br>
-      EmitDwarfOpPiece(Streamer, Size, Offset == CurPos ? 0 : Offset);<br>
-      CurPos = Offset + Size;<br>
-<br>
-      // Mark it as emitted.<br>
-      Coverage.set(Offset, Offset + Size);<br>
-    }<br>
-  }<br>
+  DebugLocDwarfExpression Expr(TM, Streamer);<br>
+  Expr.AddMachineRegPiece(MLoc.getReg(), PieceSizeInBits, PieceOffsetInBits);<br>
+}<br>
<br>
-  if (CurPos == PieceOffsetInBits) {<br>
-    // FIXME: We have no reasonable way of handling errors in here.<br>
-    Streamer.EmitInt8(dwarf::DW_OP_nop,<br>
-                      "nop (could not find a dwarf register number)");<br>
-  }<br>
+void AsmPrinter::EmitDwarfOpPiece(ByteStreamer &Streamer,<br>
+                                  unsigned PieceSizeInBits,<br>
+                                  unsigned PieceOffsetInBits) const {<br>
+  DebugLocDwarfExpression Expr(TM, Streamer);<br>
+  Expr.AddOpPiece(PieceSizeInBits, PieceOffsetInBits);<br>
 }<br>
<br>
 /// EmitDwarfRegOp - Emit dwarf register operation.<br>
 void AsmPrinter::EmitDwarfRegOp(ByteStreamer &Streamer,<br>
                                 const MachineLocation &MLoc,<br>
                                 bool Indirect) const {<br>
+  DebugLocDwarfExpression Expr(TM, Streamer);<br>
   const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();<br>
   int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);<br>
   if (Reg < 0) {<br>
     // We assume that pointers are always in an addressable register.<br>
-    if (Indirect || MLoc.isIndirect()) {<br>
+    if (Indirect || MLoc.isIndirect())<br>
       // FIXME: We have no reasonable way of handling errors in here. The<br>
       // caller might be in the middle of a dwarf expression. We should<br>
       // probably assert that Reg >= 0 once debug info generation is more<br>
       // mature.<br>
-      Streamer.EmitInt8(dwarf::DW_OP_nop,<br>
-                        "nop (invalid dwarf register number for indirect loc)");<br>
-      return;<br>
-    }<br>
+    return Expr.EmitOp(dwarf::DW_OP_nop,<br>
+                       "nop (could not find a dwarf register number)");<br>
<br>
     // Attempt to find a valid super- or sub-register.<br>
-    return EmitDwarfRegOpPiece(Streamer, MLoc);<br>
+    return Expr.AddMachineRegPiece(MLoc.getReg());<br>
   }<br>
<br>
   if (MLoc.isIndirect())<br>
-    emitDwarfRegOpIndirect(Streamer, Reg, MLoc.getOffset(), Indirect);<br>
+    Expr.AddRegIndirect(Reg, MLoc.getOffset(), Indirect);<br>
   else if (Indirect)<br>
-    emitDwarfRegOpIndirect(Streamer, Reg, 0, false);<br>
+    Expr.AddRegIndirect(Reg, 0, false);<br>
   else<br>
-    emitDwarfRegOp(Streamer, Reg);<br>
+    Expr.AddReg(Reg);<br>
 }<br>
<br>
 //===----------------------------------------------------------------------===//<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt?rev=225706&r1=225705&r2=225706&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt?rev=225706&r1=225705&r2=225706&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CMakeLists.txt Mon Jan 12 16:19:22 2015<br>
@@ -11,6 +11,7 @@ add_llvm_library(LLVMAsmPrinter<br>
   DwarfCFIException.cpp<br>
   DwarfCompileUnit.cpp<br>
   DwarfDebug.cpp<br>
+  DwarfExpression.cpp<br>
   DwarfFile.cpp<br>
   DwarfStringPool.cpp<br>
   DwarfUnit.cpp<br>
<br>
Added: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp?rev=225706&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp?rev=225706&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp (added)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp Mon Jan 12 16:19:22 2015<br>
@@ -0,0 +1,143 @@<br>
+//===-- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework ----------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file contains support for writing dwarf debug info into asm files.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "DwarfExpression.h"<br>
+#include "llvm/ADT/SmallBitVector.h"<br>
+#include "llvm/Support/Dwarf.h"<br>
+#include "llvm/Target/TargetMachine.h"<br>
+#include "llvm/Target/TargetRegisterInfo.h"<br>
+#include "llvm/Target/TargetSubtargetInfo.h"<br>
+<br>
+<br>
+using namespace llvm;<br>
+<br>
+void DwarfExpression::AddReg(int DwarfReg, const char* Comment) {<br>
+  assert(DwarfReg >= 0 && "invalid negative dwarf register number");<br>
+  if (DwarfReg < 32) {<br>
+    EmitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);<br>
+  } else {<br>
+    EmitOp(dwarf::DW_OP_regx, Comment);<br>
+    EmitUnsigned(DwarfReg);<br>
+  }<br>
+}<br>
+<br>
+void DwarfExpression::AddRegIndirect(int DwarfReg, int Offset, bool Deref) {<br>
+  assert(DwarfReg >= 0 && "invalid negative dwarf register number");<br>
+  if (DwarfReg < 32) {<br>
+    EmitOp(dwarf::DW_OP_breg0 + DwarfReg);<br>
+  } else {<br>
+    EmitOp(dwarf::DW_OP_bregx);<br>
+    EmitUnsigned(DwarfReg);<br>
+  }<br>
+  EmitSigned(Offset);<br>
+  if (Deref)<br>
+    EmitOp(dwarf::DW_OP_deref);<br>
+}<br>
+<br>
+void DwarfExpression::AddOpPiece(unsigned SizeInBits,<br>
+                                 unsigned OffsetInBits) {<br>
+  assert(SizeInBits > 0 && "piece has size zero");<br>
+  const unsigned SizeOfByte = 8;<br>
+  if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {<br>
+    EmitOp(dwarf::DW_OP_bit_piece);<br>
+    EmitUnsigned(SizeInBits);<br>
+    EmitUnsigned(OffsetInBits);<br>
+  } else {<br>
+    EmitOp(dwarf::DW_OP_piece);<br>
+    unsigned ByteSize = SizeInBits / SizeOfByte;<br>
+    EmitUnsigned(ByteSize);<br>
+  }<br>
+}<br>
+<br>
+void DwarfExpression::AddShr(unsigned ShiftBy) {<br>
+  EmitOp(dwarf::DW_OP_constu);<br>
+  EmitUnsigned(ShiftBy);<br>
+  EmitOp(dwarf::DW_OP_shr);<br>
+}<br>
+<br>
+void DwarfExpression::AddMachineRegPiece(unsigned MachineReg,<br>
+                                         unsigned PieceSizeInBits,<br>
+                                         unsigned PieceOffsetInBits) {<br>
+  const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();<br>
+  int Reg = TRI->getDwarfRegNum(MachineReg, false);<br>
+<br>
+  // If this is a valid register number, emit it.<br>
+  if (Reg >= 0) {<br>
+    AddReg(Reg);<br>
+    AddOpPiece(PieceSizeInBits, PieceOffsetInBits);<br>
+    return;<br>
+  }<br>
+<br>
+  // Walk up the super-register chain until we find a valid number.<br>
+  // For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0.<br>
+  for (MCSuperRegIterator SR(MachineReg, TRI); SR.isValid(); ++SR) {<br>
+    Reg = TRI->getDwarfRegNum(*SR, false);<br>
+    if (Reg >= 0) {<br>
+      unsigned Idx = TRI->getSubRegIndex(*SR, MachineReg);<br>
+      unsigned Size = TRI->getSubRegIdxSize(Idx);<br>
+      unsigned RegOffset = TRI->getSubRegIdxOffset(Idx);<br>
+      AddReg(Reg, "super-register");<br>
+      if (PieceOffsetInBits == RegOffset) {<br>
+        AddOpPiece(Size, RegOffset);<br>
+      } else {<br>
+        // If this is part of a variable in a sub-register at a<br>
+        // non-zero offset, we need to manually shift the value into<br>
+        // place, since the DW_OP_piece describes the part of the<br>
+        // variable, not the position of the subregister.<br>
+        if (RegOffset)<br>
+          AddShr(RegOffset);<br>
+        AddOpPiece(Size, PieceOffsetInBits);<br>
+      }<br>
+      return;<br>
+    }<br>
+  }<br>
+<br>
+  // Otherwise, attempt to find a covering set of sub-register numbers.<br>
+  // For example, Q0 on ARM is a composition of D0+D1.<br>
+  //<br>
+  // Keep track of the current position so we can emit the more<br>
+  // efficient DW_OP_piece.<br>
+  unsigned CurPos = PieceOffsetInBits;<br>
+  // The size of the register in bits, assuming 8 bits per byte.<br>
+  unsigned RegSize = TRI->getMinimalPhysRegClass(MachineReg)->getSize() * 8;<br>
+  // Keep track of the bits in the register we already emitted, so we<br>
+  // can avoid emitting redundant aliasing subregs.<br>
+  SmallBitVector Coverage(RegSize, false);<br>
+  for (MCSubRegIterator SR(MachineReg, TRI); SR.isValid(); ++SR) {<br>
+    unsigned Idx = TRI->getSubRegIndex(MachineReg, *SR);<br>
+    unsigned Size = TRI->getSubRegIdxSize(Idx);<br>
+    unsigned Offset = TRI->getSubRegIdxOffset(Idx);<br>
+    Reg = TRI->getDwarfRegNum(*SR, false);<br>
+<br>
+    // Intersection between the bits we already emitted and the bits<br>
+    // covered by this subregister.<br>
+    SmallBitVector Intersection(RegSize, false);<br>
+    Intersection.set(Offset, Offset + Size);<br>
+    Intersection ^= Coverage;<br>
+<br>
+    // If this sub-register has a DWARF number and we haven't covered<br>
+    // its range, emit a DWARF piece for it.<br>
+    if (Reg >= 0 && Intersection.any()) {<br>
+      AddReg(Reg, "sub-register");<br>
+      AddOpPiece(Size, Offset == CurPos ? 0 : Offset);<br>
+      CurPos = Offset + Size;<br>
+<br>
+      // Mark it as emitted.<br>
+      Coverage.set(Offset, Offset + Size);<br>
+    }<br>
+  }<br>
+<br>
+  if (CurPos == PieceOffsetInBits)<br>
+    // FIXME: We have no reasonable way of handling errors in here.<br>
+    EmitOp(dwarf::DW_OP_nop, "nop (could not find a dwarf register number)");<br>
+}<br>
<br>
Added: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h?rev=225706&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h?rev=225706&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h (added)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h Mon Jan 12 16:19:22 2015<br>
@@ -0,0 +1,65 @@<br>
+//===-- llvm/CodeGen/DwarfExpression.h - Dwarf Compile Unit ---*- C++ -*--===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file contains support for writing dwarf compile unit.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H<br>
+#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H<br>
+<br>
+#include "llvm/Support/DataTypes.h"<br>
+<br>
+namespace llvm {<br>
+<br>
+class TargetMachine;<br>
+<br>
+/// Base class containing the logic for constructing DWARF expressions<br>
+/// independently of whether they are emitted into a DIE or into a .debug_loc<br>
+/// entry.<br>
+class DwarfExpression {<br>
+  TargetMachine &TM;<br>
+public:<br>
+  DwarfExpression(TargetMachine &TM) : TM(TM) {}<br>
+<br>
+  virtual void EmitOp(uint8_t Op, const char* Comment = nullptr) = 0;<br>
+  virtual void EmitSigned(int Value) = 0;<br>
+  virtual void EmitUnsigned(unsigned Value) = 0;<br>
+  /// Emit a dwarf register operation.<br>
+  void AddReg(int DwarfReg, const char* Comment = nullptr);<br>
+  /// Emit an (double-)indirect dwarf register operation.<br>
+  void AddRegIndirect(int DwarfReg, int Offset, bool Deref = false);<br>
+<br>
+  /// Emit a dwarf register operation for describing<br>
+  /// - a small value occupying only part of a register or<br>
+  /// - a register representing only part of a value.<br>
+  void AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0);<br>
+  /// Emit a shift-right dwarf expression.<br>
+  void AddShr(unsigned ShiftBy);<br>
+<br>
+  /// \brief Emit a partial DWARF register operation.<br>
+  /// \param MLoc             the register<br>
+  /// \param PieceSize        size and<br>
+  /// \param PieceOffset      offset of the piece in bits, if this is one<br>
+  ///                         piece of an aggregate value.<br>
+  ///<br>
+  /// If size and offset is zero an operation for the entire<br>
+  /// register is emitted: Some targets do not provide a DWARF<br>
+  /// register number for every register.  If this is the case, this<br>
+  /// function will attempt to emit a DWARF register by emitting a<br>
+  /// piece of a super-register or by piecing together multiple<br>
+  /// subregisters that alias the register.<br>
+  void AddMachineRegPiece(unsigned MachineReg,<br>
+                          unsigned PieceSizeInBits = 0,<br>
+                          unsigned PieceOffsetInBits = 0);<br>
+};<br>
+<br>
+}<br>
+<br>
+#endif<br>
<br>
Modified: llvm/trunk/test/CodeGen/ARM/debug-info-qreg.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/debug-info-qreg.ll?rev=225706&r1=225705&r2=225706&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/debug-info-qreg.ll?rev=225706&r1=225705&r2=225706&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/ARM/debug-info-qreg.ll (original)<br>
+++ llvm/trunk/test/CodeGen/ARM/debug-info-qreg.ll Mon Jan 12 16:19:22 2015<br>
@@ -2,13 +2,11 @@<br>
 target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"<br>
 target triple = "thumbv7-apple-macosx10.6.7"<br>
<br>
-;CHECK: sub-register<br>
-;CHECK-NEXT: DW_OP_regx<br>
+;CHECK: sub-register DW_OP_regx<br>
 ;CHECK-NEXT: ascii<br>
 ;CHECK-NEXT: DW_OP_piece<br>
 ;CHECK-NEXT: byte   8<br>
-;CHECK-NEXT: sub-register<br>
-;CHECK-NEXT: DW_OP_regx<br>
+;CHECK-NEXT: sub-register DW_OP_regx<br>
 ;CHECK-NEXT: ascii<br>
 ;CHECK-NEXT: DW_OP_piece<br>
 ;CHECK-NEXT: byte   8<br>
<br>
Modified: llvm/trunk/test/CodeGen/ARM/debug-info-s16-reg.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/debug-info-s16-reg.ll?rev=225706&r1=225705&r2=225706&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/debug-info-s16-reg.ll?rev=225706&r1=225705&r2=225706&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/ARM/debug-info-s16-reg.ll (original)<br>
+++ llvm/trunk/test/CodeGen/ARM/debug-info-s16-reg.ll Mon Jan 12 16:19:22 2015<br>
@@ -1,8 +1,7 @@<br>
 ; RUN: llc < %s - | FileCheck %s<br>
 ; Radar 9309221<br>
 ; Test dwarf reg no for s16<br>
-;CHECK: super-register<br>
-;CHECK-NEXT: DW_OP_regx<br>
+;CHECK: super-register DW_OP_regx<br>
 ;CHECK-NEXT: ascii<br>
 ;CHECK-NEXT: DW_OP_piece<br>
 ;CHECK-NEXT: 4<br>
<br>
Modified: llvm/trunk/test/DebugInfo/X86/subreg.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/subreg.ll?rev=225706&r1=225705&r2=225706&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/subreg.ll?rev=225706&r1=225705&r2=225706&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/DebugInfo/X86/subreg.ll (original)<br>
+++ llvm/trunk/test/DebugInfo/X86/subreg.ll Mon Jan 12 16:19:22 2015<br>
@@ -3,8 +3,7 @@<br>
 ; We are testing that a value in a 16 bit register gets reported as<br>
 ; being in its superregister.<br>
<br>
-; CHECK: .byte   80                      # super-register<br>
-; CHECK-NEXT:                            # DW_OP_reg0<br>
+; CHECK: .byte   80                      # super-register DW_OP_reg0<br>
 ; CHECK-NEXT: .byte   147                # DW_OP_piece<br>
 ; CHECK-NEXT: .byte   2                  # 2<br>
<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>