47
47
#ifndef LLVM_IR_DEBUGPROGRAMINSTRUCTION_H
48
48
#define LLVM_IR_DEBUGPROGRAMINSTRUCTION_H
49
49
50
- #include " llvm/ADT/ilist_node.h"
51
50
#include " llvm/ADT/ilist.h"
51
+ #include " llvm/ADT/ilist_node.h"
52
52
#include " llvm/ADT/iterator.h"
53
+ #include " llvm/IR/DebugInfoMetadata.h"
53
54
#include " llvm/IR/DebugLoc.h"
55
+ #include " llvm/Support/Casting.h"
54
56
55
57
namespace llvm {
56
58
@@ -63,38 +65,92 @@ class DPMarker;
63
65
class DPValue ;
64
66
class raw_ostream ;
65
67
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.
68
+ // / Base class for non-instruction debug metadata records that have positions
69
+ // / within IR. Features various methods copied across from the Instruction
70
+ // / class to aid ease-of-use. DbgRecords should always be linked into a
71
+ // / DPMarker's StoredDPValues list. The marker connects a DbgRecord back to
72
+ // / it's position in the BasicBlock.
71
73
// /
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.
74
+ // / We need a discriminator for dyn/isa casts. In order to avoid paying for a
75
+ // / vtable for "virtual" functions too, subclasses must add a new discriminator
76
+ // / value (RecordKind) and cases to a few functions in the base class:
77
+ // / deleteRecord()
78
+ // / clone()
79
+ // / both print methods
80
+ class DbgRecord : public ilist_node <DbgRecord> {
81
+ public:
82
+ // / Marker that this DbgRecord is linked into.
83
+ DPMarker *Marker = nullptr ;
84
+ // / Subclass discriminator.
85
+ enum Kind : uint8_t { ValueKind };
80
86
81
- DILocalVariable *Variable;
82
- DIExpression *Expression;
87
+ protected:
83
88
DebugLoc DbgLoc;
89
+ Kind RecordKind; // /< Subclass discriminator.
84
90
85
91
public:
86
- void deleteInstr ();
92
+ DbgRecord (Kind RecordKind, DebugLoc DL)
93
+ : DbgLoc(DL), RecordKind(RecordKind) {}
94
+
95
+ // / Methods requiring subclass implementations.
96
+ // /@{
97
+ void deleteRecord ();
98
+ DbgRecord *clone () const ;
99
+ void print (raw_ostream &O, bool IsForDebug = false ) const ;
100
+ void print (raw_ostream &O, ModuleSlotTracker &MST, bool IsForDebug) const ;
101
+ // /@}
102
+
103
+ Kind getRecordKind () const { return RecordKind; }
104
+
105
+ void setMarker (DPMarker *M) { Marker = M; }
106
+
107
+ DPMarker *getMarker () { return Marker; }
108
+ const DPMarker *getMarker () const { return Marker; }
109
+
110
+ BasicBlock *getBlock ();
111
+ const BasicBlock *getBlock () const ;
112
+
113
+ Function *getFunction ();
114
+ const Function *getFunction () const ;
115
+
116
+ Module *getModule ();
117
+ const Module *getModule () const ;
118
+
119
+ LLVMContext &getContext ();
120
+ const LLVMContext &getContext () const ;
87
121
88
122
const BasicBlock *getParent () const ;
89
123
BasicBlock *getParent ();
90
- void dump () const ;
124
+
91
125
void removeFromParent ();
92
126
void eraseFromParent ();
93
127
94
- using self_iterator = simple_ilist<DPValue>::iterator;
95
- using const_self_iterator = simple_ilist<DPValue>::const_iterator;
128
+ DebugLoc getDebugLoc () const { return DbgLoc; }
129
+ void setDebugLoc (DebugLoc Loc) { DbgLoc = std::move (Loc); }
130
+
131
+ void dump () const ;
96
132
97
- enum class LocationType {
133
+ using self_iterator = simple_ilist<DbgRecord>::iterator;
134
+ using const_self_iterator = simple_ilist<DbgRecord>::const_iterator;
135
+
136
+ protected:
137
+ // / Similarly to Value, we avoid paying the cost of a vtable
138
+ // / by protecting the dtor and having deleteRecord dispatch
139
+ // / cleanup.
140
+ // / Use deleteRecord to delete a generic record.
141
+ ~DbgRecord () = default ;
142
+ };
143
+
144
+ // / Record of a variable value-assignment, aka a non instruction representation
145
+ // / of the dbg.value intrinsic.
146
+ // /
147
+ // / This class inherits from DebugValueUser to allow LLVM's metadata facilities
148
+ // / to update our references to metadata beneath our feet.
149
+ class DPValue : public DbgRecord , protected DebugValueUser {
150
+ friend class DebugValueUser ;
151
+
152
+ public:
153
+ enum class LocationType : uint8_t {
98
154
Declare,
99
155
Value,
100
156
@@ -104,11 +160,17 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
104
160
// / Classification of the debug-info record that this DPValue represents.
105
161
// / Essentially, "is this a dbg.value or dbg.declare?". dbg.declares are not
106
162
// / currently supported, but it would be trivial to do so.
163
+ // / FIXME: We could use spare padding bits from DbgRecord for this.
107
164
LocationType Type;
108
165
109
- // / Marker that this DPValue is linked into.
110
- DPMarker *Marker = nullptr ;
166
+ // NB: there is no explicit "Value" field in this class, it's effectively the
167
+ // DebugValueUser superclass instead. The referred to Value can either be a
168
+ // ValueAsMetadata or a DIArgList.
111
169
170
+ DILocalVariable *Variable;
171
+ DIExpression *Expression;
172
+
173
+ public:
112
174
// / Create a new DPValue representing the intrinsic \p DVI, for example the
113
175
// / assignment represented by a dbg.value.
114
176
DPValue (const DbgVariableIntrinsic *DVI);
@@ -197,9 +259,6 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
197
259
bool isAddressOfVariable () const { return Type != LocationType::Value; }
198
260
LocationType getType () const { return Type; }
199
261
200
- DebugLoc getDebugLoc () const { return DbgLoc; }
201
- void setDebugLoc (DebugLoc Loc) { DbgLoc = std::move (Loc); }
202
-
203
262
void setKillLocation ();
204
263
bool isKillLocation () const ;
205
264
@@ -230,40 +289,37 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
230
289
// / \returns A new dbg.value intrinsic representiung this DPValue.
231
290
DbgVariableIntrinsic *createDebugIntrinsic (Module *M,
232
291
Instruction *InsertBefore) const ;
292
+
233
293
// / Handle changes to the location of the Value(s) that we refer to happening
234
294
// / "under our feet".
235
295
void handleChangedLocation (Metadata *NewLocation);
236
296
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
297
void print (raw_ostream &O, bool IsForDebug = false ) const ;
255
298
void print (raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const ;
299
+
300
+ // / Filter the DbgRecord range to DPValue types only and downcast.
301
+ static inline auto
302
+ filter (iterator_range<simple_ilist<DbgRecord>::iterator> R) {
303
+ return map_range (
304
+ make_filter_range (R, [](DbgRecord &E) { return isa<DPValue>(E); }),
305
+ [](DbgRecord &E) { return std::ref (cast<DPValue>(E)); });
306
+ }
307
+
308
+ // / Support type inquiry through isa, cast, and dyn_cast.
309
+ static bool classof (const DbgRecord *E) {
310
+ return E->getRecordKind () == ValueKind;
311
+ }
256
312
};
257
313
258
314
// / Per-instruction record of debug-info. If an Instruction is the position of
259
315
// / some debugging information, it points at a DPMarker storing that info. Each
260
316
// / marker points back at the instruction that owns it. Various utilities are
261
- // / provided for manipulating the DPValues contained within this marker.
317
+ // / provided for manipulating the DbgRecords contained within this marker.
262
318
// /
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:
319
+ // / This class has a rough surface area, because it's needed to preserve the
320
+ // / one arefact that we can't yet eliminate from the intrinsic / dbg.value
321
+ // / debug-info design: the order of records is significant, and duplicates can
322
+ // / exist. Thus, if one has a run of debug-info records such as:
267
323
// / dbg.value(...
268
324
// / %foo = barinst
269
325
// / dbg.value(...
@@ -283,12 +339,11 @@ class DPMarker {
283
339
// / operations that move a marker from one instruction to another.
284
340
Instruction *MarkedInstr = nullptr ;
285
341
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;
342
+ // / List of DbgRecords, the non-instruction equivalent of llvm.dbg.*
343
+ // / intrinsics. There is a one-to-one relationship between each debug
344
+ // / intrinsic in a block and each DbgRecord once the representation has been
345
+ // / converted, and the ordering is meaningful in the same way.
346
+ simple_ilist<DbgRecord> StoredDPValues;
292
347
bool empty () const { return StoredDPValues.empty (); }
293
348
294
349
const BasicBlock *getParent () const ;
@@ -308,34 +363,34 @@ class DPMarker {
308
363
void print (raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const ;
309
364
310
365
// / Produce a range over all the DPValues in this Marker.
311
- iterator_range<simple_ilist<DPValue >::iterator> getDbgValueRange ();
366
+ iterator_range<simple_ilist<DbgRecord >::iterator> getDbgValueRange ();
312
367
// / Transfer any DPValues from \p Src into this DPMarker. If \p InsertAtHead
313
368
// / is true, place them before existing DPValues, otherwise afterwards.
314
369
void absorbDebugValues (DPMarker &Src, bool InsertAtHead);
315
370
// / Transfer the DPValues in \p Range from \p Src into this DPMarker. If
316
371
// / \p InsertAtHead is true, place them before existing DPValues, otherwise
317
372
// afterwards.
318
- void absorbDebugValues (iterator_range<DPValue ::self_iterator> Range,
373
+ void absorbDebugValues (iterator_range<DbgRecord ::self_iterator> Range,
319
374
DPMarker &Src, bool InsertAtHead);
320
375
// / Insert a DPValue into this DPMarker, at the end of the list. If
321
376
// / \p InsertAtHead is true, at the start.
322
- void insertDPValue (DPValue *New, bool InsertAtHead);
377
+ void insertDPValue (DbgRecord *New, bool InsertAtHead);
323
378
// / Clone all DPMarkers from \p From into this marker. There are numerous
324
379
// / options to customise the source/destination, due to gnarliness, see class
325
380
// / comment.
326
381
// / \p FromHere If non-null, copy from FromHere to the end of From's DPValues
327
382
// / \p InsertAtHead Place the cloned DPValues at the start of StoredDPValues
328
383
// / \returns Range over all the newly cloned DPValues
329
- iterator_range<simple_ilist<DPValue >::iterator>
384
+ iterator_range<simple_ilist<DbgRecord >::iterator>
330
385
cloneDebugInfoFrom (DPMarker *From,
331
- std::optional<simple_ilist<DPValue >::iterator> FromHere,
386
+ std::optional<simple_ilist<DbgRecord >::iterator> FromHere,
332
387
bool InsertAtHead = false );
333
388
// / Erase all DPValues in this DPMarker.
334
- void dropDPValues ();
335
- // / Erase a single DPValue from this marker. In an ideal future, we would
389
+ void dropDbgValues ();
390
+ // / Erase a single DbgRecord from this marker. In an ideal future, we would
336
391
// / 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 );
392
+ // / erasing a debug intrinsic from a block.
393
+ void dropOneDbgValue (DbgRecord *DPE );
339
394
340
395
// / We generally act like all llvm Instructions have a range of DPValues
341
396
// / attached to them, but in reality sometimes we don't allocate the DPMarker
@@ -345,8 +400,10 @@ class DPMarker {
345
400
// / DPValue in that range, but they should be using the Official (TM) API for
346
401
// / that.
347
402
static DPMarker EmptyDPMarker;
348
- static iterator_range<simple_ilist<DPValue>::iterator> getEmptyDPValueRange (){
349
- return make_range (EmptyDPMarker.StoredDPValues .end (), EmptyDPMarker.StoredDPValues .end ());
403
+ static iterator_range<simple_ilist<DbgRecord>::iterator>
404
+ getEmptyDPValueRange () {
405
+ return make_range (EmptyDPMarker.StoredDPValues .end (),
406
+ EmptyDPMarker.StoredDPValues .end ());
350
407
}
351
408
};
352
409
0 commit comments