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