Skip to content

Commit 541bd2b

Browse files
committed
[RemoveDIs][NFC] Introduce DbgRecord base class [1/3]
1 parent 3b337bb commit 541bd2b

30 files changed

+349
-213
lines changed

llvm/include/llvm/IR/BasicBlock.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,10 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
130130
DPMarker *getNextMarker(Instruction *I);
131131

132132
/// Insert a DPValue into a block at the position given by \p I.
133-
void insertDPValueAfter(DPValue *DPV, Instruction *I);
133+
void insertDPValueAfter(DbgRecord *DPV, Instruction *I);
134134

135135
/// Insert a DPValue into a block at the position given by \p Here.
136-
void insertDPValueBefore(DPValue *DPV, InstListType::iterator Here);
136+
void insertDPValueBefore(DbgRecord *DPV, InstListType::iterator Here);
137137

138138
/// Eject any debug-info trailing at the end of a block. DPValues can
139139
/// transiently be located "off the end" of a block if the blocks terminator
@@ -147,7 +147,7 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
147147
/// occur: inserting into the middle of a sequence of dbg.value intrinsics
148148
/// does not have an equivalent with DPValues.
149149
void reinsertInstInDPValues(Instruction *I,
150-
std::optional<DPValue::self_iterator> Pos);
150+
std::optional<DbgRecord::self_iterator> Pos);
151151

152152
private:
153153
void setParent(Function *parent);
@@ -194,8 +194,9 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
194194
friend void Instruction::moveBeforeImpl(BasicBlock &BB,
195195
InstListType::iterator I,
196196
bool Preserve);
197-
friend iterator_range<DPValue::self_iterator> Instruction::cloneDebugInfoFrom(
198-
const Instruction *From, std::optional<DPValue::self_iterator> FromHere,
197+
friend iterator_range<DbgRecord::self_iterator>
198+
Instruction::cloneDebugInfoFrom(
199+
const Instruction *From, std::optional<DbgRecord::self_iterator> FromHere,
199200
bool InsertAtHead);
200201

201202
/// Creates a new BasicBlock.

llvm/include/llvm/IR/DebugInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ class DebugInfoFinder {
109109
void processLocation(const Module &M, const DILocation *Loc);
110110
// Process a DPValue, much like a DbgVariableIntrinsic.
111111
void processDPValue(const Module &M, const DPValue &DPV);
112+
/// Dispatch to DbgRecord subclasses handlers.
113+
void processDbgRecord(const Module &M, const DbgRecord &DPE);
112114

113115
/// Process subprogram.
114116
void processSubprogram(DISubprogram *SP);

llvm/include/llvm/IR/DebugProgramInstruction.h

Lines changed: 122 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,12 @@
4747
#ifndef LLVM_IR_DEBUGPROGRAMINSTRUCTION_H
4848
#define LLVM_IR_DEBUGPROGRAMINSTRUCTION_H
4949

50-
#include "llvm/ADT/ilist_node.h"
5150
#include "llvm/ADT/ilist.h"
51+
#include "llvm/ADT/ilist_node.h"
5252
#include "llvm/ADT/iterator.h"
53+
#include "llvm/IR/DebugInfoMetadata.h"
5354
#include "llvm/IR/DebugLoc.h"
55+
#include "llvm/Support/Casting.h"
5456

5557
namespace llvm {
5658

@@ -63,38 +65,92 @@ class DPMarker;
6365
class DPValue;
6466
class raw_ostream;
6567

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.
7173
///
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 };
8086

81-
DILocalVariable *Variable;
82-
DIExpression *Expression;
87+
protected:
8388
DebugLoc DbgLoc;
89+
Kind RecordKind; ///< Subclass discriminator.
8490

8591
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;
87121

88122
const BasicBlock *getParent() const;
89123
BasicBlock *getParent();
90-
void dump() const;
124+
91125
void removeFromParent();
92126
void eraseFromParent();
93127

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;
96132

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 {
98154
Declare,
99155
Value,
100156

@@ -104,11 +160,17 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
104160
/// Classification of the debug-info record that this DPValue represents.
105161
/// Essentially, "is this a dbg.value or dbg.declare?". dbg.declares are not
106162
/// currently supported, but it would be trivial to do so.
163+
/// FIXME: We could use spare padding bits from DbgRecord for this.
107164
LocationType Type;
108165

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.
111169

170+
DILocalVariable *Variable;
171+
DIExpression *Expression;
172+
173+
public:
112174
/// Create a new DPValue representing the intrinsic \p DVI, for example the
113175
/// assignment represented by a dbg.value.
114176
DPValue(const DbgVariableIntrinsic *DVI);
@@ -197,9 +259,6 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
197259
bool isAddressOfVariable() const { return Type != LocationType::Value; }
198260
LocationType getType() const { return Type; }
199261

200-
DebugLoc getDebugLoc() const { return DbgLoc; }
201-
void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); }
202-
203262
void setKillLocation();
204263
bool isKillLocation() const;
205264

@@ -230,40 +289,37 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
230289
/// \returns A new dbg.value intrinsic representiung this DPValue.
231290
DbgVariableIntrinsic *createDebugIntrinsic(Module *M,
232291
Instruction *InsertBefore) const;
292+
233293
/// Handle changes to the location of the Value(s) that we refer to happening
234294
/// "under our feet".
235295
void handleChangedLocation(Metadata *NewLocation);
236296

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-
254297
void print(raw_ostream &O, bool IsForDebug = false) const;
255298
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+
}
256312
};
257313

