Skip to content

Commit ababa96

Browse files
authored
[RemoveDIs][NFC] Introduce DbgRecord base class [1/3] (#78252)
Patch 1 of 3 to add llvm.dbg.label support to the RemoveDIs project. The patch stack adds a new base class -> 1. Add DbgRecord base class for DPValue and the not-yet-added DPLabel class. 2. Add the DPLabel class. 3. Enable dbg.label conversion and add support to passes. Patches 1 and 2 are NFC. In the near future we also will rename DPValue to DbgVariableRecord and DPLabel to DbgLabelRecord, at which point we'll overhaul the function names too. The name DPLabel keeps things consistent for now.
1 parent 8f7ae64 commit ababa96

39 files changed

+461
-289
lines changed

llvm/include/llvm/IR/BasicBlock.h

+6-5
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

+2
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ class DebugInfoFinder {
111111
void processLocation(const Module &M, const DILocation *Loc);
112112
// Process a DPValue, much like a DbgVariableIntrinsic.
113113
void processDPValue(const Module &M, const DPValue &DPV);
114+
/// Dispatch to DbgRecord subclasses handlers.
115+
void processDbgRecord(const Module &M, const DbgRecord &DPE);
114116

115117
/// Process subprogram.
116118
void processSubprogram(DISubprogram *SP);

llvm/include/llvm/IR/DebugProgramInstruction.h

+140-78
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include "llvm/IR/DebugLoc.h"
5454
#include "llvm/IR/Instruction.h"
5555
#include "llvm/IR/SymbolTableListTraits.h"
56+
#include "llvm/Support/Casting.h"
5657

5758
namespace llvm {
5859

@@ -66,43 +67,105 @@ class DPMarker;
6667
class DPValue;
6768
class raw_ostream;
6869

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.
70+
/// Base class for non-instruction debug metadata records that have positions
71+
/// within IR. Features various methods copied across from the Instruction
72+
/// class to aid ease-of-use. DbgRecords should always be linked into a
73+
/// DPMarker's StoredDPValues list. The marker connects a DbgRecord back to
74+
/// it's position in the BasicBlock.
7475
///
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.
76+
/// We need a discriminator for dyn/isa casts. In order to avoid paying for a
77+
/// vtable for "virtual" functions too, subclasses must add a new discriminator
78+
/// value (RecordKind) and cases to a few functions in the base class:
79+
/// deleteRecord
80+
/// clone
81+
/// isIdenticalToWhenDefined
82+
/// isEquivalentTo
83+
/// both print methods
84+
class DbgRecord : public ilist_node<DbgRecord> {
85+
public:
86+
/// Marker that this DbgRecord is linked into.
87+
DPMarker *Marker = nullptr;
88+
/// Subclass discriminator.
89+
enum Kind : uint8_t { ValueKind };
8390

84-
DILocalVariable *Variable;
85-
DIExpression *Expression;
91+
protected:
8692
DebugLoc DbgLoc;
87-
DIExpression *AddressExpression;
93+
Kind RecordKind; ///< Subclass discriminator.
8894

8995
public:
90-
void deleteInstr();
96+
DbgRecord(Kind RecordKind, DebugLoc DL)
97+
: DbgLoc(DL), RecordKind(RecordKind) {}
98+
99+
/// Methods that dispatch to subclass implementations. These need to be
100+
/// manually updated when a new subclass is added.
101+
///@{
102+
void deleteRecord();
103+
DbgRecord *clone() const;
104+
void print(raw_ostream &O, bool IsForDebug = false) const;
105+
void print(raw_ostream &O, ModuleSlotTracker &MST, bool IsForDebug) const;
106+
bool isIdenticalToWhenDefined(const DbgRecord &R) const;
107+
bool isEquivalentTo(const DbgRecord &R) const;
108+
///@}
109+
110+
Kind getRecordKind() const { return RecordKind; }
111+
112+
void setMarker(DPMarker *M) { Marker = M; }
113+
114+
DPMarker *getMarker() { return Marker; }
115+
const DPMarker *getMarker() const { return Marker; }
116+
117+
BasicBlock *getBlock();
118+
const BasicBlock *getBlock() const;
119+
120+
Function *getFunction();
121+
const Function *getFunction() const;
122+
123+
Module *getModule();
124+
const Module *getModule() const;
125+
126+
LLVMContext &getContext();
127+
const LLVMContext &getContext() const;
91128

92129
const Instruction *getInstruction() const;
93130
const BasicBlock *getParent() const;
94131
BasicBlock *getParent();
95-
void dump() const;
132+
96133
void removeFromParent();
97134
void eraseFromParent();
98135

99-
DPValue *getNextNode() { return &*std::next(getIterator()); }
100-
DPValue *getPrevNode() { return &*std::prev(getIterator()); }
136+
DbgRecord *getNextNode() { return &*std::next(getIterator()); }
137+
DbgRecord *getPrevNode() { return &*std::prev(getIterator()); }
138+
void insertBefore(DbgRecord *InsertBefore);
139+
void insertAfter(DbgRecord *InsertAfter);
140+
void moveBefore(DbgRecord *MoveBefore);
141+
void moveAfter(DbgRecord *MoveAfter);
142+
143+
DebugLoc getDebugLoc() const { return DbgLoc; }
144+
void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); }
145+
146+
void dump() const;
147+
148+
using self_iterator = simple_ilist<DbgRecord>::iterator;
149+
using const_self_iterator = simple_ilist<DbgRecord>::const_iterator;
101150

102-
using self_iterator = simple_ilist<DPValue>::iterator;
103-
using const_self_iterator = simple_ilist<DPValue>::const_iterator;
151+
protected:
152+
/// Similarly to Value, we avoid paying the cost of a vtable
153+
/// by protecting the dtor and having deleteRecord dispatch
154+
/// cleanup.
155+
/// Use deleteRecord to delete a generic record.
156+
~DbgRecord() = default;
157+
};
158+
159+
/// Record of a variable value-assignment, aka a non instruction representation
160+
/// of the dbg.value intrinsic.
161+
///
162+
/// This class inherits from DebugValueUser to allow LLVM's metadata facilities
163+
/// to update our references to metadata beneath our feet.
164+
class DPValue : public DbgRecord, protected DebugValueUser {
165+
friend class DebugValueUser;
104166

105-
enum class LocationType {
167+
public:
168+
enum class LocationType : uint8_t {
106169
Declare,
107170
Value,
108171
Assign,
@@ -113,11 +176,18 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
113176
/// Classification of the debug-info record that this DPValue represents.
114177
/// Essentially, "is this a dbg.value or dbg.declare?". dbg.declares are not
115178
/// currently supported, but it would be trivial to do so.
179+
/// FIXME: We could use spare padding bits from DbgRecord for this.
116180
LocationType Type;
117181

118-
/// Marker that this DPValue is linked into.
119-
DPMarker *Marker = nullptr;
182+
// NB: there is no explicit "Value" field in this class, it's effectively the
183+
// DebugValueUser superclass instead. The referred to Value can either be a
184+
// ValueAsMetadata or a DIArgList.
185+
186+
DILocalVariable *Variable;
187+
DIExpression *Expression;
188+
DIExpression *AddressExpression;
120189

190+
public:
121191
/// Create a new DPValue representing the intrinsic \p DVI, for example the
122192
/// assignment represented by a dbg.value.
123193
DPValue(const DbgVariableIntrinsic *DVI);
@@ -235,9 +305,6 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
235305
bool isAddressOfVariable() const { return Type == LocationType::Declare; }
236306
LocationType getType() const { return Type; }
237307

238-
DebugLoc getDebugLoc() const { return DbgLoc; }
239-
void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); }
240-
241308
void setKillLocation();
242309
bool isKillLocation() const;
243310

@@ -270,12 +337,12 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
270337
/// is described.
271338
std::optional<uint64_t> getFragmentSizeInBits() const;
272339

273-
bool isEquivalentTo(const DPValue &Other) {
340+
bool isEquivalentTo(const DPValue &Other) const {
274341
return DbgLoc == Other.DbgLoc && isIdenticalToWhenDefined(Other);
275342
}
276343
// Matches the definition of the Instruction version, equivalent to above but
277344
// without checking DbgLoc.
278-
bool isIdenticalToWhenDefined(const DPValue &Other) {
345+
bool isIdenticalToWhenDefined(const DPValue &Other) const {
279346
return std::tie(Type, DebugValues, Variable, Expression,
280347
AddressExpression) ==
281348
std::tie(Other.Type, Other.DebugValues, Other.Variable,
@@ -314,43 +381,37 @@ class DPValue : public ilist_node<DPValue>, private DebugValueUser {
314381
/// \returns A new dbg.value intrinsic representiung this DPValue.
315382
DbgVariableIntrinsic *createDebugIntrinsic(Module *M,
316383
Instruction *InsertBefore) const;
317-
void setMarker(DPMarker *M) { Marker = M; }
318-
319-
DPMarker *getMarker() { return Marker; }
320-
const DPMarker *getMarker() const { return Marker; }
321-
322-
BasicBlock *getBlock();
323-
const BasicBlock *getBlock() const;
324-
325-
Function *getFunction();
326-
const Function *getFunction() const;
327384

328-
Module *getModule();
329-
const Module *getModule() const;
330-
331-
LLVMContext &getContext();
332-
const LLVMContext &getContext() const;
333-
334-
/// Insert this DPValue prior to \p InsertBefore. Must not be called if this
335-
/// is already contained in a DPMarker.
336-
void insertBefore(DPValue *InsertBefore);
337-
void insertAfter(DPValue *InsertAfter);
338-
void moveBefore(DPValue *MoveBefore);
339-
void moveAfter(DPValue *MoveAfter);
385+
/// Handle changes to the location of the Value(s) that we refer to happening
386+
/// "under our feet".
387+
void handleChangedLocation(Metadata *NewLocation);
340388

341389
void print(raw_ostream &O, bool IsForDebug = false) const;
342390
void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
391+
392+
/// Filter the DbgRecord range to DPValue types only and downcast.
393+
static inline auto
394+
filter(iterator_range<simple_ilist<DbgRecord>::iterator> R) {
395+
return map_range(
396+
make_filter_range(R, [](DbgRecord &E) { return isa<DPValue>(E); }),
397+
[](DbgRecord &E) { return std::ref(cast<DPValue>(E)); });
398+
}
399+
400+
/// Support type inquiry through isa, cast, and dyn_cast.
401+
static bool classof(const DbgRecord *E) {
402+
return E->getRecordKind() == ValueKind;
403+
}
343404
};
344405

345406
/// Per-instruction record of debug-info. If an Instruction is the position of
346407
/// some debugging information, it points at a DPMarker storing that info. Each
347408
/// marker points back at the instruction that owns it. Various utilities are
348-
/// provided for manipulating the DPValues contained within this marker.
409+
/// provided for manipulating the DbgRecords contained within this marker.
349410
///
350-
/// This class has a rough surface area, because it's needed to preserve the one
351-
/// arefact that we can't yet eliminate from the intrinsic / dbg.value
352-
/// debug-info design: the order of DPValues/records is significant, and
353-
/// duplicates can exist. Thus, if one has a run of debug-info records such as:
411+
/// This class has a rough surface area, because it's needed to preserve the
412+
/// one arefact that we can't yet eliminate from the intrinsic / dbg.value
413+
/// debug-info design: the order of records is significant, and duplicates can
414+
/// exist. Thus, if one has a run of debug-info records such as:
354415
/// dbg.value(...
355416
/// %foo = barinst
356417
/// dbg.value(...
@@ -370,12 +431,11 @@ class DPMarker {
370431
/// operations that move a marker from one instruction to another.
371432
Instruction *MarkedInstr = nullptr;
372433

373-
/// List of DPValues, each recording a single variable assignment, the
374-
/// equivalent of a dbg.value intrinsic. There is a one-to-one relationship
375-
/// between each dbg.value in a block and each DPValue once the
376-
/// representation has been converted, and the ordering of DPValues is
377-
/// meaningful in the same was a dbg.values.
378-
simple_ilist<DPValue> StoredDPValues;
434+
/// List of DbgRecords, the non-instruction equivalent of llvm.dbg.*
435+
/// intrinsics. There is a one-to-one relationship between each debug
436+
/// intrinsic in a block and each DbgRecord once the representation has been
437+
/// converted, and the ordering is meaningful in the same way.
438+
simple_ilist<DbgRecord> StoredDPValues;
379439
bool empty() const { return StoredDPValues.empty(); }
380440

381441
const BasicBlock *getParent() const;
@@ -395,40 +455,40 @@ class DPMarker {
395455
void print(raw_ostream &ROS, ModuleSlotTracker &MST, bool IsForDebug) const;
396456

397457
/// Produce a range over all the DPValues in this Marker.
398-
iterator_range<simple_ilist<DPValue>::iterator> getDbgValueRange();
399-
iterator_range<simple_ilist<DPValue>::const_iterator>
458+
iterator_range<simple_ilist<DbgRecord>::iterator> getDbgValueRange();
459+
iterator_range<simple_ilist<DbgRecord>::const_iterator>
400460
getDbgValueRange() const;
401461
/// Transfer any DPValues from \p Src into this DPMarker. If \p InsertAtHead
402462
/// is true, place them before existing DPValues, otherwise afterwards.
403463
void absorbDebugValues(DPMarker &Src, bool InsertAtHead);
404464
/// Transfer the DPValues in \p Range from \p Src into this DPMarker. If
405465
/// \p InsertAtHead is true, place them before existing DPValues, otherwise
406466
// afterwards.
407-
void absorbDebugValues(iterator_range<DPValue::self_iterator> Range,
467+
void absorbDebugValues(iterator_range<DbgRecord::self_iterator> Range,
408468
DPMarker &Src, bool InsertAtHead);
409469
/// Insert a DPValue into this DPMarker, at the end of the list. If
410470
/// \p InsertAtHead is true, at the start.
411-
void insertDPValue(DPValue *New, bool InsertAtHead);
471+
void insertDPValue(DbgRecord *New, bool InsertAtHead);
412472
/// Insert a DPValue prior to a DPValue contained within this marker.
413-
void insertDPValue(DPValue *New, DPValue *InsertBefore);
473+
void insertDPValue(DbgRecord *New, DbgRecord *InsertBefore);
414474
/// Insert a DPValue after a DPValue contained within this marker.
415-
void insertDPValueAfter(DPValue *New, DPValue *InsertAfter);
475+
void insertDPValueAfter(DbgRecord *New, DbgRecord *InsertAfter);
416476
/// Clone all DPMarkers from \p From into this marker. There are numerous
417477
/// options to customise the source/destination, due to gnarliness, see class
418478
/// comment.
419479
/// \p FromHere If non-null, copy from FromHere to the end of From's DPValues
420480
/// \p InsertAtHead Place the cloned DPValues at the start of StoredDPValues
421481
/// \returns Range over all the newly cloned DPValues
422-
iterator_range<simple_ilist<DPValue>::iterator>
482+
iterator_range<simple_ilist<DbgRecord>::iterator>
423483
cloneDebugInfoFrom(DPMarker *From,
424-
std::optional<simple_ilist<DPValue>::iterator> FromHere,
484+
std::optional<simple_ilist<DbgRecord>::iterator> FromHere,
425485
bool InsertAtHead = false);
426486
/// Erase all DPValues in this DPMarker.
427-
void dropDPValues();
428-
/// Erase a single DPValue from this marker. In an ideal future, we would
487+
void dropDbgValues();
488+
/// Erase a single DbgRecord from this marker. In an ideal future, we would
429489
/// never erase an assignment in this way, but it's the equivalent to
430-
/// erasing a dbg.value from a block.
431-
void dropOneDPValue(DPValue *DPV);
490+
/// erasing a debug intrinsic from a block.
491+
void dropOneDbgValue(DbgRecord *DR);
432492

433493
/// We generally act like all llvm Instructions have a range of DPValues
434494
/// attached to them, but in reality sometimes we don't allocate the DPMarker
@@ -438,8 +498,10 @@ class DPMarker {
438498
/// DPValue in that range, but they should be using the Official (TM) API for
439499
/// that.
440500
static DPMarker EmptyDPMarker;
441-
static iterator_range<simple_ilist<DPValue>::iterator> getEmptyDPValueRange(){
442-
return make_range(EmptyDPMarker.StoredDPValues.end(), EmptyDPMarker.StoredDPValues.end());
501+
static iterator_range<simple_ilist<DbgRecord>::iterator>
502+
getEmptyDPValueRange() {
503+
return make_range(EmptyDPMarker.StoredDPValues.end(),
504+
EmptyDPMarker.StoredDPValues.end());
443505
}
444506
};
445507

@@ -457,7 +519,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const DPValue &Value) {
457519
/// to be inlined as it's frequently called, but also come after the declaration
458520
/// of DPMarker. Thus: it's pre-declared by users like Instruction, then an
459521
/// inlineable body defined here.
460-
inline iterator_range<simple_ilist<DPValue>::iterator>
522+
inline iterator_range<simple_ilist<DbgRecord>::iterator>
461523
getDbgValueRange(DPMarker *DbgMarker) {
462524
if (!DbgMarker)
463525
return DPMarker::getEmptyDPValueRange();

0 commit comments

Comments
 (0)