1//=====-- DebugProgramInstruction.cpp - Implement DbgRecords/DbgMarkers --====//
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#include "llvm/IR/DebugProgramInstruction.h"
10#include "llvm/IR/DIBuilder.h"
11#include "llvm/IR/DebugInfoMetadata.h"
12#include "llvm/IR/IntrinsicInst.h"
13#include "llvm/Support/Compiler.h"
14
15using namespace llvm;
16
17namespace llvm {
18template <typename T>
19DbgRecordParamRef<T>::DbgRecordParamRef(const T *Param)
20 : Ref(const_cast<T *>(Param)) {}
21template <typename T>
22DbgRecordParamRef<T>::DbgRecordParamRef(const MDNode *Param)
23 : Ref(const_cast<MDNode *>(Param)) {}
24
25template <typename T> T *DbgRecordParamRef<T>::get() const {
26 return cast<T>(Ref);
27}
28
29template class LLVM_EXPORT_TEMPLATE DbgRecordParamRef<DIExpression>;
30template class LLVM_EXPORT_TEMPLATE DbgRecordParamRef<DILabel>;
31template class LLVM_EXPORT_TEMPLATE DbgRecordParamRef<DILocalVariable>;
32} // namespace llvm
33
34DbgVariableRecord::DbgVariableRecord(const DbgVariableIntrinsic *DVI)
35 : DbgRecord(ValueKind, DVI->getDebugLoc()),
36 DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}),
37 Variable(DVI->getVariable()), Expression(DVI->getExpression()),
38 AddressExpression() {
39 switch (DVI->getIntrinsicID()) {
40 case Intrinsic::dbg_value:
41 Type = LocationType::Value;
42 break;
43 case Intrinsic::dbg_declare:
44 Type = LocationType::Declare;
45 break;
46 case Intrinsic::dbg_assign: {
47 Type = LocationType::Assign;
48 const DbgAssignIntrinsic *Assign =
49 static_cast<const DbgAssignIntrinsic *>(DVI);
50 resetDebugValue(Idx: 1, DebugValue: Assign->getRawAddress());
51 AddressExpression = Assign->getAddressExpression();
52 setAssignId(Assign->getAssignID());
53 break;
54 }
55 default:
56 llvm_unreachable(
57 "Trying to create a DbgVariableRecord with an invalid intrinsic type!");
58 }
59}
60
61DbgVariableRecord::DbgVariableRecord(const DbgVariableRecord &DVR)
62 : DbgRecord(ValueKind, DVR.getDebugLoc()), DebugValueUser(DVR.DebugValues),
63 Type(DVR.getType()), Variable(DVR.getVariable()),
64 Expression(DVR.getExpression()),
65 AddressExpression(DVR.AddressExpression) {}
66
67DbgVariableRecord::DbgVariableRecord(Metadata *Location, DILocalVariable *DV,
68 DIExpression *Expr, const DILocation *DI,
69 LocationType Type)
70 : DbgRecord(ValueKind, DI), DebugValueUser({Location, nullptr, nullptr}),
71 Type(Type), Variable(DV), Expression(Expr) {}
72
73DbgVariableRecord::DbgVariableRecord(Metadata *Value, DILocalVariable *Variable,
74 DIExpression *Expression,
75 DIAssignID *AssignID, Metadata *Address,
76 DIExpression *AddressExpression,
77 const DILocation *DI)
78 : DbgRecord(ValueKind, DI), DebugValueUser({Value, Address, AssignID}),
79 Type(LocationType::Assign), Variable(Variable), Expression(Expression),
80 AddressExpression(AddressExpression) {}
81
82void DbgRecord::deleteRecord() {
83 switch (RecordKind) {
84 case ValueKind:
85 delete cast<DbgVariableRecord>(Val: this);
86 return;
87 case LabelKind:
88 delete cast<DbgLabelRecord>(Val: this);
89 return;
90 }
91 llvm_unreachable("unsupported DbgRecord kind");
92}
93
94void DbgRecord::print(raw_ostream &O, bool IsForDebug) const {
95 switch (RecordKind) {
96 case ValueKind:
97 cast<DbgVariableRecord>(Val: this)->print(O, IsForDebug);
98 return;
99 case LabelKind:
100 cast<DbgLabelRecord>(Val: this)->print(O, IsForDebug);
101 return;
102 };
103 llvm_unreachable("unsupported DbgRecord kind");
104}
105
106void DbgRecord::print(raw_ostream &O, ModuleSlotTracker &MST,
107 bool IsForDebug) const {
108 switch (RecordKind) {
109 case ValueKind:
110 cast<DbgVariableRecord>(Val: this)->print(ROS&: O, MST, IsForDebug);
111 return;
112 case LabelKind:
113 cast<DbgLabelRecord>(Val: this)->print(ROS&: O, MST, IsForDebug);
114 return;
115 };
116 llvm_unreachable("unsupported DbgRecord kind");
117}
118
119bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const {
120 if (RecordKind != R.RecordKind)
121 return false;
122 switch (RecordKind) {
123 case ValueKind:
124 return cast<DbgVariableRecord>(Val: this)->isIdenticalToWhenDefined(
125 Other: *cast<DbgVariableRecord>(Val: &R));
126 case LabelKind:
127 return cast<DbgLabelRecord>(Val: this)->getLabel() ==
128 cast<DbgLabelRecord>(Val: R).getLabel();
129 };
130 llvm_unreachable("unsupported DbgRecord kind");
131}
132
133bool DbgRecord::isEquivalentTo(const DbgRecord &R) const {
134 return getDebugLoc() == R.getDebugLoc() && isIdenticalToWhenDefined(R);
135}
136
137DbgInfoIntrinsic *
138DbgRecord::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
139 switch (RecordKind) {
140 case ValueKind:
141 return cast<DbgVariableRecord>(Val: this)->createDebugIntrinsic(M, InsertBefore);
142 case LabelKind:
143 return cast<DbgLabelRecord>(Val: this)->createDebugIntrinsic(M, InsertBefore);
144 };
145 llvm_unreachable("unsupported DbgRecord kind");
146}
147
148DbgLabelRecord::DbgLabelRecord(MDNode *Label, MDNode *DL)
149 : DbgRecord(LabelKind, DebugLoc(DL)), Label(Label) {
150 assert(Label && "Unexpected nullptr");
151 assert((isa<DILabel>(Label) || Label->isTemporary()) &&
152 "Label type must be or resolve to a DILabel");
153}
154DbgLabelRecord::DbgLabelRecord(DILabel *Label, DebugLoc DL)
155 : DbgRecord(LabelKind, DL), Label(Label) {
156 assert(Label && "Unexpected nullptr");
157}
158
159DbgLabelRecord *DbgLabelRecord::createUnresolvedDbgLabelRecord(MDNode *Label,
160 MDNode *DL) {
161 return new DbgLabelRecord(Label, DL);
162}
163
164DbgVariableRecord::DbgVariableRecord(DbgVariableRecord::LocationType Type,
165 Metadata *Val, MDNode *Variable,
166 MDNode *Expression, MDNode *AssignID,
167 Metadata *Address,
168 MDNode *AddressExpression, MDNode *DI)
169 : DbgRecord(ValueKind, DebugLoc(DI)),
170 DebugValueUser({Val, Address, AssignID}), Type(Type), Variable(Variable),
171 Expression(Expression), AddressExpression(AddressExpression) {}
172
173DbgVariableRecord *DbgVariableRecord::createUnresolvedDbgVariableRecord(
174 DbgVariableRecord::LocationType Type, Metadata *Val, MDNode *Variable,
175 MDNode *Expression, MDNode *AssignID, Metadata *Address,
176 MDNode *AddressExpression, MDNode *DI) {
177 return new DbgVariableRecord(Type, Val, Variable, Expression, AssignID,
178 Address, AddressExpression, DI);
179}
180
181DbgVariableRecord *
182DbgVariableRecord::createDbgVariableRecord(Value *Location, DILocalVariable *DV,
183 DIExpression *Expr,
184 const DILocation *DI) {
185 return new DbgVariableRecord(ValueAsMetadata::get(V: Location), DV, Expr, DI,
186 LocationType::Value);
187}
188
189DbgVariableRecord *DbgVariableRecord::createDbgVariableRecord(
190 Value *Location, DILocalVariable *DV, DIExpression *Expr,
191 const DILocation *DI, DbgVariableRecord &InsertBefore) {
192 auto *NewDbgVariableRecord = createDbgVariableRecord(Location, DV, Expr, DI);
193 NewDbgVariableRecord->insertBefore(InsertBefore: &InsertBefore);
194 return NewDbgVariableRecord;
195}
196
197DbgVariableRecord *DbgVariableRecord::createDVRDeclare(Value *Address,
198 DILocalVariable *DV,
199 DIExpression *Expr,
200 const DILocation *DI) {
201 return new DbgVariableRecord(ValueAsMetadata::get(V: Address), DV, Expr, DI,
202 LocationType::Declare);
203}
204
205DbgVariableRecord *
206DbgVariableRecord::createDVRDeclare(Value *Address, DILocalVariable *DV,
207 DIExpression *Expr, const DILocation *DI,
208 DbgVariableRecord &InsertBefore) {
209 auto *NewDVRDeclare = createDVRDeclare(Address, DV, Expr, DI);
210 NewDVRDeclare->insertBefore(InsertBefore: &InsertBefore);
211 return NewDVRDeclare;
212}
213
214DbgVariableRecord *
215DbgVariableRecord::createDVRDeclareValue(Value *Address, DILocalVariable *DV,
216 DIExpression *Expr,
217 const DILocation *DI) {
218 return new DbgVariableRecord(ValueAsMetadata::get(V: Address), DV, Expr, DI,
219 LocationType::DeclareValue);
220}
221
222DbgVariableRecord *DbgVariableRecord::createDVRDeclareValue(
223 Value *Address, DILocalVariable *DV, DIExpression *Expr,
224 const DILocation *DI, DbgVariableRecord &InsertBefore) {
225 auto *NewDVRCoro = createDVRDeclareValue(Address, DV, Expr, DI);
226 NewDVRCoro->insertBefore(InsertBefore: &InsertBefore);
227 return NewDVRCoro;
228}
229
230DbgVariableRecord *DbgVariableRecord::createDVRAssign(
231 Value *Val, DILocalVariable *Variable, DIExpression *Expression,
232 DIAssignID *AssignID, Value *Address, DIExpression *AddressExpression,
233 const DILocation *DI) {
234 return new DbgVariableRecord(ValueAsMetadata::get(V: Val), Variable, Expression,
235 AssignID, ValueAsMetadata::get(V: Address),
236 AddressExpression, DI);
237}
238
239DbgVariableRecord *DbgVariableRecord::createLinkedDVRAssign(
240 Instruction *LinkedInstr, Value *Val, DILocalVariable *Variable,
241 DIExpression *Expression, Value *Address, DIExpression *AddressExpression,
242 const DILocation *DI) {
243 auto *Link = LinkedInstr->getMetadata(KindID: LLVMContext::MD_DIAssignID);
244 assert(Link && "Linked instruction must have DIAssign metadata attached");
245 auto *NewDVRAssign = DbgVariableRecord::createDVRAssign(
246 Val, Variable, Expression, AssignID: cast<DIAssignID>(Val: Link), Address,
247 AddressExpression, DI);
248 LinkedInstr->getParent()->insertDbgRecordAfter(DR: NewDVRAssign, I: LinkedInstr);
249 return NewDVRAssign;
250}
251
252iterator_range<DbgVariableRecord::location_op_iterator>
253DbgVariableRecord::location_ops() const {
254 auto *MD = getRawLocation();
255 // If a Value has been deleted, the "location" for this DbgVariableRecord will
256 // be replaced by nullptr. Return an empty range.
257 if (!MD)
258 return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
259 location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
260
261 // If operand is ValueAsMetadata, return a range over just that operand.
262 if (auto *VAM = dyn_cast<ValueAsMetadata>(Val: MD))
263 return {location_op_iterator(VAM), location_op_iterator(VAM + 1)};
264
265 // If operand is DIArgList, return a range over its args.
266 if (auto *AL = dyn_cast<DIArgList>(Val: MD))
267 return {location_op_iterator(AL->args_begin()),
268 location_op_iterator(AL->args_end())};
269
270 // Operand is an empty metadata tuple, so return empty iterator.
271 assert(cast<MDNode>(MD)->getNumOperands() == 0);
272 return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
273 location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
274}
275
276unsigned DbgVariableRecord::getNumVariableLocationOps() const {
277 if (hasArgList())
278 return cast<DIArgList>(Val: getRawLocation())->getArgs().size();
279 return 1;
280}
281
282Value *DbgVariableRecord::getVariableLocationOp(unsigned OpIdx) const {
283 auto *MD = getRawLocation();
284 if (!MD)
285 return nullptr;
286
287 if (auto *AL = dyn_cast<DIArgList>(Val: MD))
288 return AL->getArgs()[OpIdx]->getValue();
289 if (isa<MDNode>(Val: MD))
290 return nullptr;
291 assert(isa<ValueAsMetadata>(MD) &&
292 "Attempted to get location operand from DbgVariableRecord with none.");
293 auto *V = cast<ValueAsMetadata>(Val: MD);
294 assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a "
295 "single location operand.");
296 return V->getValue();
297}
298
299static ValueAsMetadata *getAsMetadata(Value *V) {
300 return isa<MetadataAsValue>(Val: V) ? dyn_cast<ValueAsMetadata>(
301 Val: cast<MetadataAsValue>(Val: V)->getMetadata())
302 : ValueAsMetadata::get(V);
303}
304
305void DbgVariableRecord::replaceVariableLocationOp(Value *OldValue,
306 Value *NewValue,
307 bool AllowEmpty) {
308 assert(NewValue && "Values must be non-null");
309
310 bool DbgAssignAddrReplaced = isDbgAssign() && OldValue == getAddress();
311 if (DbgAssignAddrReplaced)
312 setAddress(NewValue);
313
314 auto Locations = location_ops();
315 auto OldIt = find(Range&: Locations, Val: OldValue);
316 if (OldIt == Locations.end()) {
317 if (AllowEmpty || DbgAssignAddrReplaced)
318 return;
319 llvm_unreachable("OldValue must be a current location");
320 }
321
322 if (!hasArgList()) {
323 // Set our location to be the MAV wrapping the new Value.
324 setRawLocation(isa<MetadataAsValue>(Val: NewValue)
325 ? cast<MetadataAsValue>(Val: NewValue)->getMetadata()
326 : ValueAsMetadata::get(V: NewValue));
327 return;
328 }
329
330 // We must be referring to a DIArgList, produce a new operands vector with the
331 // old value replaced, generate a new DIArgList and set it as our location.
332 SmallVector<ValueAsMetadata *, 4> MDs;
333 ValueAsMetadata *NewOperand = getAsMetadata(V: NewValue);
334 for (auto *VMD : Locations)
335 MDs.push_back(Elt: VMD == *OldIt ? NewOperand : getAsMetadata(V: VMD));
336 setRawLocation(DIArgList::get(Context&: getVariableLocationOp(OpIdx: 0)->getContext(), Args: MDs));
337}
338
339void DbgVariableRecord::replaceVariableLocationOp(unsigned OpIdx,
340 Value *NewValue) {
341 assert(OpIdx < getNumVariableLocationOps() && "Invalid Operand Index");
342
343 if (!hasArgList()) {
344 setRawLocation(isa<MetadataAsValue>(Val: NewValue)
345 ? cast<MetadataAsValue>(Val: NewValue)->getMetadata()
346 : ValueAsMetadata::get(V: NewValue));
347 return;
348 }
349
350 SmallVector<ValueAsMetadata *, 4> MDs;
351 ValueAsMetadata *NewOperand = getAsMetadata(V: NewValue);
352 for (unsigned Idx = 0; Idx < getNumVariableLocationOps(); ++Idx)
353 MDs.push_back(Elt: Idx == OpIdx ? NewOperand
354 : getAsMetadata(V: getVariableLocationOp(OpIdx: Idx)));
355
356 setRawLocation(DIArgList::get(Context&: getVariableLocationOp(OpIdx: 0)->getContext(), Args: MDs));
357}
358
359void DbgVariableRecord::addVariableLocationOps(ArrayRef<Value *> NewValues,
360 DIExpression *NewExpr) {
361 assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() +
362 NewValues.size()) &&
363 "NewExpr for debug variable intrinsic does not reference every "
364 "location operand.");
365 assert(!is_contained(NewValues, nullptr) && "New values must be non-null");
366 setExpression(NewExpr);
367 SmallVector<ValueAsMetadata *, 4> MDs;
368 for (auto *VMD : location_ops())
369 MDs.push_back(Elt: getAsMetadata(V: VMD));
370 for (auto *VMD : NewValues)
371 MDs.push_back(Elt: getAsMetadata(V: VMD));
372 setRawLocation(DIArgList::get(Context&: getVariableLocationOp(OpIdx: 0)->getContext(), Args: MDs));
373}
374
375void DbgVariableRecord::setKillLocation() {
376 // TODO: When/if we remove duplicate values from DIArgLists, we don't need
377 // this set anymore.
378 SmallPtrSet<Value *, 4> RemovedValues;
379 for (Value *OldValue : location_ops()) {
380 if (!RemovedValues.insert(Ptr: OldValue).second)
381 continue;
382 Value *Poison = PoisonValue::get(T: OldValue->getType());
383 replaceVariableLocationOp(OldValue, NewValue: Poison);
384 }
385}
386
387bool DbgVariableRecord::isKillLocation() const {
388 return (!hasArgList() && isa<MDNode>(Val: getRawLocation())) ||
389 (getNumVariableLocationOps() == 0 && !getExpression()->isComplex()) ||
390 any_of(Range: location_ops(), P: [](Value *V) { return isa<UndefValue>(Val: V); });
391}
392
393std::optional<DbgVariableFragmentInfo> DbgVariableRecord::getFragment() const {
394 return getExpression()->getFragmentInfo();
395}
396
397std::optional<uint64_t> DbgVariableRecord::getFragmentSizeInBits() const {
398 if (auto Fragment = getExpression()->getFragmentInfo())
399 return Fragment->SizeInBits;
400 return getVariable()->getSizeInBits();
401}
402
403DbgRecord *DbgRecord::clone() const {
404 switch (RecordKind) {
405 case ValueKind:
406 return cast<DbgVariableRecord>(Val: this)->clone();
407 case LabelKind:
408 return cast<DbgLabelRecord>(Val: this)->clone();
409 };
410 llvm_unreachable("unsupported DbgRecord kind");
411}
412
413DbgVariableRecord *DbgVariableRecord::clone() const {
414 return new DbgVariableRecord(*this);
415}
416
417DbgLabelRecord *DbgLabelRecord::clone() const {
418 return new DbgLabelRecord(getLabel(), getDebugLoc());
419}
420
421DbgVariableIntrinsic *
422DbgVariableRecord::createDebugIntrinsic(Module *M,
423 Instruction *InsertBefore) const {
424 [[maybe_unused]] DICompileUnit *Unit =
425 getDebugLoc()->getScope()->getSubprogram()->getUnit();
426 assert(M && Unit &&
427 "Cannot clone from BasicBlock that is not part of a Module or "
428 "DICompileUnit!");
429 LLVMContext &Context = getDebugLoc()->getContext();
430 Function *IntrinsicFn;
431
432 // Work out what sort of intrinsic we're going to produce.
433 switch (getType()) {
434 case DbgVariableRecord::LocationType::Declare:
435 IntrinsicFn = Intrinsic::getOrInsertDeclaration(M, id: Intrinsic::dbg_declare);
436 break;
437 case DbgVariableRecord::LocationType::Value:
438 IntrinsicFn = Intrinsic::getOrInsertDeclaration(M, id: Intrinsic::dbg_value);
439 break;
440 case DbgVariableRecord::LocationType::Assign:
441 IntrinsicFn = Intrinsic::getOrInsertDeclaration(M, id: Intrinsic::dbg_assign);
442 break;
443 case DbgVariableRecord::LocationType::End:
444 case DbgVariableRecord::LocationType::Any:
445 llvm_unreachable("Invalid LocationType");
446 break;
447 case DbgVariableRecord::LocationType::DeclareValue:
448 llvm_unreachable(
449 "#dbg_declare_value should never be converted to an intrinsic");
450 }
451
452 // Create the intrinsic from this DbgVariableRecord's information, optionally
453 // insert into the target location.
454 DbgVariableIntrinsic *DVI;
455 assert(getRawLocation() &&
456 "DbgVariableRecord's RawLocation should be non-null.");
457 if (isDbgAssign()) {
458 Value *AssignArgs[] = {
459 MetadataAsValue::get(Context, MD: getRawLocation()),
460 MetadataAsValue::get(Context, MD: getVariable()),
461 MetadataAsValue::get(Context, MD: getExpression()),
462 MetadataAsValue::get(Context, MD: getAssignID()),
463 MetadataAsValue::get(Context, MD: getRawAddress()),
464 MetadataAsValue::get(Context, MD: getAddressExpression())};
465 DVI = cast<DbgVariableIntrinsic>(Val: CallInst::Create(
466 Ty: IntrinsicFn->getFunctionType(), Func: IntrinsicFn, Args: AssignArgs));
467 } else {
468 Value *Args[] = {MetadataAsValue::get(Context, MD: getRawLocation()),
469 MetadataAsValue::get(Context, MD: getVariable()),
470 MetadataAsValue::get(Context, MD: getExpression())};
471 DVI = cast<DbgVariableIntrinsic>(
472 Val: CallInst::Create(Ty: IntrinsicFn->getFunctionType(), Func: IntrinsicFn, Args));
473 }
474 DVI->setTailCall();
475 DVI->setDebugLoc(getDebugLoc());
476 if (InsertBefore)
477 DVI->insertBefore(InsertPos: InsertBefore->getIterator());
478
479 return DVI;
480}
481
482DbgLabelInst *
483DbgLabelRecord::createDebugIntrinsic(Module *M,
484 Instruction *InsertBefore) const {
485 auto *LabelFn = Intrinsic::getOrInsertDeclaration(M, id: Intrinsic::dbg_label);
486 Value *Args[] = {
487 MetadataAsValue::get(Context&: getDebugLoc()->getContext(), MD: getLabel())};
488 DbgLabelInst *DbgLabel = cast<DbgLabelInst>(
489 Val: CallInst::Create(Ty: LabelFn->getFunctionType(), Func: LabelFn, Args));
490 DbgLabel->setTailCall();
491 DbgLabel->setDebugLoc(getDebugLoc());
492 if (InsertBefore)
493 DbgLabel->insertBefore(InsertPos: InsertBefore->getIterator());
494 return DbgLabel;
495}
496
497Value *DbgVariableRecord::getAddress() const {
498 auto *MD = getRawAddress();
499 if (auto *V = dyn_cast_or_null<ValueAsMetadata>(Val: MD))
500 return V->getValue();
501
502 // When the value goes to null, it gets replaced by an empty MDNode.
503 assert((!MD || !cast<MDNode>(MD)->getNumOperands()) &&
504 "Expected an empty MDNode");
505 return nullptr;
506}
507
508DIAssignID *DbgVariableRecord::getAssignID() const {
509 return cast<DIAssignID>(Val: DebugValues[2]);
510}
511
512void DbgVariableRecord::setAssignId(DIAssignID *New) {
513 resetDebugValue(Idx: 2, DebugValue: New);
514}
515
516void DbgVariableRecord::setKillAddress() {
517 resetDebugValue(
518 Idx: 1, DebugValue: ValueAsMetadata::get(V: PoisonValue::get(T: getAddress()->getType())));
519}
520
521bool DbgVariableRecord::isKillAddress() const {
522 Value *Addr = getAddress();
523 return !Addr || isa<UndefValue>(Val: Addr);
524}
525
526const Instruction *DbgRecord::getInstruction() const {
527 return Marker->MarkedInstr;
528}
529
530const BasicBlock *DbgRecord::getParent() const {
531 return Marker->MarkedInstr->getParent();
532}
533
534BasicBlock *DbgRecord::getParent() { return Marker->MarkedInstr->getParent(); }
535
536BasicBlock *DbgRecord::getBlock() { return Marker->getParent(); }
537
538const BasicBlock *DbgRecord::getBlock() const { return Marker->getParent(); }
539
540Function *DbgRecord::getFunction() { return getBlock()->getParent(); }
541
542const Function *DbgRecord::getFunction() const {
543 return getBlock()->getParent();
544}
545
546Module *DbgRecord::getModule() { return getFunction()->getParent(); }
547
548const Module *DbgRecord::getModule() const {
549 return getFunction()->getParent();
550}
551
552LLVMContext &DbgRecord::getContext() { return getBlock()->getContext(); }
553
554const LLVMContext &DbgRecord::getContext() const {
555 return getBlock()->getContext();
556}
557
558void DbgRecord::insertBefore(DbgRecord *InsertBefore) {
559 assert(!getMarker() &&
560 "Cannot insert a DbgRecord that is already has a DbgMarker!");
561 assert(InsertBefore->getMarker() &&
562 "Cannot insert a DbgRecord before a DbgRecord that does not have a "
563 "DbgMarker!");
564 InsertBefore->getMarker()->insertDbgRecord(New: this, InsertBefore);
565}
566void DbgRecord::insertAfter(DbgRecord *InsertAfter) {
567 assert(!getMarker() &&
568 "Cannot insert a DbgRecord that is already has a DbgMarker!");
569 assert(InsertAfter->getMarker() &&
570 "Cannot insert a DbgRecord after a DbgRecord that does not have a "
571 "DbgMarker!");
572 InsertAfter->getMarker()->insertDbgRecordAfter(New: this, InsertAfter);
573}
574
575void DbgRecord::insertBefore(self_iterator InsertBefore) {
576 assert(!getMarker() &&
577 "Cannot insert a DbgRecord that is already has a DbgMarker!");
578 assert(InsertBefore->getMarker() &&
579 "Cannot insert a DbgRecord before a DbgRecord that does not have a "
580 "DbgMarker!");
581 InsertBefore->getMarker()->insertDbgRecord(New: this, InsertBefore: &*InsertBefore);
582}
583void DbgRecord::insertAfter(self_iterator InsertAfter) {
584 assert(!getMarker() &&
585 "Cannot insert a DbgRecord that is already has a DbgMarker!");
586 assert(InsertAfter->getMarker() &&
587 "Cannot insert a DbgRecord after a DbgRecord that does not have a "
588 "DbgMarker!");
589 InsertAfter->getMarker()->insertDbgRecordAfter(New: this, InsertAfter: &*InsertAfter);
590}
591
592void DbgRecord::moveBefore(DbgRecord *MoveBefore) {
593 assert(getMarker() &&
594 "Canot move a DbgRecord that does not currently have a DbgMarker!");
595 removeFromParent();
596 insertBefore(InsertBefore: MoveBefore);
597}
598void DbgRecord::moveAfter(DbgRecord *MoveAfter) {
599 assert(getMarker() &&
600 "Canot move a DbgRecord that does not currently have a DbgMarker!");
601 removeFromParent();
602 insertAfter(InsertAfter: MoveAfter);
603}
604
605void DbgRecord::moveBefore(self_iterator MoveBefore) {
606 assert(getMarker() &&
607 "Canot move a DbgRecord that does not currently have a DbgMarker!");
608 removeFromParent();
609 insertBefore(InsertBefore: MoveBefore);
610}
611void DbgRecord::moveAfter(self_iterator MoveAfter) {
612 assert(getMarker() &&
613 "Canot move a DbgRecord that does not currently have a DbgMarker!");
614 removeFromParent();
615 insertAfter(InsertAfter: MoveAfter);
616}
617
618///////////////////////////////////////////////////////////////////////////////
619
620// An empty, global, DbgMarker for the purpose of describing empty ranges of
621// DbgRecords.
622DbgMarker DbgMarker::EmptyDbgMarker;
623
624void DbgMarker::dropDbgRecords() {
625 while (!StoredDbgRecords.empty()) {
626 auto It = StoredDbgRecords.begin();
627 DbgRecord *DR = &*It;
628 StoredDbgRecords.erase(I: It);
629 DR->deleteRecord();
630 }
631}
632
633void DbgMarker::dropOneDbgRecord(DbgRecord *DR) {
634 assert(DR->getMarker() == this);
635 StoredDbgRecords.erase(I: DR->getIterator());
636 DR->deleteRecord();
637}
638
639const BasicBlock *DbgMarker::getParent() const {
640 return MarkedInstr->getParent();
641}
642
643BasicBlock *DbgMarker::getParent() { return MarkedInstr->getParent(); }
644
645void DbgMarker::removeMarker() {
646 // Are there any DbgRecords in this DbgMarker? If not, nothing to preserve.
647 Instruction *Owner = MarkedInstr;
648 if (StoredDbgRecords.empty()) {
649 eraseFromParent();
650 Owner->DebugMarker = nullptr;
651 return;
652 }
653
654 // The attached DbgRecords need to be preserved; attach them to the next
655 // instruction. If there isn't a next instruction, put them on the
656 // "trailing" list.
657 DbgMarker *NextMarker = Owner->getParent()->getNextMarker(I: Owner);
658 if (NextMarker) {
659 NextMarker->absorbDebugValues(Src&: *this, InsertAtHead: true);
660 eraseFromParent();
661 } else {
662 // We can avoid a deallocation -- just store this marker onto the next
663 // instruction. Unless we're at the end of the block, in which case this
664 // marker becomes the trailing marker of a degenerate block.
665 BasicBlock::iterator NextIt = std::next(x: Owner->getIterator());
666 if (NextIt == getParent()->end()) {
667 getParent()->setTrailingDbgRecords(this);
668 MarkedInstr = nullptr;
669 } else {
670 NextIt->DebugMarker = this;
671 MarkedInstr = &*NextIt;
672 }
673 }
674 Owner->DebugMarker = nullptr;
675}
676
677void DbgMarker::removeFromParent() {
678 MarkedInstr->DebugMarker = nullptr;
679 MarkedInstr = nullptr;
680}
681
682void DbgMarker::eraseFromParent() {
683 if (MarkedInstr)
684 removeFromParent();
685 dropDbgRecords();
686 delete this;
687}
688
689iterator_range<DbgRecord::self_iterator> DbgMarker::getDbgRecordRange() {
690 return StoredDbgRecords;
691}
692iterator_range<DbgRecord::const_self_iterator>
693DbgMarker::getDbgRecordRange() const {
694 return StoredDbgRecords;
695}
696
697void DbgRecord::removeFromParent() {
698 getMarker()->StoredDbgRecords.erase(I: getIterator());
699 Marker = nullptr;
700}
701
702void DbgRecord::eraseFromParent() {
703 removeFromParent();
704 deleteRecord();
705}
706
707void DbgMarker::insertDbgRecord(DbgRecord *New, bool InsertAtHead) {
708 auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end();
709 StoredDbgRecords.insert(I: It, Node&: *New);
710 New->setMarker(this);
711}
712void DbgMarker::insertDbgRecord(DbgRecord *New, DbgRecord *InsertBefore) {
713 assert(InsertBefore->getMarker() == this &&
714 "DbgRecord 'InsertBefore' must be contained in this DbgMarker!");
715 StoredDbgRecords.insert(I: InsertBefore->getIterator(), Node&: *New);
716 New->setMarker(this);
717}
718void DbgMarker::insertDbgRecordAfter(DbgRecord *New, DbgRecord *InsertAfter) {
719 assert(InsertAfter->getMarker() == this &&
720 "DbgRecord 'InsertAfter' must be contained in this DbgMarker!");
721 StoredDbgRecords.insert(I: ++(InsertAfter->getIterator()), Node&: *New);
722 New->setMarker(this);
723}
724
725void DbgMarker::absorbDebugValues(DbgMarker &Src, bool InsertAtHead) {
726 auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end();
727 for (DbgRecord &DVR : Src.StoredDbgRecords)
728 DVR.setMarker(this);
729
730 StoredDbgRecords.splice(I: It, L2&: Src.StoredDbgRecords);
731}
732
733void DbgMarker::absorbDebugValues(
734 iterator_range<DbgRecord::self_iterator> Range, DbgMarker &Src,
735 bool InsertAtHead) {
736 for (DbgRecord &DR : Range)
737 DR.setMarker(this);
738
739 auto InsertPos =
740 (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end();
741
742 StoredDbgRecords.splice(I: InsertPos, Src.StoredDbgRecords, First: Range.begin(),
743 Last: Range.end());
744}
745
746iterator_range<simple_ilist<DbgRecord>::iterator> DbgMarker::cloneDebugInfoFrom(
747 DbgMarker *From, std::optional<simple_ilist<DbgRecord>::iterator> from_here,
748 bool InsertAtHead) {
749 DbgRecord *First = nullptr;
750 // Work out what range of DbgRecords to clone: normally all the contents of
751 // the "From" marker, optionally we can start from the from_here position down
752 // to end().
753 auto Range =
754 make_range(x: From->StoredDbgRecords.begin(), y: From->StoredDbgRecords.end());
755 if (from_here.has_value())
756 Range = make_range(x: *from_here, y: From->StoredDbgRecords.end());
757
758 // Clone each DbgVariableRecord and insert into StoreDbgVariableRecords;
759 // optionally place them at the start or the end of the list.
760 auto Pos = (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end();
761 for (DbgRecord &DR : Range) {
762 DbgRecord *New = DR.clone();
763 New->setMarker(this);
764 StoredDbgRecords.insert(I: Pos, Node&: *New);
765 if (!First)
766 First = New;
767 }
768
769 if (!First)
770 return {StoredDbgRecords.end(), StoredDbgRecords.end()};
771
772 if (InsertAtHead)
773 // If InsertAtHead is set, we cloned a range onto the front of of the
774 // StoredDbgRecords collection, return that range.
775 return {StoredDbgRecords.begin(), Pos};
776 else
777 // We inserted a block at the end, return that range.
778 return {First->getIterator(), StoredDbgRecords.end()};
779}
780