1 | //===-- llvm/DebugProgramInstruction.h - Stream of debug info -------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // Data structures for storing variable assignment information in LLVM. In the |
10 | // dbg.value design, a dbg.value intrinsic specifies the position in a block |
11 | // a source variable take on an LLVM Value: |
12 | // |
13 | // %foo = add i32 1, %0 |
14 | // dbg.value(metadata i32 %foo, ...) |
15 | // %bar = void call @ext(%foo); |
16 | // |
17 | // and all information is stored in the Value / Metadata hierachy defined |
18 | // elsewhere in LLVM. In the "DPValue" design, each instruction /may/ have a |
19 | // connection with a DPMarker, which identifies a position immediately before the |
20 | // instruction, and each DPMarker /may/ then have connections to DPValues which |
21 | // record the variable assignment information. To illustrate: |
22 | // |
23 | // %foo = add i32 1, %0 |
24 | // ; foo->DbgMarker == nullptr |
25 | // ;; There are no variable assignments / debug records "in front" of |
26 | // ;; the instruction for %foo, therefore it has no DbgMarker. |
27 | // %bar = void call @ext(%foo) |
28 | // ; bar->DbgMarker = { |
29 | // ; StoredDPValues = { |
30 | // ; DPValue(metadata i32 %foo, ...) |
31 | // ; } |
32 | // ; } |
33 | // ;; There is a debug-info record in front of the %bar instruction, |
34 | // ;; thus it points at a DPMarker object. That DPMarker contains a |
35 | // ;; DPValue in it's ilist, storing the equivalent information to the |
36 | // ;; dbg.value above: the Value, DILocalVariable, etc. |
37 | // |
38 | // This structure separates the two concerns of the position of the debug-info |
39 | // in the function, and the Value that it refers to. It also creates a new |
40 | // "place" in-between the Value / Metadata hierachy where we can customise |
41 | // storage and allocation techniques to better suite debug-info workloads. |
42 | // NB: as of the initial prototype, none of that has actually been attempted |
43 | // yet. |
44 | // |
45 | //===----------------------------------------------------------------------===// |
46 | |
47 | #ifndef LLVM_IR_DEBUGPROGRAMINSTRUCTION_H |
48 | #define LLVM_IR_DEBUGPROGRAMINSTRUCTION_H |
49 | |
50 | #include "llvm/ADT/ilist.h" |
51 | #include "llvm/ADT/ilist_node.h" |
52 | #include "llvm/ADT/iterator.h" |
53 | #include "llvm/IR/DebugLoc.h" |
54 | #include "llvm/IR/Instruction.h" |
55 | #include "llvm/IR/SymbolTableListTraits.h" |
56 | |
57 | namespace llvm { |
58 | |
59 | class Instruction; |
60 | class BasicBlock; |
61 | class MDNode; |
62 | class Module; |
63 | class DbgVariableIntrinsic; |
64 | class DIAssignID; |
65 | class DPMarker; |
66 | class DPValue; |
67 | class raw_ostream; |
68 | |
69 | /// Record of a variable value-assignment, aka a non instruction representation |
70 | /// of the dbg.value intrinsic. Features various methods copied across from the |
71 | /// Instruction class to aid ease-of-use. DPValue objects should always be |
72 | /// linked into a DPMarker's StoredDPValues list. The marker connects a DPValue |
73 | /// back to it's position in the BasicBlock. |
74 | /// |
75 | /// This class inherits from DebugValueUser to allow LLVM's metadata facilities |
76 | /// to update our references to metadata beneath our feet. |
77 | class DPValue : public ilist_node<DPValue>, private DebugValueUser { |
78 | friend class DebugValueUser; |
79 | |
80 | // NB: there is no explicit "Value" field in this class, it's effectively the |
81 | // DebugValueUser superclass instead. The referred to Value can either be a |
82 | // ValueAsMetadata or a DIArgList. |
83 | |
84 | DILocalVariable *Variable; |
85 | DIExpression *Expression; |
86 | DebugLoc DbgLoc; |
87 | DIExpression *AddressExpression; |
88 | |
89 | public: |
90 | void deleteInstr(); |
91 | |
92 | const Instruction *getInstruction() const; |
93 | const BasicBlock *getParent() const; |
94 | BasicBlock *getParent(); |
95 | void dump() const; |
96 | void removeFromParent(); |
97 | void eraseFromParent(); |
98 | |
99 | DPValue *getNextNode() { return &*std::next(x: getIterator()); } |
100 | DPValue *getPrevNode() { return &*std::prev(x: getIterator()); } |
101 | |
102 | using self_iterator = simple_ilist<DPValue>::iterator; |
103 | using const_self_iterator = simple_ilist<DPValue>::const_iterator; |
104 | |
105 | enum class LocationType { |
106 | Declare, |
107 | Value, |
108 | Assign, |
109 | |
110 | End, ///< Marks the end of the concrete types. |
111 | Any, ///< To indicate all LocationTypes in searches. |
112 | }; |
113 | /// Classification of the debug-info record that this DPValue represents. |
114 | /// Essentially, "is this a dbg.value or dbg.declare?". dbg.declares are not |
115 | /// currently supported, but it would be trivial to do so. |
116 | LocationType Type; |
117 | |
118 | /// Marker that this DPValue is linked into. |
119 | DPMarker *Marker = nullptr; |
120 | |
121 | /// Create a new DPValue representing the intrinsic \p DVI, for example the |
122 | /// assignment represented by a dbg.value. |
123 | DPValue(const DbgVariableIntrinsic *DVI); |
124 | DPValue(const DPValue &DPV); |
125 | /// Directly construct a new DPValue representing a dbg.value intrinsic |
126 | /// assigning \p Location to the DV / Expr / DI variable. |
127 | DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr, |
128 | const DILocation *DI, LocationType Type = LocationType::Value); |
129 | DPValue(Metadata *Value, DILocalVariable *Variable, DIExpression *Expression, |
130 | DIAssignID *AssignID, Metadata *Address, |
131 | DIExpression *AddressExpression, const DILocation *DI); |
132 | |
133 | static DPValue *createDPVAssign(Value *Val, DILocalVariable *Variable, |
134 | DIExpression *Expression, |
135 | DIAssignID *AssignID, Value *Address, |
136 | DIExpression *AddressExpression, |
137 | const DILocation *DI); |
138 | static DPValue *createLinkedDPVAssign(Instruction *LinkedInstr, Value *Val, |
139 | DILocalVariable *Variable, |
140 | DIExpression *Expression, |
141 | Value *Address, |
142 | DIExpression *AddressExpression, |
143 | const DILocation *DI); |
144 | |
145 | static DPValue *createDPValue(Value *Location, DILocalVariable *DV, |
146 | DIExpression *Expr, const DILocation *DI); |
147 | static DPValue *createDPValue(Value *Location, DILocalVariable *DV, |
148 | DIExpression *Expr, const DILocation *DI, |
149 | DPValue &InsertBefore); |
150 | static DPValue *createDPVDeclare(Value *Address, DILocalVariable *DV, |
151 | DIExpression *Expr, const DILocation *DI); |
152 | static DPValue *createDPVDeclare(Value *Address, DILocalVariable *DV, |
153 | DIExpression *Expr, const DILocation *DI, |
154 | DPValue &InsertBefore); |
155 | |
156 | /// Iterator for ValueAsMetadata that internally uses direct pointer iteration |
157 | /// over either a ValueAsMetadata* or a ValueAsMetadata**, dereferencing to the |
158 | /// ValueAsMetadata . |
159 | class location_op_iterator |
160 | : public iterator_facade_base<location_op_iterator, |
161 | std::bidirectional_iterator_tag, Value *> { |
162 | PointerUnion<ValueAsMetadata *, ValueAsMetadata **> I; |
163 | |
164 | public: |
165 | location_op_iterator(ValueAsMetadata *SingleIter) : I(SingleIter) {} |
166 | location_op_iterator(ValueAsMetadata **MultiIter) : I(MultiIter) {} |
167 | |
168 | location_op_iterator(const location_op_iterator &R) : I(R.I) {} |
169 | location_op_iterator &operator=(const location_op_iterator &R) { |
170 | I = R.I; |
171 | return *this; |
172 | } |
173 | bool operator==(const location_op_iterator &RHS) const { |
174 | return I == RHS.I; |
175 | } |
176 | const Value *operator*() const { |
177 | ValueAsMetadata *VAM = I.is<ValueAsMetadata *>() |
178 | ? I.get<ValueAsMetadata *>() |
179 | : *I.get<ValueAsMetadata **>(); |
180 | return VAM->getValue(); |
181 | }; |
182 | Value *operator*() { |
183 | ValueAsMetadata *VAM = I.is<ValueAsMetadata *>() |
184 | ? I.get<ValueAsMetadata *>() |
185 | : *I.get<ValueAsMetadata **>(); |
186 | return VAM->getValue(); |
187 | } |
188 | location_op_iterator &operator++() { |
189 | if (I.is<ValueAsMetadata *>()) |
190 | I = I.get<ValueAsMetadata *>() + 1; |
191 | else |
192 | I = I.get<ValueAsMetadata **>() + 1; |
193 | return *this; |
194 | } |
195 | location_op_iterator &operator--() { |
196 | if (I.is<ValueAsMetadata *>()) |
197 | I = I.get<ValueAsMetadata *>() - 1; |
198 | else |
199 | I = I.get<ValueAsMetadata **>() - 1; |
200 | return *this; |
201 | } |
202 | }; |
203 | |
204 | bool isDbgDeclare() { return Type == LocationType::Declare; } |
205 | bool isDbgValue() { return Type == LocationType::Value; } |
206 | |
207 | /// Get the locations corresponding to the variable referenced by the debug |
208 | /// info intrinsic. Depending on the intrinsic, this could be the |
209 | /// variable's value or its address. |
210 | iterator_range<location_op_iterator> location_ops() const; |
211 | |
212 | Value *getVariableLocationOp(unsigned OpIdx) const; |
213 | |
214 | void replaceVariableLocationOp(Value *OldValue, Value *NewValue, |
215 | bool AllowEmpty = false); |
216 | void replaceVariableLocationOp(unsigned OpIdx, Value *NewValue); |
217 | /// Adding a new location operand will always result in this intrinsic using |
218 | /// an ArgList, and must always be accompanied by a new expression that uses |
219 | /// the new operand. |
220 | void addVariableLocationOps(ArrayRef<Value *> NewValues, |
221 | DIExpression *NewExpr); |
222 | |
223 | void setVariable(DILocalVariable *NewVar) { Variable = NewVar; } |
224 | |
225 | void setExpression(DIExpression *NewExpr) { Expression = NewExpr; } |
226 | |
227 | unsigned getNumVariableLocationOps() const; |
228 | |
229 | bool hasArgList() const { return isa<DIArgList>(Val: getRawLocation()); } |
230 | /// Returns true if this DPValue has no empty MDNodes in its location list. |
231 | bool hasValidLocation() const { return getVariableLocationOp(OpIdx: 0) != nullptr; } |
232 | |
233 | /// Does this describe the address of a local variable. True for dbg.addr |
234 | /// and dbg.declare, but not dbg.value, which describes its value. |
235 | bool isAddressOfVariable() const { return Type == LocationType::Declare; } |
236 | LocationType getType() const { return Type; } |
237 | |
238 | DebugLoc getDebugLoc() const { return DbgLoc; } |
239 | void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); } |
240 | |
241 | void setKillLocation(); |
242 | bool isKillLocation() const; |
243 | |
244 | DILocalVariable *getVariable() const { return Variable; } |
245 | |
246 | DIExpression *getExpression() const { return Expression; } |
247 | |
248 | /// Returns the metadata operand for the first location description. i.e., |
249 | /// dbg intrinsic dbg.value,declare operand and dbg.assign 1st location |
250 | /// operand (the "value componenet"). Note the operand (singular) may be |
251 | /// a DIArgList which is a list of values. |
252 | Metadata *getRawLocation() const { return DebugValues[0]; } |
253 | |
254 | Value *getValue(unsigned OpIdx = 0) const { |
255 | return getVariableLocationOp(OpIdx); |
256 | } |
257 | |
258 | /// Use of this should generally be avoided; instead, |
259 | /// replaceVariableLocationOp and addVariableLocationOps should be used where |
260 | /// possible to avoid creating invalid state. |
261 | void setRawLocation(Metadata *NewLocation) { |
262 | assert( |
263 | (isa<ValueAsMetadata>(NewLocation) || isa<DIArgList>(NewLocation) || |
264 | isa<MDNode>(NewLocation)) && |
265 | "Location for a DPValue must be either ValueAsMetadata or DIArgList" ); |
266 | resetDebugValue(Idx: 0, DebugValue: NewLocation); |
267 | } |
268 | |
269 | /// Get the size (in bits) of the variable, or fragment of the variable that |
270 | /// is described. |
271 | std::optional<uint64_t> getFragmentSizeInBits() const; |
272 | |
273 | bool isEquivalentTo(const DPValue &Other) { |
274 | return std::tie(args&: Type, args&: DebugValues, args&: Variable, args&: Expression, args&: DbgLoc) == |
275 | std::tie(args: Other.Type, args: Other.DebugValues, args: Other.Variable, |
276 | args: Other.Expression, args: Other.DbgLoc); |
277 | } |
278 | // Matches the definition of the Instruction version, equivalent to above but |
279 | // without checking DbgLoc. |
280 | bool isIdenticalToWhenDefined(const DPValue &Other) { |
281 | return std::tie(args&: Type, args&: DebugValues, args&: Variable, args&: Expression) == |
282 | std::tie(args: Other.Type, args: Other.DebugValues, args: Other.Variable, |
283 | args: Other.Expression); |
284 | } |
285 | |
286 | /// @name DbgAssign Methods |
287 | /// @{ |
288 | bool isDbgAssign() const { return getType() == LocationType::Assign; } |
289 | |
290 | Value *getAddress() const; |
291 | Metadata *getRawAddress() const { |
292 | return isDbgAssign() ? DebugValues[1] : DebugValues[0]; |
293 | } |
294 | Metadata *getRawAssignID() const { return DebugValues[2]; } |
295 | DIAssignID *getAssignID() const; |
296 | DIExpression *getAddressExpression() const { return AddressExpression; } |
297 | void setAddressExpression(DIExpression *NewExpr) { |
298 | AddressExpression = NewExpr; |
299 | } |
300 | void setAssignId(DIAssignID *New); |
301 | void setAddress(Value *V) { resetDebugValue(Idx: 1, DebugValue: ValueAsMetadata::get(V)); } |
302 | /// Kill the address component. |
303 | void setKillAddress(); |
304 | /// Check whether this kills the address component. This doesn't take into |
305 | /// account the position of the intrinsic, therefore a returned value of false |
306 | /// does not guarentee the address is a valid location for the variable at the |
307 | /// intrinsic's position in IR. |
308 | bool isKillAddress() const; |
309 | |
310 | /// @} |
311 | |
312 | DPValue *clone() const; |
313 | /// Convert this DPValue back into a dbg.value intrinsic. |
314 | /// \p InsertBefore Optional position to insert this intrinsic. |
315 | /// \returns A new dbg.value intrinsic representiung this DPValue. |
316 | DbgVariableIntrinsic *createDebugIntrinsic(Module *M, |
317 | Instruction *InsertBefore) const; |
318 | void setMarker(DPMarker *M) { Marker = M; } |
319 | |
320 | DPMarker *getMarker() { return Marker; } |
321 | const DPMarker *getMarker() const { return Marker; } |
322 | |
323 | BasicBlock *getBlock(); |
324 | const BasicBlock *getBlock() const; |
325 | |
326 | Function *getFunction(); |
327 | const Function *getFunction() const; |
328 | |
329 | Module *getModule(); |
330 | const Module *getModule() const; |
331 | |
332 | LLVMContext &getContext(); |
333 | const LLVMContext &getContext() const; |
334 | |
335 | /// Insert this DPValue prior to \p InsertBefore. Must not be called if this |
336 | /// is already contained in a DPMarker. |
337 | void insertBefore(DPValue *InsertBefore); |
338 | void insertAfter(DPValue *InsertAfter); |
339 | void moveBefore(DPValue *MoveBefore); |
340 | void moveAfter(DPValue *MoveAfter); |
341 | |
342 | void print(raw_ostream &O, bool IsForDebug = false) const; |
343 | void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const; |
344 | }; |
345 | |
346 | /// Per-instruction record of debug-info. If an Instruction is the position of |
347 | /// some debugging information, it points at a DPMarker storing that info. Each |
348 | /// marker points back at the instruction that owns it. Various utilities are |
349 | /// provided for manipulating the DPValues contained within this marker. |
350 | /// |
351 | /// This class has a rough surface area, because it's needed to preserve the one |
352 | /// arefact that we can't yet eliminate from the intrinsic / dbg.value |
353 | /// debug-info design: the order of DPValues/records is significant, and |
354 | /// duplicates can exist. Thus, if one has a run of debug-info records such as: |
355 | /// dbg.value(... |
356 | /// %foo = barinst |
357 | /// dbg.value(... |
358 | /// and remove barinst, then the dbg.values must be preserved in the correct |
359 | /// order. Hence, the use of iterators to select positions to insert things |
360 | /// into, or the occasional InsertAtHead parameter indicating that new records |
361 | /// should go at the start of the list. |
362 | /// |
363 | /// There are only five or six places in LLVM that truly rely on this ordering, |
364 | /// which we can improve in the future. Additionally, many improvements in the |
365 | /// way that debug-info is stored can be achieved in this class, at a future |
366 | /// date. |
367 | class DPMarker { |
368 | public: |
369 | DPMarker() {} |
370 | /// Link back to the Instruction that owns this marker. Can be null during |
371 | /// operations that move a marker from one instruction to another. |
372 | Instruction *MarkedInstr = nullptr; |
373 | |
374 | /// List of DPValues, each recording a single variable assignment, the |
375 | /// equivalent of a dbg.value intrinsic. There is a one-to-one relationship |
376 | /// between each dbg.value in a block and each DPValue once the |
377 | /// representation has been converted, and the ordering of DPValues is |
378 | /// meaningful in the same was a dbg.values. |
379 | simple_ilist<DPValue> StoredDPValues; |
380 | bool empty() const { return StoredDPValues.empty(); } |
381 | |
382 | const BasicBlock *getParent() const; |
383 | BasicBlock *getParent(); |
384 | |
385 | /// Handle the removal of a marker: the position of debug-info has gone away, |
386 | /// but the stored debug records should not. Drop them onto the next |
387 | /// instruction, or otherwise work out what to do with them. |
388 | void removeMarker(); |
389 | void dump() const; |
390 | |
391 | void removeFromParent(); |
392 | void eraseFromParent(); |
393 | |
394 | /// Implement operator<< on DPMarker. |
395 | void print(raw_ostream &O, bool IsForDebug = false) const; |
396 | void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const; |
397 | |
398 | /// Produce a range over all the DPValues in this Marker. |
399 | iterator_range<simple_ilist<DPValue>::iterator> getDbgValueRange(); |
400 | iterator_range<simple_ilist<DPValue>::const_iterator> |
401 | getDbgValueRange() const; |
402 | /// Transfer any DPValues from \p Src into this DPMarker. If \p InsertAtHead |
403 | /// is true, place them before existing DPValues, otherwise afterwards. |
404 | void absorbDebugValues(DPMarker &Src, bool InsertAtHead); |
405 | /// Transfer the DPValues in \p Range from \p Src into this DPMarker. If |
406 | /// \p InsertAtHead is true, place them before existing DPValues, otherwise |
407 | // afterwards. |
408 | void absorbDebugValues(iterator_range<DPValue::self_iterator> Range, |
409 | DPMarker &Src, bool InsertAtHead); |
410 | /// Insert a DPValue into this DPMarker, at the end of the list. If |
411 | /// \p InsertAtHead is true, at the start. |
412 | void insertDPValue(DPValue *New, bool InsertAtHead); |
413 | /// Insert a DPValue prior to a DPValue contained within this marker. |
414 | void insertDPValue(DPValue *New, DPValue *InsertBefore); |
415 | /// Insert a DPValue after a DPValue contained within this marker. |
416 | void insertDPValueAfter(DPValue *New, DPValue *InsertAfter); |
417 | /// Clone all DPMarkers from \p From into this marker. There are numerous |
418 | /// options to customise the source/destination, due to gnarliness, see class |
419 | /// comment. |
420 | /// \p FromHere If non-null, copy from FromHere to the end of From's DPValues |
421 | /// \p InsertAtHead Place the cloned DPValues at the start of StoredDPValues |
422 | /// \returns Range over all the newly cloned DPValues |
423 | iterator_range<simple_ilist<DPValue>::iterator> |
424 | cloneDebugInfoFrom(DPMarker *From, |
425 | std::optional<simple_ilist<DPValue>::iterator> FromHere, |
426 | bool InsertAtHead = false); |
427 | /// Erase all DPValues in this DPMarker. |
428 | void dropDPValues(); |
429 | /// Erase a single DPValue from this marker. In an ideal future, we would |
430 | /// never erase an assignment in this way, but it's the equivalent to |
431 | /// erasing a dbg.value from a block. |
432 | void dropOneDPValue(DPValue *DPV); |
433 | |
434 | /// We generally act like all llvm Instructions have a range of DPValues |
435 | /// attached to them, but in reality sometimes we don't allocate the DPMarker |
436 | /// to save time and memory, but still have to return ranges of DPValues. When |
437 | /// we need to describe such an unallocated DPValue range, use this static |
438 | /// markers range instead. This will bite us if someone tries to insert a |
439 | /// DPValue in that range, but they should be using the Official (TM) API for |
440 | /// that. |
441 | static DPMarker EmptyDPMarker; |
442 | static iterator_range<simple_ilist<DPValue>::iterator> getEmptyDPValueRange(){ |
443 | return make_range(x: EmptyDPMarker.StoredDPValues.end(), y: EmptyDPMarker.StoredDPValues.end()); |
444 | } |
445 | }; |
446 | |
447 | inline raw_ostream &operator<<(raw_ostream &OS, const DPMarker &Marker) { |
448 | Marker.print(O&: OS); |
449 | return OS; |
450 | } |
451 | |
452 | inline raw_ostream &operator<<(raw_ostream &OS, const DPValue &Value) { |
453 | Value.print(O&: OS); |
454 | return OS; |
455 | } |
456 | |
457 | /// Inline helper to return a range of DPValues attached to a marker. It needs |
458 | /// to be inlined as it's frequently called, but also come after the declaration |
459 | /// of DPMarker. Thus: it's pre-declared by users like Instruction, then an |
460 | /// inlineable body defined here. |
461 | inline iterator_range<simple_ilist<DPValue>::iterator> |
462 | getDbgValueRange(DPMarker *DbgMarker) { |
463 | if (!DbgMarker) |
464 | return DPMarker::getEmptyDPValueRange(); |
465 | return DbgMarker->getDbgValueRange(); |
466 | } |
467 | |
468 | } // namespace llvm |
469 | |
470 | #endif // LLVM_IR_DEBUGPROGRAMINSTRUCTION_H |
471 | |