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