1*0fca6ea1SDimitry Andric //=====-- DebugProgramInstruction.cpp - Implement DbgRecords/DbgMarkers --====// 25f757f3fSDimitry Andric // 35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65f757f3fSDimitry Andric // 75f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 85f757f3fSDimitry Andric 95f757f3fSDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 105f757f3fSDimitry Andric #include "llvm/IR/DebugProgramInstruction.h" 115f757f3fSDimitry Andric #include "llvm/IR/DIBuilder.h" 125f757f3fSDimitry Andric #include "llvm/IR/IntrinsicInst.h" 135f757f3fSDimitry Andric 145f757f3fSDimitry Andric namespace llvm { 155f757f3fSDimitry Andric 16*0fca6ea1SDimitry Andric template <typename T> 17*0fca6ea1SDimitry Andric DbgRecordParamRef<T>::DbgRecordParamRef(const T *Param) 18*0fca6ea1SDimitry Andric : Ref(const_cast<T *>(Param)) {} 19*0fca6ea1SDimitry Andric template <typename T> 20*0fca6ea1SDimitry Andric DbgRecordParamRef<T>::DbgRecordParamRef(const MDNode *Param) 21*0fca6ea1SDimitry Andric : Ref(const_cast<MDNode *>(Param)) {} 22*0fca6ea1SDimitry Andric 23*0fca6ea1SDimitry Andric template <typename T> T *DbgRecordParamRef<T>::get() const { 24*0fca6ea1SDimitry Andric return cast<T>(Ref); 25*0fca6ea1SDimitry Andric } 26*0fca6ea1SDimitry Andric 27*0fca6ea1SDimitry Andric template class DbgRecordParamRef<DIExpression>; 28*0fca6ea1SDimitry Andric template class DbgRecordParamRef<DILabel>; 29*0fca6ea1SDimitry Andric template class DbgRecordParamRef<DILocalVariable>; 30*0fca6ea1SDimitry Andric 31*0fca6ea1SDimitry Andric DbgVariableRecord::DbgVariableRecord(const DbgVariableIntrinsic *DVI) 32*0fca6ea1SDimitry Andric : DbgRecord(ValueKind, DVI->getDebugLoc()), 33*0fca6ea1SDimitry Andric DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}), 347a6dacacSDimitry Andric Variable(DVI->getVariable()), Expression(DVI->getExpression()), 35*0fca6ea1SDimitry Andric AddressExpression() { 365f757f3fSDimitry Andric switch (DVI->getIntrinsicID()) { 375f757f3fSDimitry Andric case Intrinsic::dbg_value: 385f757f3fSDimitry Andric Type = LocationType::Value; 395f757f3fSDimitry Andric break; 405f757f3fSDimitry Andric case Intrinsic::dbg_declare: 415f757f3fSDimitry Andric Type = LocationType::Declare; 425f757f3fSDimitry Andric break; 437a6dacacSDimitry Andric case Intrinsic::dbg_assign: { 447a6dacacSDimitry Andric Type = LocationType::Assign; 457a6dacacSDimitry Andric const DbgAssignIntrinsic *Assign = 467a6dacacSDimitry Andric static_cast<const DbgAssignIntrinsic *>(DVI); 477a6dacacSDimitry Andric resetDebugValue(1, Assign->getRawAddress()); 487a6dacacSDimitry Andric AddressExpression = Assign->getAddressExpression(); 497a6dacacSDimitry Andric setAssignId(Assign->getAssignID()); 507a6dacacSDimitry Andric break; 517a6dacacSDimitry Andric } 525f757f3fSDimitry Andric default: 535f757f3fSDimitry Andric llvm_unreachable( 54*0fca6ea1SDimitry Andric "Trying to create a DbgVariableRecord with an invalid intrinsic type!"); 555f757f3fSDimitry Andric } 565f757f3fSDimitry Andric } 575f757f3fSDimitry Andric 58*0fca6ea1SDimitry Andric DbgVariableRecord::DbgVariableRecord(const DbgVariableRecord &DVR) 59*0fca6ea1SDimitry Andric : DbgRecord(ValueKind, DVR.getDebugLoc()), DebugValueUser(DVR.DebugValues), 60*0fca6ea1SDimitry Andric Type(DVR.getType()), Variable(DVR.getVariable()), 61*0fca6ea1SDimitry Andric Expression(DVR.getExpression()), 62*0fca6ea1SDimitry Andric AddressExpression(DVR.AddressExpression) {} 635f757f3fSDimitry Andric 64*0fca6ea1SDimitry Andric DbgVariableRecord::DbgVariableRecord(Metadata *Location, DILocalVariable *DV, 65*0fca6ea1SDimitry Andric DIExpression *Expr, const DILocation *DI, 66*0fca6ea1SDimitry Andric LocationType Type) 67*0fca6ea1SDimitry Andric : DbgRecord(ValueKind, DI), DebugValueUser({Location, nullptr, nullptr}), 68*0fca6ea1SDimitry Andric Type(Type), Variable(DV), Expression(Expr) {} 697a6dacacSDimitry Andric 70*0fca6ea1SDimitry Andric DbgVariableRecord::DbgVariableRecord(Metadata *Value, DILocalVariable *Variable, 71*0fca6ea1SDimitry Andric DIExpression *Expression, 72*0fca6ea1SDimitry Andric DIAssignID *AssignID, Metadata *Address, 73*0fca6ea1SDimitry Andric DIExpression *AddressExpression, 747a6dacacSDimitry Andric const DILocation *DI) 75*0fca6ea1SDimitry Andric : DbgRecord(ValueKind, DI), DebugValueUser({Value, Address, AssignID}), 76*0fca6ea1SDimitry Andric Type(LocationType::Assign), Variable(Variable), Expression(Expression), 77*0fca6ea1SDimitry Andric AddressExpression(AddressExpression) {} 785f757f3fSDimitry Andric 79*0fca6ea1SDimitry Andric void DbgRecord::deleteRecord() { 80*0fca6ea1SDimitry Andric switch (RecordKind) { 81*0fca6ea1SDimitry Andric case ValueKind: 82*0fca6ea1SDimitry Andric delete cast<DbgVariableRecord>(this); 83*0fca6ea1SDimitry Andric return; 84*0fca6ea1SDimitry Andric case LabelKind: 85*0fca6ea1SDimitry Andric delete cast<DbgLabelRecord>(this); 86*0fca6ea1SDimitry Andric return; 87*0fca6ea1SDimitry Andric } 88*0fca6ea1SDimitry Andric llvm_unreachable("unsupported DbgRecord kind"); 89*0fca6ea1SDimitry Andric } 905f757f3fSDimitry Andric 91*0fca6ea1SDimitry Andric void DbgRecord::print(raw_ostream &O, bool IsForDebug) const { 92*0fca6ea1SDimitry Andric switch (RecordKind) { 93*0fca6ea1SDimitry Andric case ValueKind: 94*0fca6ea1SDimitry Andric cast<DbgVariableRecord>(this)->print(O, IsForDebug); 95*0fca6ea1SDimitry Andric return; 96*0fca6ea1SDimitry Andric case LabelKind: 97*0fca6ea1SDimitry Andric cast<DbgLabelRecord>(this)->print(O, IsForDebug); 98*0fca6ea1SDimitry Andric return; 99*0fca6ea1SDimitry Andric }; 100*0fca6ea1SDimitry Andric llvm_unreachable("unsupported DbgRecord kind"); 101*0fca6ea1SDimitry Andric } 102*0fca6ea1SDimitry Andric 103*0fca6ea1SDimitry Andric void DbgRecord::print(raw_ostream &O, ModuleSlotTracker &MST, 104*0fca6ea1SDimitry Andric bool IsForDebug) const { 105*0fca6ea1SDimitry Andric switch (RecordKind) { 106*0fca6ea1SDimitry Andric case ValueKind: 107*0fca6ea1SDimitry Andric cast<DbgVariableRecord>(this)->print(O, MST, IsForDebug); 108*0fca6ea1SDimitry Andric return; 109*0fca6ea1SDimitry Andric case LabelKind: 110*0fca6ea1SDimitry Andric cast<DbgLabelRecord>(this)->print(O, MST, IsForDebug); 111*0fca6ea1SDimitry Andric return; 112*0fca6ea1SDimitry Andric }; 113*0fca6ea1SDimitry Andric llvm_unreachable("unsupported DbgRecord kind"); 114*0fca6ea1SDimitry Andric } 115*0fca6ea1SDimitry Andric 116*0fca6ea1SDimitry Andric bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const { 117*0fca6ea1SDimitry Andric if (RecordKind != R.RecordKind) 118*0fca6ea1SDimitry Andric return false; 119*0fca6ea1SDimitry Andric switch (RecordKind) { 120*0fca6ea1SDimitry Andric case ValueKind: 121*0fca6ea1SDimitry Andric return cast<DbgVariableRecord>(this)->isIdenticalToWhenDefined( 122*0fca6ea1SDimitry Andric *cast<DbgVariableRecord>(&R)); 123*0fca6ea1SDimitry Andric case LabelKind: 124*0fca6ea1SDimitry Andric return cast<DbgLabelRecord>(this)->getLabel() == 125*0fca6ea1SDimitry Andric cast<DbgLabelRecord>(R).getLabel(); 126*0fca6ea1SDimitry Andric }; 127*0fca6ea1SDimitry Andric llvm_unreachable("unsupported DbgRecord kind"); 128*0fca6ea1SDimitry Andric } 129*0fca6ea1SDimitry Andric 130*0fca6ea1SDimitry Andric bool DbgRecord::isEquivalentTo(const DbgRecord &R) const { 131*0fca6ea1SDimitry Andric return getDebugLoc() == R.getDebugLoc() && isIdenticalToWhenDefined(R); 132*0fca6ea1SDimitry Andric } 133*0fca6ea1SDimitry Andric 134*0fca6ea1SDimitry Andric DbgInfoIntrinsic * 135*0fca6ea1SDimitry Andric DbgRecord::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const { 136*0fca6ea1SDimitry Andric switch (RecordKind) { 137*0fca6ea1SDimitry Andric case ValueKind: 138*0fca6ea1SDimitry Andric return cast<DbgVariableRecord>(this)->createDebugIntrinsic(M, InsertBefore); 139*0fca6ea1SDimitry Andric case LabelKind: 140*0fca6ea1SDimitry Andric return cast<DbgLabelRecord>(this)->createDebugIntrinsic(M, InsertBefore); 141*0fca6ea1SDimitry Andric }; 142*0fca6ea1SDimitry Andric llvm_unreachable("unsupported DbgRecord kind"); 143*0fca6ea1SDimitry Andric } 144*0fca6ea1SDimitry Andric 145*0fca6ea1SDimitry Andric DbgLabelRecord::DbgLabelRecord(MDNode *Label, MDNode *DL) 146*0fca6ea1SDimitry Andric : DbgRecord(LabelKind, DebugLoc(DL)), Label(Label) { 147*0fca6ea1SDimitry Andric assert(Label && "Unexpected nullptr"); 148*0fca6ea1SDimitry Andric assert((isa<DILabel>(Label) || Label->isTemporary()) && 149*0fca6ea1SDimitry Andric "Label type must be or resolve to a DILabel"); 150*0fca6ea1SDimitry Andric } 151*0fca6ea1SDimitry Andric DbgLabelRecord::DbgLabelRecord(DILabel *Label, DebugLoc DL) 152*0fca6ea1SDimitry Andric : DbgRecord(LabelKind, DL), Label(Label) { 153*0fca6ea1SDimitry Andric assert(Label && "Unexpected nullptr"); 154*0fca6ea1SDimitry Andric } 155*0fca6ea1SDimitry Andric 156*0fca6ea1SDimitry Andric DbgLabelRecord *DbgLabelRecord::createUnresolvedDbgLabelRecord(MDNode *Label, 157*0fca6ea1SDimitry Andric MDNode *DL) { 158*0fca6ea1SDimitry Andric return new DbgLabelRecord(Label, DL); 159*0fca6ea1SDimitry Andric } 160*0fca6ea1SDimitry Andric 161*0fca6ea1SDimitry Andric DbgVariableRecord::DbgVariableRecord(DbgVariableRecord::LocationType Type, 162*0fca6ea1SDimitry Andric Metadata *Val, MDNode *Variable, 163*0fca6ea1SDimitry Andric MDNode *Expression, MDNode *AssignID, 164*0fca6ea1SDimitry Andric Metadata *Address, 165*0fca6ea1SDimitry Andric MDNode *AddressExpression, MDNode *DI) 166*0fca6ea1SDimitry Andric : DbgRecord(ValueKind, DebugLoc(DI)), 167*0fca6ea1SDimitry Andric DebugValueUser({Val, Address, AssignID}), Type(Type), Variable(Variable), 168*0fca6ea1SDimitry Andric Expression(Expression), AddressExpression(AddressExpression) {} 169*0fca6ea1SDimitry Andric 170*0fca6ea1SDimitry Andric DbgVariableRecord *DbgVariableRecord::createUnresolvedDbgVariableRecord( 171*0fca6ea1SDimitry Andric DbgVariableRecord::LocationType Type, Metadata *Val, MDNode *Variable, 172*0fca6ea1SDimitry Andric MDNode *Expression, MDNode *AssignID, Metadata *Address, 173*0fca6ea1SDimitry Andric MDNode *AddressExpression, MDNode *DI) { 174*0fca6ea1SDimitry Andric return new DbgVariableRecord(Type, Val, Variable, Expression, AssignID, 175*0fca6ea1SDimitry Andric Address, AddressExpression, DI); 176*0fca6ea1SDimitry Andric } 177*0fca6ea1SDimitry Andric 178*0fca6ea1SDimitry Andric DbgVariableRecord * 179*0fca6ea1SDimitry Andric DbgVariableRecord::createDbgVariableRecord(Value *Location, DILocalVariable *DV, 180*0fca6ea1SDimitry Andric DIExpression *Expr, 181*0fca6ea1SDimitry Andric const DILocation *DI) { 182*0fca6ea1SDimitry Andric return new DbgVariableRecord(ValueAsMetadata::get(Location), DV, Expr, DI, 1837a6dacacSDimitry Andric LocationType::Value); 1847a6dacacSDimitry Andric } 1857a6dacacSDimitry Andric 186*0fca6ea1SDimitry Andric DbgVariableRecord *DbgVariableRecord::createDbgVariableRecord( 187*0fca6ea1SDimitry Andric Value *Location, DILocalVariable *DV, DIExpression *Expr, 188*0fca6ea1SDimitry Andric const DILocation *DI, DbgVariableRecord &InsertBefore) { 189*0fca6ea1SDimitry Andric auto *NewDbgVariableRecord = createDbgVariableRecord(Location, DV, Expr, DI); 190*0fca6ea1SDimitry Andric NewDbgVariableRecord->insertBefore(&InsertBefore); 191*0fca6ea1SDimitry Andric return NewDbgVariableRecord; 1927a6dacacSDimitry Andric } 1937a6dacacSDimitry Andric 194*0fca6ea1SDimitry Andric DbgVariableRecord *DbgVariableRecord::createDVRDeclare(Value *Address, 195*0fca6ea1SDimitry Andric DILocalVariable *DV, 196*0fca6ea1SDimitry Andric DIExpression *Expr, 197*0fca6ea1SDimitry Andric const DILocation *DI) { 198*0fca6ea1SDimitry Andric return new DbgVariableRecord(ValueAsMetadata::get(Address), DV, Expr, DI, 1997a6dacacSDimitry Andric LocationType::Declare); 2007a6dacacSDimitry Andric } 2017a6dacacSDimitry Andric 202*0fca6ea1SDimitry Andric DbgVariableRecord * 203*0fca6ea1SDimitry Andric DbgVariableRecord::createDVRDeclare(Value *Address, DILocalVariable *DV, 2047a6dacacSDimitry Andric DIExpression *Expr, const DILocation *DI, 205*0fca6ea1SDimitry Andric DbgVariableRecord &InsertBefore) { 206*0fca6ea1SDimitry Andric auto *NewDVRDeclare = createDVRDeclare(Address, DV, Expr, DI); 207*0fca6ea1SDimitry Andric NewDVRDeclare->insertBefore(&InsertBefore); 208*0fca6ea1SDimitry Andric return NewDVRDeclare; 2097a6dacacSDimitry Andric } 2107a6dacacSDimitry Andric 211*0fca6ea1SDimitry Andric DbgVariableRecord *DbgVariableRecord::createDVRAssign( 212*0fca6ea1SDimitry Andric Value *Val, DILocalVariable *Variable, DIExpression *Expression, 213*0fca6ea1SDimitry Andric DIAssignID *AssignID, Value *Address, DIExpression *AddressExpression, 2147a6dacacSDimitry Andric const DILocation *DI) { 215*0fca6ea1SDimitry Andric return new DbgVariableRecord(ValueAsMetadata::get(Val), Variable, Expression, 216*0fca6ea1SDimitry Andric AssignID, ValueAsMetadata::get(Address), 217*0fca6ea1SDimitry Andric AddressExpression, DI); 2187a6dacacSDimitry Andric } 2197a6dacacSDimitry Andric 220*0fca6ea1SDimitry Andric DbgVariableRecord *DbgVariableRecord::createLinkedDVRAssign( 221*0fca6ea1SDimitry Andric Instruction *LinkedInstr, Value *Val, DILocalVariable *Variable, 222*0fca6ea1SDimitry Andric DIExpression *Expression, Value *Address, DIExpression *AddressExpression, 2237a6dacacSDimitry Andric const DILocation *DI) { 2247a6dacacSDimitry Andric auto *Link = LinkedInstr->getMetadata(LLVMContext::MD_DIAssignID); 2257a6dacacSDimitry Andric assert(Link && "Linked instruction must have DIAssign metadata attached"); 226*0fca6ea1SDimitry Andric auto *NewDVRAssign = DbgVariableRecord::createDVRAssign( 227*0fca6ea1SDimitry Andric Val, Variable, Expression, cast<DIAssignID>(Link), Address, 2287a6dacacSDimitry Andric AddressExpression, DI); 229*0fca6ea1SDimitry Andric LinkedInstr->getParent()->insertDbgRecordAfter(NewDVRAssign, LinkedInstr); 230*0fca6ea1SDimitry Andric return NewDVRAssign; 2317a6dacacSDimitry Andric } 2327a6dacacSDimitry Andric 233*0fca6ea1SDimitry Andric iterator_range<DbgVariableRecord::location_op_iterator> 234*0fca6ea1SDimitry Andric DbgVariableRecord::location_ops() const { 2355f757f3fSDimitry Andric auto *MD = getRawLocation(); 236*0fca6ea1SDimitry Andric // If a Value has been deleted, the "location" for this DbgVariableRecord will 237*0fca6ea1SDimitry Andric // be replaced by nullptr. Return an empty range. 2385f757f3fSDimitry Andric if (!MD) 2395f757f3fSDimitry Andric return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)), 2405f757f3fSDimitry Andric location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))}; 2415f757f3fSDimitry Andric 2425f757f3fSDimitry Andric // If operand is ValueAsMetadata, return a range over just that operand. 2435f757f3fSDimitry Andric if (auto *VAM = dyn_cast<ValueAsMetadata>(MD)) 2445f757f3fSDimitry Andric return {location_op_iterator(VAM), location_op_iterator(VAM + 1)}; 2455f757f3fSDimitry Andric 2465f757f3fSDimitry Andric // If operand is DIArgList, return a range over its args. 2475f757f3fSDimitry Andric if (auto *AL = dyn_cast<DIArgList>(MD)) 2485f757f3fSDimitry Andric return {location_op_iterator(AL->args_begin()), 2495f757f3fSDimitry Andric location_op_iterator(AL->args_end())}; 2505f757f3fSDimitry Andric 2515f757f3fSDimitry Andric // Operand is an empty metadata tuple, so return empty iterator. 2525f757f3fSDimitry Andric assert(cast<MDNode>(MD)->getNumOperands() == 0); 2535f757f3fSDimitry Andric return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)), 2545f757f3fSDimitry Andric location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))}; 2555f757f3fSDimitry Andric } 2565f757f3fSDimitry Andric 257*0fca6ea1SDimitry Andric unsigned DbgVariableRecord::getNumVariableLocationOps() const { 2585f757f3fSDimitry Andric if (hasArgList()) 2595f757f3fSDimitry Andric return cast<DIArgList>(getRawLocation())->getArgs().size(); 2605f757f3fSDimitry Andric return 1; 2615f757f3fSDimitry Andric } 2625f757f3fSDimitry Andric 263*0fca6ea1SDimitry Andric Value *DbgVariableRecord::getVariableLocationOp(unsigned OpIdx) const { 2645f757f3fSDimitry Andric auto *MD = getRawLocation(); 2655f757f3fSDimitry Andric if (!MD) 2665f757f3fSDimitry Andric return nullptr; 2675f757f3fSDimitry Andric 2685f757f3fSDimitry Andric if (auto *AL = dyn_cast<DIArgList>(MD)) 2695f757f3fSDimitry Andric return AL->getArgs()[OpIdx]->getValue(); 2705f757f3fSDimitry Andric if (isa<MDNode>(MD)) 2715f757f3fSDimitry Andric return nullptr; 2725f757f3fSDimitry Andric assert(isa<ValueAsMetadata>(MD) && 273*0fca6ea1SDimitry Andric "Attempted to get location operand from DbgVariableRecord with none."); 2745f757f3fSDimitry Andric auto *V = cast<ValueAsMetadata>(MD); 2755f757f3fSDimitry Andric assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a " 2765f757f3fSDimitry Andric "single location operand."); 2775f757f3fSDimitry Andric return V->getValue(); 2785f757f3fSDimitry Andric } 2795f757f3fSDimitry Andric 2805f757f3fSDimitry Andric static ValueAsMetadata *getAsMetadata(Value *V) { 2815f757f3fSDimitry Andric return isa<MetadataAsValue>(V) ? dyn_cast<ValueAsMetadata>( 2825f757f3fSDimitry Andric cast<MetadataAsValue>(V)->getMetadata()) 2835f757f3fSDimitry Andric : ValueAsMetadata::get(V); 2845f757f3fSDimitry Andric } 2855f757f3fSDimitry Andric 286*0fca6ea1SDimitry Andric void DbgVariableRecord::replaceVariableLocationOp(Value *OldValue, 287*0fca6ea1SDimitry Andric Value *NewValue, 2885f757f3fSDimitry Andric bool AllowEmpty) { 2895f757f3fSDimitry Andric assert(NewValue && "Values must be non-null"); 2907a6dacacSDimitry Andric 2917a6dacacSDimitry Andric bool DbgAssignAddrReplaced = isDbgAssign() && OldValue == getAddress(); 2927a6dacacSDimitry Andric if (DbgAssignAddrReplaced) 2937a6dacacSDimitry Andric setAddress(NewValue); 2947a6dacacSDimitry Andric 2955f757f3fSDimitry Andric auto Locations = location_ops(); 2965f757f3fSDimitry Andric auto OldIt = find(Locations, OldValue); 2975f757f3fSDimitry Andric if (OldIt == Locations.end()) { 2987a6dacacSDimitry Andric if (AllowEmpty || DbgAssignAddrReplaced) 2995f757f3fSDimitry Andric return; 3005f757f3fSDimitry Andric llvm_unreachable("OldValue must be a current location"); 3015f757f3fSDimitry Andric } 3025f757f3fSDimitry Andric 3035f757f3fSDimitry Andric if (!hasArgList()) { 3045f757f3fSDimitry Andric // Set our location to be the MAV wrapping the new Value. 3055f757f3fSDimitry Andric setRawLocation(isa<MetadataAsValue>(NewValue) 3065f757f3fSDimitry Andric ? cast<MetadataAsValue>(NewValue)->getMetadata() 3075f757f3fSDimitry Andric : ValueAsMetadata::get(NewValue)); 3085f757f3fSDimitry Andric return; 3095f757f3fSDimitry Andric } 3105f757f3fSDimitry Andric 3115f757f3fSDimitry Andric // We must be referring to a DIArgList, produce a new operands vector with the 3125f757f3fSDimitry Andric // old value replaced, generate a new DIArgList and set it as our location. 3135f757f3fSDimitry Andric SmallVector<ValueAsMetadata *, 4> MDs; 3145f757f3fSDimitry Andric ValueAsMetadata *NewOperand = getAsMetadata(NewValue); 3155f757f3fSDimitry Andric for (auto *VMD : Locations) 3165f757f3fSDimitry Andric MDs.push_back(VMD == *OldIt ? NewOperand : getAsMetadata(VMD)); 3175f757f3fSDimitry Andric setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs)); 3185f757f3fSDimitry Andric } 3195f757f3fSDimitry Andric 320*0fca6ea1SDimitry Andric void DbgVariableRecord::replaceVariableLocationOp(unsigned OpIdx, 321*0fca6ea1SDimitry Andric Value *NewValue) { 3225f757f3fSDimitry Andric assert(OpIdx < getNumVariableLocationOps() && "Invalid Operand Index"); 3235f757f3fSDimitry Andric 3245f757f3fSDimitry Andric if (!hasArgList()) { 3255f757f3fSDimitry Andric setRawLocation(isa<MetadataAsValue>(NewValue) 3265f757f3fSDimitry Andric ? cast<MetadataAsValue>(NewValue)->getMetadata() 3275f757f3fSDimitry Andric : ValueAsMetadata::get(NewValue)); 3285f757f3fSDimitry Andric return; 3295f757f3fSDimitry Andric } 3305f757f3fSDimitry Andric 3315f757f3fSDimitry Andric SmallVector<ValueAsMetadata *, 4> MDs; 3325f757f3fSDimitry Andric ValueAsMetadata *NewOperand = getAsMetadata(NewValue); 3335f757f3fSDimitry Andric for (unsigned Idx = 0; Idx < getNumVariableLocationOps(); ++Idx) 3345f757f3fSDimitry Andric MDs.push_back(Idx == OpIdx ? NewOperand 3355f757f3fSDimitry Andric : getAsMetadata(getVariableLocationOp(Idx))); 3365f757f3fSDimitry Andric 3375f757f3fSDimitry Andric setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs)); 3385f757f3fSDimitry Andric } 3395f757f3fSDimitry Andric 340*0fca6ea1SDimitry Andric void DbgVariableRecord::addVariableLocationOps(ArrayRef<Value *> NewValues, 3415f757f3fSDimitry Andric DIExpression *NewExpr) { 3425f757f3fSDimitry Andric assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() + 3435f757f3fSDimitry Andric NewValues.size()) && 3445f757f3fSDimitry Andric "NewExpr for debug variable intrinsic does not reference every " 3455f757f3fSDimitry Andric "location operand."); 3465f757f3fSDimitry Andric assert(!is_contained(NewValues, nullptr) && "New values must be non-null"); 3475f757f3fSDimitry Andric setExpression(NewExpr); 3485f757f3fSDimitry Andric SmallVector<ValueAsMetadata *, 4> MDs; 3495f757f3fSDimitry Andric for (auto *VMD : location_ops()) 3505f757f3fSDimitry Andric MDs.push_back(getAsMetadata(VMD)); 3515f757f3fSDimitry Andric for (auto *VMD : NewValues) 3525f757f3fSDimitry Andric MDs.push_back(getAsMetadata(VMD)); 3535f757f3fSDimitry Andric setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs)); 3545f757f3fSDimitry Andric } 3555f757f3fSDimitry Andric 356*0fca6ea1SDimitry Andric void DbgVariableRecord::setKillLocation() { 3575f757f3fSDimitry Andric // TODO: When/if we remove duplicate values from DIArgLists, we don't need 3585f757f3fSDimitry Andric // this set anymore. 3595f757f3fSDimitry Andric SmallPtrSet<Value *, 4> RemovedValues; 3605f757f3fSDimitry Andric for (Value *OldValue : location_ops()) { 3615f757f3fSDimitry Andric if (!RemovedValues.insert(OldValue).second) 3625f757f3fSDimitry Andric continue; 3635f757f3fSDimitry Andric Value *Poison = PoisonValue::get(OldValue->getType()); 3645f757f3fSDimitry Andric replaceVariableLocationOp(OldValue, Poison); 3655f757f3fSDimitry Andric } 3665f757f3fSDimitry Andric } 3675f757f3fSDimitry Andric 368*0fca6ea1SDimitry Andric bool DbgVariableRecord::isKillLocation() const { 369*0fca6ea1SDimitry Andric return (!hasArgList() && isa<MDNode>(getRawLocation())) || 370*0fca6ea1SDimitry Andric (getNumVariableLocationOps() == 0 && !getExpression()->isComplex()) || 3715f757f3fSDimitry Andric any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); }); 3725f757f3fSDimitry Andric } 3735f757f3fSDimitry Andric 374*0fca6ea1SDimitry Andric std::optional<DbgVariableFragmentInfo> DbgVariableRecord::getFragment() const { 375*0fca6ea1SDimitry Andric return getExpression()->getFragmentInfo(); 376*0fca6ea1SDimitry Andric } 377*0fca6ea1SDimitry Andric 378*0fca6ea1SDimitry Andric std::optional<uint64_t> DbgVariableRecord::getFragmentSizeInBits() const { 3795f757f3fSDimitry Andric if (auto Fragment = getExpression()->getFragmentInfo()) 3805f757f3fSDimitry Andric return Fragment->SizeInBits; 3815f757f3fSDimitry Andric return getVariable()->getSizeInBits(); 3825f757f3fSDimitry Andric } 3835f757f3fSDimitry Andric 384*0fca6ea1SDimitry Andric DbgRecord *DbgRecord::clone() const { 385*0fca6ea1SDimitry Andric switch (RecordKind) { 386*0fca6ea1SDimitry Andric case ValueKind: 387*0fca6ea1SDimitry Andric return cast<DbgVariableRecord>(this)->clone(); 388*0fca6ea1SDimitry Andric case LabelKind: 389*0fca6ea1SDimitry Andric return cast<DbgLabelRecord>(this)->clone(); 390*0fca6ea1SDimitry Andric }; 391*0fca6ea1SDimitry Andric llvm_unreachable("unsupported DbgRecord kind"); 392*0fca6ea1SDimitry Andric } 393*0fca6ea1SDimitry Andric 394*0fca6ea1SDimitry Andric DbgVariableRecord *DbgVariableRecord::clone() const { 395*0fca6ea1SDimitry Andric return new DbgVariableRecord(*this); 396*0fca6ea1SDimitry Andric } 397*0fca6ea1SDimitry Andric 398*0fca6ea1SDimitry Andric DbgLabelRecord *DbgLabelRecord::clone() const { 399*0fca6ea1SDimitry Andric return new DbgLabelRecord(getLabel(), getDebugLoc()); 400*0fca6ea1SDimitry Andric } 4015f757f3fSDimitry Andric 4025f757f3fSDimitry Andric DbgVariableIntrinsic * 403*0fca6ea1SDimitry Andric DbgVariableRecord::createDebugIntrinsic(Module *M, 404*0fca6ea1SDimitry Andric Instruction *InsertBefore) const { 4055f757f3fSDimitry Andric [[maybe_unused]] DICompileUnit *Unit = 406*0fca6ea1SDimitry Andric getDebugLoc()->getScope()->getSubprogram()->getUnit(); 4075f757f3fSDimitry Andric assert(M && Unit && 4085f757f3fSDimitry Andric "Cannot clone from BasicBlock that is not part of a Module or " 4095f757f3fSDimitry Andric "DICompileUnit!"); 4105f757f3fSDimitry Andric LLVMContext &Context = getDebugLoc()->getContext(); 4115f757f3fSDimitry Andric Function *IntrinsicFn; 4125f757f3fSDimitry Andric 4135f757f3fSDimitry Andric // Work out what sort of intrinsic we're going to produce. 4145f757f3fSDimitry Andric switch (getType()) { 415*0fca6ea1SDimitry Andric case DbgVariableRecord::LocationType::Declare: 4165f757f3fSDimitry Andric IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_declare); 4175f757f3fSDimitry Andric break; 418*0fca6ea1SDimitry Andric case DbgVariableRecord::LocationType::Value: 4195f757f3fSDimitry Andric IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_value); 4205f757f3fSDimitry Andric break; 421*0fca6ea1SDimitry Andric case DbgVariableRecord::LocationType::Assign: 4227a6dacacSDimitry Andric IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_assign); 4237a6dacacSDimitry Andric break; 424*0fca6ea1SDimitry Andric case DbgVariableRecord::LocationType::End: 425*0fca6ea1SDimitry Andric case DbgVariableRecord::LocationType::Any: 4265f757f3fSDimitry Andric llvm_unreachable("Invalid LocationType"); 4275f757f3fSDimitry Andric } 4285f757f3fSDimitry Andric 429*0fca6ea1SDimitry Andric // Create the intrinsic from this DbgVariableRecord's information, optionally 430*0fca6ea1SDimitry Andric // insert into the target location. 4317a6dacacSDimitry Andric DbgVariableIntrinsic *DVI; 432*0fca6ea1SDimitry Andric assert(getRawLocation() && 433*0fca6ea1SDimitry Andric "DbgVariableRecord's RawLocation should be non-null."); 4347a6dacacSDimitry Andric if (isDbgAssign()) { 4357a6dacacSDimitry Andric Value *AssignArgs[] = { 4367a6dacacSDimitry Andric MetadataAsValue::get(Context, getRawLocation()), 4377a6dacacSDimitry Andric MetadataAsValue::get(Context, getVariable()), 4387a6dacacSDimitry Andric MetadataAsValue::get(Context, getExpression()), 4397a6dacacSDimitry Andric MetadataAsValue::get(Context, getAssignID()), 4407a6dacacSDimitry Andric MetadataAsValue::get(Context, getRawAddress()), 4417a6dacacSDimitry Andric MetadataAsValue::get(Context, getAddressExpression())}; 4427a6dacacSDimitry Andric DVI = cast<DbgVariableIntrinsic>(CallInst::Create( 4437a6dacacSDimitry Andric IntrinsicFn->getFunctionType(), IntrinsicFn, AssignArgs)); 4447a6dacacSDimitry Andric } else { 4457a6dacacSDimitry Andric Value *Args[] = {MetadataAsValue::get(Context, getRawLocation()), 4467a6dacacSDimitry Andric MetadataAsValue::get(Context, getVariable()), 4477a6dacacSDimitry Andric MetadataAsValue::get(Context, getExpression())}; 4487a6dacacSDimitry Andric DVI = cast<DbgVariableIntrinsic>( 4495f757f3fSDimitry Andric CallInst::Create(IntrinsicFn->getFunctionType(), IntrinsicFn, Args)); 4507a6dacacSDimitry Andric } 4515f757f3fSDimitry Andric DVI->setTailCall(); 4525f757f3fSDimitry Andric DVI->setDebugLoc(getDebugLoc()); 4535f757f3fSDimitry Andric if (InsertBefore) 4545f757f3fSDimitry Andric DVI->insertBefore(InsertBefore); 4555f757f3fSDimitry Andric 4565f757f3fSDimitry Andric return DVI; 4575f757f3fSDimitry Andric } 4585f757f3fSDimitry Andric 459*0fca6ea1SDimitry Andric DbgLabelInst * 460*0fca6ea1SDimitry Andric DbgLabelRecord::createDebugIntrinsic(Module *M, 461*0fca6ea1SDimitry Andric Instruction *InsertBefore) const { 462*0fca6ea1SDimitry Andric auto *LabelFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_label); 463*0fca6ea1SDimitry Andric Value *Args[] = { 464*0fca6ea1SDimitry Andric MetadataAsValue::get(getDebugLoc()->getContext(), getLabel())}; 465*0fca6ea1SDimitry Andric DbgLabelInst *DbgLabel = cast<DbgLabelInst>( 466*0fca6ea1SDimitry Andric CallInst::Create(LabelFn->getFunctionType(), LabelFn, Args)); 467*0fca6ea1SDimitry Andric DbgLabel->setTailCall(); 468*0fca6ea1SDimitry Andric DbgLabel->setDebugLoc(getDebugLoc()); 469*0fca6ea1SDimitry Andric if (InsertBefore) 470*0fca6ea1SDimitry Andric DbgLabel->insertBefore(InsertBefore); 471*0fca6ea1SDimitry Andric return DbgLabel; 472*0fca6ea1SDimitry Andric } 473*0fca6ea1SDimitry Andric 474*0fca6ea1SDimitry Andric Value *DbgVariableRecord::getAddress() const { 4757a6dacacSDimitry Andric auto *MD = getRawAddress(); 4767a6dacacSDimitry Andric if (auto *V = dyn_cast<ValueAsMetadata>(MD)) 4777a6dacacSDimitry Andric return V->getValue(); 4787a6dacacSDimitry Andric 4797a6dacacSDimitry Andric // When the value goes to null, it gets replaced by an empty MDNode. 4807a6dacacSDimitry Andric assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode"); 4817a6dacacSDimitry Andric return nullptr; 4827a6dacacSDimitry Andric } 4837a6dacacSDimitry Andric 484*0fca6ea1SDimitry Andric DIAssignID *DbgVariableRecord::getAssignID() const { 4857a6dacacSDimitry Andric return cast<DIAssignID>(DebugValues[2]); 4867a6dacacSDimitry Andric } 4877a6dacacSDimitry Andric 488*0fca6ea1SDimitry Andric void DbgVariableRecord::setAssignId(DIAssignID *New) { 489*0fca6ea1SDimitry Andric resetDebugValue(2, New); 490*0fca6ea1SDimitry Andric } 4917a6dacacSDimitry Andric 492*0fca6ea1SDimitry Andric void DbgVariableRecord::setKillAddress() { 4937a6dacacSDimitry Andric resetDebugValue( 4947a6dacacSDimitry Andric 1, ValueAsMetadata::get(UndefValue::get(getAddress()->getType()))); 4957a6dacacSDimitry Andric } 4967a6dacacSDimitry Andric 497*0fca6ea1SDimitry Andric bool DbgVariableRecord::isKillAddress() const { 4987a6dacacSDimitry Andric Value *Addr = getAddress(); 4997a6dacacSDimitry Andric return !Addr || isa<UndefValue>(Addr); 5005f757f3fSDimitry Andric } 5015f757f3fSDimitry Andric 502*0fca6ea1SDimitry Andric const Instruction *DbgRecord::getInstruction() const { 503*0fca6ea1SDimitry Andric return Marker->MarkedInstr; 504*0fca6ea1SDimitry Andric } 505*0fca6ea1SDimitry Andric 506*0fca6ea1SDimitry Andric const BasicBlock *DbgRecord::getParent() const { 5075f757f3fSDimitry Andric return Marker->MarkedInstr->getParent(); 5085f757f3fSDimitry Andric } 5095f757f3fSDimitry Andric 510*0fca6ea1SDimitry Andric BasicBlock *DbgRecord::getParent() { return Marker->MarkedInstr->getParent(); } 5115f757f3fSDimitry Andric 512*0fca6ea1SDimitry Andric BasicBlock *DbgRecord::getBlock() { return Marker->getParent(); } 5135f757f3fSDimitry Andric 514*0fca6ea1SDimitry Andric const BasicBlock *DbgRecord::getBlock() const { return Marker->getParent(); } 5155f757f3fSDimitry Andric 516*0fca6ea1SDimitry Andric Function *DbgRecord::getFunction() { return getBlock()->getParent(); } 5175f757f3fSDimitry Andric 518*0fca6ea1SDimitry Andric const Function *DbgRecord::getFunction() const { 519*0fca6ea1SDimitry Andric return getBlock()->getParent(); 520*0fca6ea1SDimitry Andric } 5215f757f3fSDimitry Andric 522*0fca6ea1SDimitry Andric Module *DbgRecord::getModule() { return getFunction()->getParent(); } 5235f757f3fSDimitry Andric 524*0fca6ea1SDimitry Andric const Module *DbgRecord::getModule() const { 525*0fca6ea1SDimitry Andric return getFunction()->getParent(); 526*0fca6ea1SDimitry Andric } 5275f757f3fSDimitry Andric 528*0fca6ea1SDimitry Andric LLVMContext &DbgRecord::getContext() { return getBlock()->getContext(); } 5295f757f3fSDimitry Andric 530*0fca6ea1SDimitry Andric const LLVMContext &DbgRecord::getContext() const { 5315f757f3fSDimitry Andric return getBlock()->getContext(); 5325f757f3fSDimitry Andric } 5335f757f3fSDimitry Andric 534*0fca6ea1SDimitry Andric void DbgRecord::insertBefore(DbgRecord *InsertBefore) { 5357a6dacacSDimitry Andric assert(!getMarker() && 536*0fca6ea1SDimitry Andric "Cannot insert a DbgRecord that is already has a DbgMarker!"); 5377a6dacacSDimitry Andric assert(InsertBefore->getMarker() && 538*0fca6ea1SDimitry Andric "Cannot insert a DbgRecord before a DbgRecord that does not have a " 539*0fca6ea1SDimitry Andric "DbgMarker!"); 540*0fca6ea1SDimitry Andric InsertBefore->getMarker()->insertDbgRecord(this, InsertBefore); 5417a6dacacSDimitry Andric } 542*0fca6ea1SDimitry Andric void DbgRecord::insertAfter(DbgRecord *InsertAfter) { 5437a6dacacSDimitry Andric assert(!getMarker() && 544*0fca6ea1SDimitry Andric "Cannot insert a DbgRecord that is already has a DbgMarker!"); 5457a6dacacSDimitry Andric assert(InsertAfter->getMarker() && 546*0fca6ea1SDimitry Andric "Cannot insert a DbgRecord after a DbgRecord that does not have a " 547*0fca6ea1SDimitry Andric "DbgMarker!"); 548*0fca6ea1SDimitry Andric InsertAfter->getMarker()->insertDbgRecordAfter(this, InsertAfter); 5497a6dacacSDimitry Andric } 550*0fca6ea1SDimitry Andric void DbgRecord::moveBefore(DbgRecord *MoveBefore) { 5517a6dacacSDimitry Andric assert(getMarker() && 552*0fca6ea1SDimitry Andric "Canot move a DbgRecord that does not currently have a DbgMarker!"); 5537a6dacacSDimitry Andric removeFromParent(); 5547a6dacacSDimitry Andric insertBefore(MoveBefore); 5557a6dacacSDimitry Andric } 556*0fca6ea1SDimitry Andric void DbgRecord::moveAfter(DbgRecord *MoveAfter) { 5577a6dacacSDimitry Andric assert(getMarker() && 558*0fca6ea1SDimitry Andric "Canot move a DbgRecord that does not currently have a DbgMarker!"); 5597a6dacacSDimitry Andric removeFromParent(); 5607a6dacacSDimitry Andric insertAfter(MoveAfter); 5617a6dacacSDimitry Andric } 5627a6dacacSDimitry Andric 5635f757f3fSDimitry Andric /////////////////////////////////////////////////////////////////////////////// 5645f757f3fSDimitry Andric 565*0fca6ea1SDimitry Andric // An empty, global, DbgMarker for the purpose of describing empty ranges of 566*0fca6ea1SDimitry Andric // DbgRecords. 567*0fca6ea1SDimitry Andric DbgMarker DbgMarker::EmptyDbgMarker; 5685f757f3fSDimitry Andric 569*0fca6ea1SDimitry Andric void DbgMarker::dropDbgRecords() { 570*0fca6ea1SDimitry Andric while (!StoredDbgRecords.empty()) { 571*0fca6ea1SDimitry Andric auto It = StoredDbgRecords.begin(); 572*0fca6ea1SDimitry Andric DbgRecord *DR = &*It; 573*0fca6ea1SDimitry Andric StoredDbgRecords.erase(It); 574*0fca6ea1SDimitry Andric DR->deleteRecord(); 5755f757f3fSDimitry Andric } 5765f757f3fSDimitry Andric } 5775f757f3fSDimitry Andric 578*0fca6ea1SDimitry Andric void DbgMarker::dropOneDbgRecord(DbgRecord *DR) { 579*0fca6ea1SDimitry Andric assert(DR->getMarker() == this); 580*0fca6ea1SDimitry Andric StoredDbgRecords.erase(DR->getIterator()); 581*0fca6ea1SDimitry Andric DR->deleteRecord(); 5825f757f3fSDimitry Andric } 5835f757f3fSDimitry Andric 584*0fca6ea1SDimitry Andric const BasicBlock *DbgMarker::getParent() const { 5855f757f3fSDimitry Andric return MarkedInstr->getParent(); 5865f757f3fSDimitry Andric } 5875f757f3fSDimitry Andric 588*0fca6ea1SDimitry Andric BasicBlock *DbgMarker::getParent() { return MarkedInstr->getParent(); } 5895f757f3fSDimitry Andric 590*0fca6ea1SDimitry Andric void DbgMarker::removeMarker() { 591*0fca6ea1SDimitry Andric // Are there any DbgRecords in this DbgMarker? If not, nothing to preserve. 5925f757f3fSDimitry Andric Instruction *Owner = MarkedInstr; 593*0fca6ea1SDimitry Andric if (StoredDbgRecords.empty()) { 5945f757f3fSDimitry Andric eraseFromParent(); 595*0fca6ea1SDimitry Andric Owner->DebugMarker = nullptr; 5965f757f3fSDimitry Andric return; 5975f757f3fSDimitry Andric } 5985f757f3fSDimitry Andric 599*0fca6ea1SDimitry Andric // The attached DbgRecords need to be preserved; attach them to the next 6005f757f3fSDimitry Andric // instruction. If there isn't a next instruction, put them on the 6015f757f3fSDimitry Andric // "trailing" list. 602*0fca6ea1SDimitry Andric DbgMarker *NextMarker = Owner->getParent()->getNextMarker(Owner); 603*0fca6ea1SDimitry Andric if (NextMarker) { 6045f757f3fSDimitry Andric NextMarker->absorbDebugValues(*this, true); 6055f757f3fSDimitry Andric eraseFromParent(); 606*0fca6ea1SDimitry Andric } else { 607*0fca6ea1SDimitry Andric // We can avoid a deallocation -- just store this marker onto the next 608*0fca6ea1SDimitry Andric // instruction. Unless we're at the end of the block, in which case this 609*0fca6ea1SDimitry Andric // marker becomes the trailing marker of a degenerate block. 610*0fca6ea1SDimitry Andric BasicBlock::iterator NextIt = std::next(Owner->getIterator()); 611*0fca6ea1SDimitry Andric if (NextIt == getParent()->end()) { 612*0fca6ea1SDimitry Andric getParent()->setTrailingDbgRecords(this); 613*0fca6ea1SDimitry Andric MarkedInstr = nullptr; 614*0fca6ea1SDimitry Andric } else { 615*0fca6ea1SDimitry Andric NextIt->DebugMarker = this; 616*0fca6ea1SDimitry Andric MarkedInstr = &*NextIt; 617*0fca6ea1SDimitry Andric } 618*0fca6ea1SDimitry Andric } 619*0fca6ea1SDimitry Andric Owner->DebugMarker = nullptr; 6205f757f3fSDimitry Andric } 6215f757f3fSDimitry Andric 622*0fca6ea1SDimitry Andric void DbgMarker::removeFromParent() { 623*0fca6ea1SDimitry Andric MarkedInstr->DebugMarker = nullptr; 6245f757f3fSDimitry Andric MarkedInstr = nullptr; 6255f757f3fSDimitry Andric } 6265f757f3fSDimitry Andric 627*0fca6ea1SDimitry Andric void DbgMarker::eraseFromParent() { 6285f757f3fSDimitry Andric if (MarkedInstr) 6295f757f3fSDimitry Andric removeFromParent(); 630*0fca6ea1SDimitry Andric dropDbgRecords(); 6315f757f3fSDimitry Andric delete this; 6325f757f3fSDimitry Andric } 6335f757f3fSDimitry Andric 634*0fca6ea1SDimitry Andric iterator_range<DbgRecord::self_iterator> DbgMarker::getDbgRecordRange() { 635*0fca6ea1SDimitry Andric return make_range(StoredDbgRecords.begin(), StoredDbgRecords.end()); 6365f757f3fSDimitry Andric } 637*0fca6ea1SDimitry Andric iterator_range<DbgRecord::const_self_iterator> 638*0fca6ea1SDimitry Andric DbgMarker::getDbgRecordRange() const { 639*0fca6ea1SDimitry Andric return make_range(StoredDbgRecords.begin(), StoredDbgRecords.end()); 6407a6dacacSDimitry Andric } 6415f757f3fSDimitry Andric 642*0fca6ea1SDimitry Andric void DbgRecord::removeFromParent() { 643*0fca6ea1SDimitry Andric getMarker()->StoredDbgRecords.erase(getIterator()); 6447a6dacacSDimitry Andric Marker = nullptr; 6455f757f3fSDimitry Andric } 6465f757f3fSDimitry Andric 647*0fca6ea1SDimitry Andric void DbgRecord::eraseFromParent() { 6485f757f3fSDimitry Andric removeFromParent(); 649*0fca6ea1SDimitry Andric deleteRecord(); 6505f757f3fSDimitry Andric } 6515f757f3fSDimitry Andric 652*0fca6ea1SDimitry Andric void DbgMarker::insertDbgRecord(DbgRecord *New, bool InsertAtHead) { 653*0fca6ea1SDimitry Andric auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end(); 654*0fca6ea1SDimitry Andric StoredDbgRecords.insert(It, *New); 6555f757f3fSDimitry Andric New->setMarker(this); 6565f757f3fSDimitry Andric } 657*0fca6ea1SDimitry Andric void DbgMarker::insertDbgRecord(DbgRecord *New, DbgRecord *InsertBefore) { 6587a6dacacSDimitry Andric assert(InsertBefore->getMarker() == this && 659*0fca6ea1SDimitry Andric "DbgRecord 'InsertBefore' must be contained in this DbgMarker!"); 660*0fca6ea1SDimitry Andric StoredDbgRecords.insert(InsertBefore->getIterator(), *New); 6617a6dacacSDimitry Andric New->setMarker(this); 6627a6dacacSDimitry Andric } 663*0fca6ea1SDimitry Andric void DbgMarker::insertDbgRecordAfter(DbgRecord *New, DbgRecord *InsertAfter) { 6647a6dacacSDimitry Andric assert(InsertAfter->getMarker() == this && 665*0fca6ea1SDimitry Andric "DbgRecord 'InsertAfter' must be contained in this DbgMarker!"); 666*0fca6ea1SDimitry Andric StoredDbgRecords.insert(++(InsertAfter->getIterator()), *New); 6677a6dacacSDimitry Andric New->setMarker(this); 6687a6dacacSDimitry Andric } 6695f757f3fSDimitry Andric 670*0fca6ea1SDimitry Andric void DbgMarker::absorbDebugValues(DbgMarker &Src, bool InsertAtHead) { 671*0fca6ea1SDimitry Andric auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end(); 672*0fca6ea1SDimitry Andric for (DbgRecord &DVR : Src.StoredDbgRecords) 673*0fca6ea1SDimitry Andric DVR.setMarker(this); 6745f757f3fSDimitry Andric 675*0fca6ea1SDimitry Andric StoredDbgRecords.splice(It, Src.StoredDbgRecords); 6765f757f3fSDimitry Andric } 6775f757f3fSDimitry Andric 678*0fca6ea1SDimitry Andric void DbgMarker::absorbDebugValues( 679*0fca6ea1SDimitry Andric iterator_range<DbgRecord::self_iterator> Range, DbgMarker &Src, 680*0fca6ea1SDimitry Andric bool InsertAtHead) { 681*0fca6ea1SDimitry Andric for (DbgRecord &DR : Range) 682*0fca6ea1SDimitry Andric DR.setMarker(this); 6835f757f3fSDimitry Andric 6845f757f3fSDimitry Andric auto InsertPos = 685*0fca6ea1SDimitry Andric (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end(); 6865f757f3fSDimitry Andric 687*0fca6ea1SDimitry Andric StoredDbgRecords.splice(InsertPos, Src.StoredDbgRecords, Range.begin(), 6885f757f3fSDimitry Andric Range.end()); 6895f757f3fSDimitry Andric } 6905f757f3fSDimitry Andric 691*0fca6ea1SDimitry Andric iterator_range<simple_ilist<DbgRecord>::iterator> DbgMarker::cloneDebugInfoFrom( 692*0fca6ea1SDimitry Andric DbgMarker *From, std::optional<simple_ilist<DbgRecord>::iterator> from_here, 6935f757f3fSDimitry Andric bool InsertAtHead) { 694*0fca6ea1SDimitry Andric DbgRecord *First = nullptr; 695*0fca6ea1SDimitry Andric // Work out what range of DbgRecords to clone: normally all the contents of 696*0fca6ea1SDimitry Andric // the "From" marker, optionally we can start from the from_here position down 697*0fca6ea1SDimitry Andric // to end(). 6985f757f3fSDimitry Andric auto Range = 699*0fca6ea1SDimitry Andric make_range(From->StoredDbgRecords.begin(), From->StoredDbgRecords.end()); 7005f757f3fSDimitry Andric if (from_here.has_value()) 701*0fca6ea1SDimitry Andric Range = make_range(*from_here, From->StoredDbgRecords.end()); 7025f757f3fSDimitry Andric 703*0fca6ea1SDimitry Andric // Clone each DbgVariableRecord and insert into StoreDbgVariableRecords; 704*0fca6ea1SDimitry Andric // optionally place them at the start or the end of the list. 705*0fca6ea1SDimitry Andric auto Pos = (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end(); 706*0fca6ea1SDimitry Andric for (DbgRecord &DR : Range) { 707*0fca6ea1SDimitry Andric DbgRecord *New = DR.clone(); 7085f757f3fSDimitry Andric New->setMarker(this); 709*0fca6ea1SDimitry Andric StoredDbgRecords.insert(Pos, *New); 7105f757f3fSDimitry Andric if (!First) 7115f757f3fSDimitry Andric First = New; 7125f757f3fSDimitry Andric } 7135f757f3fSDimitry Andric 7145f757f3fSDimitry Andric if (!First) 715*0fca6ea1SDimitry Andric return {StoredDbgRecords.end(), StoredDbgRecords.end()}; 7165f757f3fSDimitry Andric 7175f757f3fSDimitry Andric if (InsertAtHead) 7185f757f3fSDimitry Andric // If InsertAtHead is set, we cloned a range onto the front of of the 719*0fca6ea1SDimitry Andric // StoredDbgRecords collection, return that range. 720*0fca6ea1SDimitry Andric return {StoredDbgRecords.begin(), Pos}; 7215f757f3fSDimitry Andric else 7225f757f3fSDimitry Andric // We inserted a block at the end, return that range. 723*0fca6ea1SDimitry Andric return {First->getIterator(), StoredDbgRecords.end()}; 7245f757f3fSDimitry Andric } 7255f757f3fSDimitry Andric 7265f757f3fSDimitry Andric } // end namespace llvm 727