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