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