LLVM  3.7.0
DwarfExpression.cpp
Go to the documentation of this file.
1 //===-- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework ----------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains support for writing dwarf debug info into asm files.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "DwarfExpression.h"
15 #include "DwarfDebug.h"
18 #include "llvm/Support/Dwarf.h"
22 
23 using namespace llvm;
24 
25 void DwarfExpression::AddReg(int DwarfReg, const char *Comment) {
26  assert(DwarfReg >= 0 && "invalid negative dwarf register number");
27  if (DwarfReg < 32) {
28  EmitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
29  } else {
30  EmitOp(dwarf::DW_OP_regx, Comment);
31  EmitUnsigned(DwarfReg);
32  }
33 }
34 
35 void DwarfExpression::AddRegIndirect(int DwarfReg, int Offset, bool Deref) {
36  assert(DwarfReg >= 0 && "invalid negative dwarf register number");
37  if (DwarfReg < 32) {
38  EmitOp(dwarf::DW_OP_breg0 + DwarfReg);
39  } else {
40  EmitOp(dwarf::DW_OP_bregx);
41  EmitUnsigned(DwarfReg);
42  }
43  EmitSigned(Offset);
44  if (Deref)
45  EmitOp(dwarf::DW_OP_deref);
46 }
47 
48 void DwarfExpression::AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits) {
49  assert(SizeInBits > 0 && "piece has size zero");
50  const unsigned SizeOfByte = 8;
51  if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {
52  EmitOp(dwarf::DW_OP_bit_piece);
53  EmitUnsigned(SizeInBits);
54  EmitUnsigned(OffsetInBits);
55  } else {
56  EmitOp(dwarf::DW_OP_piece);
57  unsigned ByteSize = SizeInBits / SizeOfByte;
58  EmitUnsigned(ByteSize);
59  }
60 }
61 
62 void DwarfExpression::AddShr(unsigned ShiftBy) {
63  EmitOp(dwarf::DW_OP_constu);
64  EmitUnsigned(ShiftBy);
65  EmitOp(dwarf::DW_OP_shr);
66 }
67 
68 bool DwarfExpression::AddMachineRegIndirect(unsigned MachineReg, int Offset) {
69  if (isFrameRegister(MachineReg)) {
70  // If variable offset is based in frame register then use fbreg.
71  EmitOp(dwarf::DW_OP_fbreg);
72  EmitSigned(Offset);
73  return true;
74  }
75 
76  int DwarfReg = TRI.getDwarfRegNum(MachineReg, false);
77  if (DwarfReg < 0)
78  return false;
79 
80  AddRegIndirect(DwarfReg, Offset);
81  return true;
82 }
83 
84 bool DwarfExpression::AddMachineRegPiece(unsigned MachineReg,
85  unsigned PieceSizeInBits,
86  unsigned PieceOffsetInBits) {
87  if (!TRI.isPhysicalRegister(MachineReg))
88  return false;
89 
90  int Reg = TRI.getDwarfRegNum(MachineReg, false);
91 
92  // If this is a valid register number, emit it.
93  if (Reg >= 0) {
94  AddReg(Reg);
95  if (PieceSizeInBits)
96  AddOpPiece(PieceSizeInBits, PieceOffsetInBits);
97  return true;
98  }
99 
100  // Walk up the super-register chain until we find a valid number.
101  // For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0.
102  for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
103  Reg = TRI.getDwarfRegNum(*SR, false);
104  if (Reg >= 0) {
105  unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg);
106  unsigned Size = TRI.getSubRegIdxSize(Idx);
107  unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
108  AddReg(Reg, "super-register");
109  if (PieceOffsetInBits == RegOffset) {
110  AddOpPiece(Size, RegOffset);
111  } else {
112  // If this is part of a variable in a sub-register at a
113  // non-zero offset, we need to manually shift the value into
114  // place, since the DW_OP_piece describes the part of the
115  // variable, not the position of the subregister.
116  if (RegOffset)
117  AddShr(RegOffset);
118  AddOpPiece(Size, PieceOffsetInBits);
119  }
120  return true;
121  }
122  }
123 
124  // Otherwise, attempt to find a covering set of sub-register numbers.
125  // For example, Q0 on ARM is a composition of D0+D1.
126  //
127  // Keep track of the current position so we can emit the more
128  // efficient DW_OP_piece.
129  unsigned CurPos = PieceOffsetInBits;
130  // The size of the register in bits, assuming 8 bits per byte.
131  unsigned RegSize = TRI.getMinimalPhysRegClass(MachineReg)->getSize() * 8;
132  // Keep track of the bits in the register we already emitted, so we
133  // can avoid emitting redundant aliasing subregs.
134  SmallBitVector Coverage(RegSize, false);
135  for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
136  unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR);
137  unsigned Size = TRI.getSubRegIdxSize(Idx);
138  unsigned Offset = TRI.getSubRegIdxOffset(Idx);
139  Reg = TRI.getDwarfRegNum(*SR, false);
140 
141  // Intersection between the bits we already emitted and the bits
142  // covered by this subregister.
143  SmallBitVector Intersection(RegSize, false);
144  Intersection.set(Offset, Offset + Size);
145  Intersection ^= Coverage;
146 
147  // If this sub-register has a DWARF number and we haven't covered
148  // its range, emit a DWARF piece for it.
149  if (Reg >= 0 && Intersection.any()) {
150  AddReg(Reg, "sub-register");
151  AddOpPiece(Size, Offset == CurPos ? 0 : Offset);
152  CurPos = Offset + Size;
153 
154  // Mark it as emitted.
155  Coverage.set(Offset, Offset + Size);
156  }
157  }
158 
159  return CurPos > PieceOffsetInBits;
160 }
161 
163  EmitOp(dwarf::DW_OP_consts);
164  EmitSigned(Value);
165  // The proper way to describe a constant value is
166  // DW_OP_constu <const>, DW_OP_stack_value.
167  // Unfortunately, DW_OP_stack_value was not available until DWARF-4,
168  // so we will continue to generate DW_OP_constu <const> for DWARF-2
169  // and DWARF-3. Technically, this is incorrect since DW_OP_const <const>
170  // actually describes a value at a constant addess, not a constant value.
171  // However, in the past there was no better way to describe a constant
172  // value, so the producers and consumers started to rely on heuristics
173  // to disambiguate the value vs. location status of the expression.
174  // See PR21176 for more details.
175  if (DwarfVersion >= 4)
176  EmitOp(dwarf::DW_OP_stack_value);
177 }
178 
180  EmitOp(dwarf::DW_OP_constu);
181  EmitUnsigned(Value);
182  // cf. comment in DwarfExpression::AddSignedConstant().
183  if (DwarfVersion >= 4)
184  EmitOp(dwarf::DW_OP_stack_value);
185 }
186 
187 static unsigned getOffsetOrZero(unsigned OffsetInBits,
188  unsigned PieceOffsetInBits) {
189  if (OffsetInBits == PieceOffsetInBits)
190  return 0;
191  assert(OffsetInBits >= PieceOffsetInBits && "overlapping pieces");
192  return OffsetInBits;
193 }
194 
196  unsigned MachineReg,
197  unsigned PieceOffsetInBits) {
198  auto I = Expr->expr_op_begin();
199  auto E = Expr->expr_op_end();
200  if (I == E)
201  return AddMachineRegPiece(MachineReg);
202 
203  // Pattern-match combinations for which more efficient representations exist
204  // first.
205  bool ValidReg = false;
206  switch (I->getOp()) {
207  case dwarf::DW_OP_bit_piece: {
208  unsigned OffsetInBits = I->getArg(0);
209  unsigned SizeInBits = I->getArg(1);
210  // Piece always comes at the end of the expression.
211  return AddMachineRegPiece(MachineReg, SizeInBits,
212  getOffsetOrZero(OffsetInBits, PieceOffsetInBits));
213  }
214  case dwarf::DW_OP_plus: {
215  // [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset].
216  auto N = I.getNext();
217  if (N != E && N->getOp() == dwarf::DW_OP_deref) {
218  unsigned Offset = I->getArg(0);
219  ValidReg = AddMachineRegIndirect(MachineReg, Offset);
220  std::advance(I, 2);
221  break;
222  } else
223  ValidReg = AddMachineRegPiece(MachineReg);
224  }
225  case dwarf::DW_OP_deref: {
226  // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg].
227  ValidReg = AddMachineRegIndirect(MachineReg);
228  ++I;
229  break;
230  }
231  default:
232  llvm_unreachable("unsupported operand");
233  }
234 
235  if (!ValidReg)
236  return false;
237 
238  // Emit remaining elements of the expression.
239  AddExpression(I, E, PieceOffsetInBits);
240  return true;
241 }
242 
245  unsigned PieceOffsetInBits) {
246  for (; I != E; ++I) {
247  switch (I->getOp()) {
248  case dwarf::DW_OP_bit_piece: {
249  unsigned OffsetInBits = I->getArg(0);
250  unsigned SizeInBits = I->getArg(1);
251  AddOpPiece(SizeInBits, getOffsetOrZero(OffsetInBits, PieceOffsetInBits));
252  break;
253  }
254  case dwarf::DW_OP_plus:
255  EmitOp(dwarf::DW_OP_plus_uconst);
256  EmitUnsigned(I->getArg(0));
257  break;
258  case dwarf::DW_OP_deref:
259  EmitOp(dwarf::DW_OP_deref);
260  break;
261  default:
262  llvm_unreachable("unhandled opcode found in expression");
263  }
264  }
265 }
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
SmallBitVector - This is a 'bitvector' (really, a variable-sized bit array), optimized for the case w...
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
void AddShr(unsigned ShiftBy)
Emit a shift-right dwarf expression.
bool AddMachineRegExpression(const DIExpression *Expr, unsigned MachineReg, unsigned PieceOffsetInBits=0)
Emit an entire expression on top of a machine register location.
void AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits=0)
Emit a dwarf register operation for describing.
virtual void EmitOp(uint8_t Op, const char *Comment=nullptr)=0
Output a dwarf operand and an optional assembler comment.
unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const
For a given register pair, return the sub-register index if the second register is a sub-register of ...
unsigned getSize() const
getSize - Return the size of the register in bytes, which is also the size of a stack slot allocated ...
MCSuperRegIterator enumerates all super-registers of Reg.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
static void advance(T &it, size_t Val)
Reg
All possible values of the reg field in the ModR/M byte.
expr_op_iterator expr_op_begin() const
Visit the elements via ExprOperand wrappers.
static unsigned getOffsetOrZero(unsigned OffsetInBits, unsigned PieceOffsetInBits)
void AddUnsignedConstant(unsigned Value)
Emit an unsigned constant.
void AddSignedConstant(int Value)
Emit a signed constant.
uint64_t getArg(unsigned I) const
Get an argument to the operand.
void AddRegIndirect(int DwarfReg, int Offset, bool Deref=false)
Emit an (double-)indirect dwarf register operation.
MCSubRegIterator enumerates all sub-registers of Reg.
virtual void EmitUnsigned(uint64_t Value)=0
Emit a raw unsigned value.
SmallBitVector & set()
bool AddMachineRegIndirect(unsigned MachineReg, int Offset=0)
Emit an indirect dwarf register operation for the given machine register.
DWARF expression.
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, MVT VT=MVT::Other) const
getMinimalPhysRegClass - Returns the Register Class of a physical register of the given type...
static bool isPhysicalRegister(unsigned Reg)
isPhysicalRegister - Return true if the specified register number is in the physical register namespa...
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
unsigned getSubRegIdxOffset(unsigned Idx) const
Get the offset of the bit range covered by a sub-register index.
LLVM Value Representation.
Definition: Value.h:69
bool any() const
any - Returns true if any bit is set.
virtual void EmitSigned(int64_t Value)=0
Emit a raw signed value.
An iterator for expression operands.
uint64_t getOp() const
Get the operand code.
unsigned getSubRegIdxSize(unsigned Idx) const
Get the size of the bit range covered by a sub-register index.
expr_op_iterator expr_op_end() const
void AddReg(int DwarfReg, const char *Comment=nullptr)
Emit a dwarf register operation.
const TargetRegisterInfo & TRI
bool AddMachineRegPiece(unsigned MachineReg, unsigned PieceSizeInBits=0, unsigned PieceOffsetInBits=0)
Emit a partial DWARF register operation.
void AddExpression(DIExpression::expr_op_iterator I, DIExpression::expr_op_iterator E, unsigned PieceOffsetInBits=0)
Emit a the operations remaining the DIExpressionIterator I.
virtual bool isFrameRegister(unsigned MachineReg)=0
Return whether the given machine register is the frame register in the current function.