1*5f757f3fSDimitry Andric //======-- DebugProgramInstruction.cpp - Implement DPValues/DPMarkers --======// 2*5f757f3fSDimitry Andric // 3*5f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*5f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*5f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*5f757f3fSDimitry Andric // 7*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 8*5f757f3fSDimitry Andric 9*5f757f3fSDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 10*5f757f3fSDimitry Andric #include "llvm/IR/DebugProgramInstruction.h" 11*5f757f3fSDimitry Andric #include "llvm/IR/DIBuilder.h" 12*5f757f3fSDimitry Andric #include "llvm/IR/IntrinsicInst.h" 13*5f757f3fSDimitry Andric 14*5f757f3fSDimitry Andric namespace llvm { 15*5f757f3fSDimitry Andric 16*5f757f3fSDimitry Andric DPValue::DPValue(const DbgVariableIntrinsic *DVI) 17*5f757f3fSDimitry Andric : DebugValueUser(DVI->getRawLocation()), Variable(DVI->getVariable()), 18*5f757f3fSDimitry Andric Expression(DVI->getExpression()), DbgLoc(DVI->getDebugLoc()) { 19*5f757f3fSDimitry Andric switch (DVI->getIntrinsicID()) { 20*5f757f3fSDimitry Andric case Intrinsic::dbg_value: 21*5f757f3fSDimitry Andric Type = LocationType::Value; 22*5f757f3fSDimitry Andric break; 23*5f757f3fSDimitry Andric case Intrinsic::dbg_declare: 24*5f757f3fSDimitry Andric Type = LocationType::Declare; 25*5f757f3fSDimitry Andric break; 26*5f757f3fSDimitry Andric default: 27*5f757f3fSDimitry Andric llvm_unreachable( 28*5f757f3fSDimitry Andric "Trying to create a DPValue with an invalid intrinsic type!"); 29*5f757f3fSDimitry Andric } 30*5f757f3fSDimitry Andric } 31*5f757f3fSDimitry Andric 32*5f757f3fSDimitry Andric DPValue::DPValue(const DPValue &DPV) 33*5f757f3fSDimitry Andric : DebugValueUser(DPV.getRawLocation()), 34*5f757f3fSDimitry Andric Variable(DPV.getVariable()), Expression(DPV.getExpression()), 35*5f757f3fSDimitry Andric DbgLoc(DPV.getDebugLoc()), Type(DPV.getType()) {} 36*5f757f3fSDimitry Andric 37*5f757f3fSDimitry Andric DPValue::DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr, 38*5f757f3fSDimitry Andric const DILocation *DI, LocationType Type) 39*5f757f3fSDimitry Andric : DebugValueUser(Location), Variable(DV), Expression(Expr), DbgLoc(DI), 40*5f757f3fSDimitry Andric Type(Type) {} 41*5f757f3fSDimitry Andric 42*5f757f3fSDimitry Andric void DPValue::deleteInstr() { delete this; } 43*5f757f3fSDimitry Andric 44*5f757f3fSDimitry Andric iterator_range<DPValue::location_op_iterator> DPValue::location_ops() const { 45*5f757f3fSDimitry Andric auto *MD = getRawLocation(); 46*5f757f3fSDimitry Andric // If a Value has been deleted, the "location" for this DPValue will be 47*5f757f3fSDimitry Andric // replaced by nullptr. Return an empty range. 48*5f757f3fSDimitry Andric if (!MD) 49*5f757f3fSDimitry Andric return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)), 50*5f757f3fSDimitry Andric location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))}; 51*5f757f3fSDimitry Andric 52*5f757f3fSDimitry Andric // If operand is ValueAsMetadata, return a range over just that operand. 53*5f757f3fSDimitry Andric if (auto *VAM = dyn_cast<ValueAsMetadata>(MD)) 54*5f757f3fSDimitry Andric return {location_op_iterator(VAM), location_op_iterator(VAM + 1)}; 55*5f757f3fSDimitry Andric 56*5f757f3fSDimitry Andric // If operand is DIArgList, return a range over its args. 57*5f757f3fSDimitry Andric if (auto *AL = dyn_cast<DIArgList>(MD)) 58*5f757f3fSDimitry Andric return {location_op_iterator(AL->args_begin()), 59*5f757f3fSDimitry Andric location_op_iterator(AL->args_end())}; 60*5f757f3fSDimitry Andric 61*5f757f3fSDimitry Andric // Operand is an empty metadata tuple, so return empty iterator. 62*5f757f3fSDimitry Andric assert(cast<MDNode>(MD)->getNumOperands() == 0); 63*5f757f3fSDimitry Andric return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)), 64*5f757f3fSDimitry Andric location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))}; 65*5f757f3fSDimitry Andric } 66*5f757f3fSDimitry Andric 67*5f757f3fSDimitry Andric unsigned DPValue::getNumVariableLocationOps() const { 68*5f757f3fSDimitry Andric if (hasArgList()) 69*5f757f3fSDimitry Andric return cast<DIArgList>(getRawLocation())->getArgs().size(); 70*5f757f3fSDimitry Andric return 1; 71*5f757f3fSDimitry Andric } 72*5f757f3fSDimitry Andric 73*5f757f3fSDimitry Andric Value *DPValue::getVariableLocationOp(unsigned OpIdx) const { 74*5f757f3fSDimitry Andric auto *MD = getRawLocation(); 75*5f757f3fSDimitry Andric if (!MD) 76*5f757f3fSDimitry Andric return nullptr; 77*5f757f3fSDimitry Andric 78*5f757f3fSDimitry Andric if (auto *AL = dyn_cast<DIArgList>(MD)) 79*5f757f3fSDimitry Andric return AL->getArgs()[OpIdx]->getValue(); 80*5f757f3fSDimitry Andric if (isa<MDNode>(MD)) 81*5f757f3fSDimitry Andric return nullptr; 82*5f757f3fSDimitry Andric assert(isa<ValueAsMetadata>(MD) && 83*5f757f3fSDimitry Andric "Attempted to get location operand from DPValue with none."); 84*5f757f3fSDimitry Andric auto *V = cast<ValueAsMetadata>(MD); 85*5f757f3fSDimitry Andric assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a " 86*5f757f3fSDimitry Andric "single location operand."); 87*5f757f3fSDimitry Andric return V->getValue(); 88*5f757f3fSDimitry Andric } 89*5f757f3fSDimitry Andric 90*5f757f3fSDimitry Andric static ValueAsMetadata *getAsMetadata(Value *V) { 91*5f757f3fSDimitry Andric return isa<MetadataAsValue>(V) ? dyn_cast<ValueAsMetadata>( 92*5f757f3fSDimitry Andric cast<MetadataAsValue>(V)->getMetadata()) 93*5f757f3fSDimitry Andric : ValueAsMetadata::get(V); 94*5f757f3fSDimitry Andric } 95*5f757f3fSDimitry Andric 96*5f757f3fSDimitry Andric void DPValue::replaceVariableLocationOp(Value *OldValue, Value *NewValue, 97*5f757f3fSDimitry Andric bool AllowEmpty) { 98*5f757f3fSDimitry Andric assert(NewValue && "Values must be non-null"); 99*5f757f3fSDimitry Andric auto Locations = location_ops(); 100*5f757f3fSDimitry Andric auto OldIt = find(Locations, OldValue); 101*5f757f3fSDimitry Andric if (OldIt == Locations.end()) { 102*5f757f3fSDimitry Andric if (AllowEmpty) 103*5f757f3fSDimitry Andric return; 104*5f757f3fSDimitry Andric llvm_unreachable("OldValue must be a current location"); 105*5f757f3fSDimitry Andric } 106*5f757f3fSDimitry Andric 107*5f757f3fSDimitry Andric if (!hasArgList()) { 108*5f757f3fSDimitry Andric // Set our location to be the MAV wrapping the new Value. 109*5f757f3fSDimitry Andric setRawLocation(isa<MetadataAsValue>(NewValue) 110*5f757f3fSDimitry Andric ? cast<MetadataAsValue>(NewValue)->getMetadata() 111*5f757f3fSDimitry Andric : ValueAsMetadata::get(NewValue)); 112*5f757f3fSDimitry Andric return; 113*5f757f3fSDimitry Andric } 114*5f757f3fSDimitry Andric 115*5f757f3fSDimitry Andric // We must be referring to a DIArgList, produce a new operands vector with the 116*5f757f3fSDimitry Andric // old value replaced, generate a new DIArgList and set it as our location. 117*5f757f3fSDimitry Andric SmallVector<ValueAsMetadata *, 4> MDs; 118*5f757f3fSDimitry Andric ValueAsMetadata *NewOperand = getAsMetadata(NewValue); 119*5f757f3fSDimitry Andric for (auto *VMD : Locations) 120*5f757f3fSDimitry Andric MDs.push_back(VMD == *OldIt ? NewOperand : getAsMetadata(VMD)); 121*5f757f3fSDimitry Andric setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs)); 122*5f757f3fSDimitry Andric } 123*5f757f3fSDimitry Andric 124*5f757f3fSDimitry Andric void DPValue::replaceVariableLocationOp(unsigned OpIdx, Value *NewValue) { 125*5f757f3fSDimitry Andric assert(OpIdx < getNumVariableLocationOps() && "Invalid Operand Index"); 126*5f757f3fSDimitry Andric 127*5f757f3fSDimitry Andric if (!hasArgList()) { 128*5f757f3fSDimitry Andric setRawLocation(isa<MetadataAsValue>(NewValue) 129*5f757f3fSDimitry Andric ? cast<MetadataAsValue>(NewValue)->getMetadata() 130*5f757f3fSDimitry Andric : ValueAsMetadata::get(NewValue)); 131*5f757f3fSDimitry Andric return; 132*5f757f3fSDimitry Andric } 133*5f757f3fSDimitry Andric 134*5f757f3fSDimitry Andric SmallVector<ValueAsMetadata *, 4> MDs; 135*5f757f3fSDimitry Andric ValueAsMetadata *NewOperand = getAsMetadata(NewValue); 136*5f757f3fSDimitry Andric for (unsigned Idx = 0; Idx < getNumVariableLocationOps(); ++Idx) 137*5f757f3fSDimitry Andric MDs.push_back(Idx == OpIdx ? NewOperand 138*5f757f3fSDimitry Andric : getAsMetadata(getVariableLocationOp(Idx))); 139*5f757f3fSDimitry Andric 140*5f757f3fSDimitry Andric setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs)); 141*5f757f3fSDimitry Andric } 142*5f757f3fSDimitry Andric 143*5f757f3fSDimitry Andric void DPValue::addVariableLocationOps(ArrayRef<Value *> NewValues, 144*5f757f3fSDimitry Andric DIExpression *NewExpr) { 145*5f757f3fSDimitry Andric assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() + 146*5f757f3fSDimitry Andric NewValues.size()) && 147*5f757f3fSDimitry Andric "NewExpr for debug variable intrinsic does not reference every " 148*5f757f3fSDimitry Andric "location operand."); 149*5f757f3fSDimitry Andric assert(!is_contained(NewValues, nullptr) && "New values must be non-null"); 150*5f757f3fSDimitry Andric setExpression(NewExpr); 151*5f757f3fSDimitry Andric SmallVector<ValueAsMetadata *, 4> MDs; 152*5f757f3fSDimitry Andric for (auto *VMD : location_ops()) 153*5f757f3fSDimitry Andric MDs.push_back(getAsMetadata(VMD)); 154*5f757f3fSDimitry Andric for (auto *VMD : NewValues) 155*5f757f3fSDimitry Andric MDs.push_back(getAsMetadata(VMD)); 156*5f757f3fSDimitry Andric setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs)); 157*5f757f3fSDimitry Andric } 158*5f757f3fSDimitry Andric 159*5f757f3fSDimitry Andric void DPValue::setKillLocation() { 160*5f757f3fSDimitry Andric // TODO: When/if we remove duplicate values from DIArgLists, we don't need 161*5f757f3fSDimitry Andric // this set anymore. 162*5f757f3fSDimitry Andric SmallPtrSet<Value *, 4> RemovedValues; 163*5f757f3fSDimitry Andric for (Value *OldValue : location_ops()) { 164*5f757f3fSDimitry Andric if (!RemovedValues.insert(OldValue).second) 165*5f757f3fSDimitry Andric continue; 166*5f757f3fSDimitry Andric Value *Poison = PoisonValue::get(OldValue->getType()); 167*5f757f3fSDimitry Andric replaceVariableLocationOp(OldValue, Poison); 168*5f757f3fSDimitry Andric } 169*5f757f3fSDimitry Andric } 170*5f757f3fSDimitry Andric 171*5f757f3fSDimitry Andric bool DPValue::isKillLocation() const { 172*5f757f3fSDimitry Andric return (getNumVariableLocationOps() == 0 && 173*5f757f3fSDimitry Andric !getExpression()->isComplex()) || 174*5f757f3fSDimitry Andric any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); }); 175*5f757f3fSDimitry Andric } 176*5f757f3fSDimitry Andric 177*5f757f3fSDimitry Andric std::optional<uint64_t> DPValue::getFragmentSizeInBits() const { 178*5f757f3fSDimitry Andric if (auto Fragment = getExpression()->getFragmentInfo()) 179*5f757f3fSDimitry Andric return Fragment->SizeInBits; 180*5f757f3fSDimitry Andric return getVariable()->getSizeInBits(); 181*5f757f3fSDimitry Andric } 182*5f757f3fSDimitry Andric 183*5f757f3fSDimitry Andric DPValue *DPValue::clone() const { return new DPValue(*this); } 184*5f757f3fSDimitry Andric 185*5f757f3fSDimitry Andric DbgVariableIntrinsic * 186*5f757f3fSDimitry Andric DPValue::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const { 187*5f757f3fSDimitry Andric [[maybe_unused]] DICompileUnit *Unit = 188*5f757f3fSDimitry Andric getDebugLoc().get()->getScope()->getSubprogram()->getUnit(); 189*5f757f3fSDimitry Andric assert(M && Unit && 190*5f757f3fSDimitry Andric "Cannot clone from BasicBlock that is not part of a Module or " 191*5f757f3fSDimitry Andric "DICompileUnit!"); 192*5f757f3fSDimitry Andric LLVMContext &Context = getDebugLoc()->getContext(); 193*5f757f3fSDimitry Andric Value *Args[] = {MetadataAsValue::get(Context, getRawLocation()), 194*5f757f3fSDimitry Andric MetadataAsValue::get(Context, getVariable()), 195*5f757f3fSDimitry Andric MetadataAsValue::get(Context, getExpression())}; 196*5f757f3fSDimitry Andric Function *IntrinsicFn; 197*5f757f3fSDimitry Andric 198*5f757f3fSDimitry Andric // Work out what sort of intrinsic we're going to produce. 199*5f757f3fSDimitry Andric switch (getType()) { 200*5f757f3fSDimitry Andric case DPValue::LocationType::Declare: 201*5f757f3fSDimitry Andric IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_declare); 202*5f757f3fSDimitry Andric break; 203*5f757f3fSDimitry Andric case DPValue::LocationType::Value: 204*5f757f3fSDimitry Andric IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_value); 205*5f757f3fSDimitry Andric break; 206*5f757f3fSDimitry Andric case DPValue::LocationType::End: 207*5f757f3fSDimitry Andric case DPValue::LocationType::Any: 208*5f757f3fSDimitry Andric llvm_unreachable("Invalid LocationType"); 209*5f757f3fSDimitry Andric break; 210*5f757f3fSDimitry Andric } 211*5f757f3fSDimitry Andric 212*5f757f3fSDimitry Andric // Create the intrinsic from this DPValue's information, optionally insert 213*5f757f3fSDimitry Andric // into the target location. 214*5f757f3fSDimitry Andric DbgVariableIntrinsic *DVI = cast<DbgVariableIntrinsic>( 215*5f757f3fSDimitry Andric CallInst::Create(IntrinsicFn->getFunctionType(), IntrinsicFn, Args)); 216*5f757f3fSDimitry Andric DVI->setTailCall(); 217*5f757f3fSDimitry Andric DVI->setDebugLoc(getDebugLoc()); 218*5f757f3fSDimitry Andric if (InsertBefore) 219*5f757f3fSDimitry Andric DVI->insertBefore(InsertBefore); 220*5f757f3fSDimitry Andric 221*5f757f3fSDimitry Andric return DVI; 222*5f757f3fSDimitry Andric } 223*5f757f3fSDimitry Andric 224*5f757f3fSDimitry Andric void DPValue::handleChangedLocation(Metadata *NewLocation) { 225*5f757f3fSDimitry Andric resetDebugValue(NewLocation); 226*5f757f3fSDimitry Andric } 227*5f757f3fSDimitry Andric 228*5f757f3fSDimitry Andric const BasicBlock *DPValue::getParent() const { 229*5f757f3fSDimitry Andric return Marker->MarkedInstr->getParent(); 230*5f757f3fSDimitry Andric } 231*5f757f3fSDimitry Andric 232*5f757f3fSDimitry Andric BasicBlock *DPValue::getParent() { return Marker->MarkedInstr->getParent(); } 233*5f757f3fSDimitry Andric 234*5f757f3fSDimitry Andric BasicBlock *DPValue::getBlock() { return Marker->getParent(); } 235*5f757f3fSDimitry Andric 236*5f757f3fSDimitry Andric const BasicBlock *DPValue::getBlock() const { return Marker->getParent(); } 237*5f757f3fSDimitry Andric 238*5f757f3fSDimitry Andric Function *DPValue::getFunction() { return getBlock()->getParent(); } 239*5f757f3fSDimitry Andric 240*5f757f3fSDimitry Andric const Function *DPValue::getFunction() const { return getBlock()->getParent(); } 241*5f757f3fSDimitry Andric 242*5f757f3fSDimitry Andric Module *DPValue::getModule() { return getFunction()->getParent(); } 243*5f757f3fSDimitry Andric 244*5f757f3fSDimitry Andric const Module *DPValue::getModule() const { return getFunction()->getParent(); } 245*5f757f3fSDimitry Andric 246*5f757f3fSDimitry Andric LLVMContext &DPValue::getContext() { return getBlock()->getContext(); } 247*5f757f3fSDimitry Andric 248*5f757f3fSDimitry Andric const LLVMContext &DPValue::getContext() const { 249*5f757f3fSDimitry Andric return getBlock()->getContext(); 250*5f757f3fSDimitry Andric } 251*5f757f3fSDimitry Andric 252*5f757f3fSDimitry Andric /////////////////////////////////////////////////////////////////////////////// 253*5f757f3fSDimitry Andric 254*5f757f3fSDimitry Andric // An empty, global, DPMarker for the purpose of describing empty ranges of 255*5f757f3fSDimitry Andric // DPValues. 256*5f757f3fSDimitry Andric DPMarker DPMarker::EmptyDPMarker; 257*5f757f3fSDimitry Andric 258*5f757f3fSDimitry Andric void DPMarker::dropDPValues() { 259*5f757f3fSDimitry Andric while (!StoredDPValues.empty()) { 260*5f757f3fSDimitry Andric auto It = StoredDPValues.begin(); 261*5f757f3fSDimitry Andric DPValue *DPV = &*It; 262*5f757f3fSDimitry Andric StoredDPValues.erase(It); 263*5f757f3fSDimitry Andric DPV->deleteInstr(); 264*5f757f3fSDimitry Andric } 265*5f757f3fSDimitry Andric } 266*5f757f3fSDimitry Andric 267*5f757f3fSDimitry Andric void DPMarker::dropOneDPValue(DPValue *DPV) { 268*5f757f3fSDimitry Andric assert(DPV->getMarker() == this); 269*5f757f3fSDimitry Andric StoredDPValues.erase(DPV->getIterator()); 270*5f757f3fSDimitry Andric DPV->deleteInstr(); 271*5f757f3fSDimitry Andric } 272*5f757f3fSDimitry Andric 273*5f757f3fSDimitry Andric const BasicBlock *DPMarker::getParent() const { 274*5f757f3fSDimitry Andric return MarkedInstr->getParent(); 275*5f757f3fSDimitry Andric } 276*5f757f3fSDimitry Andric 277*5f757f3fSDimitry Andric BasicBlock *DPMarker::getParent() { return MarkedInstr->getParent(); } 278*5f757f3fSDimitry Andric 279*5f757f3fSDimitry Andric void DPMarker::removeMarker() { 280*5f757f3fSDimitry Andric // Are there any DPValues in this DPMarker? If not, nothing to preserve. 281*5f757f3fSDimitry Andric Instruction *Owner = MarkedInstr; 282*5f757f3fSDimitry Andric if (StoredDPValues.empty()) { 283*5f757f3fSDimitry Andric eraseFromParent(); 284*5f757f3fSDimitry Andric Owner->DbgMarker = nullptr; 285*5f757f3fSDimitry Andric return; 286*5f757f3fSDimitry Andric } 287*5f757f3fSDimitry Andric 288*5f757f3fSDimitry Andric // The attached DPValues need to be preserved; attach them to the next 289*5f757f3fSDimitry Andric // instruction. If there isn't a next instruction, put them on the 290*5f757f3fSDimitry Andric // "trailing" list. 291*5f757f3fSDimitry Andric DPMarker *NextMarker = Owner->getParent()->getNextMarker(Owner); 292*5f757f3fSDimitry Andric if (NextMarker == nullptr) { 293*5f757f3fSDimitry Andric NextMarker = new DPMarker(); 294*5f757f3fSDimitry Andric Owner->getParent()->setTrailingDPValues(NextMarker); 295*5f757f3fSDimitry Andric } 296*5f757f3fSDimitry Andric NextMarker->absorbDebugValues(*this, true); 297*5f757f3fSDimitry Andric 298*5f757f3fSDimitry Andric eraseFromParent(); 299*5f757f3fSDimitry Andric } 300*5f757f3fSDimitry Andric 301*5f757f3fSDimitry Andric void DPMarker::removeFromParent() { 302*5f757f3fSDimitry Andric MarkedInstr->DbgMarker = nullptr; 303*5f757f3fSDimitry Andric MarkedInstr = nullptr; 304*5f757f3fSDimitry Andric } 305*5f757f3fSDimitry Andric 306*5f757f3fSDimitry Andric void DPMarker::eraseFromParent() { 307*5f757f3fSDimitry Andric if (MarkedInstr) 308*5f757f3fSDimitry Andric removeFromParent(); 309*5f757f3fSDimitry Andric dropDPValues(); 310*5f757f3fSDimitry Andric delete this; 311*5f757f3fSDimitry Andric } 312*5f757f3fSDimitry Andric 313*5f757f3fSDimitry Andric iterator_range<DPValue::self_iterator> DPMarker::getDbgValueRange() { 314*5f757f3fSDimitry Andric return make_range(StoredDPValues.begin(), StoredDPValues.end()); 315*5f757f3fSDimitry Andric } 316*5f757f3fSDimitry Andric 317*5f757f3fSDimitry Andric void DPValue::removeFromParent() { 318*5f757f3fSDimitry Andric getMarker()->StoredDPValues.erase(getIterator()); 319*5f757f3fSDimitry Andric } 320*5f757f3fSDimitry Andric 321*5f757f3fSDimitry Andric void DPValue::eraseFromParent() { 322*5f757f3fSDimitry Andric removeFromParent(); 323*5f757f3fSDimitry Andric deleteInstr(); 324*5f757f3fSDimitry Andric } 325*5f757f3fSDimitry Andric 326*5f757f3fSDimitry Andric void DPMarker::insertDPValue(DPValue *New, bool InsertAtHead) { 327*5f757f3fSDimitry Andric auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end(); 328*5f757f3fSDimitry Andric StoredDPValues.insert(It, *New); 329*5f757f3fSDimitry Andric New->setMarker(this); 330*5f757f3fSDimitry Andric } 331*5f757f3fSDimitry Andric 332*5f757f3fSDimitry Andric void DPMarker::absorbDebugValues(DPMarker &Src, bool InsertAtHead) { 333*5f757f3fSDimitry Andric auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end(); 334*5f757f3fSDimitry Andric for (DPValue &DPV : Src.StoredDPValues) 335*5f757f3fSDimitry Andric DPV.setMarker(this); 336*5f757f3fSDimitry Andric 337*5f757f3fSDimitry Andric StoredDPValues.splice(It, Src.StoredDPValues); 338*5f757f3fSDimitry Andric } 339*5f757f3fSDimitry Andric 340*5f757f3fSDimitry Andric void DPMarker::absorbDebugValues(iterator_range<DPValue::self_iterator> Range, 341*5f757f3fSDimitry Andric DPMarker &Src, bool InsertAtHead) { 342*5f757f3fSDimitry Andric for (DPValue &DPV : Range) 343*5f757f3fSDimitry Andric DPV.setMarker(this); 344*5f757f3fSDimitry Andric 345*5f757f3fSDimitry Andric auto InsertPos = 346*5f757f3fSDimitry Andric (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end(); 347*5f757f3fSDimitry Andric 348*5f757f3fSDimitry Andric StoredDPValues.splice(InsertPos, Src.StoredDPValues, Range.begin(), 349*5f757f3fSDimitry Andric Range.end()); 350*5f757f3fSDimitry Andric } 351*5f757f3fSDimitry Andric 352*5f757f3fSDimitry Andric iterator_range<simple_ilist<DPValue>::iterator> DPMarker::cloneDebugInfoFrom( 353*5f757f3fSDimitry Andric DPMarker *From, std::optional<simple_ilist<DPValue>::iterator> from_here, 354*5f757f3fSDimitry Andric bool InsertAtHead) { 355*5f757f3fSDimitry Andric DPValue *First = nullptr; 356*5f757f3fSDimitry Andric // Work out what range of DPValues to clone: normally all the contents of the 357*5f757f3fSDimitry Andric // "From" marker, optionally we can start from the from_here position down to 358*5f757f3fSDimitry Andric // end(). 359*5f757f3fSDimitry Andric auto Range = 360*5f757f3fSDimitry Andric make_range(From->StoredDPValues.begin(), From->StoredDPValues.end()); 361*5f757f3fSDimitry Andric if (from_here.has_value()) 362*5f757f3fSDimitry Andric Range = make_range(*from_here, From->StoredDPValues.end()); 363*5f757f3fSDimitry Andric 364*5f757f3fSDimitry Andric // Clone each DPValue and insert into StoreDPValues; optionally place them at 365*5f757f3fSDimitry Andric // the start or the end of the list. 366*5f757f3fSDimitry Andric auto Pos = (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end(); 367*5f757f3fSDimitry Andric for (DPValue &DPV : Range) { 368*5f757f3fSDimitry Andric DPValue *New = DPV.clone(); 369*5f757f3fSDimitry Andric New->setMarker(this); 370*5f757f3fSDimitry Andric StoredDPValues.insert(Pos, *New); 371*5f757f3fSDimitry Andric if (!First) 372*5f757f3fSDimitry Andric First = New; 373*5f757f3fSDimitry Andric } 374*5f757f3fSDimitry Andric 375*5f757f3fSDimitry Andric if (!First) 376*5f757f3fSDimitry Andric return {StoredDPValues.end(), StoredDPValues.end()}; 377*5f757f3fSDimitry Andric 378*5f757f3fSDimitry Andric if (InsertAtHead) 379*5f757f3fSDimitry Andric // If InsertAtHead is set, we cloned a range onto the front of of the 380*5f757f3fSDimitry Andric // StoredDPValues collection, return that range. 381*5f757f3fSDimitry Andric return {StoredDPValues.begin(), Pos}; 382*5f757f3fSDimitry Andric else 383*5f757f3fSDimitry Andric // We inserted a block at the end, return that range. 384*5f757f3fSDimitry Andric return {First->getIterator(), StoredDPValues.end()}; 385*5f757f3fSDimitry Andric } 386*5f757f3fSDimitry Andric 387*5f757f3fSDimitry Andric } // end namespace llvm 388*5f757f3fSDimitry Andric 389