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