brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.1 KiB · 9efa3c7 Raw
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