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