xref: /freebsd-src/contrib/llvm-project/llvm/lib/IR/DebugProgramInstruction.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1*5f757f3fSDimitry Andric //======-- DebugProgramInstruction.cpp - Implement DPValues/DPMarkers --======//
2*5f757f3fSDimitry Andric //
3*5f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*5f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*5f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*5f757f3fSDimitry Andric //
7*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
8*5f757f3fSDimitry Andric 
9*5f757f3fSDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
10*5f757f3fSDimitry Andric #include "llvm/IR/DebugProgramInstruction.h"
11*5f757f3fSDimitry Andric #include "llvm/IR/DIBuilder.h"
12*5f757f3fSDimitry Andric #include "llvm/IR/IntrinsicInst.h"
13*5f757f3fSDimitry Andric 
14*5f757f3fSDimitry Andric namespace llvm {
15*5f757f3fSDimitry Andric 
16*5f757f3fSDimitry Andric DPValue::DPValue(const DbgVariableIntrinsic *DVI)
17*5f757f3fSDimitry Andric     : DebugValueUser(DVI->getRawLocation()), Variable(DVI->getVariable()),
18*5f757f3fSDimitry Andric       Expression(DVI->getExpression()), DbgLoc(DVI->getDebugLoc()) {
19*5f757f3fSDimitry Andric   switch (DVI->getIntrinsicID()) {
20*5f757f3fSDimitry Andric   case Intrinsic::dbg_value:
21*5f757f3fSDimitry Andric     Type = LocationType::Value;
22*5f757f3fSDimitry Andric     break;
23*5f757f3fSDimitry Andric   case Intrinsic::dbg_declare:
24*5f757f3fSDimitry Andric     Type = LocationType::Declare;
25*5f757f3fSDimitry Andric     break;
26*5f757f3fSDimitry Andric   default:
27*5f757f3fSDimitry Andric     llvm_unreachable(
28*5f757f3fSDimitry Andric         "Trying to create a DPValue with an invalid intrinsic type!");
29*5f757f3fSDimitry Andric   }
30*5f757f3fSDimitry Andric }
31*5f757f3fSDimitry Andric 
32*5f757f3fSDimitry Andric DPValue::DPValue(const DPValue &DPV)
33*5f757f3fSDimitry Andric     : DebugValueUser(DPV.getRawLocation()),
34*5f757f3fSDimitry Andric       Variable(DPV.getVariable()), Expression(DPV.getExpression()),
35*5f757f3fSDimitry Andric       DbgLoc(DPV.getDebugLoc()), Type(DPV.getType()) {}
36*5f757f3fSDimitry Andric 
37*5f757f3fSDimitry Andric DPValue::DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
38*5f757f3fSDimitry Andric                  const DILocation *DI, LocationType Type)
39*5f757f3fSDimitry Andric     : DebugValueUser(Location), Variable(DV), Expression(Expr), DbgLoc(DI),
40*5f757f3fSDimitry Andric       Type(Type) {}
41*5f757f3fSDimitry Andric 
42*5f757f3fSDimitry Andric void DPValue::deleteInstr() { delete this; }
43*5f757f3fSDimitry Andric 
44*5f757f3fSDimitry Andric iterator_range<DPValue::location_op_iterator> DPValue::location_ops() const {
45*5f757f3fSDimitry Andric   auto *MD = getRawLocation();
46*5f757f3fSDimitry Andric   // If a Value has been deleted, the "location" for this DPValue will be
47*5f757f3fSDimitry Andric   // replaced by nullptr. Return an empty range.
48*5f757f3fSDimitry Andric   if (!MD)
49*5f757f3fSDimitry Andric     return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
50*5f757f3fSDimitry Andric             location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
51*5f757f3fSDimitry Andric 
52*5f757f3fSDimitry Andric   // If operand is ValueAsMetadata, return a range over just that operand.
53*5f757f3fSDimitry Andric   if (auto *VAM = dyn_cast<ValueAsMetadata>(MD))
54*5f757f3fSDimitry Andric     return {location_op_iterator(VAM), location_op_iterator(VAM + 1)};
55*5f757f3fSDimitry Andric 
56*5f757f3fSDimitry Andric   // If operand is DIArgList, return a range over its args.
57*5f757f3fSDimitry Andric   if (auto *AL = dyn_cast<DIArgList>(MD))
58*5f757f3fSDimitry Andric     return {location_op_iterator(AL->args_begin()),
59*5f757f3fSDimitry Andric             location_op_iterator(AL->args_end())};
60*5f757f3fSDimitry Andric 
61*5f757f3fSDimitry Andric   // Operand is an empty metadata tuple, so return empty iterator.
62*5f757f3fSDimitry Andric   assert(cast<MDNode>(MD)->getNumOperands() == 0);
63*5f757f3fSDimitry Andric   return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
64*5f757f3fSDimitry Andric           location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
65*5f757f3fSDimitry Andric }
66*5f757f3fSDimitry Andric 
67*5f757f3fSDimitry Andric unsigned DPValue::getNumVariableLocationOps() const {
68*5f757f3fSDimitry Andric   if (hasArgList())
69*5f757f3fSDimitry Andric     return cast<DIArgList>(getRawLocation())->getArgs().size();
70*5f757f3fSDimitry Andric   return 1;
71*5f757f3fSDimitry Andric }
72*5f757f3fSDimitry Andric 
73*5f757f3fSDimitry Andric Value *DPValue::getVariableLocationOp(unsigned OpIdx) const {
74*5f757f3fSDimitry Andric   auto *MD = getRawLocation();
75*5f757f3fSDimitry Andric   if (!MD)
76*5f757f3fSDimitry Andric     return nullptr;
77*5f757f3fSDimitry Andric 
78*5f757f3fSDimitry Andric   if (auto *AL = dyn_cast<DIArgList>(MD))
79*5f757f3fSDimitry Andric     return AL->getArgs()[OpIdx]->getValue();
80*5f757f3fSDimitry Andric   if (isa<MDNode>(MD))
81*5f757f3fSDimitry Andric     return nullptr;
82*5f757f3fSDimitry Andric   assert(isa<ValueAsMetadata>(MD) &&
83*5f757f3fSDimitry Andric          "Attempted to get location operand from DPValue with none.");
84*5f757f3fSDimitry Andric   auto *V = cast<ValueAsMetadata>(MD);
85*5f757f3fSDimitry Andric   assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a "
86*5f757f3fSDimitry Andric                        "single location operand.");
87*5f757f3fSDimitry Andric   return V->getValue();
88*5f757f3fSDimitry Andric }
89*5f757f3fSDimitry Andric 
90*5f757f3fSDimitry Andric static ValueAsMetadata *getAsMetadata(Value *V) {
91*5f757f3fSDimitry Andric   return isa<MetadataAsValue>(V) ? dyn_cast<ValueAsMetadata>(
92*5f757f3fSDimitry Andric                                        cast<MetadataAsValue>(V)->getMetadata())
93*5f757f3fSDimitry Andric                                  : ValueAsMetadata::get(V);
94*5f757f3fSDimitry Andric }
95*5f757f3fSDimitry Andric 
96*5f757f3fSDimitry Andric void DPValue::replaceVariableLocationOp(Value *OldValue, Value *NewValue,
97*5f757f3fSDimitry Andric                                         bool AllowEmpty) {
98*5f757f3fSDimitry Andric   assert(NewValue && "Values must be non-null");
99*5f757f3fSDimitry Andric   auto Locations = location_ops();
100*5f757f3fSDimitry Andric   auto OldIt = find(Locations, OldValue);
101*5f757f3fSDimitry Andric   if (OldIt == Locations.end()) {
102*5f757f3fSDimitry Andric     if (AllowEmpty)
103*5f757f3fSDimitry Andric       return;
104*5f757f3fSDimitry Andric     llvm_unreachable("OldValue must be a current location");
105*5f757f3fSDimitry Andric   }
106*5f757f3fSDimitry Andric 
107*5f757f3fSDimitry Andric   if (!hasArgList()) {
108*5f757f3fSDimitry Andric     // Set our location to be the MAV wrapping the new Value.
109*5f757f3fSDimitry Andric     setRawLocation(isa<MetadataAsValue>(NewValue)
110*5f757f3fSDimitry Andric                        ? cast<MetadataAsValue>(NewValue)->getMetadata()
111*5f757f3fSDimitry Andric                        : ValueAsMetadata::get(NewValue));
112*5f757f3fSDimitry Andric     return;
113*5f757f3fSDimitry Andric   }
114*5f757f3fSDimitry Andric 
115*5f757f3fSDimitry Andric   // We must be referring to a DIArgList, produce a new operands vector with the
116*5f757f3fSDimitry Andric   // old value replaced, generate a new DIArgList and set it as our location.
117*5f757f3fSDimitry Andric   SmallVector<ValueAsMetadata *, 4> MDs;
118*5f757f3fSDimitry Andric   ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
119*5f757f3fSDimitry Andric   for (auto *VMD : Locations)
120*5f757f3fSDimitry Andric     MDs.push_back(VMD == *OldIt ? NewOperand : getAsMetadata(VMD));
121*5f757f3fSDimitry Andric   setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
122*5f757f3fSDimitry Andric }
123*5f757f3fSDimitry Andric 
124*5f757f3fSDimitry Andric void DPValue::replaceVariableLocationOp(unsigned OpIdx, Value *NewValue) {
125*5f757f3fSDimitry Andric   assert(OpIdx < getNumVariableLocationOps() && "Invalid Operand Index");
126*5f757f3fSDimitry Andric 
127*5f757f3fSDimitry Andric   if (!hasArgList()) {
128*5f757f3fSDimitry Andric     setRawLocation(isa<MetadataAsValue>(NewValue)
129*5f757f3fSDimitry Andric                        ? cast<MetadataAsValue>(NewValue)->getMetadata()
130*5f757f3fSDimitry Andric                        : ValueAsMetadata::get(NewValue));
131*5f757f3fSDimitry Andric     return;
132*5f757f3fSDimitry Andric   }
133*5f757f3fSDimitry Andric 
134*5f757f3fSDimitry Andric   SmallVector<ValueAsMetadata *, 4> MDs;
135*5f757f3fSDimitry Andric   ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
136*5f757f3fSDimitry Andric   for (unsigned Idx = 0; Idx < getNumVariableLocationOps(); ++Idx)
137*5f757f3fSDimitry Andric     MDs.push_back(Idx == OpIdx ? NewOperand
138*5f757f3fSDimitry Andric                                : getAsMetadata(getVariableLocationOp(Idx)));
139*5f757f3fSDimitry Andric 
140*5f757f3fSDimitry Andric   setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
141*5f757f3fSDimitry Andric }
142*5f757f3fSDimitry Andric 
143*5f757f3fSDimitry Andric void DPValue::addVariableLocationOps(ArrayRef<Value *> NewValues,
144*5f757f3fSDimitry Andric                                      DIExpression *NewExpr) {
145*5f757f3fSDimitry Andric   assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() +
146*5f757f3fSDimitry Andric                                     NewValues.size()) &&
147*5f757f3fSDimitry Andric          "NewExpr for debug variable intrinsic does not reference every "
148*5f757f3fSDimitry Andric          "location operand.");
149*5f757f3fSDimitry Andric   assert(!is_contained(NewValues, nullptr) && "New values must be non-null");
150*5f757f3fSDimitry Andric   setExpression(NewExpr);
151*5f757f3fSDimitry Andric   SmallVector<ValueAsMetadata *, 4> MDs;
152*5f757f3fSDimitry Andric   for (auto *VMD : location_ops())
153*5f757f3fSDimitry Andric     MDs.push_back(getAsMetadata(VMD));
154*5f757f3fSDimitry Andric   for (auto *VMD : NewValues)
155*5f757f3fSDimitry Andric     MDs.push_back(getAsMetadata(VMD));
156*5f757f3fSDimitry Andric   setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
157*5f757f3fSDimitry Andric }
158*5f757f3fSDimitry Andric 
159*5f757f3fSDimitry Andric void DPValue::setKillLocation() {
160*5f757f3fSDimitry Andric   // TODO: When/if we remove duplicate values from DIArgLists, we don't need
161*5f757f3fSDimitry Andric   // this set anymore.
162*5f757f3fSDimitry Andric   SmallPtrSet<Value *, 4> RemovedValues;
163*5f757f3fSDimitry Andric   for (Value *OldValue : location_ops()) {
164*5f757f3fSDimitry Andric     if (!RemovedValues.insert(OldValue).second)
165*5f757f3fSDimitry Andric       continue;
166*5f757f3fSDimitry Andric     Value *Poison = PoisonValue::get(OldValue->getType());
167*5f757f3fSDimitry Andric     replaceVariableLocationOp(OldValue, Poison);
168*5f757f3fSDimitry Andric   }
169*5f757f3fSDimitry Andric }
170*5f757f3fSDimitry Andric 
171*5f757f3fSDimitry Andric bool DPValue::isKillLocation() const {
172*5f757f3fSDimitry Andric   return (getNumVariableLocationOps() == 0 &&
173*5f757f3fSDimitry Andric           !getExpression()->isComplex()) ||
174*5f757f3fSDimitry Andric          any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); });
175*5f757f3fSDimitry Andric }
176*5f757f3fSDimitry Andric 
177*5f757f3fSDimitry Andric std::optional<uint64_t> DPValue::getFragmentSizeInBits() const {
178*5f757f3fSDimitry Andric   if (auto Fragment = getExpression()->getFragmentInfo())
179*5f757f3fSDimitry Andric     return Fragment->SizeInBits;
180*5f757f3fSDimitry Andric   return getVariable()->getSizeInBits();
181*5f757f3fSDimitry Andric }
182*5f757f3fSDimitry Andric 
183*5f757f3fSDimitry Andric DPValue *DPValue::clone() const { return new DPValue(*this); }
184*5f757f3fSDimitry Andric 
185*5f757f3fSDimitry Andric DbgVariableIntrinsic *
186*5f757f3fSDimitry Andric DPValue::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
187*5f757f3fSDimitry Andric   [[maybe_unused]] DICompileUnit *Unit =
188*5f757f3fSDimitry Andric       getDebugLoc().get()->getScope()->getSubprogram()->getUnit();
189*5f757f3fSDimitry Andric   assert(M && Unit &&
190*5f757f3fSDimitry Andric          "Cannot clone from BasicBlock that is not part of a Module or "
191*5f757f3fSDimitry Andric          "DICompileUnit!");
192*5f757f3fSDimitry Andric   LLVMContext &Context = getDebugLoc()->getContext();
193*5f757f3fSDimitry Andric   Value *Args[] = {MetadataAsValue::get(Context, getRawLocation()),
194*5f757f3fSDimitry Andric                    MetadataAsValue::get(Context, getVariable()),
195*5f757f3fSDimitry Andric                    MetadataAsValue::get(Context, getExpression())};
196*5f757f3fSDimitry Andric   Function *IntrinsicFn;
197*5f757f3fSDimitry Andric 
198*5f757f3fSDimitry Andric   // Work out what sort of intrinsic we're going to produce.
199*5f757f3fSDimitry Andric   switch (getType()) {
200*5f757f3fSDimitry Andric   case DPValue::LocationType::Declare:
201*5f757f3fSDimitry Andric     IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_declare);
202*5f757f3fSDimitry Andric     break;
203*5f757f3fSDimitry Andric   case DPValue::LocationType::Value:
204*5f757f3fSDimitry Andric     IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_value);
205*5f757f3fSDimitry Andric     break;
206*5f757f3fSDimitry Andric   case DPValue::LocationType::End:
207*5f757f3fSDimitry Andric   case DPValue::LocationType::Any:
208*5f757f3fSDimitry Andric     llvm_unreachable("Invalid LocationType");
209*5f757f3fSDimitry Andric     break;
210*5f757f3fSDimitry Andric   }
211*5f757f3fSDimitry Andric 
212*5f757f3fSDimitry Andric   // Create the intrinsic from this DPValue's information, optionally insert
213*5f757f3fSDimitry Andric   // into the target location.
214*5f757f3fSDimitry Andric   DbgVariableIntrinsic *DVI = cast<DbgVariableIntrinsic>(
215*5f757f3fSDimitry Andric       CallInst::Create(IntrinsicFn->getFunctionType(), IntrinsicFn, Args));
216*5f757f3fSDimitry Andric   DVI->setTailCall();
217*5f757f3fSDimitry Andric   DVI->setDebugLoc(getDebugLoc());
218*5f757f3fSDimitry Andric   if (InsertBefore)
219*5f757f3fSDimitry Andric     DVI->insertBefore(InsertBefore);
220*5f757f3fSDimitry Andric 
221*5f757f3fSDimitry Andric   return DVI;
222*5f757f3fSDimitry Andric }
223*5f757f3fSDimitry Andric 
224*5f757f3fSDimitry Andric void DPValue::handleChangedLocation(Metadata *NewLocation) {
225*5f757f3fSDimitry Andric   resetDebugValue(NewLocation);
226*5f757f3fSDimitry Andric }
227*5f757f3fSDimitry Andric 
228*5f757f3fSDimitry Andric const BasicBlock *DPValue::getParent() const {
229*5f757f3fSDimitry Andric   return Marker->MarkedInstr->getParent();
230*5f757f3fSDimitry Andric }
231*5f757f3fSDimitry Andric 
232*5f757f3fSDimitry Andric BasicBlock *DPValue::getParent() { return Marker->MarkedInstr->getParent(); }
233*5f757f3fSDimitry Andric 
234*5f757f3fSDimitry Andric BasicBlock *DPValue::getBlock() { return Marker->getParent(); }
235*5f757f3fSDimitry Andric 
236*5f757f3fSDimitry Andric const BasicBlock *DPValue::getBlock() const { return Marker->getParent(); }
237*5f757f3fSDimitry Andric 
238*5f757f3fSDimitry Andric Function *DPValue::getFunction() { return getBlock()->getParent(); }
239*5f757f3fSDimitry Andric 
240*5f757f3fSDimitry Andric const Function *DPValue::getFunction() const { return getBlock()->getParent(); }
241*5f757f3fSDimitry Andric 
242*5f757f3fSDimitry Andric Module *DPValue::getModule() { return getFunction()->getParent(); }
243*5f757f3fSDimitry Andric 
244*5f757f3fSDimitry Andric const Module *DPValue::getModule() const { return getFunction()->getParent(); }
245*5f757f3fSDimitry Andric 
246*5f757f3fSDimitry Andric LLVMContext &DPValue::getContext() { return getBlock()->getContext(); }
247*5f757f3fSDimitry Andric 
248*5f757f3fSDimitry Andric const LLVMContext &DPValue::getContext() const {
249*5f757f3fSDimitry Andric   return getBlock()->getContext();
250*5f757f3fSDimitry Andric }
251*5f757f3fSDimitry Andric 
252*5f757f3fSDimitry Andric ///////////////////////////////////////////////////////////////////////////////
253*5f757f3fSDimitry Andric 
254*5f757f3fSDimitry Andric // An empty, global, DPMarker for the purpose of describing empty ranges of
255*5f757f3fSDimitry Andric // DPValues.
256*5f757f3fSDimitry Andric DPMarker DPMarker::EmptyDPMarker;
257*5f757f3fSDimitry Andric 
258*5f757f3fSDimitry Andric void DPMarker::dropDPValues() {
259*5f757f3fSDimitry Andric   while (!StoredDPValues.empty()) {
260*5f757f3fSDimitry Andric     auto It = StoredDPValues.begin();
261*5f757f3fSDimitry Andric     DPValue *DPV = &*It;
262*5f757f3fSDimitry Andric     StoredDPValues.erase(It);
263*5f757f3fSDimitry Andric     DPV->deleteInstr();
264*5f757f3fSDimitry Andric   }
265*5f757f3fSDimitry Andric }
266*5f757f3fSDimitry Andric 
267*5f757f3fSDimitry Andric void DPMarker::dropOneDPValue(DPValue *DPV) {
268*5f757f3fSDimitry Andric   assert(DPV->getMarker() == this);
269*5f757f3fSDimitry Andric   StoredDPValues.erase(DPV->getIterator());
270*5f757f3fSDimitry Andric   DPV->deleteInstr();
271*5f757f3fSDimitry Andric }
272*5f757f3fSDimitry Andric 
273*5f757f3fSDimitry Andric const BasicBlock *DPMarker::getParent() const {
274*5f757f3fSDimitry Andric   return MarkedInstr->getParent();
275*5f757f3fSDimitry Andric }
276*5f757f3fSDimitry Andric 
277*5f757f3fSDimitry Andric BasicBlock *DPMarker::getParent() { return MarkedInstr->getParent(); }
278*5f757f3fSDimitry Andric 
279*5f757f3fSDimitry Andric void DPMarker::removeMarker() {
280*5f757f3fSDimitry Andric   // Are there any DPValues in this DPMarker? If not, nothing to preserve.
281*5f757f3fSDimitry Andric   Instruction *Owner = MarkedInstr;
282*5f757f3fSDimitry Andric   if (StoredDPValues.empty()) {
283*5f757f3fSDimitry Andric     eraseFromParent();
284*5f757f3fSDimitry Andric     Owner->DbgMarker = nullptr;
285*5f757f3fSDimitry Andric     return;
286*5f757f3fSDimitry Andric   }
287*5f757f3fSDimitry Andric 
288*5f757f3fSDimitry Andric   // The attached DPValues need to be preserved; attach them to the next
289*5f757f3fSDimitry Andric   // instruction. If there isn't a next instruction, put them on the
290*5f757f3fSDimitry Andric   // "trailing" list.
291*5f757f3fSDimitry Andric   DPMarker *NextMarker = Owner->getParent()->getNextMarker(Owner);
292*5f757f3fSDimitry Andric   if (NextMarker == nullptr) {
293*5f757f3fSDimitry Andric     NextMarker = new DPMarker();
294*5f757f3fSDimitry Andric     Owner->getParent()->setTrailingDPValues(NextMarker);
295*5f757f3fSDimitry Andric   }
296*5f757f3fSDimitry Andric   NextMarker->absorbDebugValues(*this, true);
297*5f757f3fSDimitry Andric 
298*5f757f3fSDimitry Andric   eraseFromParent();
299*5f757f3fSDimitry Andric }
300*5f757f3fSDimitry Andric 
301*5f757f3fSDimitry Andric void DPMarker::removeFromParent() {
302*5f757f3fSDimitry Andric   MarkedInstr->DbgMarker = nullptr;
303*5f757f3fSDimitry Andric   MarkedInstr = nullptr;
304*5f757f3fSDimitry Andric }
305*5f757f3fSDimitry Andric 
306*5f757f3fSDimitry Andric void DPMarker::eraseFromParent() {
307*5f757f3fSDimitry Andric   if (MarkedInstr)
308*5f757f3fSDimitry Andric     removeFromParent();
309*5f757f3fSDimitry Andric   dropDPValues();
310*5f757f3fSDimitry Andric   delete this;
311*5f757f3fSDimitry Andric }
312*5f757f3fSDimitry Andric 
313*5f757f3fSDimitry Andric iterator_range<DPValue::self_iterator> DPMarker::getDbgValueRange() {
314*5f757f3fSDimitry Andric   return make_range(StoredDPValues.begin(), StoredDPValues.end());
315*5f757f3fSDimitry Andric }
316*5f757f3fSDimitry Andric 
317*5f757f3fSDimitry Andric void DPValue::removeFromParent() {
318*5f757f3fSDimitry Andric   getMarker()->StoredDPValues.erase(getIterator());
319*5f757f3fSDimitry Andric }
320*5f757f3fSDimitry Andric 
321*5f757f3fSDimitry Andric void DPValue::eraseFromParent() {
322*5f757f3fSDimitry Andric   removeFromParent();
323*5f757f3fSDimitry Andric   deleteInstr();
324*5f757f3fSDimitry Andric }
325*5f757f3fSDimitry Andric 
326*5f757f3fSDimitry Andric void DPMarker::insertDPValue(DPValue *New, bool InsertAtHead) {
327*5f757f3fSDimitry Andric   auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end();
328*5f757f3fSDimitry Andric   StoredDPValues.insert(It, *New);
329*5f757f3fSDimitry Andric   New->setMarker(this);
330*5f757f3fSDimitry Andric }
331*5f757f3fSDimitry Andric 
332*5f757f3fSDimitry Andric void DPMarker::absorbDebugValues(DPMarker &Src, bool InsertAtHead) {
333*5f757f3fSDimitry Andric   auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end();
334*5f757f3fSDimitry Andric   for (DPValue &DPV : Src.StoredDPValues)
335*5f757f3fSDimitry Andric     DPV.setMarker(this);
336*5f757f3fSDimitry Andric 
337*5f757f3fSDimitry Andric   StoredDPValues.splice(It, Src.StoredDPValues);
338*5f757f3fSDimitry Andric }
339*5f757f3fSDimitry Andric 
340*5f757f3fSDimitry Andric void DPMarker::absorbDebugValues(iterator_range<DPValue::self_iterator> Range,
341*5f757f3fSDimitry Andric                                  DPMarker &Src, bool InsertAtHead) {
342*5f757f3fSDimitry Andric   for (DPValue &DPV : Range)
343*5f757f3fSDimitry Andric     DPV.setMarker(this);
344*5f757f3fSDimitry Andric 
345*5f757f3fSDimitry Andric   auto InsertPos =
346*5f757f3fSDimitry Andric       (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end();
347*5f757f3fSDimitry Andric 
348*5f757f3fSDimitry Andric   StoredDPValues.splice(InsertPos, Src.StoredDPValues, Range.begin(),
349*5f757f3fSDimitry Andric                         Range.end());
350*5f757f3fSDimitry Andric }
351*5f757f3fSDimitry Andric 
352*5f757f3fSDimitry Andric iterator_range<simple_ilist<DPValue>::iterator> DPMarker::cloneDebugInfoFrom(
353*5f757f3fSDimitry Andric     DPMarker *From, std::optional<simple_ilist<DPValue>::iterator> from_here,
354*5f757f3fSDimitry Andric     bool InsertAtHead) {
355*5f757f3fSDimitry Andric   DPValue *First = nullptr;
356*5f757f3fSDimitry Andric   // Work out what range of DPValues to clone: normally all the contents of the
357*5f757f3fSDimitry Andric   // "From" marker, optionally we can start from the from_here position down to
358*5f757f3fSDimitry Andric   // end().
359*5f757f3fSDimitry Andric   auto Range =
360*5f757f3fSDimitry Andric       make_range(From->StoredDPValues.begin(), From->StoredDPValues.end());
361*5f757f3fSDimitry Andric   if (from_here.has_value())
362*5f757f3fSDimitry Andric     Range = make_range(*from_here, From->StoredDPValues.end());
363*5f757f3fSDimitry Andric 
364*5f757f3fSDimitry Andric   // Clone each DPValue and insert into StoreDPValues; optionally place them at
365*5f757f3fSDimitry Andric   // the start or the end of the list.
366*5f757f3fSDimitry Andric   auto Pos = (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end();
367*5f757f3fSDimitry Andric   for (DPValue &DPV : Range) {
368*5f757f3fSDimitry Andric     DPValue *New = DPV.clone();
369*5f757f3fSDimitry Andric     New->setMarker(this);
370*5f757f3fSDimitry Andric     StoredDPValues.insert(Pos, *New);
371*5f757f3fSDimitry Andric     if (!First)
372*5f757f3fSDimitry Andric       First = New;
373*5f757f3fSDimitry Andric   }
374*5f757f3fSDimitry Andric 
375*5f757f3fSDimitry Andric   if (!First)
376*5f757f3fSDimitry Andric     return {StoredDPValues.end(), StoredDPValues.end()};
377*5f757f3fSDimitry Andric 
378*5f757f3fSDimitry Andric   if (InsertAtHead)
379*5f757f3fSDimitry Andric     // If InsertAtHead is set, we cloned a range onto the front of of the
380*5f757f3fSDimitry Andric     // StoredDPValues collection, return that range.
381*5f757f3fSDimitry Andric     return {StoredDPValues.begin(), Pos};
382*5f757f3fSDimitry Andric   else
383*5f757f3fSDimitry Andric     // We inserted a block at the end, return that range.
384*5f757f3fSDimitry Andric     return {First->getIterator(), StoredDPValues.end()};
385*5f757f3fSDimitry Andric }
386*5f757f3fSDimitry Andric 
387*5f757f3fSDimitry Andric } // end namespace llvm
388*5f757f3fSDimitry Andric 
389