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