LLVM  4.0.0
DwarfExpression.h
Go to the documentation of this file.
1 //===-- llvm/CodeGen/DwarfExpression.h - Dwarf Compile Unit ---*- C++ -*--===//
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 compile unit.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
15 #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
16 
17 #include "llvm/IR/DebugInfo.h"
18 #include "llvm/Support/DataTypes.h"
19 
20 namespace llvm {
21 
22 class AsmPrinter;
23 class ByteStreamer;
24 class TargetRegisterInfo;
25 class DwarfUnit;
26 class DIELoc;
27 
28 /// Holds a DIExpression and keeps track of how many operands have been consumed
29 /// so far.
32 public:
34  if (!Expr) {
35  assert(Start == End);
36  return;
37  }
38  Start = Expr->expr_op_begin();
39  End = Expr->expr_op_end();
40  }
41 
43  : Start(Expr.begin()), End(Expr.end()) {}
44 
45  /// Consume one operation.
47  if (Start == End)
48  return None;
49  return *(Start++);
50  }
51 
52  /// Consume N operations.
53  void consume(unsigned N) { std::advance(Start, N); }
54 
55  /// Return the current operation.
57  if (Start == End)
58  return None;
59  return *(Start);
60  }
61 
62  /// Return the next operation.
64  if (Start == End)
65  return None;
66 
67  auto Next = Start.getNext();
68  if (Next == End)
69  return None;
70 
71  return *Next;
72  }
73  /// Determine whether there are any operations left in this expression.
74  operator bool() const { return Start != End; }
75 
76  /// Retrieve the fragment information, if any.
78  return DIExpression::getFragmentInfo(Start, End);
79  }
80 };
81 
82 /// Base class containing the logic for constructing DWARF expressions
83 /// independently of whether they are emitted into a DIE or into a .debug_loc
84 /// entry.
86 protected:
87  unsigned DwarfVersion;
88  /// Current Fragment Offset in Bits.
89  uint64_t OffsetInBits = 0;
90 
91  /// Sometimes we need to add a DW_OP_bit_piece to describe a subregister.
92  unsigned SubRegisterSizeInBits = 0;
94 
95  /// Push a DW_OP_piece / DW_OP_bit_piece for emitting later, if one is needed
96  /// to represent a subregister.
97  void setSubRegisterPiece(unsigned SizeInBits, unsigned OffsetInBits) {
98  SubRegisterSizeInBits = SizeInBits;
100  }
101 
102 public:
103  DwarfExpression(unsigned DwarfVersion) : DwarfVersion(DwarfVersion) {}
104  virtual ~DwarfExpression() {};
105 
106  /// This needs to be called last to commit any pending changes.
107  void finalize();
108 
109  /// Output a dwarf operand and an optional assembler comment.
110  virtual void EmitOp(uint8_t Op, const char *Comment = nullptr) = 0;
111  /// Emit a raw signed value.
112  virtual void EmitSigned(int64_t Value) = 0;
113  /// Emit a raw unsigned value.
114  virtual void EmitUnsigned(uint64_t Value) = 0;
115  /// Return whether the given machine register is the frame register in the
116  /// current function.
117  virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) = 0;
118 
119  /// Emit a dwarf register operation.
120  void AddReg(int DwarfReg, const char *Comment = nullptr);
121  /// Emit an (double-)indirect dwarf register operation.
122  void AddRegIndirect(int DwarfReg, int Offset, bool Deref = false);
123 
124  /// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
125  /// \param OffsetInBits This is an optional offset into the location that
126  /// is at the top of the DWARF stack.
127  void AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0);
128 
129  /// Emit a shift-right dwarf expression.
130  void AddShr(unsigned ShiftBy);
131 
132  /// Emit a DW_OP_stack_value, if supported.
133  ///
134  /// The proper way to describe a constant value is DW_OP_constu <const>,
135  /// DW_OP_stack_value. Unfortunately, DW_OP_stack_value was not available
136  /// until DWARF 4, so we will continue to generate DW_OP_constu <const> for
137  /// DWARF 2 and DWARF 3. Technically, this is incorrect since DW_OP_const
138  /// <const> actually describes a value at a constant addess, not a constant
139  /// value. However, in the past there was no better way to describe a
140  /// constant value, so the producers and consumers started to rely on
141  /// heuristics to disambiguate the value vs. location status of the
142  /// expression. See PR21176 for more details.
143  void AddStackValue();
144 
145  /// Emit an indirect dwarf register operation for the given machine register.
146  /// \return false if no DWARF register exists for MachineReg.
147  bool AddMachineRegIndirect(const TargetRegisterInfo &TRI, unsigned MachineReg,
148  int Offset = 0);
149 
150  /// Emit a partial DWARF register operation.
151  ///
152  /// \param MachineReg The register number.
153  /// \param MaxSize If the register must be composed from
154  /// sub-registers this is an upper bound
155  /// for how many bits the emitted DW_OP_piece
156  /// may cover.
157  ///
158  /// If size and offset is zero an operation for the entire register is
159  /// emitted: Some targets do not provide a DWARF register number for every
160  /// register. If this is the case, this function will attempt to emit a DWARF
161  /// register by emitting a fragment of a super-register or by piecing together
162  /// multiple subregisters that alias the register.
163  ///
164  /// \return false if no DWARF register exists for MachineReg.
165  bool AddMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg,
166  unsigned MaxSize = ~1U);
167 
168  /// Emit a signed constant.
169  void AddSignedConstant(int64_t Value);
170  /// Emit an unsigned constant.
171  void AddUnsignedConstant(uint64_t Value);
172  /// Emit an unsigned constant.
173  void AddUnsignedConstant(const APInt &Value);
174 
175  /// Emit a machine register location. As an optimization this may also consume
176  /// the prefix of a DwarfExpression if a more efficient representation for
177  /// combining the register location and the first operation exists.
178  ///
179  /// \param FragmentOffsetInBits If this is one fragment out of a fragmented
180  /// location, this is the offset of the
181  /// fragment inside the entire variable.
182  /// \return false if no DWARF register exists
183  /// for MachineReg.
185  DIExpressionCursor &Expr, unsigned MachineReg,
186  unsigned FragmentOffsetInBits = 0);
187  /// Emit all remaining operations in the DIExpressionCursor.
188  ///
189  /// \param FragmentOffsetInBits If this is one fragment out of multiple
190  /// locations, this is the offset of the
191  /// fragment inside the entire variable.
192  void AddExpression(DIExpressionCursor &&Expr,
193  unsigned FragmentOffsetInBits = 0);
194 
195  /// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to
196  /// the fragment described by \c Expr.
197  void addFragmentOffset(const DIExpression *Expr);
198 };
199 
200 /// DwarfExpression implementation for .debug_loc entries.
202  ByteStreamer &BS;
203 
204 public:
206  : DwarfExpression(DwarfVersion), BS(BS) {}
207 
208  void EmitOp(uint8_t Op, const char *Comment = nullptr) override;
209  void EmitSigned(int64_t Value) override;
210  void EmitUnsigned(uint64_t Value) override;
211  bool isFrameRegister(const TargetRegisterInfo &TRI,
212  unsigned MachineReg) override;
213 };
214 
215 /// DwarfExpression implementation for singular DW_AT_location.
217 const AsmPrinter &AP;
218  DwarfUnit &DU;
219  DIELoc &DIE;
220 
221 public:
223  void EmitOp(uint8_t Op, const char *Comment = nullptr) override;
224  void EmitSigned(int64_t Value) override;
225  void EmitUnsigned(uint64_t Value) override;
226  bool isFrameRegister(const TargetRegisterInfo &TRI,
227  unsigned MachineReg) override;
230  return &DIE;
231  }
232 };
233 }
234 
235 #endif
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:241
DIELoc - Represents an expression location.
Definition: DIE.h:829
Optional< DIExpression::ExprOperand > peek() const
Return the current operation.
void AddExpression(DIExpressionCursor &&Expr, unsigned FragmentOffsetInBits=0)
Emit all remaining operations in the DIExpressionCursor.
Base class containing the logic for constructing DWARF expressions independently of whether they are ...
bool AddMachineRegIndirect(const TargetRegisterInfo &TRI, unsigned MachineReg, int Offset=0)
Emit an indirect dwarf register operation for the given machine register.
void EmitSigned(int64_t Value) override
Emit a raw signed value.
Definition: DwarfUnit.cpp:61
const_iterator begin(StringRef path)
Get begin iterator over path.
Definition: Path.cpp:233
void AddShr(unsigned ShiftBy)
Emit a shift-right dwarf expression.
bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) override
Return whether the given machine register is the frame register in the current function.
Definition: DwarfDebug.cpp:144
bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) override
Return whether the given machine register is the frame register in the current function.
Definition: DwarfUnit.cpp:69
void AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits=0)
Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
virtual void EmitOp(uint8_t Op, const char *Comment=nullptr)=0
Output a dwarf operand and an optional assembler comment.
DwarfExpression(unsigned DwarfVersion)
static void advance(T &it, size_t Val)
void EmitOp(uint8_t Op, const char *Comment=nullptr) override
Output a dwarf operand and an optional assembler comment.
Definition: DwarfUnit.cpp:57
Holds a DIExpression and keeps track of how many operands have been consumed so far.
DwarfExpression implementation for .debug_loc entries.
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...
void EmitSigned(int64_t Value) override
Emit a raw signed value.
Definition: DwarfDebug.cpp:136
expr_op_iterator expr_op_begin() const
Visit the elements via ExprOperand wrappers.
void EmitOp(uint8_t Op, const char *Comment=nullptr) override
Output a dwarf operand and an optional assembler comment.
Definition: DwarfDebug.cpp:130
Optional< DIExpression::ExprOperand > take()
Consume one operation.
Optional< DIExpression::FragmentInfo > getFragmentInfo() const
Retrieve the fragment information, if any.
This dwarf writer support class manages information associated with a source file.
Definition: DwarfUnit.h:68
DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, DIELoc &DIE)
Definition: DwarfUnit.cpp:52
DIExpressionCursor(const DIExpression *Expr)
Optional< DIExpression::ExprOperand > peekNext() const
Return the next operation.
void EmitUnsigned(uint64_t Value) override
Emit a raw unsigned value.
Definition: DwarfUnit.cpp:65
expr_op_iterator getNext() const
Get the next iterator.
A structured debug information entry.
Definition: DIE.h:655
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:67
uint64_t OffsetInBits
Current Fragment Offset in Bits.
uint32_t Offset
void AddRegIndirect(int DwarfReg, int Offset, bool Deref=false)
Emit an (double-)indirect dwarf register operation.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual void EmitUnsigned(uint64_t Value)=0
Emit a raw unsigned value.
unsigned SubRegisterOffsetInBits
void AddUnsignedConstant(uint64_t Value)
Emit an unsigned constant.
Optional< FragmentInfo > getFragmentInfo() const
Retrieve the details of this fragment expression.
DWARF expression.
Class for arbitrary precision integers.
Definition: APInt.h:77
void EmitUnsigned(uint64_t Value) override
Emit a raw unsigned value.
Definition: DwarfDebug.cpp:140
bool AddMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg, unsigned MaxSize=~1U)
Emit a partial DWARF register operation.
unsigned SubRegisterSizeInBits
Sometimes we need to add a DW_OP_bit_piece to describe a subregister.
void consume(unsigned N)
Consume N operations.
void AddSignedConstant(int64_t Value)
Emit a signed constant.
void finalize()
This needs to be called last to commit any pending changes.
#define N
DebugLocDwarfExpression(unsigned DwarfVersion, ByteStreamer &BS)
DIExpressionCursor(ArrayRef< uint64_t > Expr)
DwarfExpression implementation for singular DW_AT_location.
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...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool AddMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, unsigned MachineReg, unsigned FragmentOffsetInBits=0)
Emit a machine register location.
LLVM Value Representation.
Definition: Value.h:71
virtual void EmitSigned(int64_t Value)=0
Emit a raw signed value.
An iterator for expression operands.
void AddStackValue()
Emit a DW_OP_stack_value, if supported.
expr_op_iterator expr_op_end() const
void AddReg(int DwarfReg, const char *Comment=nullptr)
Emit a dwarf register operation.
virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg)=0
Return whether the given machine register is the frame register in the current function.