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