10fca6ea1SDimitry 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 160fca6ea1SDimitry Andric template <typename T> 170fca6ea1SDimitry Andric DbgRecordParamRef<T>::DbgRecordParamRef(const T *Param) 180fca6ea1SDimitry Andric : Ref(const_cast<T *>(Param)) {} 190fca6ea1SDimitry Andric template <typename T> 200fca6ea1SDimitry Andric DbgRecordParamRef<T>::DbgRecordParamRef(const MDNode *Param) 210fca6ea1SDimitry Andric : Ref(const_cast<MDNode *>(Param)) {} 220fca6ea1SDimitry Andric 230fca6ea1SDimitry Andric template <typename T> T *DbgRecordParamRef<T>::get() const { 240fca6ea1SDimitry Andric return cast<T>(Ref); 250fca6ea1SDimitry Andric } 260fca6ea1SDimitry Andric 270fca6ea1SDimitry Andric template class DbgRecordParamRef<DIExpression>; 280fca6ea1SDimitry Andric template class DbgRecordParamRef<DILabel>; 290fca6ea1SDimitry Andric template class DbgRecordParamRef<DILocalVariable>; 300fca6ea1SDimitry Andric 310fca6ea1SDimitry Andric DbgVariableRecord::DbgVariableRecord(const DbgVariableIntrinsic *DVI) 320fca6ea1SDimitry Andric : DbgRecord(ValueKind, DVI->getDebugLoc()), 330fca6ea1SDimitry Andric DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}), 347a6dacacSDimitry Andric Variable(DVI->getVariable()), Expression(DVI->getExpression()), 350fca6ea1SDimitry 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( 540fca6ea1SDimitry Andric "Trying to create a DbgVariableRecord with an invalid intrinsic type!"); 555f757f3fSDimitry Andric } 565f757f3fSDimitry Andric } 575f757f3fSDimitry Andric 580fca6ea1SDimitry Andric DbgVariableRecord::DbgVariableRecord(const DbgVariableRecord &DVR) 590fca6ea1SDimitry Andric : DbgRecord(ValueKind, DVR.getDebugLoc()), DebugValueUser(DVR.DebugValues), 600fca6ea1SDimitry Andric Type(DVR.getType()), Variable(DVR.getVariable()), 610fca6ea1SDimitry Andric Expression(DVR.getExpression()), 620fca6ea1SDimitry Andric AddressExpression(DVR.AddressExpression) {} 635f757f3fSDimitry Andric 640fca6ea1SDimitry Andric DbgVariableRecord::DbgVariableRecord(Metadata *Location, DILocalVariable *DV, 650fca6ea1SDimitry Andric DIExpression *Expr, const DILocation *DI, 660fca6ea1SDimitry Andric LocationType Type) 670fca6ea1SDimitry Andric : DbgRecord(ValueKind, DI), DebugValueUser({Location, nullptr, nullptr}), 680fca6ea1SDimitry Andric Type(Type), Variable(DV), Expression(Expr) {} 697a6dacacSDimitry Andric 700fca6ea1SDimitry Andric DbgVariableRecord::DbgVariableRecord(Metadata *Value, DILocalVariable *Variable, 710fca6ea1SDimitry Andric DIExpression *Expression, 720fca6ea1SDimitry Andric DIAssignID *AssignID, Metadata *Address, 730fca6ea1SDimitry Andric DIExpression *AddressExpression, 747a6dacacSDimitry Andric const DILocation *DI) 750fca6ea1SDimitry Andric : DbgRecord(ValueKind, DI), DebugValueUser({Value, Address, AssignID}), 760fca6ea1SDimitry Andric Type(LocationType::Assign), Variable(Variable), Expression(Expression), 770fca6ea1SDimitry Andric AddressExpression(AddressExpression) {} 785f757f3fSDimitry Andric 790fca6ea1SDimitry Andric void DbgRecord::deleteRecord() { 800fca6ea1SDimitry Andric switch (RecordKind) { 810fca6ea1SDimitry Andric case ValueKind: 820fca6ea1SDimitry Andric delete cast<DbgVariableRecord>(this); 830fca6ea1SDimitry Andric return; 840fca6ea1SDimitry Andric case LabelKind: 850fca6ea1SDimitry Andric delete cast<DbgLabelRecord>(this); 860fca6ea1SDimitry Andric return; 870fca6ea1SDimitry Andric } 880fca6ea1SDimitry Andric llvm_unreachable("unsupported DbgRecord kind"); 890fca6ea1SDimitry Andric } 905f757f3fSDimitry Andric 910fca6ea1SDimitry Andric void DbgRecord::print(raw_ostream &O, bool IsForDebug) const { 920fca6ea1SDimitry Andric switch (RecordKind) { 930fca6ea1SDimitry Andric case ValueKind: 940fca6ea1SDimitry Andric cast<DbgVariableRecord>(this)->print(O, IsForDebug); 950fca6ea1SDimitry Andric return; 960fca6ea1SDimitry Andric case LabelKind: 970fca6ea1SDimitry Andric cast<DbgLabelRecord>(this)->print(O, IsForDebug); 980fca6ea1SDimitry Andric return; 990fca6ea1SDimitry Andric }; 1000fca6ea1SDimitry Andric llvm_unreachable("unsupported DbgRecord kind"); 1010fca6ea1SDimitry Andric } 1020fca6ea1SDimitry Andric 1030fca6ea1SDimitry Andric void DbgRecord::print(raw_ostream &O, ModuleSlotTracker &MST, 1040fca6ea1SDimitry Andric bool IsForDebug) const { 1050fca6ea1SDimitry Andric switch (RecordKind) { 1060fca6ea1SDimitry Andric case ValueKind: 1070fca6ea1SDimitry Andric cast<DbgVariableRecord>(this)->print(O, MST, IsForDebug); 1080fca6ea1SDimitry Andric return; 1090fca6ea1SDimitry Andric case LabelKind: 1100fca6ea1SDimitry Andric cast<DbgLabelRecord>(this)->print(O, MST, IsForDebug); 1110fca6ea1SDimitry Andric return; 1120fca6ea1SDimitry Andric }; 1130fca6ea1SDimitry Andric llvm_unreachable("unsupported DbgRecord kind"); 1140fca6ea1SDimitry Andric } 1150fca6ea1SDimitry Andric 1160fca6ea1SDimitry Andric bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const { 1170fca6ea1SDimitry Andric if (RecordKind != R.RecordKind) 1180fca6ea1SDimitry Andric return false; 1190fca6ea1SDimitry Andric switch (RecordKind) { 1200fca6ea1SDimitry Andric case ValueKind: 1210fca6ea1SDimitry Andric return cast<DbgVariableRecord>(this)->isIdenticalToWhenDefined( 1220fca6ea1SDimitry Andric *cast<DbgVariableRecord>(&R)); 1230fca6ea1SDimitry Andric case LabelKind: 1240fca6ea1SDimitry Andric return cast<DbgLabelRecord>(this)->getLabel() == 1250fca6ea1SDimitry Andric cast<DbgLabelRecord>(R).getLabel(); 1260fca6ea1SDimitry Andric }; 1270fca6ea1SDimitry Andric llvm_unreachable("unsupported DbgRecord kind"); 1280fca6ea1SDimitry Andric } 1290fca6ea1SDimitry Andric 1300fca6ea1SDimitry Andric bool DbgRecord::isEquivalentTo(const DbgRecord &R) const { 1310fca6ea1SDimitry Andric return getDebugLoc() == R.getDebugLoc() && isIdenticalToWhenDefined(R); 1320fca6ea1SDimitry Andric } 1330fca6ea1SDimitry Andric 1340fca6ea1SDimitry Andric DbgInfoIntrinsic * 1350fca6ea1SDimitry Andric DbgRecord::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const { 1360fca6ea1SDimitry Andric switch (RecordKind) { 1370fca6ea1SDimitry Andric case ValueKind: 1380fca6ea1SDimitry Andric return cast<DbgVariableRecord>(this)->createDebugIntrinsic(M, InsertBefore); 1390fca6ea1SDimitry Andric case LabelKind: 1400fca6ea1SDimitry Andric return cast<DbgLabelRecord>(this)->createDebugIntrinsic(M, InsertBefore); 1410fca6ea1SDimitry Andric }; 1420fca6ea1SDimitry Andric llvm_unreachable("unsupported DbgRecord kind"); 1430fca6ea1SDimitry Andric } 1440fca6ea1SDimitry Andric 1450fca6ea1SDimitry Andric DbgLabelRecord::DbgLabelRecord(MDNode *Label, MDNode *DL) 1460fca6ea1SDimitry Andric : DbgRecord(LabelKind, DebugLoc(DL)), Label(Label) { 1470fca6ea1SDimitry Andric assert(Label && "Unexpected nullptr"); 1480fca6ea1SDimitry Andric assert((isa<DILabel>(Label) || Label->isTemporary()) && 1490fca6ea1SDimitry Andric "Label type must be or resolve to a DILabel"); 1500fca6ea1SDimitry Andric } 1510fca6ea1SDimitry Andric DbgLabelRecord::DbgLabelRecord(DILabel *Label, DebugLoc DL) 1520fca6ea1SDimitry Andric : DbgRecord(LabelKind, DL), Label(Label) { 1530fca6ea1SDimitry Andric assert(Label && "Unexpected nullptr"); 1540fca6ea1SDimitry Andric } 1550fca6ea1SDimitry Andric 1560fca6ea1SDimitry Andric DbgLabelRecord *DbgLabelRecord::createUnresolvedDbgLabelRecord(MDNode *Label, 1570fca6ea1SDimitry Andric MDNode *DL) { 1580fca6ea1SDimitry Andric return new DbgLabelRecord(Label, DL); 1590fca6ea1SDimitry Andric } 1600fca6ea1SDimitry Andric 1610fca6ea1SDimitry Andric DbgVariableRecord::DbgVariableRecord(DbgVariableRecord::LocationType Type, 1620fca6ea1SDimitry Andric Metadata *Val, MDNode *Variable, 1630fca6ea1SDimitry Andric MDNode *Expression, MDNode *AssignID, 1640fca6ea1SDimitry Andric Metadata *Address, 1650fca6ea1SDimitry Andric MDNode *AddressExpression, MDNode *DI) 1660fca6ea1SDimitry Andric : DbgRecord(ValueKind, DebugLoc(DI)), 1670fca6ea1SDimitry Andric DebugValueUser({Val, Address, AssignID}), Type(Type), Variable(Variable), 1680fca6ea1SDimitry Andric Expression(Expression), AddressExpression(AddressExpression) {} 1690fca6ea1SDimitry Andric 1700fca6ea1SDimitry Andric DbgVariableRecord *DbgVariableRecord::createUnresolvedDbgVariableRecord( 1710fca6ea1SDimitry Andric DbgVariableRecord::LocationType Type, Metadata *Val, MDNode *Variable, 1720fca6ea1SDimitry Andric MDNode *Expression, MDNode *AssignID, Metadata *Address, 1730fca6ea1SDimitry Andric MDNode *AddressExpression, MDNode *DI) { 1740fca6ea1SDimitry Andric return new DbgVariableRecord(Type, Val, Variable, Expression, AssignID, 1750fca6ea1SDimitry Andric Address, AddressExpression, DI); 1760fca6ea1SDimitry Andric } 1770fca6ea1SDimitry Andric 1780fca6ea1SDimitry Andric DbgVariableRecord * 1790fca6ea1SDimitry Andric DbgVariableRecord::createDbgVariableRecord(Value *Location, DILocalVariable *DV, 1800fca6ea1SDimitry Andric DIExpression *Expr, 1810fca6ea1SDimitry Andric const DILocation *DI) { 1820fca6ea1SDimitry Andric return new DbgVariableRecord(ValueAsMetadata::get(Location), DV, Expr, DI, 1837a6dacacSDimitry Andric LocationType::Value); 1847a6dacacSDimitry Andric } 1857a6dacacSDimitry Andric 1860fca6ea1SDimitry Andric DbgVariableRecord *DbgVariableRecord::createDbgVariableRecord( 1870fca6ea1SDimitry Andric Value *Location, DILocalVariable *DV, DIExpression *Expr, 1880fca6ea1SDimitry Andric const DILocation *DI, DbgVariableRecord &InsertBefore) { 1890fca6ea1SDimitry Andric auto *NewDbgVariableRecord = createDbgVariableRecord(Location, DV, Expr, DI); 1900fca6ea1SDimitry Andric NewDbgVariableRecord->insertBefore(&InsertBefore); 1910fca6ea1SDimitry Andric return NewDbgVariableRecord; 1927a6dacacSDimitry Andric } 1937a6dacacSDimitry Andric 1940fca6ea1SDimitry Andric DbgVariableRecord *DbgVariableRecord::createDVRDeclare(Value *Address, 1950fca6ea1SDimitry Andric DILocalVariable *DV, 1960fca6ea1SDimitry Andric DIExpression *Expr, 1970fca6ea1SDimitry Andric const DILocation *DI) { 1980fca6ea1SDimitry Andric return new DbgVariableRecord(ValueAsMetadata::get(Address), DV, Expr, DI, 1997a6dacacSDimitry Andric LocationType::Declare); 2007a6dacacSDimitry Andric } 2017a6dacacSDimitry Andric 2020fca6ea1SDimitry Andric DbgVariableRecord * 2030fca6ea1SDimitry Andric DbgVariableRecord::createDVRDeclare(Value *Address, DILocalVariable *DV, 2047a6dacacSDimitry Andric DIExpression *Expr, const DILocation *DI, 2050fca6ea1SDimitry Andric DbgVariableRecord &InsertBefore) { 2060fca6ea1SDimitry Andric auto *NewDVRDeclare = createDVRDeclare(Address, DV, Expr, DI); 2070fca6ea1SDimitry Andric NewDVRDeclare->insertBefore(&InsertBefore); 2080fca6ea1SDimitry Andric return NewDVRDeclare; 2097a6dacacSDimitry Andric } 2107a6dacacSDimitry Andric 2110fca6ea1SDimitry Andric DbgVariableRecord *DbgVariableRecord::createDVRAssign( 2120fca6ea1SDimitry Andric Value *Val, DILocalVariable *Variable, DIExpression *Expression, 2130fca6ea1SDimitry Andric DIAssignID *AssignID, Value *Address, DIExpression *AddressExpression, 2147a6dacacSDimitry Andric const DILocation *DI) { 2150fca6ea1SDimitry Andric return new DbgVariableRecord(ValueAsMetadata::get(Val), Variable, Expression, 2160fca6ea1SDimitry Andric AssignID, ValueAsMetadata::get(Address), 2170fca6ea1SDimitry Andric AddressExpression, DI); 2187a6dacacSDimitry Andric } 2197a6dacacSDimitry Andric 2200fca6ea1SDimitry Andric DbgVariableRecord *DbgVariableRecord::createLinkedDVRAssign( 2210fca6ea1SDimitry Andric Instruction *LinkedInstr, Value *Val, DILocalVariable *Variable, 2220fca6ea1SDimitry 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"); 2260fca6ea1SDimitry Andric auto *NewDVRAssign = DbgVariableRecord::createDVRAssign( 2270fca6ea1SDimitry Andric Val, Variable, Expression, cast<DIAssignID>(Link), Address, 2287a6dacacSDimitry Andric AddressExpression, DI); 2290fca6ea1SDimitry Andric LinkedInstr->getParent()->insertDbgRecordAfter(NewDVRAssign, LinkedInstr); 2300fca6ea1SDimitry Andric return NewDVRAssign; 2317a6dacacSDimitry Andric } 2327a6dacacSDimitry Andric 2330fca6ea1SDimitry Andric iterator_range<DbgVariableRecord::location_op_iterator> 2340fca6ea1SDimitry Andric DbgVariableRecord::location_ops() const { 2355f757f3fSDimitry Andric auto *MD = getRawLocation(); 2360fca6ea1SDimitry Andric // If a Value has been deleted, the "location" for this DbgVariableRecord will 2370fca6ea1SDimitry 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 2570fca6ea1SDimitry 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 2630fca6ea1SDimitry 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) && 2730fca6ea1SDimitry 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 2860fca6ea1SDimitry Andric void DbgVariableRecord::replaceVariableLocationOp(Value *OldValue, 2870fca6ea1SDimitry 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 3200fca6ea1SDimitry Andric void DbgVariableRecord::replaceVariableLocationOp(unsigned OpIdx, 3210fca6ea1SDimitry 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 3400fca6ea1SDimitry 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 3560fca6ea1SDimitry 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 3680fca6ea1SDimitry Andric bool DbgVariableRecord::isKillLocation() const { 3690fca6ea1SDimitry Andric return (!hasArgList() && isa<MDNode>(getRawLocation())) || 3700fca6ea1SDimitry Andric (getNumVariableLocationOps() == 0 && !getExpression()->isComplex()) || 3715f757f3fSDimitry Andric any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); }); 3725f757f3fSDimitry Andric } 3735f757f3fSDimitry Andric 3740fca6ea1SDimitry Andric std::optional<DbgVariableFragmentInfo> DbgVariableRecord::getFragment() const { 3750fca6ea1SDimitry Andric return getExpression()->getFragmentInfo(); 3760fca6ea1SDimitry Andric } 3770fca6ea1SDimitry Andric 3780fca6ea1SDimitry 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 3840fca6ea1SDimitry Andric DbgRecord *DbgRecord::clone() const { 3850fca6ea1SDimitry Andric switch (RecordKind) { 3860fca6ea1SDimitry Andric case ValueKind: 3870fca6ea1SDimitry Andric return cast<DbgVariableRecord>(this)->clone(); 3880fca6ea1SDimitry Andric case LabelKind: 3890fca6ea1SDimitry Andric return cast<DbgLabelRecord>(this)->clone(); 3900fca6ea1SDimitry Andric }; 3910fca6ea1SDimitry Andric llvm_unreachable("unsupported DbgRecord kind"); 3920fca6ea1SDimitry Andric } 3930fca6ea1SDimitry Andric 3940fca6ea1SDimitry Andric DbgVariableRecord *DbgVariableRecord::clone() const { 3950fca6ea1SDimitry Andric return new DbgVariableRecord(*this); 3960fca6ea1SDimitry Andric } 3970fca6ea1SDimitry Andric 3980fca6ea1SDimitry Andric DbgLabelRecord *DbgLabelRecord::clone() const { 3990fca6ea1SDimitry Andric return new DbgLabelRecord(getLabel(), getDebugLoc()); 4000fca6ea1SDimitry Andric } 4015f757f3fSDimitry Andric 4025f757f3fSDimitry Andric DbgVariableIntrinsic * 4030fca6ea1SDimitry Andric DbgVariableRecord::createDebugIntrinsic(Module *M, 4040fca6ea1SDimitry Andric Instruction *InsertBefore) const { 4055f757f3fSDimitry Andric [[maybe_unused]] DICompileUnit *Unit = 4060fca6ea1SDimitry 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()) { 4150fca6ea1SDimitry Andric case DbgVariableRecord::LocationType::Declare: 4165f757f3fSDimitry Andric IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_declare); 4175f757f3fSDimitry Andric break; 4180fca6ea1SDimitry Andric case DbgVariableRecord::LocationType::Value: 4195f757f3fSDimitry Andric IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_value); 4205f757f3fSDimitry Andric break; 4210fca6ea1SDimitry Andric case DbgVariableRecord::LocationType::Assign: 4227a6dacacSDimitry Andric IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_assign); 4237a6dacacSDimitry Andric break; 4240fca6ea1SDimitry Andric case DbgVariableRecord::LocationType::End: 4250fca6ea1SDimitry Andric case DbgVariableRecord::LocationType::Any: 4265f757f3fSDimitry Andric llvm_unreachable("Invalid LocationType"); 4275f757f3fSDimitry Andric } 4285f757f3fSDimitry Andric 4290fca6ea1SDimitry Andric // Create the intrinsic from this DbgVariableRecord's information, optionally 4300fca6ea1SDimitry Andric // insert into the target location. 4317a6dacacSDimitry Andric DbgVariableIntrinsic *DVI; 4320fca6ea1SDimitry Andric assert(getRawLocation() && 4330fca6ea1SDimitry 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 4590fca6ea1SDimitry Andric DbgLabelInst * 4600fca6ea1SDimitry Andric DbgLabelRecord::createDebugIntrinsic(Module *M, 4610fca6ea1SDimitry Andric Instruction *InsertBefore) const { 4620fca6ea1SDimitry Andric auto *LabelFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_label); 4630fca6ea1SDimitry Andric Value *Args[] = { 4640fca6ea1SDimitry Andric MetadataAsValue::get(getDebugLoc()->getContext(), getLabel())}; 4650fca6ea1SDimitry Andric DbgLabelInst *DbgLabel = cast<DbgLabelInst>( 4660fca6ea1SDimitry Andric CallInst::Create(LabelFn->getFunctionType(), LabelFn, Args)); 4670fca6ea1SDimitry Andric DbgLabel->setTailCall(); 4680fca6ea1SDimitry Andric DbgLabel->setDebugLoc(getDebugLoc()); 4690fca6ea1SDimitry Andric if (InsertBefore) 4700fca6ea1SDimitry Andric DbgLabel->insertBefore(InsertBefore); 4710fca6ea1SDimitry Andric return DbgLabel; 4720fca6ea1SDimitry Andric } 4730fca6ea1SDimitry Andric 4740fca6ea1SDimitry Andric Value *DbgVariableRecord::getAddress() const { 4757a6dacacSDimitry Andric auto *MD = getRawAddress(); 476*6c4b055cSDimitry Andric if (auto *V = dyn_cast_or_null<ValueAsMetadata>(MD)) 4777a6dacacSDimitry Andric return V->getValue(); 4787a6dacacSDimitry Andric 4797a6dacacSDimitry Andric // When the value goes to null, it gets replaced by an empty MDNode. 480*6c4b055cSDimitry Andric assert(!MD || 481*6c4b055cSDimitry Andric !cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode"); 4827a6dacacSDimitry Andric return nullptr; 4837a6dacacSDimitry Andric } 4847a6dacacSDimitry Andric 4850fca6ea1SDimitry Andric DIAssignID *DbgVariableRecord::getAssignID() const { 4867a6dacacSDimitry Andric return cast<DIAssignID>(DebugValues[2]); 4877a6dacacSDimitry Andric } 4887a6dacacSDimitry Andric 4890fca6ea1SDimitry Andric void DbgVariableRecord::setAssignId(DIAssignID *New) { 4900fca6ea1SDimitry Andric resetDebugValue(2, New); 4910fca6ea1SDimitry Andric } 4927a6dacacSDimitry Andric 4930fca6ea1SDimitry Andric void DbgVariableRecord::setKillAddress() { 4947a6dacacSDimitry Andric resetDebugValue( 4957a6dacacSDimitry Andric 1, ValueAsMetadata::get(UndefValue::get(getAddress()->getType()))); 4967a6dacacSDimitry Andric } 4977a6dacacSDimitry Andric 4980fca6ea1SDimitry Andric bool DbgVariableRecord::isKillAddress() const { 4997a6dacacSDimitry Andric Value *Addr = getAddress(); 5007a6dacacSDimitry Andric return !Addr || isa<UndefValue>(Addr); 5015f757f3fSDimitry Andric } 5025f757f3fSDimitry Andric 5030fca6ea1SDimitry Andric const Instruction *DbgRecord::getInstruction() const { 5040fca6ea1SDimitry Andric return Marker->MarkedInstr; 5050fca6ea1SDimitry Andric } 5060fca6ea1SDimitry Andric 5070fca6ea1SDimitry Andric const BasicBlock *DbgRecord::getParent() const { 5085f757f3fSDimitry Andric return Marker->MarkedInstr->getParent(); 5095f757f3fSDimitry Andric } 5105f757f3fSDimitry Andric 5110fca6ea1SDimitry Andric BasicBlock *DbgRecord::getParent() { return Marker->MarkedInstr->getParent(); } 5125f757f3fSDimitry Andric 5130fca6ea1SDimitry Andric BasicBlock *DbgRecord::getBlock() { return Marker->getParent(); } 5145f757f3fSDimitry Andric 5150fca6ea1SDimitry Andric const BasicBlock *DbgRecord::getBlock() const { return Marker->getParent(); } 5165f757f3fSDimitry Andric 5170fca6ea1SDimitry Andric Function *DbgRecord::getFunction() { return getBlock()->getParent(); } 5185f757f3fSDimitry Andric 5190fca6ea1SDimitry Andric const Function *DbgRecord::getFunction() const { 5200fca6ea1SDimitry Andric return getBlock()->getParent(); 5210fca6ea1SDimitry Andric } 5225f757f3fSDimitry Andric 5230fca6ea1SDimitry Andric Module *DbgRecord::getModule() { return getFunction()->getParent(); } 5245f757f3fSDimitry Andric 5250fca6ea1SDimitry Andric const Module *DbgRecord::getModule() const { 5260fca6ea1SDimitry Andric return getFunction()->getParent(); 5270fca6ea1SDimitry Andric } 5285f757f3fSDimitry Andric 5290fca6ea1SDimitry Andric LLVMContext &DbgRecord::getContext() { return getBlock()->getContext(); } 5305f757f3fSDimitry Andric 5310fca6ea1SDimitry Andric const LLVMContext &DbgRecord::getContext() const { 5325f757f3fSDimitry Andric return getBlock()->getContext(); 5335f757f3fSDimitry Andric } 5345f757f3fSDimitry Andric 5350fca6ea1SDimitry Andric void DbgRecord::insertBefore(DbgRecord *InsertBefore) { 5367a6dacacSDimitry Andric assert(!getMarker() && 5370fca6ea1SDimitry Andric "Cannot insert a DbgRecord that is already has a DbgMarker!"); 5387a6dacacSDimitry Andric assert(InsertBefore->getMarker() && 5390fca6ea1SDimitry Andric "Cannot insert a DbgRecord before a DbgRecord that does not have a " 5400fca6ea1SDimitry Andric "DbgMarker!"); 5410fca6ea1SDimitry Andric InsertBefore->getMarker()->insertDbgRecord(this, InsertBefore); 5427a6dacacSDimitry Andric } 5430fca6ea1SDimitry Andric void DbgRecord::insertAfter(DbgRecord *InsertAfter) { 5447a6dacacSDimitry Andric assert(!getMarker() && 5450fca6ea1SDimitry Andric "Cannot insert a DbgRecord that is already has a DbgMarker!"); 5467a6dacacSDimitry Andric assert(InsertAfter->getMarker() && 5470fca6ea1SDimitry Andric "Cannot insert a DbgRecord after a DbgRecord that does not have a " 5480fca6ea1SDimitry Andric "DbgMarker!"); 5490fca6ea1SDimitry Andric InsertAfter->getMarker()->insertDbgRecordAfter(this, InsertAfter); 5507a6dacacSDimitry Andric } 5510fca6ea1SDimitry Andric void DbgRecord::moveBefore(DbgRecord *MoveBefore) { 5527a6dacacSDimitry Andric assert(getMarker() && 5530fca6ea1SDimitry Andric "Canot move a DbgRecord that does not currently have a DbgMarker!"); 5547a6dacacSDimitry Andric removeFromParent(); 5557a6dacacSDimitry Andric insertBefore(MoveBefore); 5567a6dacacSDimitry Andric } 5570fca6ea1SDimitry Andric void DbgRecord::moveAfter(DbgRecord *MoveAfter) { 5587a6dacacSDimitry Andric assert(getMarker() && 5590fca6ea1SDimitry Andric "Canot move a DbgRecord that does not currently have a DbgMarker!"); 5607a6dacacSDimitry Andric removeFromParent(); 5617a6dacacSDimitry Andric insertAfter(MoveAfter); 5627a6dacacSDimitry Andric } 5637a6dacacSDimitry Andric 5645f757f3fSDimitry Andric /////////////////////////////////////////////////////////////////////////////// 5655f757f3fSDimitry Andric 5660fca6ea1SDimitry Andric // An empty, global, DbgMarker for the purpose of describing empty ranges of 5670fca6ea1SDimitry Andric // DbgRecords. 5680fca6ea1SDimitry Andric DbgMarker DbgMarker::EmptyDbgMarker; 5695f757f3fSDimitry Andric 5700fca6ea1SDimitry Andric void DbgMarker::dropDbgRecords() { 5710fca6ea1SDimitry Andric while (!StoredDbgRecords.empty()) { 5720fca6ea1SDimitry Andric auto It = StoredDbgRecords.begin(); 5730fca6ea1SDimitry Andric DbgRecord *DR = &*It; 5740fca6ea1SDimitry Andric StoredDbgRecords.erase(It); 5750fca6ea1SDimitry Andric DR->deleteRecord(); 5765f757f3fSDimitry Andric } 5775f757f3fSDimitry Andric } 5785f757f3fSDimitry Andric 5790fca6ea1SDimitry Andric void DbgMarker::dropOneDbgRecord(DbgRecord *DR) { 5800fca6ea1SDimitry Andric assert(DR->getMarker() == this); 5810fca6ea1SDimitry Andric StoredDbgRecords.erase(DR->getIterator()); 5820fca6ea1SDimitry Andric DR->deleteRecord(); 5835f757f3fSDimitry Andric } 5845f757f3fSDimitry Andric 5850fca6ea1SDimitry Andric const BasicBlock *DbgMarker::getParent() const { 5865f757f3fSDimitry Andric return MarkedInstr->getParent(); 5875f757f3fSDimitry Andric } 5885f757f3fSDimitry Andric 5890fca6ea1SDimitry Andric BasicBlock *DbgMarker::getParent() { return MarkedInstr->getParent(); } 5905f757f3fSDimitry Andric 5910fca6ea1SDimitry Andric void DbgMarker::removeMarker() { 5920fca6ea1SDimitry Andric // Are there any DbgRecords in this DbgMarker? If not, nothing to preserve. 5935f757f3fSDimitry Andric Instruction *Owner = MarkedInstr; 5940fca6ea1SDimitry Andric if (StoredDbgRecords.empty()) { 5955f757f3fSDimitry Andric eraseFromParent(); 5960fca6ea1SDimitry Andric Owner->DebugMarker = nullptr; 5975f757f3fSDimitry Andric return; 5985f757f3fSDimitry Andric } 5995f757f3fSDimitry Andric 6000fca6ea1SDimitry Andric // The attached DbgRecords need to be preserved; attach them to the next 6015f757f3fSDimitry Andric // instruction. If there isn't a next instruction, put them on the 6025f757f3fSDimitry Andric // "trailing" list. 6030fca6ea1SDimitry Andric DbgMarker *NextMarker = Owner->getParent()->getNextMarker(Owner); 6040fca6ea1SDimitry Andric if (NextMarker) { 6055f757f3fSDimitry Andric NextMarker->absorbDebugValues(*this, true); 6065f757f3fSDimitry Andric eraseFromParent(); 6070fca6ea1SDimitry Andric } else { 6080fca6ea1SDimitry Andric // We can avoid a deallocation -- just store this marker onto the next 6090fca6ea1SDimitry Andric // instruction. Unless we're at the end of the block, in which case this 6100fca6ea1SDimitry Andric // marker becomes the trailing marker of a degenerate block. 6110fca6ea1SDimitry Andric BasicBlock::iterator NextIt = std::next(Owner->getIterator()); 6120fca6ea1SDimitry Andric if (NextIt == getParent()->end()) { 6130fca6ea1SDimitry Andric getParent()->setTrailingDbgRecords(this); 6140fca6ea1SDimitry Andric MarkedInstr = nullptr; 6150fca6ea1SDimitry Andric } else { 6160fca6ea1SDimitry Andric NextIt->DebugMarker = this; 6170fca6ea1SDimitry Andric MarkedInstr = &*NextIt; 6180fca6ea1SDimitry Andric } 6190fca6ea1SDimitry Andric } 6200fca6ea1SDimitry Andric Owner->DebugMarker = nullptr; 6215f757f3fSDimitry Andric } 6225f757f3fSDimitry Andric 6230fca6ea1SDimitry Andric void DbgMarker::removeFromParent() { 6240fca6ea1SDimitry Andric MarkedInstr->DebugMarker = nullptr; 6255f757f3fSDimitry Andric MarkedInstr = nullptr; 6265f757f3fSDimitry Andric } 6275f757f3fSDimitry Andric 6280fca6ea1SDimitry Andric void DbgMarker::eraseFromParent() { 6295f757f3fSDimitry Andric if (MarkedInstr) 6305f757f3fSDimitry Andric removeFromParent(); 6310fca6ea1SDimitry Andric dropDbgRecords(); 6325f757f3fSDimitry Andric delete this; 6335f757f3fSDimitry Andric } 6345f757f3fSDimitry Andric 6350fca6ea1SDimitry Andric iterator_range<DbgRecord::self_iterator> DbgMarker::getDbgRecordRange() { 6360fca6ea1SDimitry Andric return make_range(StoredDbgRecords.begin(), StoredDbgRecords.end()); 6375f757f3fSDimitry Andric } 6380fca6ea1SDimitry Andric iterator_range<DbgRecord::const_self_iterator> 6390fca6ea1SDimitry Andric DbgMarker::getDbgRecordRange() const { 6400fca6ea1SDimitry Andric return make_range(StoredDbgRecords.begin(), StoredDbgRecords.end()); 6417a6dacacSDimitry Andric } 6425f757f3fSDimitry Andric 6430fca6ea1SDimitry Andric void DbgRecord::removeFromParent() { 6440fca6ea1SDimitry Andric getMarker()->StoredDbgRecords.erase(getIterator()); 6457a6dacacSDimitry Andric Marker = nullptr; 6465f757f3fSDimitry Andric } 6475f757f3fSDimitry Andric 6480fca6ea1SDimitry Andric void DbgRecord::eraseFromParent() { 6495f757f3fSDimitry Andric removeFromParent(); 6500fca6ea1SDimitry Andric deleteRecord(); 6515f757f3fSDimitry Andric } 6525f757f3fSDimitry Andric 6530fca6ea1SDimitry Andric void DbgMarker::insertDbgRecord(DbgRecord *New, bool InsertAtHead) { 6540fca6ea1SDimitry Andric auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end(); 6550fca6ea1SDimitry Andric StoredDbgRecords.insert(It, *New); 6565f757f3fSDimitry Andric New->setMarker(this); 6575f757f3fSDimitry Andric } 6580fca6ea1SDimitry Andric void DbgMarker::insertDbgRecord(DbgRecord *New, DbgRecord *InsertBefore) { 6597a6dacacSDimitry Andric assert(InsertBefore->getMarker() == this && 6600fca6ea1SDimitry Andric "DbgRecord 'InsertBefore' must be contained in this DbgMarker!"); 6610fca6ea1SDimitry Andric StoredDbgRecords.insert(InsertBefore->getIterator(), *New); 6627a6dacacSDimitry Andric New->setMarker(this); 6637a6dacacSDimitry Andric } 6640fca6ea1SDimitry Andric void DbgMarker::insertDbgRecordAfter(DbgRecord *New, DbgRecord *InsertAfter) { 6657a6dacacSDimitry Andric assert(InsertAfter->getMarker() == this && 6660fca6ea1SDimitry Andric "DbgRecord 'InsertAfter' must be contained in this DbgMarker!"); 6670fca6ea1SDimitry Andric StoredDbgRecords.insert(++(InsertAfter->getIterator()), *New); 6687a6dacacSDimitry Andric New->setMarker(this); 6697a6dacacSDimitry Andric } 6705f757f3fSDimitry Andric 6710fca6ea1SDimitry Andric void DbgMarker::absorbDebugValues(DbgMarker &Src, bool InsertAtHead) { 6720fca6ea1SDimitry Andric auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end(); 6730fca6ea1SDimitry Andric for (DbgRecord &DVR : Src.StoredDbgRecords) 6740fca6ea1SDimitry Andric DVR.setMarker(this); 6755f757f3fSDimitry Andric 6760fca6ea1SDimitry Andric StoredDbgRecords.splice(It, Src.StoredDbgRecords); 6775f757f3fSDimitry Andric } 6785f757f3fSDimitry Andric 6790fca6ea1SDimitry Andric void DbgMarker::absorbDebugValues( 6800fca6ea1SDimitry Andric iterator_range<DbgRecord::self_iterator> Range, DbgMarker &Src, 6810fca6ea1SDimitry Andric bool InsertAtHead) { 6820fca6ea1SDimitry Andric for (DbgRecord &DR : Range) 6830fca6ea1SDimitry Andric DR.setMarker(this); 6845f757f3fSDimitry Andric 6855f757f3fSDimitry Andric auto InsertPos = 6860fca6ea1SDimitry Andric (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end(); 6875f757f3fSDimitry Andric 6880fca6ea1SDimitry Andric StoredDbgRecords.splice(InsertPos, Src.StoredDbgRecords, Range.begin(), 6895f757f3fSDimitry Andric Range.end()); 6905f757f3fSDimitry Andric } 6915f757f3fSDimitry Andric 6920fca6ea1SDimitry Andric iterator_range<simple_ilist<DbgRecord>::iterator> DbgMarker::cloneDebugInfoFrom( 6930fca6ea1SDimitry Andric DbgMarker *From, std::optional<simple_ilist<DbgRecord>::iterator> from_here, 6945f757f3fSDimitry Andric bool InsertAtHead) { 6950fca6ea1SDimitry Andric DbgRecord *First = nullptr; 6960fca6ea1SDimitry Andric // Work out what range of DbgRecords to clone: normally all the contents of 6970fca6ea1SDimitry Andric // the "From" marker, optionally we can start from the from_here position down 6980fca6ea1SDimitry Andric // to end(). 6995f757f3fSDimitry Andric auto Range = 7000fca6ea1SDimitry Andric make_range(From->StoredDbgRecords.begin(), From->StoredDbgRecords.end()); 7015f757f3fSDimitry Andric if (from_here.has_value()) 7020fca6ea1SDimitry Andric Range = make_range(*from_here, From->StoredDbgRecords.end()); 7035f757f3fSDimitry Andric 7040fca6ea1SDimitry Andric // Clone each DbgVariableRecord and insert into StoreDbgVariableRecords; 7050fca6ea1SDimitry Andric // optionally place them at the start or the end of the list. 7060fca6ea1SDimitry Andric auto Pos = (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end(); 7070fca6ea1SDimitry Andric for (DbgRecord &DR : Range) { 7080fca6ea1SDimitry Andric DbgRecord *New = DR.clone(); 7095f757f3fSDimitry Andric New->setMarker(this); 7100fca6ea1SDimitry Andric StoredDbgRecords.insert(Pos, *New); 7115f757f3fSDimitry Andric if (!First) 7125f757f3fSDimitry Andric First = New; 7135f757f3fSDimitry Andric } 7145f757f3fSDimitry Andric 7155f757f3fSDimitry Andric if (!First) 7160fca6ea1SDimitry Andric return {StoredDbgRecords.end(), StoredDbgRecords.end()}; 7175f757f3fSDimitry Andric 7185f757f3fSDimitry Andric if (InsertAtHead) 7195f757f3fSDimitry Andric // If InsertAtHead is set, we cloned a range onto the front of of the 7200fca6ea1SDimitry Andric // StoredDbgRecords collection, return that range. 7210fca6ea1SDimitry Andric return {StoredDbgRecords.begin(), Pos}; 7225f757f3fSDimitry Andric else 7235f757f3fSDimitry Andric // We inserted a block at the end, return that range. 7240fca6ea1SDimitry Andric return {First->getIterator(), StoredDbgRecords.end()}; 7255f757f3fSDimitry Andric } 7265f757f3fSDimitry Andric 7275f757f3fSDimitry Andric } // end namespace llvm 728