[llvm] r202416 - Debug info: Remove ARMAsmPrinter::EmitDwarfRegOp(). AsmPrinter can now

Adrian Prantl aprantl at apple.com
Thu Feb 27 09:56:08 PST 2014


Author: adrian
Date: Thu Feb 27 11:56:08 2014
New Revision: 202416

URL: http://llvm.org/viewvc/llvm-project?rev=202416&view=rev
Log:
Debug info: Remove ARMAsmPrinter::EmitDwarfRegOp(). AsmPrinter can now
scan the register file for sub- and super-registers.
No functionality change intended.

(Tests are updated because the comments in the assembler output are
different.)

Modified:
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
    llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h
    llvm/trunk/test/CodeGen/ARM/debug-info-qreg.ll
    llvm/trunk/test/CodeGen/ARM/debug-info-s16-reg.ll
    llvm/trunk/test/CodeGen/ARM/debug-info-sreg2.ll
    llvm/trunk/test/DebugInfo/X86/subreg.ll

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=202416&r1=202415&r2=202416&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Thu Feb 27 11:56:08 2014
@@ -15,6 +15,7 @@
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "DwarfDebug.h"
 #include "DwarfException.h"
+#include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/ConstantFolding.h"
@@ -908,13 +909,9 @@ static void emitDwarfRegOpIndirect(const
 /// Emit a dwarf register operation for describing
 /// - a small value occupying only part of a register or
 /// - a small register representing only part of a value.
-static void emitDwarfRegOpPiece(const AsmPrinter &AP,
-                                int Reg, unsigned Size, unsigned Offset) {
-  assert(Reg >= 0);
+static void emitDwarfOpPiece(const AsmPrinter &AP,
+                                unsigned Size, unsigned Offset) {
   assert(Size > 0);
-
-  emitDwarfRegOp(AP, Reg);
-  // Emit Mask
   if (Offset > 0) {
     AP.OutStreamer.AddComment("DW_OP_bit_piece");
     AP.EmitInt8(dwarf::DW_OP_bit_piece);
@@ -931,41 +928,93 @@ static void emitDwarfRegOpPiece(const As
   }
 }
 
+/// Some targets do not provide a DWARF register number for every
+/// register.  This function attempts to emit a dwarf register by
+/// emitting a piece of a super-register or by piecing together
+/// multiple subregisters that alias the register.
+static void EmitDwarfRegOpPiece(const AsmPrinter &AP,
+                                const MachineLocation &MLoc) {
+  assert(!MLoc.isIndirect());
+  const TargetRegisterInfo *TRI = AP.TM.getRegisterInfo();
+  int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);
+
+  // Walk up the super-register chain until we find a valid number.
+  // For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0.
+  for (MCSuperRegIterator SR(MLoc.getReg(), TRI); SR.isValid(); ++SR) {
+    Reg = TRI->getDwarfRegNum(*SR, false);
+    if (Reg >= 0) {
+      unsigned Idx = TRI->getSubRegIndex(*SR, MLoc.getReg());
+      unsigned Size = TRI->getSubRegIdxSize(Idx);
+      unsigned Offset = TRI->getSubRegIdxOffset(Idx);
+      AP.OutStreamer.AddComment("super-register");
+      emitDwarfRegOp(AP, Reg);
+      emitDwarfOpPiece(AP, Size, Offset);
+      return;
+    }
+  }
+
+  // Otherwise, attempt to find a covering set of sub-register numbers.
+  // For example, Q0 on ARM is a composition of D0+D1.
+  //
+  // Keep track of the current position so we can emit the more
+  // efficient DW_OP_piece.
+  unsigned CurPos = 0;
+  // The size of the register in bits, assuming 8 bits per byte.
+  unsigned RegSize = TRI->getMinimalPhysRegClass(MLoc.getReg())->getSize()*8;
+  // Keep track of the bits in the register we already emitted, so we
+  // can avoid emitting redundant aliasing subregs.
+  SmallBitVector Coverage(RegSize, false);
+  for (MCSubRegIterator SR(MLoc.getReg(), TRI); SR.isValid(); ++SR) {
+    unsigned Idx = TRI->getSubRegIndex(MLoc.getReg(), *SR);
+    unsigned Size = TRI->getSubRegIdxSize(Idx);
+    unsigned Offset = TRI->getSubRegIdxOffset(Idx);
+    Reg = TRI->getDwarfRegNum(*SR, false);
+
+    // Intersection between the bits we already emitted and the bits
+    // covered by this subregister.
+    SmallBitVector Intersection(RegSize, false);
+    Intersection.set(Offset, Offset+Size);
+    Intersection ^= Coverage;
+
+    // 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()) {
+      AP.OutStreamer.AddComment("sub-register");
+      emitDwarfRegOp(AP, Reg);
+      emitDwarfOpPiece(AP, Size, Offset == CurPos ? 0 : Offset);
+      CurPos = Offset+Size;
+
+      // Mark it as emitted.
+      Coverage.set(Offset, Offset+Size);
+    }
+  }
+
+  if (CurPos == 0) {
+    // FIXME: We have no reasonable way of handling errors in here.
+    AP.OutStreamer.AddComment("nop (could not find a dwarf register number)");
+    AP.EmitInt8(dwarf::DW_OP_nop);
+  }
+}
+
 /// EmitDwarfRegOp - Emit dwarf register operation.
 void AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc,
                                 bool Indirect) const {
   const TargetRegisterInfo *TRI = TM.getRegisterInfo();
   int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);
