1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

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.)

llvm-svn: 202416
This commit is contained in:
Adrian Prantl 2014-02-27 17:56:08 +00:00
parent 947c19eaa0
commit d7f77dd966
7 changed files with 101 additions and 112 deletions

View File

@ -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 AsmPrinter &AP,
/// 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 AsmPrinter &AP,
}
}
/// 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())

View File

@ -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.

View File

@ -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())

View File

@ -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]

View File

@ -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"

View File

@ -12,7 +12,10 @@ target triple = "thumbv7-apple-macosx10.6.7"
;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:

View File

@ -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: