xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/DebugProgramInstruction.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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_node.h"
51 #include "llvm/ADT/ilist.h"
52 #include "llvm/ADT/iterator.h"
53 #include "llvm/IR/DebugLoc.h"
54 
55 namespace llvm {
56 
57 class Instruction;
58 class BasicBlock;
59 class MDNode;
60 class Module;
61 class DbgVariableIntrinsic;
62 class DPMarker;
63 class DPValue;
64 class raw_ostream;
65 
66 /// Record of a variable value-assignment, aka a non instruction representation
67 /// of the dbg.value intrinsic. Features various methods copied across from the
68 /// Instruction class to aid ease-of-use. DPValue objects should always be
69 /// linked into a DPMarker's StoredDPValues list. The marker connects a DPValue
70 /// back to it's position in the BasicBlock.
71 ///
72 /// This class inherits from DebugValueUser to allow LLVM's metadata facilities
73 /// to update our references to metadata beneath our feet.
74 class DPValue : public ilist_node<DPValue>, private DebugValueUser {
75   friend class DebugValueUser;
76 
77   // NB: there is no explicit "Value" field in this class, it's effectively the
78   // DebugValueUser superclass instead. The referred to Value can either be a
79   // ValueAsMetadata or a DIArgList.
80 
81   DILocalVariable *Variable;
82   DIExpression *Expression;
83   DebugLoc DbgLoc;
84 
85 public:
86   void deleteInstr();
87 
88   const BasicBlock *getParent() const;
89   BasicBlock *getParent();
90   void dump() const;
91   void removeFromParent();
92   void eraseFromParent();
93 
94   using self_iterator = simple_ilist<DPValue>::iterator;
95   using const_self_iterator = simple_ilist<DPValue>::const_iterator;
96 
97   enum class LocationType {
98     Declare,
99     Value,
100 
101     End, ///< Marks the end of the concrete types.
102     Any, ///< To indicate all LocationTypes in searches.
103   };
104   /// Classification of the debug-info record that this DPValue represents.
105   /// Essentially, "is this a dbg.value or dbg.declare?". dbg.declares are not
106   /// currently supported, but it would be trivial to do so.
107   LocationType Type;
108 
109   /// Marker that this DPValue is linked into.
110   DPMarker *Marker = nullptr;
111 
112   /// Create a new DPValue representing the intrinsic \p DVI, for example the
113   /// assignment represented by a dbg.value.
114   DPValue(const DbgVariableIntrinsic *DVI);
115   DPValue(const DPValue &DPV);
116   /// Directly construct a new DPValue representing a dbg.value intrinsic
117   /// assigning \p Location to the DV / Expr / DI variable.
118   DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
119           const DILocation *DI, LocationType Type = LocationType::Value);
120 
121   /// Iterator for ValueAsMetadata that internally uses direct pointer iteration
122   /// over either a ValueAsMetadata* or a ValueAsMetadata**, dereferencing to the
123   /// ValueAsMetadata .
124   class location_op_iterator
125       : public iterator_facade_base<location_op_iterator,
126                                     std::bidirectional_iterator_tag, Value *> {
127     PointerUnion<ValueAsMetadata *, ValueAsMetadata **> I;
128 
129   public:
130     location_op_iterator(ValueAsMetadata *SingleIter) : I(SingleIter) {}
131     location_op_iterator(ValueAsMetadata **MultiIter) : I(MultiIter) {}
132 
133     location_op_iterator(const location_op_iterator &R) : I(R.I) {}
134     location_op_iterator &operator=(const location_op_iterator &R) {
135       I = R.I;
136       return *this;
137     }
138     bool operator==(const location_op_iterator &RHS) const {
139       return I == RHS.I;
140     }
141     const Value *operator*() const {
142       ValueAsMetadata *VAM = I.is<ValueAsMetadata *>()
143                                  ? I.get<ValueAsMetadata *>()
144                                  : *I.get<ValueAsMetadata **>();
145       return VAM->getValue();
146     };
147     Value *operator*() {
148       ValueAsMetadata *VAM = I.is<ValueAsMetadata *>()
149                                  ? I.get<ValueAsMetadata *>()
150                                  : *I.get<ValueAsMetadata **>();
151       return VAM->getValue();
152     }
153     location_op_iterator &operator++() {
154       if (I.is<ValueAsMetadata *>())
155         I = I.get<ValueAsMetadata *>() + 1;
156       else
157         I = I.get<ValueAsMetadata **>() + 1;
158       return *this;
159     }
160     location_op_iterator &operator--() {
161       if (I.is<ValueAsMetadata *>())
162         I = I.get<ValueAsMetadata *>() - 1;
163       else
164         I = I.get<ValueAsMetadata **>() - 1;
165       return *this;
166     }
167   };
168 
169   /// Get the locations corresponding to the variable referenced by the debug
170   /// info intrinsic.  Depending on the intrinsic, this could be the
171   /// variable's value or its address.
172   iterator_range<location_op_iterator> location_ops() const;
173 
174   Value *getVariableLocationOp(unsigned OpIdx) const;
175 
176   void replaceVariableLocationOp(Value *OldValue, Value *NewValue,
177                                  bool AllowEmpty = false);
178   void replaceVariableLocationOp(unsigned OpIdx, Value *NewValue);
179   /// Adding a new location operand will always result in this intrinsic using
180   /// an ArgList, and must always be accompanied by a new expression that uses
181   /// the new operand.
182   void addVariableLocationOps(ArrayRef<Value *> NewValues,
183                               DIExpression *NewExpr);
184 
185   void setVariable(DILocalVariable *NewVar) { Variable = NewVar; }
186 
187   void setExpression(DIExpression *NewExpr) { Expression = NewExpr; }
188 
189   unsigned getNumVariableLocationOps() const;
190 
191   bool hasArgList() const { return isa<DIArgList>(getRawLocation()); }
192   /// Returns true if this DPValue has no empty MDNodes in its location list.
193   bool hasValidLocation() const { return getVariableLocationOp(0) != nullptr; }
194 
195   /// Does this describe the address of a local variable. True for dbg.addr
196   /// and dbg.declare, but not dbg.value, which describes its value.
197   bool isAddressOfVariable() const { return Type != LocationType::Value; }
198   LocationType getType() const { return Type; }
199 
200   DebugLoc getDebugLoc() const { return DbgLoc; }
201   void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); }
202 
203   void setKillLocation();
204   bool isKillLocation() const;
205 
206   DILocalVariable *getVariable() const { return Variable; }
207 
208   DIExpression *getExpression() const { return Expression; }
209 
210   Metadata *getRawLocation() const { return DebugValue; }
211 
212   /// Use of this should generally be avoided; instead,
213   /// replaceVariableLocationOp and addVariableLocationOps should be used where
214   /// possible to avoid creating invalid state.
215   void setRawLocation(Metadata *NewLocation) {
216     assert(
217         (isa<ValueAsMetadata>(NewLocation) || isa<DIArgList>(NewLocation) ||
218          isa<MDNode>(NewLocation)) &&
219         "Location for a DPValue must be either ValueAsMetadata or DIArgList");
220     resetDebugValue(NewLocation);
221   }
222 
223   /// Get the size (in bits) of the variable, or fragment of the variable that
224   /// is described.
225   std::optional<uint64_t> getFragmentSizeInBits() const;
226 
227   DPValue *clone() const;
228   /// Convert this DPValue back into a dbg.value intrinsic.
229   /// \p InsertBefore Optional position to insert this intrinsic.
230   /// \returns A new dbg.value intrinsic representiung this DPValue.
231   DbgVariableIntrinsic *createDebugIntrinsic(Module *M,
232                                              Instruction *InsertBefore) const;
233   /// Handle changes to the location of the Value(s) that we refer to happening
234   /// "under our feet".
235   void handleChangedLocation(Metadata *NewLocation);
236 
237   void setMarker(DPMarker *M) { Marker = M; }
238 
239   DPMarker *getMarker() { return Marker; }
240   const DPMarker *getMarker() const { return Marker; }
241 
242   BasicBlock *getBlock();
243   const BasicBlock *getBlock() const;
244 
245   Function *getFunction();
246   const Function *getFunction() const;
247 
248   Module *getModule();
249   const Module *getModule() const;
250 
251   LLVMContext &getContext();
252   const LLVMContext &getContext() const;
253 
254   void print(raw_ostream &O, bool IsForDebug = false) const;
255   void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
256 };
257 
258 /// Per-instruction record of debug-info. If an Instruction is the position of
259 /// some debugging information, it points at a DPMarker storing that info. Each
260 /// marker points back at the instruction that owns it. Various utilities are
261 /// provided for manipulating the DPValues contained within this marker.
262 ///
263 /// This class has a rough surface area, because it's needed to preserve the one
264 /// arefact that we can't yet eliminate from the intrinsic / dbg.value
265 /// debug-info design: the order of DPValues/records is significant, and
266 /// duplicates can exist. Thus, if one has a run of debug-info records such as:
267 ///    dbg.value(...
268 ///    %foo = barinst
269 ///    dbg.value(...
270 /// and remove barinst, then the dbg.values must be preserved in the correct
271 /// order. Hence, the use of iterators to select positions to insert things
272 /// into, or the occasional InsertAtHead parameter indicating that new records
273 /// should go at the start of the list.
274 ///
275 /// There are only five or six places in LLVM that truly rely on this ordering,
276 /// which we can improve in the future. Additionally, many improvements in the
277 /// way that debug-info is stored can be achieved in this class, at a future
278 /// date.
279 class DPMarker {
280 public:
281   DPMarker() {}
282   /// Link back to the Instruction that owns this marker. Can be null during
283   /// operations that move a marker from one instruction to another.
284   Instruction *MarkedInstr = nullptr;
285 
286   /// List of DPValues, each recording a single variable assignment, the
287   /// equivalent of a dbg.value intrinsic. There is a one-to-one relationship
288   /// between each dbg.value in a block and each DPValue once the
289   /// representation has been converted, and the ordering of DPValues is
290   /// meaningful in the same was a dbg.values.
291   simple_ilist<DPValue> StoredDPValues;
292   bool empty() const { return StoredDPValues.empty(); }
293 
294   const BasicBlock *getParent() const;
295   BasicBlock *getParent();
296 
297   /// Handle the removal of a marker: the position of debug-info has gone away,
298   /// but the stored debug records should not. Drop them onto the next
299   /// instruction, or otherwise work out what to do with them.
300   void removeMarker();
301   void dump() const;
302 
303   void removeFromParent();
304   void eraseFromParent();
305 
306   /// Implement operator<< on DPMarker.
307   void print(raw_ostream &O, bool IsForDebug = false) const;
308   void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
309 
310   /// Produce a range over all the DPValues in this Marker.
311   iterator_range<simple_ilist<DPValue>::iterator> getDbgValueRange();
312   /// Transfer any DPValues from \p Src into this DPMarker. If \p InsertAtHead
313   /// is true, place them before existing DPValues, otherwise afterwards.
314   void absorbDebugValues(DPMarker &Src, bool InsertAtHead);
315   /// Transfer the DPValues in \p Range from \p Src into this DPMarker. If
316   /// \p InsertAtHead is true, place them before existing DPValues, otherwise
317   // afterwards.
318   void absorbDebugValues(iterator_range<DPValue::self_iterator> Range,
319                          DPMarker &Src, bool InsertAtHead);
320   /// Insert a DPValue into this DPMarker, at the end of the list. If
321   /// \p InsertAtHead is true, at the start.
322   void insertDPValue(DPValue *New, bool InsertAtHead);
323   /// Clone all DPMarkers from \p From into this marker. There are numerous
324   /// options to customise the source/destination, due to gnarliness, see class
325   /// comment.
326   /// \p FromHere If non-null, copy from FromHere to the end of From's DPValues
327   /// \p InsertAtHead Place the cloned DPValues at the start of StoredDPValues
328   /// \returns Range over all the newly cloned DPValues
329   iterator_range<simple_ilist<DPValue>::iterator>
330   cloneDebugInfoFrom(DPMarker *From,
331                      std::optional<simple_ilist<DPValue>::iterator> FromHere,
332                      bool InsertAtHead = false);
333   /// Erase all DPValues in this DPMarker.
334   void dropDPValues();
335   /// Erase a single DPValue from this marker. In an ideal future, we would
336   /// never erase an assignment in this way, but it's the equivalent to
337   /// erasing a dbg.value from a block.
338   void dropOneDPValue(DPValue *DPV);
339 
340   /// We generally act like all llvm Instructions have a range of DPValues
341   /// attached to them, but in reality sometimes we don't allocate the DPMarker
342   /// to save time and memory, but still have to return ranges of DPValues. When
343   /// we need to describe such an unallocated DPValue range, use this static
344   /// markers range instead. This will bite us if someone tries to insert a
345   /// DPValue in that range, but they should be using the Official (TM) API for
346   /// that.
347   static DPMarker EmptyDPMarker;
348   static iterator_range<simple_ilist<DPValue>::iterator> getEmptyDPValueRange(){
349     return make_range(EmptyDPMarker.StoredDPValues.end(), EmptyDPMarker.StoredDPValues.end());
350   }
351 };
352 
353 inline raw_ostream &operator<<(raw_ostream &OS, const DPMarker &Marker) {
354   Marker.print(OS);
355   return OS;
356 }
357 
358 inline raw_ostream &operator<<(raw_ostream &OS, const DPValue &Value) {
359   Value.print(OS);
360   return OS;
361 }
362 
363 } // namespace llvm
364 
365 #endif // LLVM_IR_DEBUGPROGRAMINSTRUCTION_H
366