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