1ac9a064cSDimitry Andric //=====-- DebugProgramInstruction.cpp - Implement DbgRecords/DbgMarkers --====//
2b1c73532SDimitry Andric //
3b1c73532SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4b1c73532SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5b1c73532SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b1c73532SDimitry Andric //
7b1c73532SDimitry Andric //===----------------------------------------------------------------------===//
8b1c73532SDimitry Andric
9b1c73532SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
10b1c73532SDimitry Andric #include "llvm/IR/DebugProgramInstruction.h"
11b1c73532SDimitry Andric #include "llvm/IR/DIBuilder.h"
12b1c73532SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
13b1c73532SDimitry Andric
14b1c73532SDimitry Andric namespace llvm {
15b1c73532SDimitry Andric
16ac9a064cSDimitry Andric template <typename T>
DbgRecordParamRef(const T * Param)17ac9a064cSDimitry Andric DbgRecordParamRef<T>::DbgRecordParamRef(const T *Param)
18ac9a064cSDimitry Andric : Ref(const_cast<T *>(Param)) {}
19ac9a064cSDimitry Andric template <typename T>
DbgRecordParamRef(const MDNode * Param)20ac9a064cSDimitry Andric DbgRecordParamRef<T>::DbgRecordParamRef(const MDNode *Param)
21ac9a064cSDimitry Andric : Ref(const_cast<MDNode *>(Param)) {}
22ac9a064cSDimitry Andric
get() const23ac9a064cSDimitry Andric template <typename T> T *DbgRecordParamRef<T>::get() const {
24ac9a064cSDimitry Andric return cast<T>(Ref);
25ac9a064cSDimitry Andric }
26ac9a064cSDimitry Andric
27ac9a064cSDimitry Andric template class DbgRecordParamRef<DIExpression>;
28ac9a064cSDimitry Andric template class DbgRecordParamRef<DILabel>;
29ac9a064cSDimitry Andric template class DbgRecordParamRef<DILocalVariable>;
30ac9a064cSDimitry Andric
DbgVariableRecord(const DbgVariableIntrinsic * DVI)31ac9a064cSDimitry Andric DbgVariableRecord::DbgVariableRecord(const DbgVariableIntrinsic *DVI)
32ac9a064cSDimitry Andric : DbgRecord(ValueKind, DVI->getDebugLoc()),
33ac9a064cSDimitry Andric DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}),
344df029ccSDimitry Andric Variable(DVI->getVariable()), Expression(DVI->getExpression()),
35ac9a064cSDimitry Andric AddressExpression() {
36b1c73532SDimitry Andric switch (DVI->getIntrinsicID()) {
37b1c73532SDimitry Andric case Intrinsic::dbg_value:
38b1c73532SDimitry Andric Type = LocationType::Value;
39b1c73532SDimitry Andric break;
40b1c73532SDimitry Andric case Intrinsic::dbg_declare:
41b1c73532SDimitry Andric Type = LocationType::Declare;
42b1c73532SDimitry Andric break;
434df029ccSDimitry Andric case Intrinsic::dbg_assign: {
444df029ccSDimitry Andric Type = LocationType::Assign;
454df029ccSDimitry Andric const DbgAssignIntrinsic *Assign =
464df029ccSDimitry Andric static_cast<const DbgAssignIntrinsic *>(DVI);
474df029ccSDimitry Andric resetDebugValue(1, Assign->getRawAddress());
484df029ccSDimitry Andric AddressExpression = Assign->getAddressExpression();
494df029ccSDimitry Andric setAssignId(Assign->getAssignID());
504df029ccSDimitry Andric break;
514df029ccSDimitry Andric }
52b1c73532SDimitry Andric default:
53b1c73532SDimitry Andric llvm_unreachable(
54ac9a064cSDimitry Andric "Trying to create a DbgVariableRecord with an invalid intrinsic type!");
55b1c73532SDimitry Andric }
56b1c73532SDimitry Andric }
57b1c73532SDimitry Andric
DbgVariableRecord(const DbgVariableRecord & DVR)58ac9a064cSDimitry Andric DbgVariableRecord::DbgVariableRecord(const DbgVariableRecord &DVR)
59ac9a064cSDimitry Andric : DbgRecord(ValueKind, DVR.getDebugLoc()), DebugValueUser(DVR.DebugValues),
60ac9a064cSDimitry Andric Type(DVR.getType()), Variable(DVR.getVariable()),
61ac9a064cSDimitry Andric Expression(DVR.getExpression()),
62ac9a064cSDimitry Andric AddressExpression(DVR.AddressExpression) {}
63b1c73532SDimitry Andric
DbgVariableRecord(Metadata * Location,DILocalVariable * DV,DIExpression * Expr,const DILocation * DI,LocationType Type)64ac9a064cSDimitry Andric DbgVariableRecord::DbgVariableRecord(Metadata *Location, DILocalVariable *DV,
65ac9a064cSDimitry Andric DIExpression *Expr, const DILocation *DI,
66ac9a064cSDimitry Andric LocationType Type)
67ac9a064cSDimitry Andric : DbgRecord(ValueKind, DI), DebugValueUser({Location, nullptr, nullptr}),
68ac9a064cSDimitry Andric Type(Type), Variable(DV), Expression(Expr) {}
694df029ccSDimitry Andric
DbgVariableRecord(Metadata * Value,DILocalVariable * Variable,DIExpression * Expression,DIAssignID * AssignID,Metadata * Address,DIExpression * AddressExpression,const DILocation * DI)70ac9a064cSDimitry Andric DbgVariableRecord::DbgVariableRecord(Metadata *Value, DILocalVariable *Variable,
71ac9a064cSDimitry Andric DIExpression *Expression,
72ac9a064cSDimitry Andric DIAssignID *AssignID, Metadata *Address,
73ac9a064cSDimitry Andric DIExpression *AddressExpression,
744df029ccSDimitry Andric const DILocation *DI)
75ac9a064cSDimitry Andric : DbgRecord(ValueKind, DI), DebugValueUser({Value, Address, AssignID}),
76ac9a064cSDimitry Andric Type(LocationType::Assign), Variable(Variable), Expression(Expression),
77ac9a064cSDimitry Andric AddressExpression(AddressExpression) {}
78b1c73532SDimitry Andric
deleteRecord()79ac9a064cSDimitry Andric void DbgRecord::deleteRecord() {
80ac9a064cSDimitry Andric switch (RecordKind) {
81ac9a064cSDimitry Andric case ValueKind:
82ac9a064cSDimitry Andric delete cast<DbgVariableRecord>(this);
83ac9a064cSDimitry Andric return;
84ac9a064cSDimitry Andric case LabelKind:
85ac9a064cSDimitry Andric delete cast<DbgLabelRecord>(this);
86ac9a064cSDimitry Andric return;
87ac9a064cSDimitry Andric }
88ac9a064cSDimitry Andric llvm_unreachable("unsupported DbgRecord kind");
89ac9a064cSDimitry Andric }
90b1c73532SDimitry Andric
print(raw_ostream & O,bool IsForDebug) const91ac9a064cSDimitry Andric void DbgRecord::print(raw_ostream &O, bool IsForDebug) const {
92ac9a064cSDimitry Andric switch (RecordKind) {
93ac9a064cSDimitry Andric case ValueKind:
94ac9a064cSDimitry Andric cast<DbgVariableRecord>(this)->print(O, IsForDebug);
95ac9a064cSDimitry Andric return;
96ac9a064cSDimitry Andric case LabelKind:
97ac9a064cSDimitry Andric cast<DbgLabelRecord>(this)->print(O, IsForDebug);
98ac9a064cSDimitry Andric return;
99ac9a064cSDimitry Andric };
100ac9a064cSDimitry Andric llvm_unreachable("unsupported DbgRecord kind");
101ac9a064cSDimitry Andric }
102ac9a064cSDimitry Andric
print(raw_ostream & O,ModuleSlotTracker & MST,bool IsForDebug) const103ac9a064cSDimitry Andric void DbgRecord::print(raw_ostream &O, ModuleSlotTracker &MST,
104ac9a064cSDimitry Andric bool IsForDebug) const {
105ac9a064cSDimitry Andric switch (RecordKind) {
106ac9a064cSDimitry Andric case ValueKind:
107ac9a064cSDimitry Andric cast<DbgVariableRecord>(this)->print(O, MST, IsForDebug);
108ac9a064cSDimitry Andric return;
109ac9a064cSDimitry Andric case LabelKind:
110ac9a064cSDimitry Andric cast<DbgLabelRecord>(this)->print(O, MST, IsForDebug);
111ac9a064cSDimitry Andric return;
112ac9a064cSDimitry Andric };
113ac9a064cSDimitry Andric llvm_unreachable("unsupported DbgRecord kind");
114ac9a064cSDimitry Andric }
115ac9a064cSDimitry Andric
isIdenticalToWhenDefined(const DbgRecord & R) const116ac9a064cSDimitry Andric bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const {
117ac9a064cSDimitry Andric if (RecordKind != R.RecordKind)
118ac9a064cSDimitry Andric return false;
119ac9a064cSDimitry Andric switch (RecordKind) {
120ac9a064cSDimitry Andric case ValueKind:
121ac9a064cSDimitry Andric return cast<DbgVariableRecord>(this)->isIdenticalToWhenDefined(
122ac9a064cSDimitry Andric *cast<DbgVariableRecord>(&R));
123ac9a064cSDimitry Andric case LabelKind:
124ac9a064cSDimitry Andric return cast<DbgLabelRecord>(this)->getLabel() ==
125ac9a064cSDimitry Andric cast<DbgLabelRecord>(R).getLabel();
126ac9a064cSDimitry Andric };
127ac9a064cSDimitry Andric llvm_unreachable("unsupported DbgRecord kind");
128ac9a064cSDimitry Andric }
129ac9a064cSDimitry Andric
isEquivalentTo(const DbgRecord & R) const130ac9a064cSDimitry Andric bool DbgRecord::isEquivalentTo(const DbgRecord &R) const {
131ac9a064cSDimitry Andric return getDebugLoc() == R.getDebugLoc() && isIdenticalToWhenDefined(R);
132ac9a064cSDimitry Andric }
133ac9a064cSDimitry Andric
134ac9a064cSDimitry Andric DbgInfoIntrinsic *
createDebugIntrinsic(Module * M,Instruction * InsertBefore) const135ac9a064cSDimitry Andric DbgRecord::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
136ac9a064cSDimitry Andric switch (RecordKind) {
137ac9a064cSDimitry Andric case ValueKind:
138ac9a064cSDimitry Andric return cast<DbgVariableRecord>(this)->createDebugIntrinsic(M, InsertBefore);
139ac9a064cSDimitry Andric case LabelKind:
140ac9a064cSDimitry Andric return cast<DbgLabelRecord>(this)->createDebugIntrinsic(M, InsertBefore);
141ac9a064cSDimitry Andric };
142ac9a064cSDimitry Andric llvm_unreachable("unsupported DbgRecord kind");
143ac9a064cSDimitry Andric }
144ac9a064cSDimitry Andric
DbgLabelRecord(MDNode * Label,MDNode * DL)145ac9a064cSDimitry Andric DbgLabelRecord::DbgLabelRecord(MDNode *Label, MDNode *DL)
146ac9a064cSDimitry Andric : DbgRecord(LabelKind, DebugLoc(DL)), Label(Label) {
147ac9a064cSDimitry Andric assert(Label && "Unexpected nullptr");
148ac9a064cSDimitry Andric assert((isa<DILabel>(Label) || Label->isTemporary()) &&
149ac9a064cSDimitry Andric "Label type must be or resolve to a DILabel");
150ac9a064cSDimitry Andric }
DbgLabelRecord(DILabel * Label,DebugLoc DL)151ac9a064cSDimitry Andric DbgLabelRecord::DbgLabelRecord(DILabel *Label, DebugLoc DL)
152ac9a064cSDimitry Andric : DbgRecord(LabelKind, DL), Label(Label) {
153ac9a064cSDimitry Andric assert(Label && "Unexpected nullptr");
154ac9a064cSDimitry Andric }
155ac9a064cSDimitry Andric
createUnresolvedDbgLabelRecord(MDNode * Label,MDNode * DL)156ac9a064cSDimitry Andric DbgLabelRecord *DbgLabelRecord::createUnresolvedDbgLabelRecord(MDNode *Label,
157ac9a064cSDimitry Andric MDNode *DL) {
158ac9a064cSDimitry Andric return new DbgLabelRecord(Label, DL);
159ac9a064cSDimitry Andric }
160ac9a064cSDimitry Andric
DbgVariableRecord(DbgVariableRecord::LocationType Type,Metadata * Val,MDNode * Variable,MDNode * Expression,MDNode * AssignID,Metadata * Address,MDNode * AddressExpression,MDNode * DI)161ac9a064cSDimitry Andric DbgVariableRecord::DbgVariableRecord(DbgVariableRecord::LocationType Type,
162ac9a064cSDimitry Andric Metadata *Val, MDNode *Variable,
163ac9a064cSDimitry Andric MDNode *Expression, MDNode *AssignID,
164ac9a064cSDimitry Andric Metadata *Address,
165ac9a064cSDimitry Andric MDNode *AddressExpression, MDNode *DI)
166ac9a064cSDimitry Andric : DbgRecord(ValueKind, DebugLoc(DI)),
167ac9a064cSDimitry Andric DebugValueUser({Val, Address, AssignID}), Type(Type), Variable(Variable),
168ac9a064cSDimitry Andric Expression(Expression), AddressExpression(AddressExpression) {}
169ac9a064cSDimitry Andric
createUnresolvedDbgVariableRecord(DbgVariableRecord::LocationType Type,Metadata * Val,MDNode * Variable,MDNode * Expression,MDNode * AssignID,Metadata * Address,MDNode * AddressExpression,MDNode * DI)170ac9a064cSDimitry Andric DbgVariableRecord *DbgVariableRecord::createUnresolvedDbgVariableRecord(
171ac9a064cSDimitry Andric DbgVariableRecord::LocationType Type, Metadata *Val, MDNode *Variable,
172ac9a064cSDimitry Andric MDNode *Expression, MDNode *AssignID, Metadata *Address,
173ac9a064cSDimitry Andric MDNode *AddressExpression, MDNode *DI) {
174ac9a064cSDimitry Andric return new DbgVariableRecord(Type, Val, Variable, Expression, AssignID,
175ac9a064cSDimitry Andric Address, AddressExpression, DI);
176ac9a064cSDimitry Andric }
177ac9a064cSDimitry Andric
178ac9a064cSDimitry Andric DbgVariableRecord *
createDbgVariableRecord(Value * Location,DILocalVariable * DV,DIExpression * Expr,const DILocation * DI)179ac9a064cSDimitry Andric DbgVariableRecord::createDbgVariableRecord(Value *Location, DILocalVariable *DV,
180ac9a064cSDimitry Andric DIExpression *Expr,
181ac9a064cSDimitry Andric const DILocation *DI) {
182ac9a064cSDimitry Andric return new DbgVariableRecord(ValueAsMetadata::get(Location), DV, Expr, DI,
1834df029ccSDimitry Andric LocationType::Value);
1844df029ccSDimitry Andric }
1854df029ccSDimitry Andric
createDbgVariableRecord(Value * Location,DILocalVariable * DV,DIExpression * Expr,const DILocation * DI,DbgVariableRecord & InsertBefore)186ac9a064cSDimitry Andric DbgVariableRecord *DbgVariableRecord::createDbgVariableRecord(
187ac9a064cSDimitry Andric Value *Location, DILocalVariable *DV, DIExpression *Expr,
188ac9a064cSDimitry Andric const DILocation *DI, DbgVariableRecord &InsertBefore) {
189ac9a064cSDimitry Andric auto *NewDbgVariableRecord = createDbgVariableRecord(Location, DV, Expr, DI);
190ac9a064cSDimitry Andric NewDbgVariableRecord->insertBefore(&InsertBefore);
191ac9a064cSDimitry Andric return NewDbgVariableRecord;
1924df029ccSDimitry Andric }
1934df029ccSDimitry Andric
createDVRDeclare(Value * Address,DILocalVariable * DV,DIExpression * Expr,const DILocation * DI)194ac9a064cSDimitry Andric DbgVariableRecord *DbgVariableRecord::createDVRDeclare(Value *Address,
195ac9a064cSDimitry Andric DILocalVariable *DV,
196ac9a064cSDimitry Andric DIExpression *Expr,
197ac9a064cSDimitry Andric const DILocation *DI) {
198ac9a064cSDimitry Andric return new DbgVariableRecord(ValueAsMetadata::get(Address), DV, Expr, DI,
1994df029ccSDimitry Andric LocationType::Declare);
2004df029ccSDimitry Andric }
2014df029ccSDimitry Andric
202ac9a064cSDimitry Andric DbgVariableRecord *
createDVRDeclare(Value * Address,DILocalVariable * DV,DIExpression * Expr,const DILocation * DI,DbgVariableRecord & InsertBefore)203ac9a064cSDimitry Andric DbgVariableRecord::createDVRDeclare(Value *Address, DILocalVariable *DV,
2044df029ccSDimitry Andric DIExpression *Expr, const DILocation *DI,
205ac9a064cSDimitry Andric DbgVariableRecord &InsertBefore) {
206ac9a064cSDimitry Andric auto *NewDVRDeclare = createDVRDeclare(Address, DV, Expr, DI);
207ac9a064cSDimitry Andric NewDVRDeclare->insertBefore(&InsertBefore);
208ac9a064cSDimitry Andric return NewDVRDeclare;
2094df029ccSDimitry Andric }
2104df029ccSDimitry Andric
createDVRAssign(Value * Val,DILocalVariable * Variable,DIExpression * Expression,DIAssignID * AssignID,Value * Address,DIExpression * AddressExpression,const DILocation * DI)211ac9a064cSDimitry Andric DbgVariableRecord *DbgVariableRecord::createDVRAssign(
212ac9a064cSDimitry Andric Value *Val, DILocalVariable *Variable, DIExpression *Expression,
213ac9a064cSDimitry Andric DIAssignID *AssignID, Value *Address, DIExpression *AddressExpression,
2144df029ccSDimitry Andric const DILocation *DI) {
215ac9a064cSDimitry Andric return new DbgVariableRecord(ValueAsMetadata::get(Val), Variable, Expression,
216ac9a064cSDimitry Andric AssignID, ValueAsMetadata::get(Address),
217ac9a064cSDimitry Andric AddressExpression, DI);
2184df029ccSDimitry Andric }
2194df029ccSDimitry Andric
createLinkedDVRAssign(Instruction * LinkedInstr,Value * Val,DILocalVariable * Variable,DIExpression * Expression,Value * Address,DIExpression * AddressExpression,const DILocation * DI)220ac9a064cSDimitry Andric DbgVariableRecord *DbgVariableRecord::createLinkedDVRAssign(
221ac9a064cSDimitry Andric Instruction *LinkedInstr, Value *Val, DILocalVariable *Variable,
222ac9a064cSDimitry Andric DIExpression *Expression, Value *Address, DIExpression *AddressExpression,
2234df029ccSDimitry Andric const DILocation *DI) {
2244df029ccSDimitry Andric auto *Link = LinkedInstr->getMetadata(LLVMContext::MD_DIAssignID);
2254df029ccSDimitry Andric assert(Link && "Linked instruction must have DIAssign metadata attached");
226ac9a064cSDimitry Andric auto *NewDVRAssign = DbgVariableRecord::createDVRAssign(
227ac9a064cSDimitry Andric Val, Variable, Expression, cast<DIAssignID>(Link), Address,
2284df029ccSDimitry Andric AddressExpression, DI);
229ac9a064cSDimitry Andric LinkedInstr->getParent()->insertDbgRecordAfter(NewDVRAssign, LinkedInstr);
230ac9a064cSDimitry Andric return NewDVRAssign;
2314df029ccSDimitry Andric }
2324df029ccSDimitry Andric
233ac9a064cSDimitry Andric iterator_range<DbgVariableRecord::location_op_iterator>
location_ops() const234ac9a064cSDimitry Andric DbgVariableRecord::location_ops() const {
235b1c73532SDimitry Andric auto *MD = getRawLocation();
236ac9a064cSDimitry Andric // If a Value has been deleted, the "location" for this DbgVariableRecord will
237ac9a064cSDimitry Andric // be replaced by nullptr. Return an empty range.
238b1c73532SDimitry Andric if (!MD)
239b1c73532SDimitry Andric return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
240b1c73532SDimitry Andric location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
241b1c73532SDimitry Andric
242b1c73532SDimitry Andric // If operand is ValueAsMetadata, return a range over just that operand.
243b1c73532SDimitry Andric if (auto *VAM = dyn_cast<ValueAsMetadata>(MD))
244b1c73532SDimitry Andric return {location_op_iterator(VAM), location_op_iterator(VAM + 1)};
245b1c73532SDimitry Andric
246b1c73532SDimitry Andric // If operand is DIArgList, return a range over its args.
247b1c73532SDimitry Andric if (auto *AL = dyn_cast<DIArgList>(MD))
248b1c73532SDimitry Andric return {location_op_iterator(AL->args_begin()),
249b1c73532SDimitry Andric location_op_iterator(AL->args_end())};
250b1c73532SDimitry Andric
251b1c73532SDimitry Andric // Operand is an empty metadata tuple, so return empty iterator.
252b1c73532SDimitry Andric assert(cast<MDNode>(MD)->getNumOperands() == 0);
253b1c73532SDimitry Andric return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
254b1c73532SDimitry Andric location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
255b1c73532SDimitry Andric }
256b1c73532SDimitry Andric
getNumVariableLocationOps() const257ac9a064cSDimitry Andric unsigned DbgVariableRecord::getNumVariableLocationOps() const {
258b1c73532SDimitry Andric if (hasArgList())
259b1c73532SDimitry Andric return cast<DIArgList>(getRawLocation())->getArgs().size();
260b1c73532SDimitry Andric return 1;
261b1c73532SDimitry Andric }
262b1c73532SDimitry Andric
getVariableLocationOp(unsigned OpIdx) const263ac9a064cSDimitry Andric Value *DbgVariableRecord::getVariableLocationOp(unsigned OpIdx) const {
264b1c73532SDimitry Andric auto *MD = getRawLocation();
265b1c73532SDimitry Andric if (!MD)
266b1c73532SDimitry Andric return nullptr;
267b1c73532SDimitry Andric
268b1c73532SDimitry Andric if (auto *AL = dyn_cast<DIArgList>(MD))
269b1c73532SDimitry Andric return AL->getArgs()[OpIdx]->getValue();
270b1c73532SDimitry Andric if (isa<MDNode>(MD))
271b1c73532SDimitry Andric return nullptr;
272b1c73532SDimitry Andric assert(isa<ValueAsMetadata>(MD) &&
273ac9a064cSDimitry Andric "Attempted to get location operand from DbgVariableRecord with none.");
274b1c73532SDimitry Andric auto *V = cast<ValueAsMetadata>(MD);
275b1c73532SDimitry Andric assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a "
276b1c73532SDimitry Andric "single location operand.");
277b1c73532SDimitry Andric return V->getValue();
278b1c73532SDimitry Andric }
279b1c73532SDimitry Andric
getAsMetadata(Value * V)280b1c73532SDimitry Andric static ValueAsMetadata *getAsMetadata(Value *V) {
281b1c73532SDimitry Andric return isa<MetadataAsValue>(V) ? dyn_cast<ValueAsMetadata>(
282b1c73532SDimitry Andric cast<MetadataAsValue>(V)->getMetadata())
283b1c73532SDimitry Andric : ValueAsMetadata::get(V);
284b1c73532SDimitry Andric }
285b1c73532SDimitry Andric
replaceVariableLocationOp(Value * OldValue,Value * NewValue,bool AllowEmpty)286ac9a064cSDimitry Andric void DbgVariableRecord::replaceVariableLocationOp(Value *OldValue,
287ac9a064cSDimitry Andric Value *NewValue,
288b1c73532SDimitry Andric bool AllowEmpty) {
289b1c73532SDimitry Andric assert(NewValue && "Values must be non-null");
2904df029ccSDimitry Andric
2914df029ccSDimitry Andric bool DbgAssignAddrReplaced = isDbgAssign() && OldValue == getAddress();
2924df029ccSDimitry Andric if (DbgAssignAddrReplaced)
2934df029ccSDimitry Andric setAddress(NewValue);
2944df029ccSDimitry Andric
295b1c73532SDimitry Andric auto Locations = location_ops();
296b1c73532SDimitry Andric auto OldIt = find(Locations, OldValue);
297b1c73532SDimitry Andric if (OldIt == Locations.end()) {
2984df029ccSDimitry Andric if (AllowEmpty || DbgAssignAddrReplaced)
299b1c73532SDimitry Andric return;
300b1c73532SDimitry Andric llvm_unreachable("OldValue must be a current location");
301b1c73532SDimitry Andric }
302b1c73532SDimitry Andric
303b1c73532SDimitry Andric if (!hasArgList()) {
304b1c73532SDimitry Andric // Set our location to be the MAV wrapping the new Value.
305b1c73532SDimitry Andric setRawLocation(isa<MetadataAsValue>(NewValue)
306b1c73532SDimitry Andric ? cast<MetadataAsValue>(NewValue)->getMetadata()
307b1c73532SDimitry Andric : ValueAsMetadata::get(NewValue));
308b1c73532SDimitry Andric return;
309b1c73532SDimitry Andric }
310b1c73532SDimitry Andric
311b1c73532SDimitry Andric // We must be referring to a DIArgList, produce a new operands vector with the
312b1c73532SDimitry Andric // old value replaced, generate a new DIArgList and set it as our location.
313b1c73532SDimitry Andric SmallVector<ValueAsMetadata *, 4> MDs;
314b1c73532SDimitry Andric ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
315b1c73532SDimitry Andric for (auto *VMD : Locations)
316b1c73532SDimitry Andric MDs.push_back(VMD == *OldIt ? NewOperand : getAsMetadata(VMD));
317b1c73532SDimitry Andric setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
318b1c73532SDimitry Andric }
319b1c73532SDimitry Andric
replaceVariableLocationOp(unsigned OpIdx,Value * NewValue)320ac9a064cSDimitry Andric void DbgVariableRecord::replaceVariableLocationOp(unsigned OpIdx,
321ac9a064cSDimitry Andric Value *NewValue) {
322b1c73532SDimitry Andric assert(OpIdx < getNumVariableLocationOps() && "Invalid Operand Index");
323b1c73532SDimitry Andric
324b1c73532SDimitry Andric if (!hasArgList()) {
325b1c73532SDimitry Andric setRawLocation(isa<MetadataAsValue>(NewValue)
326b1c73532SDimitry Andric ? cast<MetadataAsValue>(NewValue)->getMetadata()
327b1c73532SDimitry Andric : ValueAsMetadata::get(NewValue));
328b1c73532SDimitry Andric return;
329b1c73532SDimitry Andric }
330b1c73532SDimitry Andric
331b1c73532SDimitry Andric SmallVector<ValueAsMetadata *, 4> MDs;
332b1c73532SDimitry Andric ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
333b1c73532SDimitry Andric for (unsigned Idx = 0; Idx < getNumVariableLocationOps(); ++Idx)
334b1c73532SDimitry Andric MDs.push_back(Idx == OpIdx ? NewOperand
335b1c73532SDimitry Andric : getAsMetadata(getVariableLocationOp(Idx)));
336b1c73532SDimitry Andric
337b1c73532SDimitry Andric setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
338b1c73532SDimitry Andric }
339b1c73532SDimitry Andric
addVariableLocationOps(ArrayRef<Value * > NewValues,DIExpression * NewExpr)340ac9a064cSDimitry Andric void DbgVariableRecord::addVariableLocationOps(ArrayRef<Value *> NewValues,
341b1c73532SDimitry Andric DIExpression *NewExpr) {
342b1c73532SDimitry Andric assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() +
343b1c73532SDimitry Andric NewValues.size()) &&
344b1c73532SDimitry Andric "NewExpr for debug variable intrinsic does not reference every "
345b1c73532SDimitry Andric "location operand.");
346b1c73532SDimitry Andric assert(!is_contained(NewValues, nullptr) && "New values must be non-null");
347b1c73532SDimitry Andric setExpression(NewExpr);
348b1c73532SDimitry Andric SmallVector<ValueAsMetadata *, 4> MDs;
349b1c73532SDimitry Andric for (auto *VMD : location_ops())
350b1c73532SDimitry Andric MDs.push_back(getAsMetadata(VMD));
351b1c73532SDimitry Andric for (auto *VMD : NewValues)
352b1c73532SDimitry Andric MDs.push_back(getAsMetadata(VMD));
353b1c73532SDimitry Andric setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
354b1c73532SDimitry Andric }
355b1c73532SDimitry Andric
setKillLocation()356ac9a064cSDimitry Andric void DbgVariableRecord::setKillLocation() {
357b1c73532SDimitry Andric // TODO: When/if we remove duplicate values from DIArgLists, we don't need
358b1c73532SDimitry Andric // this set anymore.
359b1c73532SDimitry Andric SmallPtrSet<Value *, 4> RemovedValues;
360b1c73532SDimitry Andric for (Value *OldValue : location_ops()) {
361b1c73532SDimitry Andric if (!RemovedValues.insert(OldValue).second)
362b1c73532SDimitry Andric continue;
363b1c73532SDimitry Andric Value *Poison = PoisonValue::get(OldValue->getType());
364b1c73532SDimitry Andric replaceVariableLocationOp(OldValue, Poison);
365b1c73532SDimitry Andric }
366b1c73532SDimitry Andric }
367b1c73532SDimitry Andric
isKillLocation() const368ac9a064cSDimitry Andric bool DbgVariableRecord::isKillLocation() const {
369ac9a064cSDimitry Andric return (!hasArgList() && isa<MDNode>(getRawLocation())) ||
370ac9a064cSDimitry Andric (getNumVariableLocationOps() == 0 && !getExpression()->isComplex()) ||
371b1c73532SDimitry Andric any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); });
372b1c73532SDimitry Andric }
373b1c73532SDimitry Andric
getFragment() const374ac9a064cSDimitry Andric std::optional<DbgVariableFragmentInfo> DbgVariableRecord::getFragment() const {
375ac9a064cSDimitry Andric return getExpression()->getFragmentInfo();
376ac9a064cSDimitry Andric }
377ac9a064cSDimitry Andric
getFragmentSizeInBits() const378ac9a064cSDimitry Andric std::optional<uint64_t> DbgVariableRecord::getFragmentSizeInBits() const {
379b1c73532SDimitry Andric if (auto Fragment = getExpression()->getFragmentInfo())
380b1c73532SDimitry Andric return Fragment->SizeInBits;
381b1c73532SDimitry Andric return getVariable()->getSizeInBits();
382b1c73532SDimitry Andric }
383b1c73532SDimitry Andric
clone() const384ac9a064cSDimitry Andric DbgRecord *DbgRecord::clone() const {
385ac9a064cSDimitry Andric switch (RecordKind) {
386ac9a064cSDimitry Andric case ValueKind:
387ac9a064cSDimitry Andric return cast<DbgVariableRecord>(this)->clone();
388ac9a064cSDimitry Andric case LabelKind:
389ac9a064cSDimitry Andric return cast<DbgLabelRecord>(this)->clone();
390ac9a064cSDimitry Andric };
391ac9a064cSDimitry Andric llvm_unreachable("unsupported DbgRecord kind");
392ac9a064cSDimitry Andric }
393ac9a064cSDimitry Andric
clone() const394ac9a064cSDimitry Andric DbgVariableRecord *DbgVariableRecord::clone() const {
395ac9a064cSDimitry Andric return new DbgVariableRecord(*this);
396ac9a064cSDimitry Andric }
397ac9a064cSDimitry Andric
clone() const398ac9a064cSDimitry Andric DbgLabelRecord *DbgLabelRecord::clone() const {
399ac9a064cSDimitry Andric return new DbgLabelRecord(getLabel(), getDebugLoc());
400ac9a064cSDimitry Andric }
401b1c73532SDimitry Andric
402b1c73532SDimitry Andric DbgVariableIntrinsic *
createDebugIntrinsic(Module * M,Instruction * InsertBefore) const403ac9a064cSDimitry Andric DbgVariableRecord::createDebugIntrinsic(Module *M,
404ac9a064cSDimitry Andric Instruction *InsertBefore) const {
405b1c73532SDimitry Andric [[maybe_unused]] DICompileUnit *Unit =
406ac9a064cSDimitry Andric getDebugLoc()->getScope()->getSubprogram()->getUnit();
407b1c73532SDimitry Andric assert(M && Unit &&
408b1c73532SDimitry Andric "Cannot clone from BasicBlock that is not part of a Module or "
409b1c73532SDimitry Andric "DICompileUnit!");
410b1c73532SDimitry Andric LLVMContext &Context = getDebugLoc()->getContext();
411b1c73532SDimitry Andric Function *IntrinsicFn;
412b1c73532SDimitry Andric
413b1c73532SDimitry Andric // Work out what sort of intrinsic we're going to produce.
414b1c73532SDimitry Andric switch (getType()) {
415ac9a064cSDimitry Andric case DbgVariableRecord::LocationType::Declare:
416b1c73532SDimitry Andric IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_declare);
417b1c73532SDimitry Andric break;
418ac9a064cSDimitry Andric case DbgVariableRecord::LocationType::Value:
419b1c73532SDimitry Andric IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_value);
420b1c73532SDimitry Andric break;
421ac9a064cSDimitry Andric case DbgVariableRecord::LocationType::Assign:
4224df029ccSDimitry Andric IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_assign);
4234df029ccSDimitry Andric break;
424ac9a064cSDimitry Andric case DbgVariableRecord::LocationType::End:
425ac9a064cSDimitry Andric case DbgVariableRecord::LocationType::Any:
426312c0ed1SDimitry Andric llvm_unreachable("Invalid LocationType");
427b1c73532SDimitry Andric }
428b1c73532SDimitry Andric
429ac9a064cSDimitry Andric // Create the intrinsic from this DbgVariableRecord's information, optionally
430ac9a064cSDimitry Andric // insert into the target location.
4314df029ccSDimitry Andric DbgVariableIntrinsic *DVI;
432ac9a064cSDimitry Andric assert(getRawLocation() &&
433ac9a064cSDimitry Andric "DbgVariableRecord's RawLocation should be non-null.");
4344df029ccSDimitry Andric if (isDbgAssign()) {
4354df029ccSDimitry Andric Value *AssignArgs[] = {
4364df029ccSDimitry Andric MetadataAsValue::get(Context, getRawLocation()),
4374df029ccSDimitry Andric MetadataAsValue::get(Context, getVariable()),
4384df029ccSDimitry Andric MetadataAsValue::get(Context, getExpression()),
4394df029ccSDimitry Andric MetadataAsValue::get(Context, getAssignID()),
4404df029ccSDimitry Andric MetadataAsValue::get(Context, getRawAddress()),
4414df029ccSDimitry Andric MetadataAsValue::get(Context, getAddressExpression())};
4424df029ccSDimitry Andric DVI = cast<DbgVariableIntrinsic>(CallInst::Create(
4434df029ccSDimitry Andric IntrinsicFn->getFunctionType(), IntrinsicFn, AssignArgs));
4444df029ccSDimitry Andric } else {
4454df029ccSDimitry Andric Value *Args[] = {MetadataAsValue::get(Context, getRawLocation()),
4464df029ccSDimitry Andric MetadataAsValue::get(Context, getVariable()),
4474df029ccSDimitry Andric MetadataAsValue::get(Context, getExpression())};
4484df029ccSDimitry Andric DVI = cast<DbgVariableIntrinsic>(
449b1c73532SDimitry Andric CallInst::Create(IntrinsicFn->getFunctionType(), IntrinsicFn, Args));
4504df029ccSDimitry Andric }
451b1c73532SDimitry Andric DVI->setTailCall();
452b1c73532SDimitry Andric DVI->setDebugLoc(getDebugLoc());
453b1c73532SDimitry Andric if (InsertBefore)
454b1c73532SDimitry Andric DVI->insertBefore(InsertBefore);
455b1c73532SDimitry Andric
456b1c73532SDimitry Andric return DVI;
457b1c73532SDimitry Andric }
458b1c73532SDimitry Andric
459ac9a064cSDimitry Andric DbgLabelInst *
createDebugIntrinsic(Module * M,Instruction * InsertBefore) const460ac9a064cSDimitry Andric DbgLabelRecord::createDebugIntrinsic(Module *M,
461ac9a064cSDimitry Andric Instruction *InsertBefore) const {
462ac9a064cSDimitry Andric auto *LabelFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_label);
463ac9a064cSDimitry Andric Value *Args[] = {
464ac9a064cSDimitry Andric MetadataAsValue::get(getDebugLoc()->getContext(), getLabel())};
465ac9a064cSDimitry Andric DbgLabelInst *DbgLabel = cast<DbgLabelInst>(
466ac9a064cSDimitry Andric CallInst::Create(LabelFn->getFunctionType(), LabelFn, Args));
467ac9a064cSDimitry Andric DbgLabel->setTailCall();
468ac9a064cSDimitry Andric DbgLabel->setDebugLoc(getDebugLoc());
469ac9a064cSDimitry Andric if (InsertBefore)
470ac9a064cSDimitry Andric DbgLabel->insertBefore(InsertBefore);
471ac9a064cSDimitry Andric return DbgLabel;
472ac9a064cSDimitry Andric }
473ac9a064cSDimitry Andric
getAddress() const474ac9a064cSDimitry Andric Value *DbgVariableRecord::getAddress() const {
4754df029ccSDimitry Andric auto *MD = getRawAddress();
4767432c960SDimitry Andric if (auto *V = dyn_cast_or_null<ValueAsMetadata>(MD))
4774df029ccSDimitry Andric return V->getValue();
4784df029ccSDimitry Andric
4794df029ccSDimitry Andric // When the value goes to null, it gets replaced by an empty MDNode.
4807432c960SDimitry Andric assert(!MD ||
4817432c960SDimitry Andric !cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");
4824df029ccSDimitry Andric return nullptr;
4834df029ccSDimitry Andric }
4844df029ccSDimitry Andric
getAssignID() const485ac9a064cSDimitry Andric DIAssignID *DbgVariableRecord::getAssignID() const {
4864df029ccSDimitry Andric return cast<DIAssignID>(DebugValues[2]);
4874df029ccSDimitry Andric }
4884df029ccSDimitry Andric
setAssignId(DIAssignID * New)489ac9a064cSDimitry Andric void DbgVariableRecord::setAssignId(DIAssignID *New) {
490ac9a064cSDimitry Andric resetDebugValue(2, New);
491ac9a064cSDimitry Andric }
4924df029ccSDimitry Andric
setKillAddress()493ac9a064cSDimitry Andric void DbgVariableRecord::setKillAddress() {
4944df029ccSDimitry Andric resetDebugValue(
4954df029ccSDimitry Andric 1, ValueAsMetadata::get(UndefValue::get(getAddress()->getType())));
4964df029ccSDimitry Andric }
4974df029ccSDimitry Andric
isKillAddress() const498ac9a064cSDimitry Andric bool DbgVariableRecord::isKillAddress() const {
4994df029ccSDimitry Andric Value *Addr = getAddress();
5004df029ccSDimitry Andric return !Addr || isa<UndefValue>(Addr);
501b1c73532SDimitry Andric }
502b1c73532SDimitry Andric
getInstruction() const503ac9a064cSDimitry Andric const Instruction *DbgRecord::getInstruction() const {
504ac9a064cSDimitry Andric return Marker->MarkedInstr;
505ac9a064cSDimitry Andric }
506ac9a064cSDimitry Andric
getParent() const507ac9a064cSDimitry Andric const BasicBlock *DbgRecord::getParent() const {
508b1c73532SDimitry Andric return Marker->MarkedInstr->getParent();
509b1c73532SDimitry Andric }
510b1c73532SDimitry Andric
getParent()511ac9a064cSDimitry Andric BasicBlock *DbgRecord::getParent() { return Marker->MarkedInstr->getParent(); }
512b1c73532SDimitry Andric
getBlock()513ac9a064cSDimitry Andric BasicBlock *DbgRecord::getBlock() { return Marker->getParent(); }
514b1c73532SDimitry Andric
getBlock() const515ac9a064cSDimitry Andric const BasicBlock *DbgRecord::getBlock() const { return Marker->getParent(); }
516b1c73532SDimitry Andric
getFunction()517ac9a064cSDimitry Andric Function *DbgRecord::getFunction() { return getBlock()->getParent(); }
518b1c73532SDimitry Andric
getFunction() const519ac9a064cSDimitry Andric const Function *DbgRecord::getFunction() const {
520ac9a064cSDimitry Andric return getBlock()->getParent();
521ac9a064cSDimitry Andric }
522b1c73532SDimitry Andric
getModule()523ac9a064cSDimitry Andric Module *DbgRecord::getModule() { return getFunction()->getParent(); }
524b1c73532SDimitry Andric
getModule() const525ac9a064cSDimitry Andric const Module *DbgRecord::getModule() const {
526ac9a064cSDimitry Andric return getFunction()->getParent();
527ac9a064cSDimitry Andric }
528b1c73532SDimitry Andric
getContext()529ac9a064cSDimitry Andric LLVMContext &DbgRecord::getContext() { return getBlock()->getContext(); }
530b1c73532SDimitry Andric
getContext() const531ac9a064cSDimitry Andric const LLVMContext &DbgRecord::getContext() const {
532b1c73532SDimitry Andric return getBlock()->getContext();
533b1c73532SDimitry Andric }
534b1c73532SDimitry Andric
insertBefore(DbgRecord * InsertBefore)535ac9a064cSDimitry Andric void DbgRecord::insertBefore(DbgRecord *InsertBefore) {
5364df029ccSDimitry Andric assert(!getMarker() &&
537ac9a064cSDimitry Andric "Cannot insert a DbgRecord that is already has a DbgMarker!");
5384df029ccSDimitry Andric assert(InsertBefore->getMarker() &&
539ac9a064cSDimitry Andric "Cannot insert a DbgRecord before a DbgRecord that does not have a "
540ac9a064cSDimitry Andric "DbgMarker!");
541ac9a064cSDimitry Andric InsertBefore->getMarker()->insertDbgRecord(this, InsertBefore);
5424df029ccSDimitry Andric }
insertAfter(DbgRecord * InsertAfter)543ac9a064cSDimitry Andric void DbgRecord::insertAfter(DbgRecord *InsertAfter) {
5444df029ccSDimitry Andric assert(!getMarker() &&
545ac9a064cSDimitry Andric "Cannot insert a DbgRecord that is already has a DbgMarker!");
5464df029ccSDimitry Andric assert(InsertAfter->getMarker() &&
547ac9a064cSDimitry Andric "Cannot insert a DbgRecord after a DbgRecord that does not have a "
548ac9a064cSDimitry Andric "DbgMarker!");
549ac9a064cSDimitry Andric InsertAfter->getMarker()->insertDbgRecordAfter(this, InsertAfter);
5504df029ccSDimitry Andric }
moveBefore(DbgRecord * MoveBefore)551ac9a064cSDimitry Andric void DbgRecord::moveBefore(DbgRecord *MoveBefore) {
5524df029ccSDimitry Andric assert(getMarker() &&
553ac9a064cSDimitry Andric "Canot move a DbgRecord that does not currently have a DbgMarker!");
5544df029ccSDimitry Andric removeFromParent();
5554df029ccSDimitry Andric insertBefore(MoveBefore);
5564df029ccSDimitry Andric }
moveAfter(DbgRecord * MoveAfter)557ac9a064cSDimitry Andric void DbgRecord::moveAfter(DbgRecord *MoveAfter) {
5584df029ccSDimitry Andric assert(getMarker() &&
559ac9a064cSDimitry Andric "Canot move a DbgRecord that does not currently have a DbgMarker!");
5604df029ccSDimitry Andric removeFromParent();
5614df029ccSDimitry Andric insertAfter(MoveAfter);
5624df029ccSDimitry Andric }
5634df029ccSDimitry Andric
564b1c73532SDimitry Andric ///////////////////////////////////////////////////////////////////////////////
565b1c73532SDimitry Andric
566ac9a064cSDimitry Andric // An empty, global, DbgMarker for the purpose of describing empty ranges of
567ac9a064cSDimitry Andric // DbgRecords.
568ac9a064cSDimitry Andric DbgMarker DbgMarker::EmptyDbgMarker;
569b1c73532SDimitry Andric
dropDbgRecords()570ac9a064cSDimitry Andric void DbgMarker::dropDbgRecords() {
571ac9a064cSDimitry Andric while (!StoredDbgRecords.empty()) {
572ac9a064cSDimitry Andric auto It = StoredDbgRecords.begin();
573ac9a064cSDimitry Andric DbgRecord *DR = &*It;
574ac9a064cSDimitry Andric StoredDbgRecords.erase(It);
575ac9a064cSDimitry Andric DR->deleteRecord();
576b1c73532SDimitry Andric }
577b1c73532SDimitry Andric }
578b1c73532SDimitry Andric
dropOneDbgRecord(DbgRecord * DR)579ac9a064cSDimitry Andric void DbgMarker::dropOneDbgRecord(DbgRecord *DR) {
580ac9a064cSDimitry Andric assert(DR->getMarker() == this);
581ac9a064cSDimitry Andric StoredDbgRecords.erase(DR->getIterator());
582ac9a064cSDimitry Andric DR->deleteRecord();
583b1c73532SDimitry Andric }
584b1c73532SDimitry Andric
getParent() const585ac9a064cSDimitry Andric const BasicBlock *DbgMarker::getParent() const {
586b1c73532SDimitry Andric return MarkedInstr->getParent();
587b1c73532SDimitry Andric }
588b1c73532SDimitry Andric
getParent()589ac9a064cSDimitry Andric BasicBlock *DbgMarker::getParent() { return MarkedInstr->getParent(); }
590b1c73532SDimitry Andric
removeMarker()591ac9a064cSDimitry Andric void DbgMarker::removeMarker() {
592ac9a064cSDimitry Andric // Are there any DbgRecords in this DbgMarker? If not, nothing to preserve.
593b1c73532SDimitry Andric Instruction *Owner = MarkedInstr;
594ac9a064cSDimitry Andric if (StoredDbgRecords.empty()) {
595b1c73532SDimitry Andric eraseFromParent();
596ac9a064cSDimitry Andric Owner->DebugMarker = nullptr;
597b1c73532SDimitry Andric return;
598b1c73532SDimitry Andric }
599b1c73532SDimitry Andric
600ac9a064cSDimitry Andric // The attached DbgRecords need to be preserved; attach them to the next
601b1c73532SDimitry Andric // instruction. If there isn't a next instruction, put them on the
602b1c73532SDimitry Andric // "trailing" list.
603ac9a064cSDimitry Andric DbgMarker *NextMarker = Owner->getParent()->getNextMarker(Owner);
604ac9a064cSDimitry Andric if (NextMarker) {
605b1c73532SDimitry Andric NextMarker->absorbDebugValues(*this, true);
606b1c73532SDimitry Andric eraseFromParent();
607ac9a064cSDimitry Andric } else {
608ac9a064cSDimitry Andric // We can avoid a deallocation -- just store this marker onto the next
609ac9a064cSDimitry Andric // instruction. Unless we're at the end of the block, in which case this
610ac9a064cSDimitry Andric // marker becomes the trailing marker of a degenerate block.
611ac9a064cSDimitry Andric BasicBlock::iterator NextIt = std::next(Owner->getIterator());
612ac9a064cSDimitry Andric if (NextIt == getParent()->end()) {
613ac9a064cSDimitry Andric getParent()->setTrailingDbgRecords(this);
614ac9a064cSDimitry Andric MarkedInstr = nullptr;
615ac9a064cSDimitry Andric } else {
616ac9a064cSDimitry Andric NextIt->DebugMarker = this;
617ac9a064cSDimitry Andric MarkedInstr = &*NextIt;
618ac9a064cSDimitry Andric }
619ac9a064cSDimitry Andric }
620ac9a064cSDimitry Andric Owner->DebugMarker = nullptr;
621b1c73532SDimitry Andric }
622b1c73532SDimitry Andric
removeFromParent()623ac9a064cSDimitry Andric void DbgMarker::removeFromParent() {
624ac9a064cSDimitry Andric MarkedInstr->DebugMarker = nullptr;
625b1c73532SDimitry Andric MarkedInstr = nullptr;
626b1c73532SDimitry Andric }
627b1c73532SDimitry Andric
eraseFromParent()628ac9a064cSDimitry Andric void DbgMarker::eraseFromParent() {
629b1c73532SDimitry Andric if (MarkedInstr)
630b1c73532SDimitry Andric removeFromParent();
631ac9a064cSDimitry Andric dropDbgRecords();
632b1c73532SDimitry Andric delete this;
633b1c73532SDimitry Andric }
634b1c73532SDimitry Andric
getDbgRecordRange()635ac9a064cSDimitry Andric iterator_range<DbgRecord::self_iterator> DbgMarker::getDbgRecordRange() {
636ac9a064cSDimitry Andric return make_range(StoredDbgRecords.begin(), StoredDbgRecords.end());
637b1c73532SDimitry Andric }
638ac9a064cSDimitry Andric iterator_range<DbgRecord::const_self_iterator>
getDbgRecordRange() const639ac9a064cSDimitry Andric DbgMarker::getDbgRecordRange() const {
640ac9a064cSDimitry Andric return make_range(StoredDbgRecords.begin(), StoredDbgRecords.end());
6414df029ccSDimitry Andric }
642b1c73532SDimitry Andric
removeFromParent()643ac9a064cSDimitry Andric void DbgRecord::removeFromParent() {
644ac9a064cSDimitry Andric getMarker()->StoredDbgRecords.erase(getIterator());
6454df029ccSDimitry Andric Marker = nullptr;
646b1c73532SDimitry Andric }
647b1c73532SDimitry Andric
eraseFromParent()648ac9a064cSDimitry Andric void DbgRecord::eraseFromParent() {
649b1c73532SDimitry Andric removeFromParent();
650ac9a064cSDimitry Andric deleteRecord();
651b1c73532SDimitry Andric }
652b1c73532SDimitry Andric
insertDbgRecord(DbgRecord * New,bool InsertAtHead)653ac9a064cSDimitry Andric void DbgMarker::insertDbgRecord(DbgRecord *New, bool InsertAtHead) {
654ac9a064cSDimitry Andric auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end();
655ac9a064cSDimitry Andric StoredDbgRecords.insert(It, *New);
656b1c73532SDimitry Andric New->setMarker(this);
657b1c73532SDimitry Andric }
insertDbgRecord(DbgRecord * New,DbgRecord * InsertBefore)658ac9a064cSDimitry Andric void DbgMarker::insertDbgRecord(DbgRecord *New, DbgRecord *InsertBefore) {
6594df029ccSDimitry Andric assert(InsertBefore->getMarker() == this &&
660ac9a064cSDimitry Andric "DbgRecord 'InsertBefore' must be contained in this DbgMarker!");
661ac9a064cSDimitry Andric StoredDbgRecords.insert(InsertBefore->getIterator(), *New);
6624df029ccSDimitry Andric New->setMarker(this);
6634df029ccSDimitry Andric }
insertDbgRecordAfter(DbgRecord * New,DbgRecord * InsertAfter)664ac9a064cSDimitry Andric void DbgMarker::insertDbgRecordAfter(DbgRecord *New, DbgRecord *InsertAfter) {
6654df029ccSDimitry Andric assert(InsertAfter->getMarker() == this &&
666ac9a064cSDimitry Andric "DbgRecord 'InsertAfter' must be contained in this DbgMarker!");
667ac9a064cSDimitry Andric StoredDbgRecords.insert(++(InsertAfter->getIterator()), *New);
6684df029ccSDimitry Andric New->setMarker(this);
6694df029ccSDimitry Andric }
670b1c73532SDimitry Andric
absorbDebugValues(DbgMarker & Src,bool InsertAtHead)671ac9a064cSDimitry Andric void DbgMarker::absorbDebugValues(DbgMarker &Src, bool InsertAtHead) {
672ac9a064cSDimitry Andric auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end();
673ac9a064cSDimitry Andric for (DbgRecord &DVR : Src.StoredDbgRecords)
674ac9a064cSDimitry Andric DVR.setMarker(this);
675b1c73532SDimitry Andric
676ac9a064cSDimitry Andric StoredDbgRecords.splice(It, Src.StoredDbgRecords);
677b1c73532SDimitry Andric }
678b1c73532SDimitry Andric
absorbDebugValues(iterator_range<DbgRecord::self_iterator> Range,DbgMarker & Src,bool InsertAtHead)679ac9a064cSDimitry Andric void DbgMarker::absorbDebugValues(
680ac9a064cSDimitry Andric iterator_range<DbgRecord::self_iterator> Range, DbgMarker &Src,
681ac9a064cSDimitry Andric bool InsertAtHead) {
682ac9a064cSDimitry Andric for (DbgRecord &DR : Range)
683ac9a064cSDimitry Andric DR.setMarker(this);
684b1c73532SDimitry Andric
685b1c73532SDimitry Andric auto InsertPos =
686ac9a064cSDimitry Andric (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end();
687b1c73532SDimitry Andric
688ac9a064cSDimitry Andric StoredDbgRecords.splice(InsertPos, Src.StoredDbgRecords, Range.begin(),
689b1c73532SDimitry Andric Range.end());
690b1c73532SDimitry Andric }
691b1c73532SDimitry Andric
cloneDebugInfoFrom(DbgMarker * From,std::optional<simple_ilist<DbgRecord>::iterator> from_here,bool InsertAtHead)692ac9a064cSDimitry Andric iterator_range<simple_ilist<DbgRecord>::iterator> DbgMarker::cloneDebugInfoFrom(
693ac9a064cSDimitry Andric DbgMarker *From, std::optional<simple_ilist<DbgRecord>::iterator> from_here,
694b1c73532SDimitry Andric bool InsertAtHead) {
695ac9a064cSDimitry Andric DbgRecord *First = nullptr;
696ac9a064cSDimitry Andric // Work out what range of DbgRecords to clone: normally all the contents of
697ac9a064cSDimitry Andric // the "From" marker, optionally we can start from the from_here position down
698ac9a064cSDimitry Andric // to end().
699b1c73532SDimitry Andric auto Range =
700ac9a064cSDimitry Andric make_range(From->StoredDbgRecords.begin(), From->StoredDbgRecords.end());
701b1c73532SDimitry Andric if (from_here.has_value())
702ac9a064cSDimitry Andric Range = make_range(*from_here, From->StoredDbgRecords.end());
703b1c73532SDimitry Andric
704ac9a064cSDimitry Andric // Clone each DbgVariableRecord and insert into StoreDbgVariableRecords;
705ac9a064cSDimitry Andric // optionally place them at the start or the end of the list.
706ac9a064cSDimitry Andric auto Pos = (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end();
707ac9a064cSDimitry Andric for (DbgRecord &DR : Range) {
708ac9a064cSDimitry Andric DbgRecord *New = DR.clone();
709b1c73532SDimitry Andric New->setMarker(this);
710ac9a064cSDimitry Andric StoredDbgRecords.insert(Pos, *New);
711b1c73532SDimitry Andric if (!First)
712b1c73532SDimitry Andric First = New;
713b1c73532SDimitry Andric }
714b1c73532SDimitry Andric
715b1c73532SDimitry Andric if (!First)
716ac9a064cSDimitry Andric return {StoredDbgRecords.end(), StoredDbgRecords.end()};
717b1c73532SDimitry Andric
718b1c73532SDimitry Andric if (InsertAtHead)
719b1c73532SDimitry Andric // If InsertAtHead is set, we cloned a range onto the front of of the
720ac9a064cSDimitry Andric // StoredDbgRecords collection, return that range.
721ac9a064cSDimitry Andric return {StoredDbgRecords.begin(), Pos};
722b1c73532SDimitry Andric else
723b1c73532SDimitry Andric // We inserted a block at the end, return that range.
724ac9a064cSDimitry Andric return {First->getIterator(), StoredDbgRecords.end()};
725b1c73532SDimitry Andric }
726b1c73532SDimitry Andric
727b1c73532SDimitry Andric } // end namespace llvm
728