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