LLVM  6.0.0svn
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 "llvm/ADT/APInt.h"
21 #include <algorithm>
22 #include <cassert>
23 #include <cstdint>
24 
25 using namespace llvm;
26 
27 void DwarfExpression::addReg(int DwarfReg, const char *Comment) {
28  assert(DwarfReg >= 0 && "invalid negative dwarf register number");
30  "location description already locked down");
32  if (DwarfReg < 32) {
33  emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
34  } else {
35  emitOp(dwarf::DW_OP_regx, Comment);
36  emitUnsigned(DwarfReg);
37  }
38 }
39 
40 void DwarfExpression::addBReg(int DwarfReg, int Offset) {
41  assert(DwarfReg >= 0 && "invalid negative dwarf register number");
42  assert(LocationKind != Register && "location description already locked down");
43  if (DwarfReg < 32) {
44  emitOp(dwarf::DW_OP_breg0 + DwarfReg);
45  } else {
46  emitOp(dwarf::DW_OP_bregx);
47  emitUnsigned(DwarfReg);
48  }
49  emitSigned(Offset);
50 }
51 
53  emitOp(dwarf::DW_OP_fbreg);
54  emitSigned(Offset);
55 }
56 
57 void DwarfExpression::addOpPiece(unsigned SizeInBits, unsigned OffsetInBits) {
58  if (!SizeInBits)
59  return;
60 
61  const unsigned SizeOfByte = 8;
62  if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {
63  emitOp(dwarf::DW_OP_bit_piece);
64  emitUnsigned(SizeInBits);
65  emitUnsigned(OffsetInBits);
66  } else {
67  emitOp(dwarf::DW_OP_piece);
68  unsigned ByteSize = SizeInBits / SizeOfByte;
69  emitUnsigned(ByteSize);
70  }
71  this->OffsetInBits += SizeInBits;
72 }
73 
74 void DwarfExpression::addShr(unsigned ShiftBy) {
75  emitOp(dwarf::DW_OP_constu);
76  emitUnsigned(ShiftBy);
77  emitOp(dwarf::DW_OP_shr);
78 }
79 
80 void DwarfExpression::addAnd(unsigned Mask) {
81  emitOp(dwarf::DW_OP_constu);
82  emitUnsigned(Mask);
83  emitOp(dwarf::DW_OP_and);
84 }
85 
87  unsigned MachineReg, unsigned MaxSize) {
88  if (!TRI.isPhysicalRegister(MachineReg)) {
89  if (isFrameRegister(TRI, MachineReg)) {
90  DwarfRegs.push_back({-1, 0, nullptr});
91  return true;
92  }
93  return false;
94  }
95 
96  int Reg = TRI.getDwarfRegNum(MachineReg, false);
97 
98  // If this is a valid register number, emit it.
99  if (Reg >= 0) {
100  DwarfRegs.push_back({Reg, 0, nullptr});
101  return true;
102  }
103 
104  // Walk up the super-register chain until we find a valid number.
105  // For example, EAX on x86_64 is a 32-bit fragment of RAX with offset 0.
106  for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
107  Reg = TRI.getDwarfRegNum(*SR, false);
108  if (Reg >= 0) {
109  unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg);
110  unsigned Size = TRI.getSubRegIdxSize(Idx);
111  unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
112  DwarfRegs.push_back({Reg, 0, "super-register"});
113  // Use a DW_OP_bit_piece to describe the sub-register.
114  setSubRegisterPiece(Size, RegOffset);
115  return true;
116  }
117  }
118 
119  // Otherwise, attempt to find a covering set of sub-register numbers.
120  // For example, Q0 on ARM is a composition of D0+D1.
121  unsigned CurPos = 0;
122  // The size of the register in bits.
123  const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg);
124  unsigned RegSize = TRI.getRegSizeInBits(*RC);
125  // Keep track of the bits in the register we already emitted, so we
126  // can avoid emitting redundant aliasing subregs.
127  SmallBitVector Coverage(RegSize, false);
128  for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
129  unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR);
130  unsigned Size = TRI.getSubRegIdxSize(Idx);
131  unsigned Offset = TRI.getSubRegIdxOffset(Idx);
132  Reg = TRI.getDwarfRegNum(*SR, false);
133  if (Reg < 0)
134  continue;
135 
136  // Intersection between the bits we already emitted and the bits
137  // covered by this subregister.
138  SmallBitVector CurSubReg(RegSize, false);
139  CurSubReg.set(Offset, Offset + Size);
140 
141  // If this sub-register has a DWARF number and we haven't covered
142  // its range, emit a DWARF piece for it.
143  if (CurSubReg.test(Coverage)) {
144  // Emit a piece for any gap in the coverage.
145  if (Offset > CurPos)
146  DwarfRegs.push_back({-1, Offset - CurPos, nullptr});
147  DwarfRegs.push_back(
148  {Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"});
149  if (Offset >= MaxSize)
150  break;
151 
152  // Mark it as emitted.
153  Coverage.set(Offset, Offset + Size);
154  CurPos = Offset + Size;
155  }
156  }
157 
158  return CurPos;
159 }
160 
162  if (DwarfVersion >= 4)
163  emitOp(dwarf::DW_OP_stack_value);
164 }
165 
169  emitOp(dwarf::DW_OP_consts);
170  emitSigned(Value);
171 }
172 
176  emitOp(dwarf::DW_OP_constu);
177  emitUnsigned(Value);
178 }
179 
183 
184  unsigned Size = Value.getBitWidth();
185  const uint64_t *Data = Value.getRawData();
186 
187  // Chop it up into 64-bit pieces, because that's the maximum that
188  // addUnsignedConstant takes.
189  unsigned Offset = 0;
190  while (Offset < Size) {
191  addUnsignedConstant(*Data++);
192  if (Offset == 0 && Size <= 64)
193  break;
194  addStackValue();
195  addOpPiece(std::min(Size - Offset, 64u), Offset);
196  Offset += 64;
197  }
198 }
199 
201  DIExpressionCursor &ExprCursor,
202  unsigned MachineReg,
203  unsigned FragmentOffsetInBits) {
204  auto Fragment = ExprCursor.getFragmentInfo();
205  if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
207  return false;
208  }
209 
210  bool HasComplexExpression = false;
211  auto Op = ExprCursor.peek();
212  if (Op && Op->getOp() != dwarf::DW_OP_LLVM_fragment)
213  HasComplexExpression = true;
214 
215  // If the register can only be described by a complex expression (i.e.,
216  // multiple subregisters) it doesn't safely compose with another complex
217  // expression. For example, it is not possible to apply a DW_OP_deref
218  // operation to multiple DW_OP_pieces.
219  if (HasComplexExpression && DwarfRegs.size() > 1) {
220  DwarfRegs.clear();
222  return false;
223  }
224 
225  // Handle simple register locations.
226  if (LocationKind != Memory && !HasComplexExpression) {
227  for (auto &Reg : DwarfRegs) {
228  if (Reg.DwarfRegNo >= 0)
229  addReg(Reg.DwarfRegNo, Reg.Comment);
230  addOpPiece(Reg.Size);
231  }
232  DwarfRegs.clear();
233  return true;
234  }
235 
236  // Don't emit locations that cannot be expressed without DW_OP_stack_value.
237  if (DwarfVersion < 4)
238  if (std::any_of(ExprCursor.begin(), ExprCursor.end(),
239  [](DIExpression::ExprOperand Op) -> bool {
240  return Op.getOp() == dwarf::DW_OP_stack_value;
241  })) {
242  DwarfRegs.clear();
244  return false;
245  }
246 
247  assert(DwarfRegs.size() == 1);
248  auto Reg = DwarfRegs[0];
249  bool FBReg = isFrameRegister(TRI, MachineReg);
250  int SignedOffset = 0;
251  assert(Reg.Size == 0 && "subregister has same size as superregister");
252 
253  // Pattern-match combinations for which more efficient representations exist.
254  // [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset].
255  if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) {
256  SignedOffset = Op->getArg(0);
257  ExprCursor.take();
258  }
259 
260  // [Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset]
261  // [Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset]
262  // If Reg is a subregister we need to mask it out before subtracting.
263  if (Op && Op->getOp() == dwarf::DW_OP_constu) {
264  auto N = ExprCursor.peekNext();
265  if (N && (N->getOp() == dwarf::DW_OP_plus ||
266  (N->getOp() == dwarf::DW_OP_minus && !SubRegisterSizeInBits))) {
267  int Offset = Op->getArg(0);
268  SignedOffset = (N->getOp() == dwarf::DW_OP_minus) ? -Offset : Offset;
269  ExprCursor.consume(2);
270  }
271  }
272 
273  if (FBReg)
274  addFBReg(SignedOffset);
275  else
276  addBReg(Reg.DwarfRegNo, SignedOffset);
277  DwarfRegs.clear();
278  return true;
279 }
280 
281 /// Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?".
282 static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
283  while (ExprCursor) {
284  auto Op = ExprCursor.take();
285  switch (Op->getOp()) {
286  case dwarf::DW_OP_deref:
288  break;
289  default:
290  return false;
291  }
292  }
293  return true;
294 }
295 
297  unsigned FragmentOffsetInBits) {
298  // If we need to mask out a subregister, do it now, unless the next
299  // operation would emit an OpPiece anyway.
300  auto N = ExprCursor.peek();
301  if (SubRegisterSizeInBits && N && (N->getOp() != dwarf::DW_OP_LLVM_fragment))
302  maskSubRegister();
303 
304  while (ExprCursor) {
305  auto Op = ExprCursor.take();
306  switch (Op->getOp()) {
308  unsigned SizeInBits = Op->getArg(1);
309  unsigned FragmentOffset = Op->getArg(0);
310  // The fragment offset must have already been adjusted by emitting an
311  // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base
312  // location.
313  assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");
314 
315  // If addMachineReg already emitted DW_OP_piece operations to represent
316  // a super-register by splicing together sub-registers, subtract the size
317  // of the pieces that was already emitted.
318  SizeInBits -= OffsetInBits - FragmentOffset;
319 
320  // If addMachineReg requested a DW_OP_bit_piece to stencil out a
321  // sub-register that is smaller than the current fragment's size, use it.
323  SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits);
324 
325  // Emit a DW_OP_stack_value for implicit location descriptions.
326  if (LocationKind == Implicit)
327  addStackValue();
328 
329  // Emit the DW_OP_piece.
330  addOpPiece(SizeInBits, SubRegisterOffsetInBits);
331  setSubRegisterPiece(0, 0);
332  // Reset the location description kind.
334  return;
335  }
336  case dwarf::DW_OP_plus_uconst:
338  emitOp(dwarf::DW_OP_plus_uconst);
339  emitUnsigned(Op->getArg(0));
340  break;
341  case dwarf::DW_OP_plus:
342  case dwarf::DW_OP_minus:
343  case dwarf::DW_OP_mul:
344  emitOp(Op->getOp());
345  break;
346  case dwarf::DW_OP_deref:
348  if (LocationKind != Memory && isMemoryLocation(ExprCursor))
349  // Turning this into a memory location description makes the deref
350  // implicit.
352  else
353  emitOp(dwarf::DW_OP_deref);
354  break;
355  case dwarf::DW_OP_constu:
357  emitOp(dwarf::DW_OP_constu);
358  emitUnsigned(Op->getArg(0));
359  break;
360  case dwarf::DW_OP_stack_value:
362  break;
363  case dwarf::DW_OP_swap:
365  emitOp(dwarf::DW_OP_swap);
366  break;
367  case dwarf::DW_OP_xderef:
369  emitOp(dwarf::DW_OP_xderef);
370  break;
371  default:
372  llvm_unreachable("unhandled opcode found in expression");
373  }
374  }
375 
376  if (LocationKind == Implicit)
377  // Turn this into an implicit location description.
378  addStackValue();
379 }
380 
381 /// add masking operations to stencil out a subregister.
383  assert(SubRegisterSizeInBits && "no subregister was registered");
384  if (SubRegisterOffsetInBits > 0)
386  uint64_t Mask = (1ULL << (uint64_t)SubRegisterSizeInBits) - 1ULL;
387  addAnd(Mask);
388 }
389 
391  assert(DwarfRegs.size() == 0 && "dwarf registers not emitted");
392  // Emit any outstanding DW_OP_piece operations to mask out subregisters.
393  if (SubRegisterSizeInBits == 0)
394  return;
395  // Don't emit a DW_OP_piece for a subregister at offset 0.
396  if (SubRegisterOffsetInBits == 0)
397  return;
399 }
400 
402  if (!Expr || !Expr->isFragment())
403  return;
404 
405  uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits;
406  assert(FragmentOffset >= OffsetInBits &&
407  "overlapping or duplicate fragments");
408  if (FragmentOffset > OffsetInBits)
409  addOpPiece(FragmentOffset - OffsetInBits);
410  OffsetInBits = FragmentOffset;
411 }
This is a &#39;bitvector&#39; (really, a variable-sized bit array), optimized for the case when the array is ...
void addShr(unsigned ShiftBy)
Emit a shift-right dwarf operation.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
void addUnsignedConstant(uint64_t Value)
Emit an unsigned constant.
This class provides various memory handling functions that manipulate MemoryBlock instances...
Definition: Memory.h:46
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 getBitWidth() const
Return the number of bits in the APInt.
Definition: APInt.h:1488
bool test(unsigned Idx) const
MCSuperRegIterator enumerates all super-registers of Reg.
Reg
All possible values of the reg field in the ModR/M byte.
void addBReg(int DwarfReg, int Offset)
Emit a DW_OP_breg operation.
void addFBReg(int Offset)
Emit DW_OP_fbreg <Offset>.
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
Only used in LLVM metadata.
Definition: Dwarf.h:125
Holds a DIExpression and keeps track of how many operands have been consumed so far.
This file implements a class to represent arbitrary precision integral constant values and operations...
void addReg(int DwarfReg, const char *Comment=nullptr)
Emit a DW_OP_reg operation.
void setSubRegisterPiece(unsigned SizeInBits, unsigned OffsetInBits)
Push a DW_OP_piece / DW_OP_bit_piece for emitting later, if one is needed to represent a subregister...
Optional< DIExpression::ExprOperand > peek() const
Return the current operation.
static Optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
void maskSubRegister()
Add masking operations to stencil out a subregister.
Optional< DIExpression::ExprOperand > peekNext() const
Return the next operation.
virtual void emitUnsigned(uint64_t Value)=0
Emit a raw unsigned value.
Optional< DIExpression::ExprOperand > take()
Consume one operation.
virtual void emitOp(uint8_t Op, const char *Comment=nullptr)=0
Output a dwarf operand and an optional assembler comment.
enum llvm::DwarfExpression::@303 LocationKind
The kind of location description being produced.
A lightweight wrapper around an expression operand.
uint64_t OffsetInBits
Current Fragment Offset in Bits.
bool any_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:774
virtual void emitSigned(int64_t Value)=0
Emit a raw signed value.
unsigned getSubRegIdxOffset(unsigned Idx) const
Get the offset of the bit range covered by a sub-register index.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
MCSubRegIterator enumerates all sub-registers of Reg.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
SmallBitVector & set()
void addExpression(DIExpressionCursor &&Expr, unsigned FragmentOffsetInBits=0)
Emit all remaining operations in the DIExpressionCursor.
bool addMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg, unsigned MaxSize=~1U)
Emit a partial DWARF register operation.
void addStackValue()
Emit a DW_OP_stack_value, if supported.
DWARF expression.
This file contains constants used for implementing Dwarf debug support.
Class for arbitrary precision integers.
Definition: APInt.h:69
void addAnd(unsigned Mask)
Emit a bitwise and dwarf operation.
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
Optional< DIExpression::FragmentInfo > getFragmentInfo() const
Retrieve the fragment information, if any.
const uint64_t * getRawData() const
This function returns a pointer to the internal storage of the APInt.
Definition: APInt.h:668
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
unsigned SubRegisterSizeInBits
Sometimes we need to add a DW_OP_bit_piece to describe a subregister.
void consume(unsigned N)
Consume N operations.
DIExpression::expr_op_iterator begin() const
void finalize()
This needs to be called last to commit any pending changes.
#define N
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
void addFragmentOffset(const DIExpression *Expr)
If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to the fragment described by Ex...
Holds information about all subregisters comprising a register location.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:73
void addOpPiece(unsigned SizeInBits, unsigned OffsetInBits=0)
Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E&#39;s largest value.
Definition: BitmaskEnum.h:81
static bool isMemoryLocation(DIExpressionCursor ExprCursor)
Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?".
void addSignedConstant(int64_t Value)
Emit a signed constant.
unsigned getSubRegIdxSize(unsigned Idx) const
Get the size of the bit range covered by a sub-register index.
SmallVector< Register, 2 > DwarfRegs
The register location, if any.
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
DIExpression::expr_op_iterator end() const
bool isFragment() const
Return whether this is a piece of an aggregate variable.
bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, unsigned MachineReg, unsigned FragmentOffsetInBits=0)
Emit a machine register location.
virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg)=0
Return whether the given machine register is the frame register in the current function.