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 (getNumVariableLocationOps() == 0 &&
370 !getExpression()->isComplex()) ||
371 any_of(Range: location_ops(), P: [](Value *V) { return isa<UndefValue>(Val: V); });
372}
373
374std::optional<uint64_t> DbgVariableRecord::getFragmentSizeInBits() const {
375 if (auto Fragment = getExpression()->getFragmentInfo())
376 return Fragment->SizeInBits;
377 return getVariable()->getSizeInBits();
378}
379
380DbgRecord *DbgRecord::clone() const {
381 switch (RecordKind) {
382 case ValueKind:
383 return cast<DbgVariableRecord>(Val: this)->clone();
384 case LabelKind:
385 return cast<DbgLabelRecord>(Val: this)->clone();
386 };
387 llvm_unreachable("unsupported DbgRecord kind");
388}
389
390DbgVariableRecord *DbgVariableRecord::clone() const {
391 return new DbgVariableRecord(*this);
392}
393
394DbgLabelRecord *DbgLabelRecord::clone() const {
395 return new DbgLabelRecord(getLabel(), getDebugLoc());
396}
397
398DbgVariableIntrinsic *
399DbgVariableRecord::createDebugIntrinsic(Module *M,
400 Instruction *InsertBefore) const {
401 [[maybe_unused]] DICompileUnit *Unit =
402 getDebugLoc().get()->getScope()->getSubprogram()->getUnit();
403 assert(M && Unit &&
404 "Cannot clone from BasicBlock that is not part of a Module or "
405 "DICompileUnit!");
406 LLVMContext &Context = getDebugLoc()->getContext();
407 Function *IntrinsicFn;
408
409 // Work out what sort of intrinsic we're going to produce.
410 switch (getType()) {
411 case DbgVariableRecord::LocationType::Declare:
412 IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::id: dbg_declare);
413 break;
414 case DbgVariableRecord::LocationType::Value:
415 IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::id: dbg_value);
416 break;
417 case DbgVariableRecord::LocationType::Assign:
418 IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::id: dbg_assign);
419 break;
420 case DbgVariableRecord::LocationType::End:
421 case DbgVariableRecord::LocationType::Any:
422 llvm_unreachable("Invalid LocationType");
423 }
424
425 // Create the intrinsic from this DbgVariableRecord's information, optionally
426 // insert into the target location.
427 DbgVariableIntrinsic *DVI;
428 assert(getRawLocation() &&
429 "DbgVariableRecord's RawLocation should be non-null.");
430 if (isDbgAssign()) {
431 Value *AssignArgs[] = {
432 MetadataAsValue::get(Context, MD: getRawLocation()),
433 MetadataAsValue::get(Context, MD: getVariable()),
434 MetadataAsValue::get(Context, MD: getExpression()),
435 MetadataAsValue::get(Context, MD: getAssignID()),
436 MetadataAsValue::get(Context, MD: getRawAddress()),
437 MetadataAsValue::get(Context, MD: getAddressExpression())};
438 DVI = cast<DbgVariableIntrinsic>(Val: CallInst::Create(
439 Ty: IntrinsicFn->getFunctionType(), Func: IntrinsicFn, Args: AssignArgs));
440 } else {
441 Value *Args[] = {MetadataAsValue::get(Context, MD: getRawLocation()),
442 MetadataAsValue::get(Context, MD: getVariable()),
443 MetadataAsValue::get(Context, MD: getExpression())};
444 DVI = cast<DbgVariableIntrinsic>(
445 Val: CallInst::Create(Ty: IntrinsicFn->getFunctionType(), Func: IntrinsicFn, Args));
446 }
447 DVI->setTailCall();
448 DVI->setDebugLoc(getDebugLoc());
449 if (InsertBefore)
450 DVI->insertBefore(InsertPos: InsertBefore);
451
452 return DVI;
453}
454
455DbgLabelInst *
456DbgLabelRecord::createDebugIntrinsic(Module *M,
457 Instruction *InsertBefore) const {
458 auto *LabelFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_label);
459 Value *Args[] = {
460 MetadataAsValue::get(Context&: getDebugLoc()->getContext(), MD: getLabel())};
461 DbgLabelInst *DbgLabel = cast<DbgLabelInst>(
462 CallInst::Create(LabelFn->getFunctionType(), LabelFn, Args));
463 DbgLabel->setTailCall();
464 DbgLabel->setDebugLoc(getDebugLoc());
465 if (InsertBefore)
466 DbgLabel->insertBefore(InsertPos: InsertBefore);
467 return DbgLabel;
468}
469
470Value *DbgVariableRecord::getAddress() const {
471 auto *MD = getRawAddress();
472 if (auto *V = dyn_cast<ValueAsMetadata>(Val: MD))
473 return V->getValue();
474
475 // When the value goes to null, it gets replaced by an empty MDNode.
476 assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");
477 return nullptr;
478}
479
480DIAssignID *DbgVariableRecord::getAssignID() const {
481 return cast<DIAssignID>(Val: DebugValues[2]);
482}
483
484void DbgVariableRecord::setAssignId(DIAssignID *New) {
485 resetDebugValue(Idx: 2, DebugValue: New);
486}
487
488void DbgVariableRecord::setKillAddress() {
489 resetDebugValue(
490 Idx: 1, DebugValue: ValueAsMetadata::get(V: UndefValue::get(T: getAddress()->getType())));
491}
492
493bool DbgVariableRecord::isKillAddress() const {
494 Value *Addr = getAddress();
495 return !Addr || isa<UndefValue>(Val: Addr);
496}
497
498const Instruction *DbgRecord::getInstruction() const {
499 return Marker->MarkedInstr;
500}
501
502const BasicBlock *DbgRecord::getParent() const {
503 return Marker->MarkedInstr->getParent();
504}
505
506BasicBlock *DbgRecord::getParent() { return Marker->MarkedInstr->getParent(); }
507
508BasicBlock *DbgRecord::getBlock() { return Marker->getParent(); }
509
510const BasicBlock *DbgRecord::getBlock() const { return Marker->getParent(); }
511
512Function *DbgRecord::getFunction() { return getBlock()->getParent(); }
513
514const Function *DbgRecord::getFunction() const {
515 return getBlock()->getParent();
516}
517
518Module *DbgRecord::getModule() { return getFunction()->getParent(); }
519
520const Module *DbgRecord::getModule() const {
521 return getFunction()->getParent();
522}
523
524LLVMContext &DbgRecord::getContext() { return getBlock()->getContext(); }
525
526const LLVMContext &DbgRecord::getContext() const {
527 return getBlock()->getContext();
528}
529
530void DbgRecord::insertBefore(DbgRecord *InsertBefore) {
531 assert(!getMarker() &&
532 "Cannot insert a DbgRecord that is already has a DbgMarker!");
533 assert(InsertBefore->getMarker() &&
534 "Cannot insert a DbgRecord before a DbgRecord that does not have a "
535 "DbgMarker!");
536 InsertBefore->getMarker()->insertDbgRecord(New: this, InsertBefore);
537}
538void DbgRecord::insertAfter(DbgRecord *InsertAfter) {
539 assert(!getMarker() &&
540 "Cannot insert a DbgRecord that is already has a DbgMarker!");
541 assert(InsertAfter->getMarker() &&
542 "Cannot insert a DbgRecord after a DbgRecord that does not have a "
543 "DbgMarker!");
544 InsertAfter->getMarker()->insertDbgRecordAfter(New: this, InsertAfter);
545}
546void DbgRecord::moveBefore(DbgRecord *MoveBefore) {
547 assert(getMarker() &&
548 "Canot move a DbgRecord that does not currently have a DbgMarker!");
549 removeFromParent();
550 insertBefore(InsertBefore: MoveBefore);
551}
552void DbgRecord::moveAfter(DbgRecord *MoveAfter) {
553 assert(getMarker() &&
554 "Canot move a DbgRecord that does not currently have a DbgMarker!");
555 removeFromParent();
556 insertAfter(InsertAfter: MoveAfter);
557}
558
559///////////////////////////////////////////////////////////////////////////////
560
561// An empty, global, DbgMarker for the purpose of describing empty ranges of
562// DbgRecords.
563DbgMarker DbgMarker::EmptyDbgMarker;
564
565void DbgMarker::dropDbgRecords() {
566 while (!StoredDbgRecords.empty()) {
567 auto It = StoredDbgRecords.begin();
568 DbgRecord *DR = &*It;
569 StoredDbgRecords.erase(I: It);
570 DR->deleteRecord();
571 }
572}
573
574void DbgMarker::dropOneDbgRecord(DbgRecord *DR) {
575 assert(DR->getMarker() == this);
576 StoredDbgRecords.erase(I: DR->getIterator());
577 DR->deleteRecord();
578}
579
580const BasicBlock *DbgMarker::getParent() const {
581 return MarkedInstr->getParent();
582}
583
584BasicBlock *DbgMarker::getParent() { return MarkedInstr->getParent(); }
585
586void DbgMarker::removeMarker() {
587 // Are there any DbgRecords in this DbgMarker? If not, nothing to preserve.
588 Instruction *Owner = MarkedInstr;
589 if (StoredDbgRecords.empty()) {
590 eraseFromParent();
591 Owner->DebugMarker = nullptr;
592 return;
593 }
594
595 // The attached DbgRecords need to be preserved; attach them to the next
596 // instruction. If there isn't a next instruction, put them on the
597 // "trailing" list.
598 DbgMarker *NextMarker = Owner->getParent()->getNextMarker(I: Owner);
599 if (NextMarker) {
600 NextMarker->absorbDebugValues(Src&: *this, InsertAtHead: true);
601 eraseFromParent();
602 } else {
603 // We can avoid a deallocation -- just store this marker onto the next
604 // instruction. Unless we're at the end of the block, in which case this
605 // marker becomes the trailing marker of a degenerate block.
606 BasicBlock::iterator NextIt = std::next(x: Owner->getIterator());
607 if (NextIt == getParent()->end()) {
608 getParent()->setTrailingDbgRecords(this);
609 MarkedInstr = nullptr;
610 } else {
611 NextIt->DebugMarker = this;
612 MarkedInstr = &*NextIt;
613 }
614 }
615 Owner->DebugMarker = nullptr;
616}
617
618void DbgMarker::removeFromParent() {
619 MarkedInstr->DebugMarker = nullptr;
620 MarkedInstr = nullptr;
621}
622
623void DbgMarker::eraseFromParent() {
624 if (MarkedInstr)
625 removeFromParent();
626 dropDbgRecords();
627 delete this;
628}
629
630iterator_range<DbgRecord::self_iterator> DbgMarker::getDbgRecordRange() {
631 return make_range(x: StoredDbgRecords.begin(), y: StoredDbgRecords.end());
632}
633iterator_range<DbgRecord::const_self_iterator>
634DbgMarker::getDbgRecordRange() const {
635 return make_range(x: StoredDbgRecords.begin(), y: StoredDbgRecords.end());
636}
637
638void DbgRecord::removeFromParent() {
639 getMarker()->StoredDbgRecords.erase(I: getIterator());
640 Marker = nullptr;
641}
642
643void DbgRecord::eraseFromParent() {
644 removeFromParent();
645 deleteRecord();
646}
647
648void DbgMarker::insertDbgRecord(DbgRecord *New, bool InsertAtHead) {
649 auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end();
650 StoredDbgRecords.insert(I: It, Node&: *New);
651 New->setMarker(this);
652}
653void DbgMarker::insertDbgRecord(DbgRecord *New, DbgRecord *InsertBefore) {
654 assert(InsertBefore->getMarker() == this &&
655 "DbgRecord 'InsertBefore' must be contained in this DbgMarker!");
656 StoredDbgRecords.insert(I: InsertBefore->getIterator(), Node&: *New);
657 New->setMarker(this);
658}
659void DbgMarker::insertDbgRecordAfter(DbgRecord *New, DbgRecord *InsertAfter) {
660 assert(InsertAfter->getMarker() == this &&
661 "DbgRecord 'InsertAfter' must be contained in this DbgMarker!");
662 StoredDbgRecords.insert(I: ++(InsertAfter->getIterator()), Node&: *New);
663 New->setMarker(this);
664}
665
666void DbgMarker::absorbDebugValues(DbgMarker &Src, bool InsertAtHead) {
667 auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end();
668 for (DbgRecord &DVR : Src.StoredDbgRecords)
669 DVR.setMarker(this);
670
671 StoredDbgRecords.splice(I: It, L2&: Src.StoredDbgRecords);
672}
673
674void DbgMarker::absorbDebugValues(
675 iterator_range<DbgRecord::self_iterator> Range, DbgMarker &Src,
676 bool InsertAtHead) {
677 for (DbgRecord &DR : Range)
678 DR.setMarker(this);
679
680 auto InsertPos =
681 (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end();
682
683 StoredDbgRecords.splice(I: InsertPos, Src.StoredDbgRecords, First: Range.begin(),
684 Last: Range.end());
685}
686
687iterator_range<simple_ilist<DbgRecord>::iterator> DbgMarker::cloneDebugInfoFrom(
688 DbgMarker *From, std::optional<simple_ilist<DbgRecord>::iterator> from_here,
689 bool InsertAtHead) {
690 DbgRecord *First = nullptr;
691 // Work out what range of DbgRecords to clone: normally all the contents of
692 // the "From" marker, optionally we can start from the from_here position down
693 // to end().
694 auto Range =
695 make_range(x: From->StoredDbgRecords.begin(), y: From->StoredDbgRecords.end());
696 if (from_here.has_value())
697 Range = make_range(x: *from_here, y: From->StoredDbgRecords.end());
698
699 // Clone each DbgVariableRecord and insert into StoreDbgVariableRecords;
700 // optionally place them at the start or the end of the list.
701 auto Pos = (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end();
702 for (DbgRecord &DR : Range) {
703 DbgRecord *New = DR.clone();
704 New->setMarker(this);
705 StoredDbgRecords.insert(I: Pos, Node&: *New);
706 if (!First)
707 First = New;
708 }
709
710 if (!First)
711 return {StoredDbgRecords.end(), StoredDbgRecords.end()};
712
713 if (InsertAtHead)
714 // If InsertAtHead is set, we cloned a range onto the front of of the
715 // StoredDbgRecords collection, return that range.
716 return {StoredDbgRecords.begin(), Pos};
717 else
718 // We inserted a block at the end, return that range.
719 return {First->getIterator(), StoredDbgRecords.end()};
720}
721
722} // end namespace llvm
723

source code of llvm/lib/IR/DebugProgramInstruction.cpp