xref: /freebsd-src/contrib/llvm-project/llvm/lib/IR/DebugProgramInstruction.cpp (revision 6c4b055cfb6bf549e9145dde6454cc6b178c35e4)
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