Skip to content

Commit b3c2c5a

Browse files
authored
[RemoveDIs][DebugInfo] Verifier and printing fixes for DPLabel (#83242)
`DPLabel`, the RemoveDI version of `llvm.dbg.label`, was landed recently at the same time the RemoveDIs IR printing and verifier patches were landing. The patches were updated to not miscompile, but did not have full-featured and correct support for DPLabel built in; this patch makes the remaining set of changes to enable DPLabel support.
1 parent 27ce512 commit b3c2c5a

File tree

5 files changed

+261
-65
lines changed

5 files changed

+261
-65
lines changed

llvm/include/llvm/IR/DebugProgramInstruction.h

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,53 @@ class DPMarker;
6969
class DPValue;
7070
class raw_ostream;
7171

72+
/// A typed tracking MDNode reference that does not require a definition for its
73+
/// parameter type. Necessary to avoid including DebugInfoMetadata.h, which has
74+
/// a significant impact on compile times if included in this file.
75+
template <typename T> class DbgRecordParamRef {
76+
TrackingMDNodeRef Ref;
77+
78+
public:
79+
public:
80+
DbgRecordParamRef() = default;
81+
82+
/// Construct from the templated type.
83+
DbgRecordParamRef(const T *Param);
84+
85+
/// Construct from an \a MDNode.
86+
///
87+
/// Note: if \c Param does not have the template type, a verifier check will
88+
/// fail, and accessors will crash. However, construction from other nodes
89+
/// is supported in order to handle forward references when reading textual
90+
/// IR.
91+
explicit DbgRecordParamRef(const MDNode *Param);
92+
93+
/// Get the underlying type.
94+
///
95+
/// \pre !*this or \c isa<T>(getAsMDNode()).
96+
/// @{
97+
T *get() const;
98+
operator T *() const { return get(); }
99+
T *operator->() const { return get(); }
100+
T &operator*() const { return *get(); }
101+
/// @}
102+
103+
/// Check for null.
104+
///
105+
/// Check for null in a way that is safe with broken debug info.
106+
explicit operator bool() const { return Ref; }
107+
108+
/// Return \c this as a \a MDNode.
109+
MDNode *getAsMDNode() const { return Ref; }
110+
111+
bool operator==(const DbgRecordParamRef &Other) const {
112+
return Ref == Other.Ref;
113+
}
114+
bool operator!=(const DbgRecordParamRef &Other) const {
115+
return Ref != Other.Ref;
116+
}
117+
};
118+
72119
/// Base class for non-instruction debug metadata records that have positions
73120
/// within IR. Features various methods copied across from the Instruction
74121
/// class to aid ease-of-use. DbgRecords should always be linked into a
@@ -174,13 +221,10 @@ inline raw_ostream &operator<<(raw_ostream &OS, const DbgRecord &R) {
174221
/// llvm.dbg.label intrinsic.
175222
/// FIXME: Rename DbgLabelRecord when DPValue is renamed to DbgVariableRecord.
176223
class DPLabel : public DbgRecord {
177-
DILabel *Label;
224+
DbgRecordParamRef<DILabel> Label;
178225

179226
public:
180-
DPLabel(DILabel *Label, DebugLoc DL)
181-
: DbgRecord(LabelKind, DL), Label(Label) {
182-
assert(Label && "Unexpected nullptr");
183-
}
227+
DPLabel(DILabel *Label, DebugLoc DL);
184228

185229
DPLabel *clone() const;
186230
void print(raw_ostream &O, bool IsForDebug = false) const;
@@ -189,7 +233,8 @@ class DPLabel : public DbgRecord {
189233
Instruction *InsertBefore) const;
190234

191235
void setLabel(DILabel *NewLabel) { Label = NewLabel; }
192-
DILabel *getLabel() const { return Label; }
236+
DILabel *getLabel() const { return Label.get(); }
237+
MDNode *getRawLabel() const { return Label.getAsMDNode(); };
193238

194239
/// Support type inquiry through isa, cast, and dyn_cast.
195240
static bool classof(const DbgRecord *E) {
@@ -224,9 +269,9 @@ class DPValue : public DbgRecord, protected DebugValueUser {
224269
// DebugValueUser superclass instead. The referred to Value can either be a
225270
// ValueAsMetadata or a DIArgList.
226271

227-
TrackingMDNodeRef Variable;
228-
DIExpression *Expression;
229-
DIExpression *AddressExpression;
272+
DbgRecordParamRef<DILocalVariable> Variable;
273+
DbgRecordParamRef<DIExpression> Expression;
274+
DbgRecordParamRef<DIExpression> AddressExpression;
230275

231276
public:
232277
/// Create a new DPValue representing the intrinsic \p DVI, for example the
@@ -331,10 +376,6 @@ class DPValue : public DbgRecord, protected DebugValueUser {
331376
void addVariableLocationOps(ArrayRef<Value *> NewValues,
332377
DIExpression *NewExpr);
333378

334-
void setVariable(DILocalVariable *NewVar);
335-
336-
void setExpression(DIExpression *NewExpr) { Expression = NewExpr; }
337-
338379
unsigned getNumVariableLocationOps() const;
339380

340381
bool hasArgList() const { return isa<DIArgList>(getRawLocation()); }
@@ -349,10 +390,13 @@ class DPValue : public DbgRecord, protected DebugValueUser {
349390
void setKillLocation();
350391
bool isKillLocation() const;
351392

352-
DILocalVariable *getVariable() const;
353-
MDNode *getRawVariable() const { return Variable; }
393+
void setVariable(DILocalVariable *NewVar) { Variable = NewVar; }
394+
DILocalVariable *getVariable() const { return Variable.get(); };
395+
MDNode *getRawVariable() const { return Variable.getAsMDNode(); }
354396

355-
DIExpression *getExpression() const { return Expression; }
397+
void setExpression(DIExpression *NewExpr) { Expression = NewExpr; }
398+
DIExpression *getExpression() const { return Expression.get(); }
399+
MDNode *getRawExpression() const { return Expression.getAsMDNode(); }
356400

357401
/// Returns the metadata operand for the first location description. i.e.,
358402
/// dbg intrinsic dbg.value,declare operand and dbg.assign 1st location
@@ -401,7 +445,10 @@ class DPValue : public DbgRecord, protected DebugValueUser {
401445
}
402446
Metadata *getRawAssignID() const { return DebugValues[2]; }
403447
DIAssignID *getAssignID() const;
404-
DIExpression *getAddressExpression() const { return AddressExpression; }
448+
DIExpression *getAddressExpression() const { return AddressExpression.get(); }
449+
MDNode *getRawAddressExpression() const {
450+
return AddressExpression.getAsMDNode();
451+
}
405452
void setAddressExpression(DIExpression *NewExpr) {
406453
AddressExpression = NewExpr;
407454
}

llvm/lib/IR/AsmWriter.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,7 +1147,7 @@ void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) {
11471147
if (DPV->isDbgAssign())
11481148
CreateMetadataSlot(cast<MDNode>(DPV->getRawAssignID()));
11491149
} else if (const DPLabel *DPL = dyn_cast<const DPLabel>(&DR)) {
1150-
CreateMetadataSlot(DPL->getLabel());
1150+
CreateMetadataSlot(DPL->getRawLabel());
11511151
} else {
11521152
llvm_unreachable("unsupported DbgRecord kind");
11531153
}
@@ -4631,16 +4631,16 @@ void AssemblyWriter::printDPValue(const DPValue &DPV) {
46314631
Out << "(";
46324632
WriteAsOperandInternal(Out, DPV.getRawLocation(), WriterCtx, true);
46334633
Out << ", ";
4634-
WriteAsOperandInternal(Out, DPV.getVariable(), WriterCtx, true);
4634+
WriteAsOperandInternal(Out, DPV.getRawVariable(), WriterCtx, true);
46354635
Out << ", ";
4636-
WriteAsOperandInternal(Out, DPV.getExpression(), WriterCtx, true);
4636+
WriteAsOperandInternal(Out, DPV.getRawExpression(), WriterCtx, true);
46374637
Out << ", ";
46384638
if (DPV.isDbgAssign()) {
4639-
WriteAsOperandInternal(Out, DPV.getAssignID(), WriterCtx, true);
4639+
WriteAsOperandInternal(Out, DPV.getRawAssignID(), WriterCtx, true);
46404640
Out << ", ";
46414641
WriteAsOperandInternal(Out, DPV.getRawAddress(), WriterCtx, true);
46424642
Out << ", ";
4643-
WriteAsOperandInternal(Out, DPV.getAddressExpression(), WriterCtx, true);
4643+
WriteAsOperandInternal(Out, DPV.getRawAddressExpression(), WriterCtx, true);
46444644
Out << ", ";
46454645
}
46464646
WriteAsOperandInternal(Out, DPV.getDebugLoc().getAsMDNode(), WriterCtx, true);
@@ -4659,7 +4659,9 @@ void AssemblyWriter::printDbgRecordLine(const DbgRecord &DR) {
46594659
void AssemblyWriter::printDPLabel(const DPLabel &Label) {
46604660
auto WriterCtx = getContext();
46614661
Out << "#dbg_label(";
4662-
WriteAsOperandInternal(Out, Label.getLabel(), WriterCtx, true);
4662+
WriteAsOperandInternal(Out, Label.getRawLabel(), WriterCtx, true);
4663+
Out << ", ";
4664+
WriteAsOperandInternal(Out, Label.getDebugLoc(), WriterCtx, true);
46634665
Out << ")";
46644666
}
46654667

llvm/lib/IR/DebugProgramInstruction.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,26 @@
1313

1414
namespace llvm {
1515

16+
template <typename T>
17+
DbgRecordParamRef<T>::DbgRecordParamRef(const T *Param)
18+
: Ref(const_cast<T *>(Param)) {}
19+
template <typename T>
20+
DbgRecordParamRef<T>::DbgRecordParamRef(const MDNode *Param)
21+
: Ref(const_cast<MDNode *>(Param)) {}
22+
23+
template <typename T> T *DbgRecordParamRef<T>::get() const {
24+
return cast<T>(Ref);
25+
}
26+
27+
template class DbgRecordParamRef<DIExpression>;
28+
template class DbgRecordParamRef<DILabel>;
29+
template class DbgRecordParamRef<DILocalVariable>;
30+
1631
DPValue::DPValue(const DbgVariableIntrinsic *DVI)
1732
: DbgRecord(ValueKind, DVI->getDebugLoc()),
1833
DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}),
1934
Variable(DVI->getVariable()), Expression(DVI->getExpression()),
20-
AddressExpression(nullptr) {
35+
AddressExpression() {
2136
switch (DVI->getIntrinsicID()) {
2237
case Intrinsic::dbg_value:
2338
Type = LocationType::Value;
@@ -123,6 +138,11 @@ DbgRecord::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
123138
llvm_unreachable("unsupported DbgRecord kind");
124139
}
125140

141+
DPLabel::DPLabel(DILabel *Label, DebugLoc DL)
142+
: DbgRecord(LabelKind, DL), Label(Label) {
143+
assert(Label && "Unexpected nullptr");
144+
}
145+
126146
DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV,
127147
DIExpression *Expr, const DILocation *DI) {
128148
return new DPValue(ValueAsMetadata::get(Location), DV, Expr, DI,
@@ -175,8 +195,6 @@ DPValue *DPValue::createLinkedDPVAssign(Instruction *LinkedInstr, Value *Val,
175195
return NewDPVAssign;
176196
}
177197

178-
void DPValue::setVariable(DILocalVariable *NewVar) { Variable.reset(NewVar); }
179-
180198
iterator_range<DPValue::location_op_iterator> DPValue::location_ops() const {
181199
auto *MD = getRawLocation();
182200
// If a Value has been deleted, the "location" for this DPValue will be
@@ -315,10 +333,6 @@ bool DPValue::isKillLocation() const {
315333
any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); });
316334
}
317335

318-
DILocalVariable *DPValue::getVariable() const {
319-
return cast<DILocalVariable>(Variable.get());
320-
}
321-
322336
std::optional<uint64_t> DPValue::getFragmentSizeInBits() const {
323337
if (auto Fragment = getExpression()->getFragmentInfo())
324338
return Fragment->SizeInBits;
@@ -337,7 +351,9 @@ DbgRecord *DbgRecord::clone() const {
337351

338352
DPValue *DPValue::clone() const { return new DPValue(*this); }
339353

340-
DPLabel *DPLabel::clone() const { return new DPLabel(Label, getDebugLoc()); }
354+
DPLabel *DPLabel::clone() const {
355+
return new DPLabel(getLabel(), getDebugLoc());
356+
}
341357

342358
DbgVariableIntrinsic *
343359
DPValue::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {

0 commit comments

Comments
 (0)