-
   if (Reg < 0) {
-    // Walk up the super-register chain until we find a valid number.
-    for (MCSuperRegIterator SR(MLoc.getReg(), TRI); SR.isValid(); ++SR) {
-      Reg = TRI->getDwarfRegNum(*SR, false);
-      if (Reg >= 0) {
-        unsigned Idx = TRI->getSubRegIndex(*SR, MLoc.getReg());
-        unsigned Size = TRI->getSubRegIdxSize(Idx);
-        unsigned Offset = TRI->getSubRegIdxOffset(Idx);
-        emitDwarfRegOpPiece(*this, Reg, Size, Offset);
-
-        if (MLoc.isIndirect())
-          EmitInt8(dwarf::DW_OP_deref);
-
-        if (Indirect)
-          EmitInt8(dwarf::DW_OP_deref);
-
-        return;
-      }
-
-      // FIXME: Handle cases like a super register being encoded as
-      // DW_OP_reg 32 DW_OP_piece 4 DW_OP_reg 33
-
+    // We assume that pointers are always in an addressable register.
+    if (Indirect || MLoc.isIndirect()) {
+      // FIXME: We have no reasonable way of handling errors in here. The
+      // caller might be in the middle of a dwarf expression. We should
+      // probably assert that Reg >= 0 once debug info generation is more mature.
+      OutStreamer.AddComment("nop (invalid dwarf register number for indirect loc)");
+      EmitInt8(dwarf::DW_OP_nop);
+      return;
     }
-    // FIXME: We have no reasonable way of handling errors in here. The
-    // caller might be in the middle of an dwarf expression. We should
-    // probably assert that Reg >= 0 once debug info generation is more mature.
-    OutStreamer.AddComment("nop (invalid dwarf register number)");
-    EmitInt8(dwarf::DW_OP_nop);
-    return;
+
+    // Attempt to find a valid super- or sub-register.
+    if (!Indirect && !MLoc.isIndirect())
+      return EmitDwarfRegOpPiece(*this, MLoc);
   }
 
   if (MLoc.isIndirect())

Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=202416&r1=202415&r2=202416&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Thu Feb 27 11:56:08 2014
@@ -55,70 +55,6 @@
 #include <cctype>
 using namespace llvm;
 
-/// EmitDwarfRegOp - Emit dwarf register operation.
-void ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc,
-                                   bool Indirect) const {
-  const TargetRegisterInfo *RI = TM.getRegisterInfo();
-  if (RI->getDwarfRegNum(MLoc.getReg(), false) != -1) {
-    AsmPrinter::EmitDwarfRegOp(MLoc, Indirect);
-    return;
-  }
-  assert(MLoc.isReg() && !Indirect &&
-         "This doesn't support offset/indirection - implement it if needed");
-  unsigned Reg = MLoc.getReg();
-  if (Reg >= ARM::S0 && Reg <= ARM::S31) {
-    assert(ARM::S0 + 31 == ARM::S31 && "Unexpected ARM S register numbering");
-    // S registers are described as bit-pieces of a register
-    // S[2x] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 0)
-    // S[2x+1] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 32)
-
-    unsigned SReg = Reg - ARM::S0;
-    bool odd = SReg & 0x1;
-    unsigned Rx = 256 + (SReg >> 1);
-
-    OutStreamer.AddComment("DW_OP_regx for S register");
-    EmitInt8(dwarf::DW_OP_regx);
-
-    OutStreamer.AddComment(Twine(SReg));
-    EmitULEB128(Rx);
-
-    if (odd) {
-      OutStreamer.AddComment("DW_OP_bit_piece 32 32");
-      EmitInt8(dwarf::DW_OP_bit_piece);
-      EmitULEB128(32);
-      EmitULEB128(32);
-    } else {
-      OutStreamer.AddComment("DW_OP_bit_piece 32 0");
-      EmitInt8(dwarf::DW_OP_bit_piece);
-      EmitULEB128(32);
-      EmitULEB128(0);
-    }
-  } else if (Reg >= ARM::Q0 && Reg <= ARM::Q15) {
-    assert(ARM::Q0 + 15 == ARM::Q15 && "Unexpected ARM Q register numbering");
-    // Q registers Q0-Q15 are described by composing two D registers together.
-    // Qx = DW_OP_regx(256+2x) DW_OP_piece(8) DW_OP_regx(256+2x+1)
-    // DW_OP_piece(8)
-
-    unsigned QReg = Reg - ARM::Q0;
-    unsigned D1 = 256 + 2 * QReg;
-    unsigned D2 = D1 + 1;
-
-    OutStreamer.AddComment("DW_OP_regx for Q register: D1");
-    EmitInt8(dwarf::DW_OP_regx);
-    EmitULEB128(D1);
-    OutStreamer.AddComment("DW_OP_piece 8");
-    EmitInt8(dwarf::DW_OP_piece);
-    EmitULEB128(8);
-
-    OutStreamer.AddComment("DW_OP_regx for Q register: D2");
-    EmitInt8(dwarf::DW_OP_regx);
-    EmitULEB128(D2);
-    OutStreamer.AddComment("DW_OP_piece 8");
-    EmitInt8(dwarf::DW_OP_piece);
-    EmitULEB128(8);
-  }
-}
-
 void ARMAsmPrinter::EmitFunctionBodyEnd() {
   // Make sure to terminate any constant pools that were at the end
   // of the function.

Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h?rev=202416&r1=202415&r2=202416&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.h Thu Feb 27 11:56:08 2014
@@ -98,10 +98,6 @@ private:
                                    const MachineInstr *MI);
 
 public:
