xref: /llvm-project/llvm/lib/IR/DebugProgramInstruction.cpp (revision 8e702735090388a3231a863e343f880d0f96fecb)
175dfa58eSStephen Tozer //=====-- DebugProgramInstruction.cpp - Implement DbgRecords/DbgMarkers --====//
2f1b0a544SJeremy Morse //
3f1b0a544SJeremy Morse // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f1b0a544SJeremy Morse // See https://llvm.org/LICENSE.txt for license information.
5f1b0a544SJeremy Morse // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f1b0a544SJeremy Morse //
7f1b0a544SJeremy Morse //===----------------------------------------------------------------------===//
8f1b0a544SJeremy Morse 
9b90cba10SJeremy Morse #include "llvm/IR/DebugInfoMetadata.h"
10f1b0a544SJeremy Morse #include "llvm/IR/DebugProgramInstruction.h"
11f1b0a544SJeremy Morse #include "llvm/IR/DIBuilder.h"
12f1b0a544SJeremy Morse #include "llvm/IR/IntrinsicInst.h"
13f1b0a544SJeremy Morse 
14f1b0a544SJeremy Morse namespace llvm {
15f1b0a544SJeremy Morse 
16b3c2c5a8SStephen Tozer template <typename T>
17b3c2c5a8SStephen Tozer DbgRecordParamRef<T>::DbgRecordParamRef(const T *Param)
18b3c2c5a8SStephen Tozer     : Ref(const_cast<T *>(Param)) {}
19b3c2c5a8SStephen Tozer template <typename T>
20b3c2c5a8SStephen Tozer DbgRecordParamRef<T>::DbgRecordParamRef(const MDNode *Param)
21b3c2c5a8SStephen Tozer     : Ref(const_cast<MDNode *>(Param)) {}
22b3c2c5a8SStephen Tozer 
23b3c2c5a8SStephen Tozer template <typename T> T *DbgRecordParamRef<T>::get() const {
24b3c2c5a8SStephen Tozer   return cast<T>(Ref);
25b3c2c5a8SStephen Tozer }
26b3c2c5a8SStephen Tozer 
27b3c2c5a8SStephen Tozer template class DbgRecordParamRef<DIExpression>;
28b3c2c5a8SStephen Tozer template class DbgRecordParamRef<DILabel>;
29b3c2c5a8SStephen Tozer template class DbgRecordParamRef<DILocalVariable>;
30b3c2c5a8SStephen Tozer 
31ffd08c77SStephen Tozer DbgVariableRecord::DbgVariableRecord(const DbgVariableIntrinsic *DVI)
32ababa964SOrlando Cazalet-Hyams     : DbgRecord(ValueKind, DVI->getDebugLoc()),
33ababa964SOrlando Cazalet-Hyams       DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}),
34d499df02SStephen Tozer       Variable(DVI->getVariable()), Expression(DVI->getExpression()),
35b3c2c5a8SStephen Tozer       AddressExpression() {
36f1b0a544SJeremy Morse   switch (DVI->getIntrinsicID()) {
37f1b0a544SJeremy Morse   case Intrinsic::dbg_value:
38f1b0a544SJeremy Morse     Type = LocationType::Value;
39f1b0a544SJeremy Morse     break;
40f1b0a544SJeremy Morse   case Intrinsic::dbg_declare:
41f1b0a544SJeremy Morse     Type = LocationType::Declare;
42f1b0a544SJeremy Morse     break;
43d499df02SStephen Tozer   case Intrinsic::dbg_assign: {
44d499df02SStephen Tozer     Type = LocationType::Assign;
45d499df02SStephen Tozer     const DbgAssignIntrinsic *Assign =
46d499df02SStephen Tozer         static_cast<const DbgAssignIntrinsic *>(DVI);
47d499df02SStephen Tozer     resetDebugValue(1, Assign->getRawAddress());
48d499df02SStephen Tozer     AddressExpression = Assign->getAddressExpression();
49d499df02SStephen Tozer     setAssignId(Assign->getAssignID());
50d499df02SStephen Tozer     break;
51d499df02SStephen Tozer   }
52f1b0a544SJeremy Morse   default:
53f1b0a544SJeremy Morse     llvm_unreachable(
54ffd08c77SStephen Tozer         "Trying to create a DbgVariableRecord with an invalid intrinsic type!");
55f1b0a544SJeremy Morse   }
56f1b0a544SJeremy Morse }
57f1b0a544SJeremy Morse 
58ffd08c77SStephen Tozer DbgVariableRecord::DbgVariableRecord(const DbgVariableRecord &DVR)
59ffd08c77SStephen Tozer     : DbgRecord(ValueKind, DVR.getDebugLoc()), DebugValueUser(DVR.DebugValues),
60ffd08c77SStephen Tozer       Type(DVR.getType()), Variable(DVR.getVariable()),
61ffd08c77SStephen Tozer       Expression(DVR.getExpression()),
62ffd08c77SStephen Tozer       AddressExpression(DVR.AddressExpression) {}
63f1b0a544SJeremy Morse 
64ffd08c77SStephen Tozer DbgVariableRecord::DbgVariableRecord(Metadata *Location, DILocalVariable *DV,
65ffd08c77SStephen Tozer                                      DIExpression *Expr, const DILocation *DI,
66ffd08c77SStephen Tozer                                      LocationType Type)
67ababa964SOrlando Cazalet-Hyams     : DbgRecord(ValueKind, DI), DebugValueUser({Location, nullptr, nullptr}),
68ababa964SOrlando Cazalet-Hyams       Type(Type), Variable(DV), Expression(Expr) {}
69d499df02SStephen Tozer 
70ffd08c77SStephen Tozer DbgVariableRecord::DbgVariableRecord(Metadata *Value, DILocalVariable *Variable,
71ffd08c77SStephen Tozer                                      DIExpression *Expression,
72ffd08c77SStephen Tozer                                      DIAssignID *AssignID, Metadata *Address,
73ffd08c77SStephen Tozer                                      DIExpression *AddressExpression,
74d499df02SStephen Tozer                                      const DILocation *DI)
75ababa964SOrlando Cazalet-Hyams     : DbgRecord(ValueKind, DI), DebugValueUser({Value, Address, AssignID}),
76ababa964SOrlando Cazalet-Hyams       Type(LocationType::Assign), Variable(Variable), Expression(Expression),
77ababa964SOrlando Cazalet-Hyams       AddressExpression(AddressExpression) {}
78f1b0a544SJeremy Morse 
79ababa964SOrlando Cazalet-Hyams void DbgRecord::deleteRecord() {
80ababa964SOrlando Cazalet-Hyams   switch (RecordKind) {
81ababa964SOrlando Cazalet-Hyams   case ValueKind:
82ffd08c77SStephen Tozer     delete cast<DbgVariableRecord>(this);
834a23ab43SOrlando Cazalet-Hyams     return;
8420434bf3SOrlando Cazalet-Hyams   case LabelKind:
85bdc77d1eSStephen Tozer     delete cast<DbgLabelRecord>(this);
8620434bf3SOrlando Cazalet-Hyams     return;
87ababa964SOrlando Cazalet-Hyams   }
884a23ab43SOrlando Cazalet-Hyams   llvm_unreachable("unsupported DbgRecord kind");
89ababa964SOrlando Cazalet-Hyams }
90ababa964SOrlando Cazalet-Hyams 
91ababa964SOrlando Cazalet-Hyams void DbgRecord::print(raw_ostream &O, bool IsForDebug) const {
92ababa964SOrlando Cazalet-Hyams   switch (RecordKind) {
93ababa964SOrlando Cazalet-Hyams   case ValueKind:
94ffd08c77SStephen Tozer     cast<DbgVariableRecord>(this)->print(O, IsForDebug);
954a23ab43SOrlando Cazalet-Hyams     return;
9620434bf3SOrlando Cazalet-Hyams   case LabelKind:
97bdc77d1eSStephen Tozer     cast<DbgLabelRecord>(this)->print(O, IsForDebug);
9820434bf3SOrlando Cazalet-Hyams     return;
99ababa964SOrlando Cazalet-Hyams   };
1004a23ab43SOrlando Cazalet-Hyams   llvm_unreachable("unsupported DbgRecord kind");
101ababa964SOrlando Cazalet-Hyams }
102ababa964SOrlando Cazalet-Hyams 
103ababa964SOrlando Cazalet-Hyams void DbgRecord::print(raw_ostream &O, ModuleSlotTracker &MST,
104ababa964SOrlando Cazalet-Hyams                       bool IsForDebug) const {
105ababa964SOrlando Cazalet-Hyams   switch (RecordKind) {
106ababa964SOrlando Cazalet-Hyams   case ValueKind:
107ffd08c77SStephen Tozer     cast<DbgVariableRecord>(this)->print(O, MST, IsForDebug);
1084a23ab43SOrlando Cazalet-Hyams     return;
10920434bf3SOrlando Cazalet-Hyams   case LabelKind:
110bdc77d1eSStephen Tozer     cast<DbgLabelRecord>(this)->print(O, MST, IsForDebug);
11120434bf3SOrlando Cazalet-Hyams     return;
112ababa964SOrlando Cazalet-Hyams   };
1134a23ab43SOrlando Cazalet-Hyams   llvm_unreachable("unsupported DbgRecord kind");
114ababa964SOrlando Cazalet-Hyams }
115ababa964SOrlando Cazalet-Hyams 
116ababa964SOrlando Cazalet-Hyams bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const {
117ababa964SOrlando Cazalet-Hyams   if (RecordKind != R.RecordKind)
118ababa964SOrlando Cazalet-Hyams     return false;
119ababa964SOrlando Cazalet-Hyams   switch (RecordKind) {
120ababa964SOrlando Cazalet-Hyams   case ValueKind:
121ffd08c77SStephen Tozer     return cast<DbgVariableRecord>(this)->isIdenticalToWhenDefined(
122ffd08c77SStephen Tozer         *cast<DbgVariableRecord>(&R));
12320434bf3SOrlando Cazalet-Hyams   case LabelKind:
124bdc77d1eSStephen Tozer     return cast<DbgLabelRecord>(this)->getLabel() ==
125bdc77d1eSStephen Tozer            cast<DbgLabelRecord>(R).getLabel();
126ababa964SOrlando Cazalet-Hyams   };
1274a23ab43SOrlando Cazalet-Hyams   llvm_unreachable("unsupported DbgRecord kind");
128ababa964SOrlando Cazalet-Hyams }
129ababa964SOrlando Cazalet-Hyams 
130ababa964SOrlando Cazalet-Hyams bool DbgRecord::isEquivalentTo(const DbgRecord &R) const {
13120434bf3SOrlando Cazalet-Hyams   return getDebugLoc() == R.getDebugLoc() && isIdenticalToWhenDefined(R);
132ababa964SOrlando Cazalet-Hyams }
133f1b0a544SJeremy Morse 
1343356818eSOrlando Cazalet-Hyams DbgInfoIntrinsic *
1353356818eSOrlando Cazalet-Hyams DbgRecord::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
1363356818eSOrlando Cazalet-Hyams   switch (RecordKind) {
1373356818eSOrlando Cazalet-Hyams   case ValueKind:
138ffd08c77SStephen Tozer     return cast<DbgVariableRecord>(this)->createDebugIntrinsic(M, InsertBefore);
1393356818eSOrlando Cazalet-Hyams   case LabelKind:
140bdc77d1eSStephen Tozer     return cast<DbgLabelRecord>(this)->createDebugIntrinsic(M, InsertBefore);
1413356818eSOrlando Cazalet-Hyams   };
1423356818eSOrlando Cazalet-Hyams   llvm_unreachable("unsupported DbgRecord kind");
1433356818eSOrlando Cazalet-Hyams }
1443356818eSOrlando Cazalet-Hyams 
145bdc77d1eSStephen Tozer DbgLabelRecord::DbgLabelRecord(MDNode *Label, MDNode *DL)
146464d9d96SStephen Tozer     : DbgRecord(LabelKind, DebugLoc(DL)), Label(Label) {
147464d9d96SStephen Tozer   assert(Label && "Unexpected nullptr");
148464d9d96SStephen Tozer   assert((isa<DILabel>(Label) || Label->isTemporary()) &&
149464d9d96SStephen Tozer          "Label type must be or resolve to a DILabel");
150464d9d96SStephen Tozer }
151bdc77d1eSStephen Tozer DbgLabelRecord::DbgLabelRecord(DILabel *Label, DebugLoc DL)
152b3c2c5a8SStephen Tozer     : DbgRecord(LabelKind, DL), Label(Label) {
153b3c2c5a8SStephen Tozer   assert(Label && "Unexpected nullptr");
154b3c2c5a8SStephen Tozer }
155b3c2c5a8SStephen Tozer 
156bdc77d1eSStephen Tozer DbgLabelRecord *DbgLabelRecord::createUnresolvedDbgLabelRecord(MDNode *Label,
157bdc77d1eSStephen Tozer                                                                MDNode *DL) {
158bdc77d1eSStephen Tozer   return new DbgLabelRecord(Label, DL);
159464d9d96SStephen Tozer }
160464d9d96SStephen Tozer 
161ffd08c77SStephen Tozer DbgVariableRecord::DbgVariableRecord(DbgVariableRecord::LocationType Type,
162ffd08c77SStephen Tozer                                      Metadata *Val, MDNode *Variable,
163ffd08c77SStephen Tozer                                      MDNode *Expression, MDNode *AssignID,
164ffd08c77SStephen Tozer                                      Metadata *Address,
165464d9d96SStephen Tozer                                      MDNode *AddressExpression, MDNode *DI)
166464d9d96SStephen Tozer     : DbgRecord(ValueKind, DebugLoc(DI)),
167464d9d96SStephen Tozer       DebugValueUser({Val, Address, AssignID}), Type(Type), Variable(Variable),
168464d9d96SStephen Tozer       Expression(Expression), AddressExpression(AddressExpression) {}
169464d9d96SStephen Tozer 
170ffd08c77SStephen Tozer DbgVariableRecord *DbgVariableRecord::createUnresolvedDbgVariableRecord(
171ffd08c77SStephen Tozer     DbgVariableRecord::LocationType Type, Metadata *Val, MDNode *Variable,
172ffd08c77SStephen Tozer     MDNode *Expression, MDNode *AssignID, Metadata *Address,
173ffd08c77SStephen Tozer     MDNode *AddressExpression, MDNode *DI) {
174ffd08c77SStephen Tozer   return new DbgVariableRecord(Type, Val, Variable, Expression, AssignID,
175ffd08c77SStephen Tozer                                Address, AddressExpression, DI);
176464d9d96SStephen Tozer }
177464d9d96SStephen Tozer 
178ffd08c77SStephen Tozer DbgVariableRecord *
179ffd08c77SStephen Tozer DbgVariableRecord::createDbgVariableRecord(Value *Location, DILocalVariable *DV,
180ffd08c77SStephen Tozer                                            DIExpression *Expr,
181ffd08c77SStephen Tozer                                            const DILocation *DI) {
182ffd08c77SStephen Tozer   return new DbgVariableRecord(ValueAsMetadata::get(Location), DV, Expr, DI,
1832b08de43SStephen Tozer                                LocationType::Value);
1842b08de43SStephen Tozer }
1852b08de43SStephen Tozer 
186ffd08c77SStephen Tozer DbgVariableRecord *DbgVariableRecord::createDbgVariableRecord(
187ffd08c77SStephen Tozer     Value *Location, DILocalVariable *DV, DIExpression *Expr,
188ffd08c77SStephen Tozer     const DILocation *DI, DbgVariableRecord &InsertBefore) {
189ffd08c77SStephen Tozer   auto *NewDbgVariableRecord = createDbgVariableRecord(Location, DV, Expr, DI);
190ffd08c77SStephen Tozer   NewDbgVariableRecord->insertBefore(&InsertBefore);
191ffd08c77SStephen Tozer   return NewDbgVariableRecord;
1922b08de43SStephen Tozer }
1932b08de43SStephen Tozer 
194ffd08c77SStephen Tozer DbgVariableRecord *DbgVariableRecord::createDVRDeclare(Value *Address,
195ffd08c77SStephen Tozer                                                        DILocalVariable *DV,
196ffd08c77SStephen Tozer                                                        DIExpression *Expr,
197ffd08c77SStephen Tozer                                                        const DILocation *DI) {
198ffd08c77SStephen Tozer   return new DbgVariableRecord(ValueAsMetadata::get(Address), DV, Expr, DI,
1992b08de43SStephen Tozer                                LocationType::Declare);
2002b08de43SStephen Tozer }
2012b08de43SStephen Tozer 
202ffd08c77SStephen Tozer DbgVariableRecord *
203ffd08c77SStephen Tozer DbgVariableRecord::createDVRDeclare(Value *Address, DILocalVariable *DV,
2042b08de43SStephen Tozer                                     DIExpression *Expr, const DILocation *DI,
205ffd08c77SStephen Tozer                                     DbgVariableRecord &InsertBefore) {
206ffd08c77SStephen Tozer   auto *NewDVRDeclare = createDVRDeclare(Address, DV, Expr, DI);
207ffd08c77SStephen Tozer   NewDVRDeclare->insertBefore(&InsertBefore);
208ffd08c77SStephen Tozer   return NewDVRDeclare;
2092b08de43SStephen Tozer }
2102b08de43SStephen Tozer 
211ffd08c77SStephen Tozer DbgVariableRecord *DbgVariableRecord::createDVRAssign(
212ffd08c77SStephen Tozer     Value *Val, DILocalVariable *Variable, DIExpression *Expression,
213ffd08c77SStephen Tozer     DIAssignID *AssignID, Value *Address, DIExpression *AddressExpression,
214d499df02SStephen Tozer     const DILocation *DI) {
215ffd08c77SStephen Tozer   return new DbgVariableRecord(ValueAsMetadata::get(Val), Variable, Expression,
216ffd08c77SStephen Tozer                                AssignID, ValueAsMetadata::get(Address),
217ffd08c77SStephen Tozer                                AddressExpression, DI);
218d499df02SStephen Tozer }
219d499df02SStephen Tozer 
220ffd08c77SStephen Tozer DbgVariableRecord *DbgVariableRecord::createLinkedDVRAssign(
221ffd08c77SStephen Tozer     Instruction *LinkedInstr, Value *Val, DILocalVariable *Variable,
222ffd08c77SStephen Tozer     DIExpression *Expression, Value *Address, DIExpression *AddressExpression,
223d499df02SStephen Tozer     const DILocation *DI) {
224d499df02SStephen Tozer   auto *Link = LinkedInstr->getMetadata(LLVMContext::MD_DIAssignID);
225d499df02SStephen Tozer   assert(Link && "Linked instruction must have DIAssign metadata attached");
226ffd08c77SStephen Tozer   auto *NewDVRAssign = DbgVariableRecord::createDVRAssign(
227ffd08c77SStephen Tozer       Val, Variable, Expression, cast<DIAssignID>(Link), Address,
228d499df02SStephen Tozer       AddressExpression, DI);
229ffd08c77SStephen Tozer   LinkedInstr->getParent()->insertDbgRecordAfter(NewDVRAssign, LinkedInstr);
230ffd08c77SStephen Tozer   return NewDVRAssign;
231d499df02SStephen Tozer }
232d499df02SStephen Tozer 
233ffd08c77SStephen Tozer iterator_range<DbgVariableRecord::location_op_iterator>
234ffd08c77SStephen Tozer DbgVariableRecord::location_ops() const {
235f1b0a544SJeremy Morse   auto *MD = getRawLocation();
236ffd08c77SStephen Tozer   // If a Value has been deleted, the "location" for this DbgVariableRecord will
237ffd08c77SStephen Tozer   // be replaced by nullptr. Return an empty range.
238f1b0a544SJeremy Morse   if (!MD)
239f1b0a544SJeremy Morse     return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
240f1b0a544SJeremy Morse             location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
241f1b0a544SJeremy Morse 
242f1b0a544SJeremy Morse   // If operand is ValueAsMetadata, return a range over just that operand.
243f1b0a544SJeremy Morse   if (auto *VAM = dyn_cast<ValueAsMetadata>(MD))
244f1b0a544SJeremy Morse     return {location_op_iterator(VAM), location_op_iterator(VAM + 1)};
245f1b0a544SJeremy Morse 
246f1b0a544SJeremy Morse   // If operand is DIArgList, return a range over its args.
247f1b0a544SJeremy Morse   if (auto *AL = dyn_cast<DIArgList>(MD))
248f1b0a544SJeremy Morse     return {location_op_iterator(AL->args_begin()),
249f1b0a544SJeremy Morse             location_op_iterator(AL->args_end())};
250f1b0a544SJeremy Morse 
251f1b0a544SJeremy Morse   // Operand is an empty metadata tuple, so return empty iterator.
252f1b0a544SJeremy Morse   assert(cast<MDNode>(MD)->getNumOperands() == 0);
253f1b0a544SJeremy Morse   return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
254f1b0a544SJeremy Morse           location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
255f1b0a544SJeremy Morse }
256f1b0a544SJeremy Morse 
257ffd08c77SStephen Tozer unsigned DbgVariableRecord::getNumVariableLocationOps() const {
258b90cba10SJeremy Morse   if (hasArgList())
259b90cba10SJeremy Morse     return cast<DIArgList>(getRawLocation())->getArgs().size();
260b90cba10SJeremy Morse   return 1;
261b90cba10SJeremy Morse }
262b90cba10SJeremy Morse 
263ffd08c77SStephen Tozer Value *DbgVariableRecord::getVariableLocationOp(unsigned OpIdx) const {
264f1b0a544SJeremy Morse   auto *MD = getRawLocation();
265f1b0a544SJeremy Morse   if (!MD)
266f1b0a544SJeremy Morse     return nullptr;
267f1b0a544SJeremy Morse 
268f1b0a544SJeremy Morse   if (auto *AL = dyn_cast<DIArgList>(MD))
269f1b0a544SJeremy Morse     return AL->getArgs()[OpIdx]->getValue();
270f1b0a544SJeremy Morse   if (isa<MDNode>(MD))
271f1b0a544SJeremy Morse     return nullptr;
272f1b0a544SJeremy Morse   assert(isa<ValueAsMetadata>(MD) &&
273ffd08c77SStephen Tozer          "Attempted to get location operand from DbgVariableRecord with none.");
274f1b0a544SJeremy Morse   auto *V = cast<ValueAsMetadata>(MD);
275f1b0a544SJeremy Morse   assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a "
276f1b0a544SJeremy Morse                        "single location operand.");
277f1b0a544SJeremy Morse   return V->getValue();
278f1b0a544SJeremy Morse }
279f1b0a544SJeremy Morse 
280f1b0a544SJeremy Morse static ValueAsMetadata *getAsMetadata(Value *V) {
281f1b0a544SJeremy Morse   return isa<MetadataAsValue>(V) ? dyn_cast<ValueAsMetadata>(
282f1b0a544SJeremy Morse                                        cast<MetadataAsValue>(V)->getMetadata())
283f1b0a544SJeremy Morse                                  : ValueAsMetadata::get(V);
284f1b0a544SJeremy Morse }
285f1b0a544SJeremy Morse 
286ffd08c77SStephen Tozer void DbgVariableRecord::replaceVariableLocationOp(Value *OldValue,
287ffd08c77SStephen Tozer                                                   Value *NewValue,
288f1b0a544SJeremy Morse                                                   bool AllowEmpty) {
289f1b0a544SJeremy Morse   assert(NewValue && "Values must be non-null");
290d499df02SStephen Tozer 
291d499df02SStephen Tozer   bool DbgAssignAddrReplaced = isDbgAssign() && OldValue == getAddress();
292d499df02SStephen Tozer   if (DbgAssignAddrReplaced)
293d499df02SStephen Tozer     setAddress(NewValue);
294d499df02SStephen Tozer 
295f1b0a544SJeremy Morse   auto Locations = location_ops();
296f1b0a544SJeremy Morse   auto OldIt = find(Locations, OldValue);
297f1b0a544SJeremy Morse   if (OldIt == Locations.end()) {
298d499df02SStephen Tozer     if (AllowEmpty || DbgAssignAddrReplaced)
299f1b0a544SJeremy Morse       return;
300f1b0a544SJeremy Morse     llvm_unreachable("OldValue must be a current location");
301f1b0a544SJeremy Morse   }
302f1b0a544SJeremy Morse 
303f1b0a544SJeremy Morse   if (!hasArgList()) {
304f1b0a544SJeremy Morse     // Set our location to be the MAV wrapping the new Value.
305f1b0a544SJeremy Morse     setRawLocation(isa<MetadataAsValue>(NewValue)
306f1b0a544SJeremy Morse                        ? cast<MetadataAsValue>(NewValue)->getMetadata()
307f1b0a544SJeremy Morse                        : ValueAsMetadata::get(NewValue));
308f1b0a544SJeremy Morse     return;
309f1b0a544SJeremy Morse   }
310f1b0a544SJeremy Morse 
311f1b0a544SJeremy Morse   // We must be referring to a DIArgList, produce a new operands vector with the
312f1b0a544SJeremy Morse   // old value replaced, generate a new DIArgList and set it as our location.
313f1b0a544SJeremy Morse   SmallVector<ValueAsMetadata *, 4> MDs;
314f1b0a544SJeremy Morse   ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
315f1b0a544SJeremy Morse   for (auto *VMD : Locations)
316f1b0a544SJeremy Morse     MDs.push_back(VMD == *OldIt ? NewOperand : getAsMetadata(VMD));
317f1b0a544SJeremy Morse   setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
318f1b0a544SJeremy Morse }
319f1b0a544SJeremy Morse 
320ffd08c77SStephen Tozer void DbgVariableRecord::replaceVariableLocationOp(unsigned OpIdx,
321ffd08c77SStephen Tozer                                                   Value *NewValue) {
322f1b0a544SJeremy Morse   assert(OpIdx < getNumVariableLocationOps() && "Invalid Operand Index");
323f1b0a544SJeremy Morse 
324f1b0a544SJeremy Morse   if (!hasArgList()) {
325f1b0a544SJeremy Morse     setRawLocation(isa<MetadataAsValue>(NewValue)
326f1b0a544SJeremy Morse                        ? cast<MetadataAsValue>(NewValue)->getMetadata()
327f1b0a544SJeremy Morse                        : ValueAsMetadata::get(NewValue));
328f1b0a544SJeremy Morse     return;
329f1b0a544SJeremy Morse   }
330f1b0a544SJeremy Morse 
331f1b0a544SJeremy Morse   SmallVector<ValueAsMetadata *, 4> MDs;
332f1b0a544SJeremy Morse   ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
333f1b0a544SJeremy Morse   for (unsigned Idx = 0; Idx < getNumVariableLocationOps(); ++Idx)
334f1b0a544SJeremy Morse     MDs.push_back(Idx == OpIdx ? NewOperand
335f1b0a544SJeremy Morse                                : getAsMetadata(getVariableLocationOp(Idx)));
336f1b0a544SJeremy Morse 
337f1b0a544SJeremy Morse   setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
338f1b0a544SJeremy Morse }
339f1b0a544SJeremy Morse 
340ffd08c77SStephen Tozer void DbgVariableRecord::addVariableLocationOps(ArrayRef<Value *> NewValues,
341f1b0a544SJeremy Morse                                                DIExpression *NewExpr) {
342f1b0a544SJeremy Morse   assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() +
343f1b0a544SJeremy Morse                                     NewValues.size()) &&
344f1b0a544SJeremy Morse          "NewExpr for debug variable intrinsic does not reference every "
345f1b0a544SJeremy Morse          "location operand.");
346f1b0a544SJeremy Morse   assert(!is_contained(NewValues, nullptr) && "New values must be non-null");
347f1b0a544SJeremy Morse   setExpression(NewExpr);
348f1b0a544SJeremy Morse   SmallVector<ValueAsMetadata *, 4> MDs;
349f1b0a544SJeremy Morse   for (auto *VMD : location_ops())
350f1b0a544SJeremy Morse     MDs.push_back(getAsMetadata(VMD));
351f1b0a544SJeremy Morse   for (auto *VMD : NewValues)
352f1b0a544SJeremy Morse     MDs.push_back(getAsMetadata(VMD));
353f1b0a544SJeremy Morse   setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
354f1b0a544SJeremy Morse }
355f1b0a544SJeremy Morse 
356ffd08c77SStephen Tozer void DbgVariableRecord::setKillLocation() {
357b90cba10SJeremy Morse   // TODO: When/if we remove duplicate values from DIArgLists, we don't need
358b90cba10SJeremy Morse   // this set anymore.
359b90cba10SJeremy Morse   SmallPtrSet<Value *, 4> RemovedValues;
360b90cba10SJeremy Morse   for (Value *OldValue : location_ops()) {
361b90cba10SJeremy Morse     if (!RemovedValues.insert(OldValue).second)
362b90cba10SJeremy Morse       continue;
363b90cba10SJeremy Morse     Value *Poison = PoisonValue::get(OldValue->getType());
364b90cba10SJeremy Morse     replaceVariableLocationOp(OldValue, Poison);
365b90cba10SJeremy Morse   }
366b90cba10SJeremy Morse }
367b90cba10SJeremy Morse 
368ffd08c77SStephen Tozer bool DbgVariableRecord::isKillLocation() const {
369dc726c34SStephen Tozer   return (!hasArgList() && isa<MDNode>(getRawLocation())) ||
370dc726c34SStephen Tozer          (getNumVariableLocationOps() == 0 && !getExpression()->isComplex()) ||
371b90cba10SJeremy Morse          any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); });
372b90cba10SJeremy Morse }
373b90cba10SJeremy Morse 
374deb6b603SOrlando Cazalet-Hyams std::optional<DbgVariableFragmentInfo> DbgVariableRecord::getFragment() const {
375deb6b603SOrlando Cazalet-Hyams   return getExpression()->getFragmentInfo();
376deb6b603SOrlando Cazalet-Hyams }
377deb6b603SOrlando Cazalet-Hyams 
378ffd08c77SStephen Tozer std::optional<uint64_t> DbgVariableRecord::getFragmentSizeInBits() const {
379f1b0a544SJeremy Morse   if (auto Fragment = getExpression()->getFragmentInfo())
380f1b0a544SJeremy Morse     return Fragment->SizeInBits;
381f1b0a544SJeremy Morse   return getVariable()->getSizeInBits();
382f1b0a544SJeremy Morse }
383f1b0a544SJeremy Morse 
384ababa964SOrlando Cazalet-Hyams DbgRecord *DbgRecord::clone() const {
385ababa964SOrlando Cazalet-Hyams   switch (RecordKind) {
386ababa964SOrlando Cazalet-Hyams   case ValueKind:
387ffd08c77SStephen Tozer     return cast<DbgVariableRecord>(this)->clone();
38820434bf3SOrlando Cazalet-Hyams   case LabelKind:
389bdc77d1eSStephen Tozer     return cast<DbgLabelRecord>(this)->clone();
390ababa964SOrlando Cazalet-Hyams   };
3914a23ab43SOrlando Cazalet-Hyams   llvm_unreachable("unsupported DbgRecord kind");
392ababa964SOrlando Cazalet-Hyams }
393ababa964SOrlando Cazalet-Hyams 
394ffd08c77SStephen Tozer DbgVariableRecord *DbgVariableRecord::clone() const {
395ffd08c77SStephen Tozer   return new DbgVariableRecord(*this);
396ffd08c77SStephen Tozer }
397f1b0a544SJeremy Morse 
398bdc77d1eSStephen Tozer DbgLabelRecord *DbgLabelRecord::clone() const {
399bdc77d1eSStephen Tozer   return new DbgLabelRecord(getLabel(), getDebugLoc());
400b3c2c5a8SStephen Tozer }
40120434bf3SOrlando Cazalet-Hyams 
402f1b0a544SJeremy Morse DbgVariableIntrinsic *
403ffd08c77SStephen Tozer DbgVariableRecord::createDebugIntrinsic(Module *M,
404ffd08c77SStephen Tozer                                         Instruction *InsertBefore) const {
405f1b0a544SJeremy Morse   [[maybe_unused]] DICompileUnit *Unit =
40675bc20ffSKazu Hirata       getDebugLoc()->getScope()->getSubprogram()->getUnit();
407f1b0a544SJeremy Morse   assert(M && Unit &&
408f1b0a544SJeremy Morse          "Cannot clone from BasicBlock that is not part of a Module or "
409f1b0a544SJeremy Morse          "DICompileUnit!");
410f1b0a544SJeremy Morse   LLVMContext &Context = getDebugLoc()->getContext();
411f1b0a544SJeremy Morse   Function *IntrinsicFn;
412f1b0a544SJeremy Morse 
413f1b0a544SJeremy Morse   // Work out what sort of intrinsic we're going to produce.
414f1b0a544SJeremy Morse   switch (getType()) {
415ffd08c77SStephen Tozer   case DbgVariableRecord::LocationType::Declare:
416fa789dffSRahul Joshi     IntrinsicFn = Intrinsic::getOrInsertDeclaration(M, Intrinsic::dbg_declare);
417f1b0a544SJeremy Morse     break;
418ffd08c77SStephen Tozer   case DbgVariableRecord::LocationType::Value:
419fa789dffSRahul Joshi     IntrinsicFn = Intrinsic::getOrInsertDeclaration(M, Intrinsic::dbg_value);
420f1b0a544SJeremy Morse     break;
421ffd08c77SStephen Tozer   case DbgVariableRecord::LocationType::Assign:
422fa789dffSRahul Joshi     IntrinsicFn = Intrinsic::getOrInsertDeclaration(M, Intrinsic::dbg_assign);
423d499df02SStephen Tozer     break;
424ffd08c77SStephen Tozer   case DbgVariableRecord::LocationType::End:
425ffd08c77SStephen Tozer   case DbgVariableRecord::LocationType::Any:
4265457fab1SOCHyams     llvm_unreachable("Invalid LocationType");
427f1b0a544SJeremy Morse   }
428f1b0a544SJeremy Morse 
429ffd08c77SStephen Tozer   // Create the intrinsic from this DbgVariableRecord's information, optionally
430ffd08c77SStephen Tozer   // insert into the target location.
431d499df02SStephen Tozer   DbgVariableIntrinsic *DVI;
432ffd08c77SStephen Tozer   assert(getRawLocation() &&
433ffd08c77SStephen Tozer          "DbgVariableRecord's RawLocation should be non-null.");
434d499df02SStephen Tozer   if (isDbgAssign()) {
435d499df02SStephen Tozer     Value *AssignArgs[] = {
436d499df02SStephen Tozer         MetadataAsValue::get(Context, getRawLocation()),
437d499df02SStephen Tozer         MetadataAsValue::get(Context, getVariable()),
438d499df02SStephen Tozer         MetadataAsValue::get(Context, getExpression()),
439d499df02SStephen Tozer         MetadataAsValue::get(Context, getAssignID()),
440d499df02SStephen Tozer         MetadataAsValue::get(Context, getRawAddress()),
441d499df02SStephen Tozer         MetadataAsValue::get(Context, getAddressExpression())};
442d499df02SStephen Tozer     DVI = cast<DbgVariableIntrinsic>(CallInst::Create(
443d499df02SStephen Tozer         IntrinsicFn->getFunctionType(), IntrinsicFn, AssignArgs));
444d499df02SStephen Tozer   } else {
445d499df02SStephen Tozer     Value *Args[] = {MetadataAsValue::get(Context, getRawLocation()),
446d499df02SStephen Tozer                      MetadataAsValue::get(Context, getVariable()),
447d499df02SStephen Tozer                      MetadataAsValue::get(Context, getExpression())};
448d499df02SStephen Tozer     DVI = cast<DbgVariableIntrinsic>(
449f1b0a544SJeremy Morse         CallInst::Create(IntrinsicFn->getFunctionType(), IntrinsicFn, Args));
450d499df02SStephen Tozer   }
451f1b0a544SJeremy Morse   DVI->setTailCall();
452f1b0a544SJeremy Morse   DVI->setDebugLoc(getDebugLoc());
453f1b0a544SJeremy Morse   if (InsertBefore)
454*8e702735SJeremy Morse     DVI->insertBefore(InsertBefore->getIterator());
455f1b0a544SJeremy Morse 
456f1b0a544SJeremy Morse   return DVI;
457f1b0a544SJeremy Morse }
458f1b0a544SJeremy Morse 
459bdc77d1eSStephen Tozer DbgLabelInst *
460bdc77d1eSStephen Tozer DbgLabelRecord::createDebugIntrinsic(Module *M,
4613356818eSOrlando Cazalet-Hyams                                      Instruction *InsertBefore) const {
462fa789dffSRahul Joshi   auto *LabelFn = Intrinsic::getOrInsertDeclaration(M, Intrinsic::dbg_label);
4633356818eSOrlando Cazalet-Hyams   Value *Args[] = {
4643356818eSOrlando Cazalet-Hyams       MetadataAsValue::get(getDebugLoc()->getContext(), getLabel())};
4653356818eSOrlando Cazalet-Hyams   DbgLabelInst *DbgLabel = cast<DbgLabelInst>(
4663356818eSOrlando Cazalet-Hyams       CallInst::Create(LabelFn->getFunctionType(), LabelFn, Args));
4673356818eSOrlando Cazalet-Hyams   DbgLabel->setTailCall();
4683356818eSOrlando Cazalet-Hyams   DbgLabel->setDebugLoc(getDebugLoc());
4693356818eSOrlando Cazalet-Hyams   if (InsertBefore)
470*8e702735SJeremy Morse     DbgLabel->insertBefore(InsertBefore->getIterator());
4713356818eSOrlando Cazalet-Hyams   return DbgLabel;
4723356818eSOrlando Cazalet-Hyams }
4733356818eSOrlando Cazalet-Hyams 
474ffd08c77SStephen Tozer Value *DbgVariableRecord::getAddress() const {
475d499df02SStephen Tozer   auto *MD = getRawAddress();
47625f87f2dSJeremy Morse   if (auto *V = dyn_cast_or_null<ValueAsMetadata>(MD))
477d499df02SStephen Tozer     return V->getValue();
478d499df02SStephen Tozer 
479d499df02SStephen Tozer   // When the value goes to null, it gets replaced by an empty MDNode.
480851bacb7SSimon Pilgrim   assert((!MD || !cast<MDNode>(MD)->getNumOperands()) &&
481851bacb7SSimon Pilgrim          "Expected an empty MDNode");
482d499df02SStephen Tozer   return nullptr;
483d499df02SStephen Tozer }
484d499df02SStephen Tozer 
485ffd08c77SStephen Tozer DIAssignID *DbgVariableRecord::getAssignID() const {
486d499df02SStephen Tozer   return cast<DIAssignID>(DebugValues[2]);
487d499df02SStephen Tozer }
488d499df02SStephen Tozer 
489ffd08c77SStephen Tozer void DbgVariableRecord::setAssignId(DIAssignID *New) {
490ffd08c77SStephen Tozer   resetDebugValue(2, New);
491ffd08c77SStephen Tozer }
492d499df02SStephen Tozer 
493ffd08c77SStephen Tozer void DbgVariableRecord::setKillAddress() {
494d499df02SStephen Tozer   resetDebugValue(
4952499978aSNuno Lopes       1, ValueAsMetadata::get(PoisonValue::get(getAddress()->getType())));
496d499df02SStephen Tozer }
497d499df02SStephen Tozer 
498ffd08c77SStephen Tozer bool DbgVariableRecord::isKillAddress() const {
499d499df02SStephen Tozer   Value *Addr = getAddress();
500d499df02SStephen Tozer   return !Addr || isa<UndefValue>(Addr);
501f1b0a544SJeremy Morse }
502f1b0a544SJeremy Morse 
503ababa964SOrlando Cazalet-Hyams const Instruction *DbgRecord::getInstruction() const {
50419b65a9cSJeremy Morse   return Marker->MarkedInstr;
50519b65a9cSJeremy Morse }
50619b65a9cSJeremy Morse 
507ababa964SOrlando Cazalet-Hyams const BasicBlock *DbgRecord::getParent() const {
508f1b0a544SJeremy Morse   return Marker->MarkedInstr->getParent();
509f1b0a544SJeremy Morse }
510f1b0a544SJeremy Morse 
511ababa964SOrlando Cazalet-Hyams BasicBlock *DbgRecord::getParent() { return Marker->MarkedInstr->getParent(); }
512f1b0a544SJeremy Morse 
513ababa964SOrlando Cazalet-Hyams BasicBlock *DbgRecord::getBlock() { return Marker->getParent(); }
514f1b0a544SJeremy Morse 
515ababa964SOrlando Cazalet-Hyams const BasicBlock *DbgRecord::getBlock() const { return Marker->getParent(); }
516f1b0a544SJeremy Morse 
517ababa964SOrlando Cazalet-Hyams Function *DbgRecord::getFunction() { return getBlock()->getParent(); }
518f1b0a544SJeremy Morse 
519ababa964SOrlando Cazalet-Hyams const Function *DbgRecord::getFunction() const {
520ababa964SOrlando Cazalet-Hyams   return getBlock()->getParent();
521ababa964SOrlando Cazalet-Hyams }
522f1b0a544SJeremy Morse 
523ababa964SOrlando Cazalet-Hyams Module *DbgRecord::getModule() { return getFunction()->getParent(); }
524f1b0a544SJeremy Morse 
525ababa964SOrlando Cazalet-Hyams const Module *DbgRecord::getModule() const {
526ababa964SOrlando Cazalet-Hyams   return getFunction()->getParent();
527ababa964SOrlando Cazalet-Hyams }
528f1b0a544SJeremy Morse 
529ababa964SOrlando Cazalet-Hyams LLVMContext &DbgRecord::getContext() { return getBlock()->getContext(); }
530f1b0a544SJeremy Morse 
531ababa964SOrlando Cazalet-Hyams const LLVMContext &DbgRecord::getContext() const {
532f1b0a544SJeremy Morse   return getBlock()->getContext();
533f1b0a544SJeremy Morse }
534f1b0a544SJeremy Morse 
535ababa964SOrlando Cazalet-Hyams void DbgRecord::insertBefore(DbgRecord *InsertBefore) {
5362b08de43SStephen Tozer   assert(!getMarker() &&
53775dfa58eSStephen Tozer          "Cannot insert a DbgRecord that is already has a DbgMarker!");
5382b08de43SStephen Tozer   assert(InsertBefore->getMarker() &&
539ababa964SOrlando Cazalet-Hyams          "Cannot insert a DbgRecord before a DbgRecord that does not have a "
54075dfa58eSStephen Tozer          "DbgMarker!");
54115f3f446SStephen Tozer   InsertBefore->getMarker()->insertDbgRecord(this, InsertBefore);
5422b08de43SStephen Tozer }
543ababa964SOrlando Cazalet-Hyams void DbgRecord::insertAfter(DbgRecord *InsertAfter) {
5442b08de43SStephen Tozer   assert(!getMarker() &&
54575dfa58eSStephen Tozer          "Cannot insert a DbgRecord that is already has a DbgMarker!");
5462b08de43SStephen Tozer   assert(InsertAfter->getMarker() &&
547ababa964SOrlando Cazalet-Hyams          "Cannot insert a DbgRecord after a DbgRecord that does not have a "
54875dfa58eSStephen Tozer          "DbgMarker!");
54915f3f446SStephen Tozer   InsertAfter->getMarker()->insertDbgRecordAfter(this, InsertAfter);
5502b08de43SStephen Tozer }
551*8e702735SJeremy Morse 
552*8e702735SJeremy Morse void DbgRecord::insertBefore(self_iterator InsertBefore) {
553*8e702735SJeremy Morse   assert(!getMarker() &&
554*8e702735SJeremy Morse          "Cannot insert a DbgRecord that is already has a DbgMarker!");
555*8e702735SJeremy Morse   assert(InsertBefore->getMarker() &&
556*8e702735SJeremy Morse          "Cannot insert a DbgRecord before a DbgRecord that does not have a "
557*8e702735SJeremy Morse          "DbgMarker!");
558*8e702735SJeremy Morse   InsertBefore->getMarker()->insertDbgRecord(this, &*InsertBefore);
559*8e702735SJeremy Morse }
560*8e702735SJeremy Morse void DbgRecord::insertAfter(self_iterator InsertAfter) {
561*8e702735SJeremy Morse   assert(!getMarker() &&
562*8e702735SJeremy Morse          "Cannot insert a DbgRecord that is already has a DbgMarker!");
563*8e702735SJeremy Morse   assert(InsertAfter->getMarker() &&
564*8e702735SJeremy Morse          "Cannot insert a DbgRecord after a DbgRecord that does not have a "
565*8e702735SJeremy Morse          "DbgMarker!");
566*8e702735SJeremy Morse   InsertAfter->getMarker()->insertDbgRecordAfter(this, &*InsertAfter);
567*8e702735SJeremy Morse }
568*8e702735SJeremy Morse 
569ababa964SOrlando Cazalet-Hyams void DbgRecord::moveBefore(DbgRecord *MoveBefore) {
5702b08de43SStephen Tozer   assert(getMarker() &&
57175dfa58eSStephen Tozer          "Canot move a DbgRecord that does not currently have a DbgMarker!");
5722b08de43SStephen Tozer   removeFromParent();
5732b08de43SStephen Tozer   insertBefore(MoveBefore);
5742b08de43SStephen Tozer }
575ababa964SOrlando Cazalet-Hyams void DbgRecord::moveAfter(DbgRecord *MoveAfter) {
5762b08de43SStephen Tozer   assert(getMarker() &&
57775dfa58eSStephen Tozer          "Canot move a DbgRecord that does not currently have a DbgMarker!");
5782b08de43SStephen Tozer   removeFromParent();
5792b08de43SStephen Tozer   insertAfter(MoveAfter);
5802b08de43SStephen Tozer }
5812b08de43SStephen Tozer 
582*8e702735SJeremy Morse void DbgRecord::moveBefore(self_iterator MoveBefore) {
583*8e702735SJeremy Morse   assert(getMarker() &&
584*8e702735SJeremy Morse          "Canot move a DbgRecord that does not currently have a DbgMarker!");
585*8e702735SJeremy Morse   removeFromParent();
586*8e702735SJeremy Morse   insertBefore(MoveBefore);
587*8e702735SJeremy Morse }
588*8e702735SJeremy Morse void DbgRecord::moveAfter(self_iterator MoveAfter) {
589*8e702735SJeremy Morse   assert(getMarker() &&
590*8e702735SJeremy Morse          "Canot move a DbgRecord that does not currently have a DbgMarker!");
591*8e702735SJeremy Morse   removeFromParent();
592*8e702735SJeremy Morse   insertAfter(MoveAfter);
593*8e702735SJeremy Morse }
594*8e702735SJeremy Morse 
595f1b0a544SJeremy Morse ///////////////////////////////////////////////////////////////////////////////
596f1b0a544SJeremy Morse 
59775dfa58eSStephen Tozer // An empty, global, DbgMarker for the purpose of describing empty ranges of
598360da838SStephen Tozer // DbgRecords.
59975dfa58eSStephen Tozer DbgMarker DbgMarker::EmptyDbgMarker;
600f1b0a544SJeremy Morse 
60175dfa58eSStephen Tozer void DbgMarker::dropDbgRecords() {
602360da838SStephen Tozer   while (!StoredDbgRecords.empty()) {
603360da838SStephen Tozer     auto It = StoredDbgRecords.begin();
604ababa964SOrlando Cazalet-Hyams     DbgRecord *DR = &*It;
605360da838SStephen Tozer     StoredDbgRecords.erase(It);
606ababa964SOrlando Cazalet-Hyams     DR->deleteRecord();
607f1b0a544SJeremy Morse   }
608f1b0a544SJeremy Morse }
609f1b0a544SJeremy Morse 
61075dfa58eSStephen Tozer void DbgMarker::dropOneDbgRecord(DbgRecord *DR) {
611ababa964SOrlando Cazalet-Hyams   assert(DR->getMarker() == this);
612360da838SStephen Tozer   StoredDbgRecords.erase(DR->getIterator());
613ababa964SOrlando Cazalet-Hyams   DR->deleteRecord();
614f1b0a544SJeremy Morse }
615f1b0a544SJeremy Morse 
61675dfa58eSStephen Tozer const BasicBlock *DbgMarker::getParent() const {
617f1b0a544SJeremy Morse   return MarkedInstr->getParent();
618f1b0a544SJeremy Morse }
619f1b0a544SJeremy Morse 
62075dfa58eSStephen Tozer BasicBlock *DbgMarker::getParent() { return MarkedInstr->getParent(); }
621f1b0a544SJeremy Morse 
62275dfa58eSStephen Tozer void DbgMarker::removeMarker() {
62375dfa58eSStephen Tozer   // Are there any DbgRecords in this DbgMarker? If not, nothing to preserve.
624f1b0a544SJeremy Morse   Instruction *Owner = MarkedInstr;
625360da838SStephen Tozer   if (StoredDbgRecords.empty()) {
626f1b0a544SJeremy Morse     eraseFromParent();
62775dfa58eSStephen Tozer     Owner->DebugMarker = nullptr;
628f1b0a544SJeremy Morse     return;
629f1b0a544SJeremy Morse   }
630f1b0a544SJeremy Morse 
631360da838SStephen Tozer   // The attached DbgRecords need to be preserved; attach them to the next
632f1b0a544SJeremy Morse   // instruction. If there isn't a next instruction, put them on the
633f1b0a544SJeremy Morse   // "trailing" list.
63475dfa58eSStephen Tozer   DbgMarker *NextMarker = Owner->getParent()->getNextMarker(Owner);
635ddc49357SJeremy Morse   if (NextMarker) {
636f1b0a544SJeremy Morse     NextMarker->absorbDebugValues(*this, true);
637f1b0a544SJeremy Morse     eraseFromParent();
638ddc49357SJeremy Morse   } else {
639ddc49357SJeremy Morse     // We can avoid a deallocation -- just store this marker onto the next
640ddc49357SJeremy Morse     // instruction. Unless we're at the end of the block, in which case this
641ddc49357SJeremy Morse     // marker becomes the trailing marker of a degenerate block.
642ddc49357SJeremy Morse     BasicBlock::iterator NextIt = std::next(Owner->getIterator());
643ddc49357SJeremy Morse     if (NextIt == getParent()->end()) {
64415f3f446SStephen Tozer       getParent()->setTrailingDbgRecords(this);
645ddc49357SJeremy Morse       MarkedInstr = nullptr;
646ddc49357SJeremy Morse     } else {
64775dfa58eSStephen Tozer       NextIt->DebugMarker = this;
648ddc49357SJeremy Morse       MarkedInstr = &*NextIt;
649ddc49357SJeremy Morse     }
650ddc49357SJeremy Morse   }
65175dfa58eSStephen Tozer   Owner->DebugMarker = nullptr;
652f1b0a544SJeremy Morse }
653f1b0a544SJeremy Morse 
65475dfa58eSStephen Tozer void DbgMarker::removeFromParent() {
65575dfa58eSStephen Tozer   MarkedInstr->DebugMarker = nullptr;
656f1b0a544SJeremy Morse   MarkedInstr = nullptr;
657f1b0a544SJeremy Morse }
658f1b0a544SJeremy Morse 
65975dfa58eSStephen Tozer void DbgMarker::eraseFromParent() {
660f1b0a544SJeremy Morse   if (MarkedInstr)
661f1b0a544SJeremy Morse     removeFromParent();
66215f3f446SStephen Tozer   dropDbgRecords();
663f1b0a544SJeremy Morse   delete this;
664f1b0a544SJeremy Morse }
665f1b0a544SJeremy Morse 
66675dfa58eSStephen Tozer iterator_range<DbgRecord::self_iterator> DbgMarker::getDbgRecordRange() {
667360da838SStephen Tozer   return make_range(StoredDbgRecords.begin(), StoredDbgRecords.end());
668f1b0a544SJeremy Morse }
669ababa964SOrlando Cazalet-Hyams iterator_range<DbgRecord::const_self_iterator>
67075dfa58eSStephen Tozer DbgMarker::getDbgRecordRange() const {
671360da838SStephen Tozer   return make_range(StoredDbgRecords.begin(), StoredDbgRecords.end());
6722b08de43SStephen Tozer }
673f1b0a544SJeremy Morse 
674ababa964SOrlando Cazalet-Hyams void DbgRecord::removeFromParent() {
675360da838SStephen Tozer   getMarker()->StoredDbgRecords.erase(getIterator());
6762b08de43SStephen Tozer   Marker = nullptr;
677f1b0a544SJeremy Morse }
678f1b0a544SJeremy Morse 
679ababa964SOrlando Cazalet-Hyams void DbgRecord::eraseFromParent() {
680f1b0a544SJeremy Morse   removeFromParent();
681ababa964SOrlando Cazalet-Hyams   deleteRecord();
682f1b0a544SJeremy Morse }
683f1b0a544SJeremy Morse 
68475dfa58eSStephen Tozer void DbgMarker::insertDbgRecord(DbgRecord *New, bool InsertAtHead) {
685360da838SStephen Tozer   auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end();
686360da838SStephen Tozer   StoredDbgRecords.insert(It, *New);
687f1b0a544SJeremy Morse   New->setMarker(this);
688f1b0a544SJeremy Morse }
68975dfa58eSStephen Tozer void DbgMarker::insertDbgRecord(DbgRecord *New, DbgRecord *InsertBefore) {
6902b08de43SStephen Tozer   assert(InsertBefore->getMarker() == this &&
69175dfa58eSStephen Tozer          "DbgRecord 'InsertBefore' must be contained in this DbgMarker!");
692360da838SStephen Tozer   StoredDbgRecords.insert(InsertBefore->getIterator(), *New);
6932b08de43SStephen Tozer   New->setMarker(this);
6942b08de43SStephen Tozer }
69575dfa58eSStephen Tozer void DbgMarker::insertDbgRecordAfter(DbgRecord *New, DbgRecord *InsertAfter) {
6962b08de43SStephen Tozer   assert(InsertAfter->getMarker() == this &&
69775dfa58eSStephen Tozer          "DbgRecord 'InsertAfter' must be contained in this DbgMarker!");
698360da838SStephen Tozer   StoredDbgRecords.insert(++(InsertAfter->getIterator()), *New);
6992b08de43SStephen Tozer   New->setMarker(this);
7002b08de43SStephen Tozer }
701f1b0a544SJeremy Morse 
70275dfa58eSStephen Tozer void DbgMarker::absorbDebugValues(DbgMarker &Src, bool InsertAtHead) {
703360da838SStephen Tozer   auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end();
704ffd08c77SStephen Tozer   for (DbgRecord &DVR : Src.StoredDbgRecords)
705ffd08c77SStephen Tozer     DVR.setMarker(this);
706f1b0a544SJeremy Morse 
707360da838SStephen Tozer   StoredDbgRecords.splice(It, Src.StoredDbgRecords);
708f1b0a544SJeremy Morse }
709f1b0a544SJeremy Morse 
71075dfa58eSStephen Tozer void DbgMarker::absorbDebugValues(
71175dfa58eSStephen Tozer     iterator_range<DbgRecord::self_iterator> Range, DbgMarker &Src,
71275dfa58eSStephen Tozer     bool InsertAtHead) {
713ababa964SOrlando Cazalet-Hyams   for (DbgRecord &DR : Range)
714ababa964SOrlando Cazalet-Hyams     DR.setMarker(this);
7152ec0283cSJeremy Morse 
7162ec0283cSJeremy Morse   auto InsertPos =
717360da838SStephen Tozer       (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end();
7182ec0283cSJeremy Morse 
719360da838SStephen Tozer   StoredDbgRecords.splice(InsertPos, Src.StoredDbgRecords, Range.begin(),
7202ec0283cSJeremy Morse                           Range.end());
7212ec0283cSJeremy Morse }
7222ec0283cSJeremy Morse 
72375dfa58eSStephen Tozer iterator_range<simple_ilist<DbgRecord>::iterator> DbgMarker::cloneDebugInfoFrom(
72475dfa58eSStephen Tozer     DbgMarker *From, std::optional<simple_ilist<DbgRecord>::iterator> from_here,
725f1b0a544SJeremy Morse     bool InsertAtHead) {
726ababa964SOrlando Cazalet-Hyams   DbgRecord *First = nullptr;
727360da838SStephen Tozer   // Work out what range of DbgRecords to clone: normally all the contents of
728360da838SStephen Tozer   // the "From" marker, optionally we can start from the from_here position down
729360da838SStephen Tozer   // to end().
730f1b0a544SJeremy Morse   auto Range =
731360da838SStephen Tozer       make_range(From->StoredDbgRecords.begin(), From->StoredDbgRecords.end());
732f1b0a544SJeremy Morse   if (from_here.has_value())
733360da838SStephen Tozer     Range = make_range(*from_here, From->StoredDbgRecords.end());
734f1b0a544SJeremy Morse 
735ffd08c77SStephen Tozer   // Clone each DbgVariableRecord and insert into StoreDbgVariableRecords;
736ffd08c77SStephen Tozer   // optionally place them at the start or the end of the list.
737360da838SStephen Tozer   auto Pos = (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end();
738ababa964SOrlando Cazalet-Hyams   for (DbgRecord &DR : Range) {
739ababa964SOrlando Cazalet-Hyams     DbgRecord *New = DR.clone();
740f1b0a544SJeremy Morse     New->setMarker(this);
741360da838SStephen Tozer     StoredDbgRecords.insert(Pos, *New);
742f1b0a544SJeremy Morse     if (!First)
743f1b0a544SJeremy Morse       First = New;
744f1b0a544SJeremy Morse   }
745f1b0a544SJeremy Morse 
746f1b0a544SJeremy Morse   if (!First)
747360da838SStephen Tozer     return {StoredDbgRecords.end(), StoredDbgRecords.end()};
748f1b0a544SJeremy Morse 
749f1b0a544SJeremy Morse   if (InsertAtHead)
750f1b0a544SJeremy Morse     // If InsertAtHead is set, we cloned a range onto the front of of the
751360da838SStephen Tozer     // StoredDbgRecords collection, return that range.
752360da838SStephen Tozer     return {StoredDbgRecords.begin(), Pos};
753f1b0a544SJeremy Morse   else
754f1b0a544SJeremy Morse     // We inserted a block at the end, return that range.
755360da838SStephen Tozer     return {First->getIterator(), StoredDbgRecords.end()};
756f1b0a544SJeremy Morse }
757f1b0a544SJeremy Morse 
758f1b0a544SJeremy Morse } // end namespace llvm
759