Line data Source code
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/ADT/ArrayRef.h"
18 : #include "llvm/ADT/None.h"
19 : #include "llvm/ADT/Optional.h"
20 : #include "llvm/ADT/SmallVector.h"
21 : #include "llvm/IR/DebugInfoMetadata.h"
22 : #include <cassert>
23 : #include <cstdint>
24 : #include <iterator>
25 :
26 : namespace llvm {
27 :
28 : class AsmPrinter;
29 : class APInt;
30 : class ByteStreamer;
31 : class DwarfUnit;
32 : class DIELoc;
33 : class TargetRegisterInfo;
34 :
35 : /// Holds a DIExpression and keeps track of how many operands have been consumed
36 : /// so far.
37 : class DIExpressionCursor {
38 : DIExpression::expr_op_iterator Start, End;
39 :
40 : public:
41 13164 : DIExpressionCursor(const DIExpression *Expr) {
42 2370 : if (!Expr) {
43 : assert(Start == End);
44 : return;
45 : }
46 2451 : Start = Expr->expr_op_begin();
47 2451 : End = Expr->expr_op_end();
48 : }
49 :
50 : DIExpressionCursor(ArrayRef<uint64_t> Expr)
51 : : Start(Expr.begin()), End(Expr.end()) {}
52 :
53 : DIExpressionCursor(const DIExpressionCursor &) = default;
54 :
55 : /// Consume one operation.
56 : Optional<DIExpression::ExprOperand> take() {
57 19233 : if (Start == End)
58 : return None;
59 : return *(Start++);
60 : }
61 :
62 : /// Consume N operations.
63 : void consume(unsigned N) { std::advance(Start, N); }
64 :
65 : /// Return the current operation.
66 : Optional<DIExpression::ExprOperand> peek() const {
67 185247 : if (Start == End)
68 : return None;
69 : return *(Start);
70 : }
71 :
72 : /// Return the next operation.
73 990 : Optional<DIExpression::ExprOperand> peekNext() const {
74 990 : if (Start == End)
75 : return None;
76 :
77 990 : auto Next = Start.getNext();
78 990 : if (Next == End)
79 : return None;
80 :
81 : return *Next;
82 : }
83 :
84 : /// Determine whether there are any operations left in this expression.
85 : operator bool() const { return Start != End; }
86 :
87 0 : DIExpression::expr_op_iterator begin() const { return Start; }
88 0 : DIExpression::expr_op_iterator end() const { return End; }
89 :
90 : /// Retrieve the fragment information, if any.
91 0 : Optional<DIExpression::FragmentInfo> getFragmentInfo() const {
92 97715 : return DIExpression::getFragmentInfo(Start, End);
93 : }
94 : };
95 :
96 : /// Base class containing the logic for constructing DWARF expressions
97 : /// independently of whether they are emitted into a DIE or into a .debug_loc
98 : /// entry.
99 : class DwarfExpression {
100 : protected:
101 : /// Holds information about all subregisters comprising a register location.
102 : struct Register {
103 : int DwarfRegNo;
104 : unsigned Size;
105 : const char *Comment;
106 : };
107 :
108 : /// The register location, if any.
109 : SmallVector<Register, 2> DwarfRegs;
110 :
111 : /// Current Fragment Offset in Bits.
112 : uint64_t OffsetInBits = 0;
113 : unsigned DwarfVersion;
114 :
115 : /// Sometimes we need to add a DW_OP_bit_piece to describe a subregister.
116 : unsigned SubRegisterSizeInBits = 0;
117 : unsigned SubRegisterOffsetInBits = 0;
118 :
119 : /// The kind of location description being produced.
120 : enum { Unknown = 0, Register, Memory, Implicit } LocationKind = Unknown;
121 :
122 : /// Push a DW_OP_piece / DW_OP_bit_piece for emitting later, if one is needed
123 : /// to represent a subregister.
124 0 : void setSubRegisterPiece(unsigned SizeInBits, unsigned OffsetInBits) {
125 3288 : SubRegisterSizeInBits = SizeInBits;
126 3288 : SubRegisterOffsetInBits = OffsetInBits;
127 0 : }
128 :
129 : /// Add masking operations to stencil out a subregister.
130 : void maskSubRegister();
131 :
132 : /// Output a dwarf operand and an optional assembler comment.
133 : virtual void emitOp(uint8_t Op, const char *Comment = nullptr) = 0;
134 :
135 : /// Emit a raw signed value.
136 : virtual void emitSigned(int64_t Value) = 0;
137 :
138 : /// Emit a raw unsigned value.
139 : virtual void emitUnsigned(uint64_t Value) = 0;
140 :
141 : /// Emit a normalized unsigned constant.
142 : void emitConstu(uint64_t Value);
143 :
144 : /// Return whether the given machine register is the frame register in the
145 : /// current function.
146 : virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) = 0;
147 :
148 : /// Emit a DW_OP_reg operation. Note that this is only legal inside a DWARF
149 : /// register location description.
150 : void addReg(int DwarfReg, const char *Comment = nullptr);
151 :
152 : /// Emit a DW_OP_breg operation.
153 : void addBReg(int DwarfReg, int Offset);
154 :
155 : /// Emit DW_OP_fbreg <Offset>.
156 : void addFBReg(int Offset);
157 :
158 : /// Emit a partial DWARF register operation.
159 : ///
160 : /// \param MachineReg The register number.
161 : /// \param MaxSize If the register must be composed from
162 : /// sub-registers this is an upper bound
163 : /// for how many bits the emitted DW_OP_piece
164 : /// may cover.
165 : ///
166 : /// If size and offset is zero an operation for the entire register is
167 : /// emitted: Some targets do not provide a DWARF register number for every
168 : /// register. If this is the case, this function will attempt to emit a DWARF
169 : /// register by emitting a fragment of a super-register or by piecing together
170 : /// multiple subregisters that alias the register.
171 : ///
172 : /// \return false if no DWARF register exists for MachineReg.
173 : bool addMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg,
174 : unsigned MaxSize = ~1U);
175 :
176 : /// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
177 : /// \param OffsetInBits This is an optional offset into the location that
178 : /// is at the top of the DWARF stack.
179 : void addOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0);
180 :
181 : /// Emit a shift-right dwarf operation.
182 : void addShr(unsigned ShiftBy);
183 :
184 : /// Emit a bitwise and dwarf operation.
185 : void addAnd(unsigned Mask);
186 :
187 : /// Emit a DW_OP_stack_value, if supported.
188 : ///
189 : /// The proper way to describe a constant value is DW_OP_constu <const>,
190 : /// DW_OP_stack_value. Unfortunately, DW_OP_stack_value was not available
191 : /// until DWARF 4, so we will continue to generate DW_OP_constu <const> for
192 : /// DWARF 2 and DWARF 3. Technically, this is incorrect since DW_OP_const
193 : /// <const> actually describes a value at a constant addess, not a constant
194 : /// value. However, in the past there was no better way to describe a
195 : /// constant value, so the producers and consumers started to rely on
196 : /// heuristics to disambiguate the value vs. location status of the
197 : /// expression. See PR21176 for more details.
198 : void addStackValue();
199 :
200 98289 : ~DwarfExpression() = default;
201 :
202 : public:
203 198422 : DwarfExpression(unsigned DwarfVersion) : DwarfVersion(DwarfVersion) {}
204 :
205 : /// This needs to be called last to commit any pending changes.
206 : void finalize();
207 :
208 : /// Emit a signed constant.
209 : void addSignedConstant(int64_t Value);
210 :
211 : /// Emit an unsigned constant.
212 : void addUnsignedConstant(uint64_t Value);
213 :
214 : /// Emit an unsigned constant.
215 : void addUnsignedConstant(const APInt &Value);
216 :
217 : bool isMemoryLocation() const { return LocationKind == Memory; }
218 0 : bool isUnknownLocation() const { return LocationKind == Unknown; }
219 :
220 : /// Lock this down to become a memory location description.
221 0 : void setMemoryLocationKind() {
222 : assert(LocationKind == Unknown);
223 1666 : LocationKind = Memory;
224 0 : }
225 :
226 : /// Emit a machine register location. As an optimization this may also consume
227 : /// the prefix of a DwarfExpression if a more efficient representation for
228 : /// combining the register location and the first operation exists.
229 : ///
230 : /// \param FragmentOffsetInBits If this is one fragment out of a
231 : /// fragmented
232 : /// location, this is the offset of the
233 : /// fragment inside the entire variable.
234 : /// \return false if no DWARF register exists
235 : /// for MachineReg.
236 : bool addMachineRegExpression(const TargetRegisterInfo &TRI,
237 : DIExpressionCursor &Expr, unsigned MachineReg,
238 : unsigned FragmentOffsetInBits = 0);
239 :
240 : /// Emit all remaining operations in the DIExpressionCursor.
241 : ///
242 : /// \param FragmentOffsetInBits If this is one fragment out of multiple
243 : /// locations, this is the offset of the
244 : /// fragment inside the entire variable.
245 : void addExpression(DIExpressionCursor &&Expr,
246 : unsigned FragmentOffsetInBits = 0);
247 :
248 : /// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to
249 : /// the fragment described by \c Expr.
250 : void addFragmentOffset(const DIExpression *Expr);
251 : };
252 :
253 : /// DwarfExpression implementation for .debug_loc entries.
254 85416 : class DebugLocDwarfExpression final : public DwarfExpression {
255 : ByteStreamer &BS;
256 :
257 : void emitOp(uint8_t Op, const char *Comment = nullptr) override;
258 : void emitSigned(int64_t Value) override;
259 : void emitUnsigned(uint64_t Value) override;
260 : bool isFrameRegister(const TargetRegisterInfo &TRI,
261 : unsigned MachineReg) override;
262 :
263 : public:
264 : DebugLocDwarfExpression(unsigned DwarfVersion, ByteStreamer &BS)
265 170832 : : DwarfExpression(DwarfVersion), BS(BS) {}
266 : };
267 :
268 : /// DwarfExpression implementation for singular DW_AT_location.
269 0 : class DIEDwarfExpression final : public DwarfExpression {
270 : const AsmPrinter &AP;
271 : DwarfUnit &DU;
272 : DIELoc &DIE;
273 :
274 : void emitOp(uint8_t Op, const char *Comment = nullptr) override;
275 : void emitSigned(int64_t Value) override;
276 : void emitUnsigned(uint64_t Value) override;
277 : bool isFrameRegister(const TargetRegisterInfo &TRI,
278 : unsigned MachineReg) override;
279 : public:
280 : DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, DIELoc &DIE);
281 :
282 : DIELoc *finalize() {
283 7871 : DwarfExpression::finalize();
284 7871 : return &DIE;
285 : }
286 : };
287 :
288 : } // end namespace llvm
289 :
290 : #endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
|