-  /// EmitDwarfRegOp - Emit dwarf register operation.
-  virtual void EmitDwarfRegOp(const MachineLocation &MLoc, bool Indirect) const
-      LLVM_OVERRIDE;
-
   virtual unsigned getISAEncoding() LLVM_OVERRIDE {
     // ARM/Darwin adds ISA to the DWARF info for each function.
     if (!Subtarget->isTargetMachO())

Modified: llvm/trunk/test/CodeGen/ARM/debug-info-qreg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/debug-info-qreg.ll?rev=202416&r1=202415&r2=202416&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/debug-info-qreg.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/debug-info-qreg.ll Thu Feb 27 11:56:08 2014
@@ -2,13 +2,15 @@
 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"
 target triple = "thumbv7-apple-macosx10.6.7"
 
-;CHECK: DW_OP_regx for Q register: D1
+;CHECK: sub-register
+;CHECK-NEXT: DW_OP_regx
 ;CHECK-NEXT: ascii
-;CHECK-NEXT: DW_OP_piece 8
+;CHECK-NEXT: DW_OP_piece
 ;CHECK-NEXT: byte   8
-;CHECK-NEXT: DW_OP_regx for Q register: D2
+;CHECK-NEXT: sub-register
+;CHECK-NEXT: DW_OP_regx
 ;CHECK-NEXT: ascii
-;CHECK-NEXT: DW_OP_piece 8
+;CHECK-NEXT: DW_OP_piece
 ;CHECK-NEXT: byte   8
 
 @.str = external constant [13 x i8]

Modified: llvm/trunk/test/CodeGen/ARM/debug-info-s16-reg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/debug-info-s16-reg.ll?rev=202416&r1=202415&r2=202416&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/debug-info-s16-reg.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/debug-info-s16-reg.ll Thu Feb 27 11:56:08 2014
@@ -1,9 +1,11 @@
 ; RUN: llc < %s - | FileCheck %s
 ; Radar 9309221
 ; Test dwarf reg no for s16
-;CHECK: DW_OP_regx for S register
+;CHECK: super-register
+;CHECK-NEXT: DW_OP_regx
 ;CHECK-NEXT: ascii
-;CHECK-NEXT: DW_OP_bit_piece 32 0
+;CHECK-NEXT: DW_OP_piece
+;CHECK-NEXT: 4
 
 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"
 target triple = "thumbv7-apple-macosx10.6.7"

Modified: llvm/trunk/test/CodeGen/ARM/debug-info-sreg2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/debug-info-sreg2.ll?rev=202416&r1=202415&r2=202416&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/debug-info-sreg2.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/debug-info-sreg2.ll Thu Feb 27 11:56:08 2014
@@ -12,7 +12,10 @@ target triple = "thumbv7-apple-macosx10.
 ;CHECK-NEXT: Lset[[N:[0-9]+]] = Ltmp{{[0-9]+}}-Ltmp[[M:[0-9]+]]        @ Loc expr size
 ;CHECK-NEXT:        .short  Lset[[N]]
 ;CHECK-NEXT: Ltmp[[M]]:
-;CHECK-NEXT:        .byte   144                     @ DW_OP_regx for S register
+;CHECK-NEXT:        .byte   144                     @ super-register
+;CHECK-NEXT:                                        @ DW_OP_regx
+;CHECK-NEXT:        .ascii
+;CHECK-NEXT:        .byte   {{[0-9]+}}              @ DW_OP_{{.*}}piece
 
 define void @_Z3foov() optsize ssp {
 entry:

Modified: llvm/trunk/test/DebugInfo/X86/subreg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/subreg.ll?rev=202416&r1=202415&r2=202416&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/subreg.ll (original)
+++ llvm/trunk/test/DebugInfo/X86/subreg.ll Thu Feb 27 11:56:08 2014
@@ -3,9 +3,10 @@
 ; We are testing that a value in a 16 bit register gets reported as
 ; being in its superregister.
 
-; CHECK: .byte   80                      # DW_OP_reg0
-; CHECK: .byte   147                     # DW_OP_piece
-; CHECK: .byte   2                       # 2
+; CHECK: .byte   80                      # super-register
+; CHECK-NEXT:                            # DW_OP_reg0
+; CHECK-NEXT: .byte   147                # DW_OP_piece
+; CHECK-NEXT: .byte   2                  # 2
 
 define i16 @f(i16 signext %zzz) nounwind {
 entry:





More information about the llvm-commits mailing list