1 //======-- DebugProgramInstruction.cpp - Implement DPValues/DPMarkers --======//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/IR/DebugInfoMetadata.h"
10 #include "llvm/IR/DebugProgramInstruction.h"
11 #include "llvm/IR/DIBuilder.h"
12 #include "llvm/IR/IntrinsicInst.h"
13
14 namespace llvm {
15
DPValue(const DbgVariableIntrinsic * DVI)16 DPValue::DPValue(const DbgVariableIntrinsic *DVI)
17 : DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}),
18 Variable(DVI->getVariable()), Expression(DVI->getExpression()),
19 DbgLoc(DVI->getDebugLoc()), AddressExpression(nullptr) {
20 switch (DVI->getIntrinsicID()) {
21 case Intrinsic::dbg_value:
22 Type = LocationType::Value;
23 break;
24 case Intrinsic::dbg_declare:
25 Type = LocationType::Declare;
26 break;
27 case Intrinsic::dbg_assign: {
28 Type = LocationType::Assign;
29 const DbgAssignIntrinsic *Assign =
30 static_cast<const DbgAssignIntrinsic *>(DVI);
31 resetDebugValue(1, Assign->getRawAddress());
32 AddressExpression = Assign->getAddressExpression();
33 setAssignId(Assign->getAssignID());
34 break;
35 }
36 default:
37 llvm_unreachable(
38 "Trying to create a DPValue with an invalid intrinsic type!");
39 }
40 }
41
DPValue(const DPValue & DPV)42 DPValue::DPValue(const DPValue &DPV)
43 : DebugValueUser(DPV.DebugValues), Variable(DPV.getVariable()),
44 Expression(DPV.getExpression()), DbgLoc(DPV.getDebugLoc()),
45 AddressExpression(DPV.AddressExpression), Type(DPV.getType()) {}
46
DPValue(Metadata * Location,DILocalVariable * DV,DIExpression * Expr,const DILocation * DI,LocationType Type)47 DPValue::DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
48 const DILocation *DI, LocationType Type)
49 : DebugValueUser({Location, nullptr, nullptr}), Variable(DV),
50 Expression(Expr), DbgLoc(DI), Type(Type) {}
51
DPValue(Metadata * Value,DILocalVariable * Variable,DIExpression * Expression,DIAssignID * AssignID,Metadata * Address,DIExpression * AddressExpression,const DILocation * DI)52 DPValue::DPValue(Metadata *Value, DILocalVariable *Variable,
53 DIExpression *Expression, DIAssignID *AssignID,
54 Metadata *Address, DIExpression *AddressExpression,
55 const DILocation *DI)
56 : DebugValueUser({Value, Address, AssignID}), Variable(Variable),
57 Expression(Expression), DbgLoc(DI), AddressExpression(AddressExpression),
58 Type(LocationType::Assign) {}
59
deleteInstr()60 void DPValue::deleteInstr() { delete this; }
61
createDPValue(Value * Location,DILocalVariable * DV,DIExpression * Expr,const DILocation * DI)62 DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV,
63 DIExpression *Expr, const DILocation *DI) {
64 return new DPValue(ValueAsMetadata::get(Location), DV, Expr, DI,
65 LocationType::Value);
66 }
67
createDPValue(Value * Location,DILocalVariable * DV,DIExpression * Expr,const DILocation * DI,DPValue & InsertBefore)68 DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV,
69 DIExpression *Expr, const DILocation *DI,
70 DPValue &InsertBefore) {
71 auto *NewDPValue = createDPValue(Location, DV, Expr, DI);
72 NewDPValue->insertBefore(&InsertBefore);
73 return NewDPValue;
74 }
75
createDPVDeclare(Value * Address,DILocalVariable * DV,DIExpression * Expr,const DILocation * DI)76 DPValue *DPValue::createDPVDeclare(Value *Address, DILocalVariable *DV,
77 DIExpression *Expr, const DILocation *DI) {
78 return new DPValue(ValueAsMetadata::get(Address), DV, Expr, DI,
79 LocationType::Declare);
80 }
81
createDPVDeclare(Value * Address,DILocalVariable * DV,DIExpression * Expr,const DILocation * DI,DPValue & InsertBefore)82 DPValue *DPValue::createDPVDeclare(Value *Address, DILocalVariable *DV,
83 DIExpression *Expr, const DILocation *DI,
84 DPValue &InsertBefore) {
85 auto *NewDPVDeclare = createDPVDeclare(Address, DV, Expr, DI);
86 NewDPVDeclare->insertBefore(&InsertBefore);
87 return NewDPVDeclare;
88 }
89
createDPVAssign(Value * Val,DILocalVariable * Variable,DIExpression * Expression,DIAssignID * AssignID,Value * Address,DIExpression * AddressExpression,const DILocation * DI)90 DPValue *DPValue::createDPVAssign(Value *Val, DILocalVariable *Variable,
91 DIExpression *Expression,
92 DIAssignID *AssignID, Value *Address,
93 DIExpression *AddressExpression,
94 const DILocation *DI) {
95 return new DPValue(ValueAsMetadata::get(Val), Variable, Expression, AssignID,
96 ValueAsMetadata::get(Address), AddressExpression, DI);
97 }
98
createLinkedDPVAssign(Instruction * LinkedInstr,Value * Val,DILocalVariable * Variable,DIExpression * Expression,Value * Address,DIExpression * AddressExpression,const DILocation * DI)99 DPValue *DPValue::createLinkedDPVAssign(Instruction *LinkedInstr, Value *Val,
100 DILocalVariable *Variable,
101 DIExpression *Expression,
102 Value *Address,
103 DIExpression *AddressExpression,
104 const DILocation *DI) {
105 auto *Link = LinkedInstr->getMetadata(LLVMContext::MD_DIAssignID);
106 assert(Link && "Linked instruction must have DIAssign metadata attached");
107 auto *NewDPVAssign = DPValue::createDPVAssign(Val, Variable, Expression,
108 cast<DIAssignID>(Link), Address,
109 AddressExpression, DI);
110 LinkedInstr->getParent()->insertDPValueAfter(NewDPVAssign, LinkedInstr);
111 return NewDPVAssign;
112 }
113
location_ops() const114 iterator_range<DPValue::location_op_iterator> DPValue::location_ops() const {
115 auto *MD = getRawLocation();
116 // If a Value has been deleted, the "location" for this DPValue will be
117 // replaced by nullptr. Return an empty range.
118 if (!MD)
119 return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
120 location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
121
122 // If operand is ValueAsMetadata, return a range over just that operand.
123 if (auto *VAM = dyn_cast<ValueAsMetadata>(MD))
124 return {location_op_iterator(VAM), location_op_iterator(VAM + 1)};
125
126 // If operand is DIArgList, return a range over its args.
127 if (auto *AL = dyn_cast<DIArgList>(MD))
128 return {location_op_iterator(AL->args_begin()),
129 location_op_iterator(AL->args_end())};
130
131 // Operand is an empty metadata tuple, so return empty iterator.
132 assert(cast<MDNode>(MD)->getNumOperands() == 0);
133 return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
134 location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
135 }
136
getNumVariableLocationOps() const137 unsigned DPValue::getNumVariableLocationOps() const {
138 if (hasArgList())
139 return cast<DIArgList>(getRawLocation())->getArgs().size();
140 return 1;
141 }
142
getVariableLocationOp(unsigned OpIdx) const143 Value *DPValue::getVariableLocationOp(unsigned OpIdx) const {
144 auto *MD = getRawLocation();
145 if (!MD)
146 return nullptr;
147
148 if (auto *AL = dyn_cast<DIArgList>(MD))
149 return AL->getArgs()[OpIdx]->getValue();
150 if (isa<MDNode>(MD))
151 return nullptr;
152 assert(isa<ValueAsMetadata>(MD) &&
153 "Attempted to get location operand from DPValue with none.");
154 auto *V = cast<ValueAsMetadata>(MD);
155 assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a "
156 "single location operand.");
157 return V->getValue();
158 }
159
getAsMetadata(Value * V)160 static ValueAsMetadata *getAsMetadata(Value *V) {
161 return isa<MetadataAsValue>(V) ? dyn_cast<ValueAsMetadata>(
162 cast<MetadataAsValue>(V)->getMetadata())
163 : ValueAsMetadata::get(V);
164 }
165
replaceVariableLocationOp(Value * OldValue,Value * NewValue,bool AllowEmpty)166 void DPValue::replaceVariableLocationOp(Value *OldValue, Value *NewValue,
167 bool AllowEmpty) {
168 assert(NewValue && "Values must be non-null");
169
170 bool DbgAssignAddrReplaced = isDbgAssign() && OldValue == getAddress();
171 if (DbgAssignAddrReplaced)
172 setAddress(NewValue);
173
174 auto Locations = location_ops();
175 auto OldIt = find(Locations, OldValue);
176 if (OldIt == Locations.end()) {
177 if (AllowEmpty || DbgAssignAddrReplaced)
178 return;
179 llvm_unreachable("OldValue must be a current location");
180 }
181
182 if (!hasArgList()) {
183 // Set our location to be the MAV wrapping the new Value.
184 setRawLocation(isa<MetadataAsValue>(NewValue)
185 ? cast<MetadataAsValue>(NewValue)->getMetadata()
186 : ValueAsMetadata::get(NewValue));
187 return;
188 }
189
190 // We must be referring to a DIArgList, produce a new operands vector with the
191 // old value replaced, generate a new DIArgList and set it as our location.
192 SmallVector<ValueAsMetadata *, 4> MDs;
193 ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
194 for (auto *VMD : Locations)
195 MDs.push_back(VMD == *OldIt ? NewOperand : getAsMetadata(VMD));
196 setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
197 }
198
replaceVariableLocationOp(unsigned OpIdx,Value * NewValue)199 void DPValue::replaceVariableLocationOp(unsigned OpIdx, Value *NewValue) {
200 assert(OpIdx < getNumVariableLocationOps() && "Invalid Operand Index");
201
202 if (!hasArgList()) {
203 setRawLocation(isa<MetadataAsValue>(NewValue)
204 ? cast<MetadataAsValue>(NewValue)->getMetadata()
205 : ValueAsMetadata::get(NewValue));
206 return;
207 }
208
209 SmallVector<ValueAsMetadata *, 4> MDs;
210 ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
211 for (unsigned Idx = 0; Idx < getNumVariableLocationOps(); ++Idx)
212 MDs.push_back(Idx == OpIdx ? NewOperand
213 : getAsMetadata(getVariableLocationOp(Idx)));
214
215 setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
216 }
217
addVariableLocationOps(ArrayRef<Value * > NewValues,DIExpression * NewExpr)218 void DPValue::addVariableLocationOps(ArrayRef<Value *> NewValues,
219 DIExpression *NewExpr) {
220 assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() +
221 NewValues.size()) &&
222 "NewExpr for debug variable intrinsic does not reference every "
223 "location operand.");
224 assert(!is_contained(NewValues, nullptr) && "New values must be non-null");
225 setExpression(NewExpr);
226 SmallVector<ValueAsMetadata *, 4> MDs;
227 for (auto *VMD : location_ops())
228 MDs.push_back(getAsMetadata(VMD));
229 for (auto *VMD : NewValues)
230 MDs.push_back(getAsMetadata(VMD));
231 setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
232 }
233
setKillLocation()234 void DPValue::setKillLocation() {
235 // TODO: When/if we remove duplicate values from DIArgLists, we don't need
236 // this set anymore.
237 SmallPtrSet<Value *, 4> RemovedValues;
238 for (Value *OldValue : location_ops()) {
239 if (!RemovedValues.insert(OldValue).second)
240 continue;
241 Value *Poison = PoisonValue::get(OldValue->getType());
242 replaceVariableLocationOp(OldValue, Poison);
243 }
244 }
245
isKillLocation() const246 bool DPValue::isKillLocation() const {
247 return (getNumVariableLocationOps() == 0 &&
248 !getExpression()->isComplex()) ||
249 any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); });
250 }
251
getFragmentSizeInBits() const252 std::optional<uint64_t> DPValue::getFragmentSizeInBits() const {
253 if (auto Fragment = getExpression()->getFragmentInfo())
254 return Fragment->SizeInBits;
255 return getVariable()->getSizeInBits();
256 }
257
clone() const258 DPValue *DPValue::clone() const { return new DPValue(*this); }
259
260 DbgVariableIntrinsic *
createDebugIntrinsic(Module * M,Instruction * InsertBefore) const261 DPValue::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
262 [[maybe_unused]] DICompileUnit *Unit =
263 getDebugLoc().get()->getScope()->getSubprogram()->getUnit();
264 assert(M && Unit &&
265 "Cannot clone from BasicBlock that is not part of a Module or "
266 "DICompileUnit!");
267 LLVMContext &Context = getDebugLoc()->getContext();
268 Function *IntrinsicFn;
269
270 // Work out what sort of intrinsic we're going to produce.
271 switch (getType()) {
272 case DPValue::LocationType::Declare:
273 IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_declare);
274 break;
275 case DPValue::LocationType::Value:
276 IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_value);
277 break;
278 case DPValue::LocationType::Assign:
279 IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_assign);
280 break;
281 case DPValue::LocationType::End:
282 case DPValue::LocationType::Any:
283 llvm_unreachable("Invalid LocationType");
284 }
285
286 // Create the intrinsic from this DPValue's information, optionally insert
287 // into the target location.
288 DbgVariableIntrinsic *DVI;
289 if (isDbgAssign()) {
290 Value *AssignArgs[] = {
291 MetadataAsValue::get(Context, getRawLocation()),
292 MetadataAsValue::get(Context, getVariable()),
293 MetadataAsValue::get(Context, getExpression()),
294 MetadataAsValue::get(Context, getAssignID()),
295 MetadataAsValue::get(Context, getRawAddress()),
296 MetadataAsValue::get(Context, getAddressExpression())};
297 DVI = cast<DbgVariableIntrinsic>(CallInst::Create(
298 IntrinsicFn->getFunctionType(), IntrinsicFn, AssignArgs));
299 } else {
300 Value *Args[] = {MetadataAsValue::get(Context, getRawLocation()),
301 MetadataAsValue::get(Context, getVariable()),
302 MetadataAsValue::get(Context, getExpression())};
303 DVI = cast<DbgVariableIntrinsic>(
304 CallInst::Create(IntrinsicFn->getFunctionType(), IntrinsicFn, Args));
305 }
306 DVI->setTailCall();
307 DVI->setDebugLoc(getDebugLoc());
308 if (InsertBefore)
309 DVI->insertBefore(InsertBefore);
310
311 return DVI;
312 }
313
getAddress() const314 Value *DPValue::getAddress() const {
315 auto *MD = getRawAddress();
316 if (auto *V = dyn_cast<ValueAsMetadata>(MD))
317 return V->getValue();
318
319 // When the value goes to null, it gets replaced by an empty MDNode.
320 assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");
321 return nullptr;
322 }
323
getAssignID() const324 DIAssignID *DPValue::getAssignID() const {
325 return cast<DIAssignID>(DebugValues[2]);
326 }
327
setAssignId(DIAssignID * New)328 void DPValue::setAssignId(DIAssignID *New) { resetDebugValue(2, New); }
329
setKillAddress()330 void DPValue::setKillAddress() {
331 resetDebugValue(
332 1, ValueAsMetadata::get(UndefValue::get(getAddress()->getType())));
333 }
334
isKillAddress() const335 bool DPValue::isKillAddress() const {
336 Value *Addr = getAddress();
337 return !Addr || isa<UndefValue>(Addr);
338 }
339
getParent() const340 const BasicBlock *DPValue::getParent() const {
341 return Marker->MarkedInstr->getParent();
342 }
343
getParent()344 BasicBlock *DPValue::getParent() { return Marker->MarkedInstr->getParent(); }
345
getBlock()346 BasicBlock *DPValue::getBlock() { return Marker->getParent(); }
347
getBlock() const348 const BasicBlock *DPValue::getBlock() const { return Marker->getParent(); }
349
getFunction()350 Function *DPValue::getFunction() { return getBlock()->getParent(); }
351
getFunction() const352 const Function *DPValue::getFunction() const { return getBlock()->getParent(); }
353
getModule()354 Module *DPValue::getModule() { return getFunction()->getParent(); }
355
getModule() const356 const Module *DPValue::getModule() const { return getFunction()->getParent(); }
357
getContext()358 LLVMContext &DPValue::getContext() { return getBlock()->getContext(); }
359
getContext() const360 const LLVMContext &DPValue::getContext() const {
361 return getBlock()->getContext();
362 }
363
insertBefore(DPValue * InsertBefore)364 void DPValue::insertBefore(DPValue *InsertBefore) {
365 assert(!getMarker() &&
366 "Cannot insert a DPValue that is already has a DPMarker!");
367 assert(InsertBefore->getMarker() &&
368 "Cannot insert a DPValue before a DPValue that does not have a "
369 "DPMarker!");
370 InsertBefore->getMarker()->insertDPValue(this, InsertBefore);
371 }
insertAfter(DPValue * InsertAfter)372 void DPValue::insertAfter(DPValue *InsertAfter) {
373 assert(!getMarker() &&
374 "Cannot insert a DPValue that is already has a DPMarker!");
375 assert(InsertAfter->getMarker() &&
376 "Cannot insert a DPValue after a DPValue that does not have a "
377 "DPMarker!");
378 InsertAfter->getMarker()->insertDPValueAfter(this, InsertAfter);
379 }
moveBefore(DPValue * MoveBefore)380 void DPValue::moveBefore(DPValue *MoveBefore) {
381 assert(getMarker() &&
382 "Canot move a DPValue that does not currently have a DPMarker!");
383 removeFromParent();
384 insertBefore(MoveBefore);
385 }
moveAfter(DPValue * MoveAfter)386 void DPValue::moveAfter(DPValue *MoveAfter) {
387 assert(getMarker() &&
388 "Canot move a DPValue that does not currently have a DPMarker!");
389 removeFromParent();
390 insertAfter(MoveAfter);
391 }
392
393 ///////////////////////////////////////////////////////////////////////////////
394
395 // An empty, global, DPMarker for the purpose of describing empty ranges of
396 // DPValues.
397 DPMarker DPMarker::EmptyDPMarker;
398
dropDPValues()399 void DPMarker::dropDPValues() {
400 while (!StoredDPValues.empty()) {
401 auto It = StoredDPValues.begin();
402 DPValue *DPV = &*It;
403 StoredDPValues.erase(It);
404 DPV->deleteInstr();
405 }
406 }
407
dropOneDPValue(DPValue * DPV)408 void DPMarker::dropOneDPValue(DPValue *DPV) {
409 assert(DPV->getMarker() == this);
410 StoredDPValues.erase(DPV->getIterator());
411 DPV->deleteInstr();
412 }
413
getParent() const414 const BasicBlock *DPMarker::getParent() const {
415 return MarkedInstr->getParent();
416 }
417
getParent()418 BasicBlock *DPMarker::getParent() { return MarkedInstr->getParent(); }
419
removeMarker()420 void DPMarker::removeMarker() {
421 // Are there any DPValues in this DPMarker? If not, nothing to preserve.
422 Instruction *Owner = MarkedInstr;
423 if (StoredDPValues.empty()) {
424 eraseFromParent();
425 Owner->DbgMarker = nullptr;
426 return;
427 }
428
429 // The attached DPValues need to be preserved; attach them to the next
430 // instruction. If there isn't a next instruction, put them on the
431 // "trailing" list.
432 DPMarker *NextMarker = Owner->getParent()->getNextMarker(Owner);
433 if (NextMarker == nullptr) {
434 NextMarker = new DPMarker();
435 Owner->getParent()->setTrailingDPValues(NextMarker);
436 }
437 NextMarker->absorbDebugValues(*this, true);
438
439 eraseFromParent();
440 }
441
removeFromParent()442 void DPMarker::removeFromParent() {
443 MarkedInstr->DbgMarker = nullptr;
444 MarkedInstr = nullptr;
445 }
446
eraseFromParent()447 void DPMarker::eraseFromParent() {
448 if (MarkedInstr)
449 removeFromParent();
450 dropDPValues();
451 delete this;
452 }
453
getDbgValueRange()454 iterator_range<DPValue::self_iterator> DPMarker::getDbgValueRange() {
455 return make_range(StoredDPValues.begin(), StoredDPValues.end());
456 }
457 iterator_range<DPValue::const_self_iterator>
getDbgValueRange() const458 DPMarker::getDbgValueRange() const {
459 return make_range(StoredDPValues.begin(), StoredDPValues.end());
460 }
461
removeFromParent()462 void DPValue::removeFromParent() {
463 getMarker()->StoredDPValues.erase(getIterator());
464 Marker = nullptr;
465 }
466
eraseFromParent()467 void DPValue::eraseFromParent() {
468 removeFromParent();
469 deleteInstr();
470 }
471
insertDPValue(DPValue * New,bool InsertAtHead)472 void DPMarker::insertDPValue(DPValue *New, bool InsertAtHead) {
473 auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end();
474 StoredDPValues.insert(It, *New);
475 New->setMarker(this);
476 }
insertDPValue(DPValue * New,DPValue * InsertBefore)477 void DPMarker::insertDPValue(DPValue *New, DPValue *InsertBefore) {
478 assert(InsertBefore->getMarker() == this &&
479 "DPValue 'InsertBefore' must be contained in this DPMarker!");
480 StoredDPValues.insert(InsertBefore->getIterator(), *New);
481 New->setMarker(this);
482 }
insertDPValueAfter(DPValue * New,DPValue * InsertAfter)483 void DPMarker::insertDPValueAfter(DPValue *New, DPValue *InsertAfter) {
484 assert(InsertAfter->getMarker() == this &&
485 "DPValue 'InsertAfter' must be contained in this DPMarker!");
486 StoredDPValues.insert(++(InsertAfter->getIterator()), *New);
487 New->setMarker(this);
488 }
489
absorbDebugValues(DPMarker & Src,bool InsertAtHead)490 void DPMarker::absorbDebugValues(DPMarker &Src, bool InsertAtHead) {
491 auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end();
492 for (DPValue &DPV : Src.StoredDPValues)
493 DPV.setMarker(this);
494
495 StoredDPValues.splice(It, Src.StoredDPValues);
496 }
497
absorbDebugValues(iterator_range<DPValue::self_iterator> Range,DPMarker & Src,bool InsertAtHead)498 void DPMarker::absorbDebugValues(iterator_range<DPValue::self_iterator> Range,
499 DPMarker &Src, bool InsertAtHead) {
500 for (DPValue &DPV : Range)
501 DPV.setMarker(this);
502
503 auto InsertPos =
504 (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end();
505
506 StoredDPValues.splice(InsertPos, Src.StoredDPValues, Range.begin(),
507 Range.end());
508 }
509
cloneDebugInfoFrom(DPMarker * From,std::optional<simple_ilist<DPValue>::iterator> from_here,bool InsertAtHead)510 iterator_range<simple_ilist<DPValue>::iterator> DPMarker::cloneDebugInfoFrom(
511 DPMarker *From, std::optional<simple_ilist<DPValue>::iterator> from_here,
512 bool InsertAtHead) {
513 DPValue *First = nullptr;
514 // Work out what range of DPValues to clone: normally all the contents of the
515 // "From" marker, optionally we can start from the from_here position down to
516 // end().
517 auto Range =
518 make_range(From->StoredDPValues.begin(), From->StoredDPValues.end());
519 if (from_here.has_value())
520 Range = make_range(*from_here, From->StoredDPValues.end());
521
522 // Clone each DPValue and insert into StoreDPValues; optionally place them at
523 // the start or the end of the list.
524 auto Pos = (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end();
525 for (DPValue &DPV : Range) {
526 DPValue *New = DPV.clone();
527 New->setMarker(this);
528 StoredDPValues.insert(Pos, *New);
529 if (!First)
530 First = New;
531 }
532
533 if (!First)
534 return {StoredDPValues.end(), StoredDPValues.end()};
535
536 if (InsertAtHead)
537 // If InsertAtHead is set, we cloned a range onto the front of of the
538 // StoredDPValues collection, return that range.
539 return {StoredDPValues.begin(), Pos};
540 else
541 // We inserted a block at the end, return that range.
542 return {First->getIterator(), StoredDPValues.end()};
543 }
544
545 } // end namespace llvm
546
547