258314
/// Per-instruction record of debug-info. If an Instruction is the position of
259315
/// some debugging information, it points at a DPMarker storing that info. Each
260316
/// 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.
262318
///
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:
267323
/// dbg.value(...
268324
/// %foo = barinst
269325
/// dbg.value(...
@@ -283,12 +339,11 @@ class DPMarker {
283339
/// operations that move a marker from one instruction to another.
284340
Instruction *MarkedInstr = nullptr;
285341

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;
292347
bool empty() const { return StoredDPValues.empty(); }
293348

294349
const BasicBlock *getParent() const;
@@ -308,34 +363,34 @@ class DPMarker {
308363
void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
309364

310365
/// 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();
312367
/// Transfer any DPValues from \p Src into this DPMarker. If \p InsertAtHead
313368
/// is true, place them before existing DPValues, otherwise afterwards.
314369
void absorbDebugValues(DPMarker &Src, bool InsertAtHead);
315370
/// Transfer the DPValues in \p Range from \p Src into this DPMarker. If
316371
/// \p InsertAtHead is true, place them before existing DPValues, otherwise
317372
// afterwards.
318-
void absorbDebugValues(iterator_range<DPValue::self_iterator> Range,
373+
void absorbDebugValues(iterator_range<DbgRecord::self_iterator> Range,
319374
DPMarker &Src, bool InsertAtHead);
320375
/// Insert a DPValue into this DPMarker, at the end of the list. If
321376
/// \p InsertAtHead is true, at the start.
322-
void insertDPValue(DPValue *New, bool InsertAtHead);
377+
void insertDPValue(DbgRecord *New, bool InsertAtHead);
323378
/// Clone all DPMarkers from \p From into this marker. There are numerous
324379
/// options to customise the source/destination, due to gnarliness, see class
325380
/// comment.
326381
/// \p FromHere If non-null, copy from FromHere to the end of From's DPValues
327382
/// \p InsertAtHead Place the cloned DPValues at the start of StoredDPValues
328383
/// \returns Range over all the newly cloned DPValues
329-
iterator_range<simple_ilist<DPValue>::iterator>
384+
iterator_range<simple_ilist<DbgRecord>::iterator>
330385
cloneDebugInfoFrom(DPMarker *From,
331-
std::optional<simple_ilist<DPValue>::iterator> FromHere,
386+
std::optional<simple_ilist<DbgRecord>::iterator> FromHere,
332387
bool InsertAtHead = false);
333388
/// 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
336391
/// 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);
339394

340395
/// We generally act like all llvm Instructions have a range of DPValues
341396
/// attached to them, but in reality sometimes we don't allocate the DPMarker
@@ -345,8 +400,10 @@ class DPMarker {
345400
/// DPValue in that range, but they should be using the Official (TM) API for
346401
/// that.
347402
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());
350407
}
351408
};
352409

llvm/include/llvm/IR/Instruction.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class MDNode;
3535
class Module;
3636
struct AAMDNodes;
3737
class DPMarker;
38+
class DbgRecord;
3839

3940
template <> struct ilist_alloc_traits<Instruction> {
4041
static inline void deleteNode(Instruction *V);
@@ -70,18 +71,18 @@ class Instruction : public User,
7071
/// \p InsertAtHead Whether the cloned DPValues should be placed at the end
7172
/// or the beginning of existing DPValues attached to this.
7273
/// \returns A range over the newly cloned DPValues.
73-
iterator_range<simple_ilist<DPValue>::iterator> cloneDebugInfoFrom(
74+
iterator_range<simple_ilist<DbgRecord>::iterator> cloneDebugInfoFrom(
7475
const Instruction *From,
75-
std::optional<simple_ilist<DPValue>::iterator> FromHere = std::nullopt,
76+
std::optional<simple_ilist<DbgRecord>::iterator> FromHere = std::nullopt,
7677
bool InsertAtHead = false);
7778

7879
/// Return a range over the DPValues attached to this instruction.
79-
iterator_range<simple_ilist<DPValue>::iterator> getDbgValueRange() const;
80+
iterator_range<simple_ilist<DbgRecord>::iterator> getDbgValueRange() const;
8081

8182
/// Return an iterator to the position of the "Next" DPValue after this
8283
/// instruction, or std::nullopt. This is the position to pass to
8384
/// BasicBlock::reinsertInstInDPValues when re-inserting an instruction.
84-
std::optional<simple_ilist<DPValue>::iterator> getDbgReinsertionPosition();
85+
std::optional<simple_ilist<DbgRecord>::iterator> getDbgReinsertionPosition();
8586

8687
/// Returns true if any DPValues are attached to this instruction.
8788
bool hasDbgValues() const;
@@ -90,7 +91,7 @@ class Instruction : public User,
9091
void dropDbgValues();
9192

9293
/// Erase a single DPValue \p I that is attached to this instruction.
93-
void dropOneDbgValue(DPValue *I);
94+
void dropOneDbgValue(DbgRecord *I);
9495

9596
/// Handle the debug-info implications of this instruction being removed. Any
9697
/// attached DPValues need to "fall" down onto the next instruction.

llvm/include/llvm/IR/Metadata.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class Module;
4444
class ModuleSlotTracker;
4545
class raw_ostream;
4646
class DPValue;
47+
class DbgRecord;
4748
template <typename T> class StringMapEntry;
4849
template <typename ValueTy> class StringMapEntryStorage;
4950
class Type;

0 commit comments

Comments
 (0)