1 | //=====-- DebugProgramInstruction.cpp - Implement DbgRecords/DbgMarkers --====// |
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 | template <typename T> |
17 | DbgRecordParamRef<T>::DbgRecordParamRef(const T *Param) |
18 | : Ref(const_cast<T *>(Param)) {} |
19 | template <typename T> |
20 | DbgRecordParamRef<T>::DbgRecordParamRef(const MDNode *Param) |
21 | : Ref(const_cast<MDNode *>(Param)) {} |
22 | |
23 | template <typename T> T *DbgRecordParamRef<T>::get() const { |
24 | return cast<T>(Ref); |
25 | } |
26 | |
27 | template class DbgRecordParamRef<DIExpression>; |
28 | template class DbgRecordParamRef<DILabel>; |
29 | template class DbgRecordParamRef<DILocalVariable>; |
30 | |
31 | DbgVariableRecord::DbgVariableRecord(const DbgVariableIntrinsic *DVI) |
32 | : DbgRecord(ValueKind, DVI->getDebugLoc()), |
33 | DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}), |
34 | Variable(DVI->getVariable()), Expression(DVI->getExpression()), |
35 | AddressExpression() { |
36 | switch (DVI->getIntrinsicID()) { |
37 | case Intrinsic::dbg_value: |
38 | Type = LocationType::Value; |
39 | break; |
40 | case Intrinsic::dbg_declare: |
41 | Type = LocationType::Declare; |
42 | break; |
43 | case Intrinsic::dbg_assign: { |
44 | Type = LocationType::Assign; |
45 | const DbgAssignIntrinsic *Assign = |
46 | static_cast<const DbgAssignIntrinsic *>(DVI); |
47 | resetDebugValue(Idx: 1, DebugValue: Assign->getRawAddress()); |
48 | AddressExpression = Assign->getAddressExpression(); |
49 | setAssignId(Assign->getAssignID()); |
50 | break; |
51 | } |
52 | default: |
53 | llvm_unreachable( |
54 | "Trying to create a DbgVariableRecord with an invalid intrinsic type!" ); |
55 | } |
56 | } |
57 | |
58 | DbgVariableRecord::DbgVariableRecord(const DbgVariableRecord &DVR) |
59 | : DbgRecord(ValueKind, DVR.getDebugLoc()), DebugValueUser(DVR.DebugValues), |
60 | Type(DVR.getType()), Variable(DVR.getVariable()), |
61 | Expression(DVR.getExpression()), |
62 | AddressExpression(DVR.AddressExpression) {} |
63 | |
64 | DbgVariableRecord::DbgVariableRecord(Metadata *Location, DILocalVariable *DV, |
65 | DIExpression *Expr, const DILocation *DI, |
66 | LocationType Type) |
67 | : DbgRecord(ValueKind, DI), DebugValueUser({Location, nullptr, nullptr}), |
68 | Type(Type), Variable(DV), Expression(Expr) {} |
69 | |
70 | DbgVariableRecord::DbgVariableRecord(Metadata *Value, DILocalVariable *Variable, |
71 | DIExpression *Expression, |
72 | DIAssignID *AssignID, Metadata *Address, |
73 | DIExpression *AddressExpression, |
74 | const DILocation *DI) |
75 | : DbgRecord(ValueKind, DI), DebugValueUser({Value, Address, AssignID}), |
76 | Type(LocationType::Assign), Variable(Variable), Expression(Expression), |
77 | AddressExpression(AddressExpression) {} |
78 | |
79 | void DbgRecord::deleteRecord() { |
80 | switch (RecordKind) { |
81 | case ValueKind: |
82 | delete cast<DbgVariableRecord>(Val: this); |
83 | return; |
84 | case LabelKind: |
85 | delete cast<DbgLabelRecord>(Val: this); |
86 | return; |
87 | } |
88 | llvm_unreachable("unsupported DbgRecord kind" ); |
89 | } |
90 | |
91 | void DbgRecord::print(raw_ostream &O, bool IsForDebug) const { |
92 | switch (RecordKind) { |
93 | case ValueKind: |
94 | cast<DbgVariableRecord>(Val: this)->print(O, IsForDebug); |
95 | return; |
96 | case LabelKind: |
97 | cast<DbgLabelRecord>(Val: this)->print(O, IsForDebug); |
98 | return; |
99 | }; |
100 | llvm_unreachable("unsupported DbgRecord kind" ); |
101 | } |
102 | |
103 | void DbgRecord::print(raw_ostream &O, ModuleSlotTracker &MST, |
104 | bool IsForDebug) const { |
105 | switch (RecordKind) { |
106 | case ValueKind: |
107 | cast<DbgVariableRecord>(Val: this)->print(ROS&: O, MST, IsForDebug); |
108 | return; |
109 | case LabelKind: |
110 | cast<DbgLabelRecord>(Val: this)->print(ROS&: O, MST, IsForDebug); |
111 | return; |
112 | }; |
113 | llvm_unreachable("unsupported DbgRecord kind" ); |
114 | } |
115 | |
116 | bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const { |
117 | if (RecordKind != R.RecordKind) |
118 | return false; |
119 | switch (RecordKind) { |
120 | case ValueKind: |
121 | return cast<DbgVariableRecord>(Val: this)->isIdenticalToWhenDefined( |
122 | Other: *cast<DbgVariableRecord>(Val: &R)); |
123 | case LabelKind: |
124 | return cast<DbgLabelRecord>(Val: this)->getLabel() == |
125 | cast<DbgLabelRecord>(Val: R).getLabel(); |
126 | }; |
127 | llvm_unreachable("unsupported DbgRecord kind" ); |
128 | } |
129 | |
130 | bool DbgRecord::isEquivalentTo(const DbgRecord &R) const { |
131 | return getDebugLoc() == R.getDebugLoc() && isIdenticalToWhenDefined(R); |
132 | } |
133 | |
134 | DbgInfoIntrinsic * |
135 | DbgRecord::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const { |
136 | switch (RecordKind) { |
137 | case ValueKind: |
138 | return cast<DbgVariableRecord>(Val: this)->createDebugIntrinsic(M, InsertBefore); |
139 | case LabelKind: |
140 | return cast<DbgLabelRecord>(Val: this)->createDebugIntrinsic(M, InsertBefore); |
141 | }; |
142 | llvm_unreachable("unsupported DbgRecord kind" ); |
143 | } |
144 | |
145 | DbgLabelRecord::DbgLabelRecord(MDNode *Label, MDNode *DL) |
146 | : DbgRecord(LabelKind, DebugLoc(DL)), Label(Label) { |
147 | assert(Label && "Unexpected nullptr" ); |
148 | assert((isa<DILabel>(Label) || Label->isTemporary()) && |
149 | "Label type must be or resolve to a DILabel" ); |
150 | } |
151 | DbgLabelRecord::DbgLabelRecord(DILabel *Label, DebugLoc DL) |
152 | : DbgRecord(LabelKind, DL), Label(Label) { |
153 | assert(Label && "Unexpected nullptr" ); |
154 | } |
155 | |
156 | DbgLabelRecord *DbgLabelRecord::createUnresolvedDbgLabelRecord(MDNode *Label, |
157 | MDNode *DL) { |
158 | return new DbgLabelRecord(Label, DL); |
159 | } |
160 | |
161 | DbgVariableRecord::DbgVariableRecord(DbgVariableRecord::LocationType Type, |
162 | Metadata *Val, MDNode *Variable, |
163 | MDNode *Expression, MDNode *AssignID, |
164 | Metadata *Address, |
165 | MDNode *AddressExpression, MDNode *DI) |
166 | : DbgRecord(ValueKind, DebugLoc(DI)), |
167 | DebugValueUser({Val, Address, AssignID}), Type(Type), Variable(Variable), |
168 | Expression(Expression), AddressExpression(AddressExpression) {} |
169 | |
170 | DbgVariableRecord *DbgVariableRecord::createUnresolvedDbgVariableRecord( |
171 | DbgVariableRecord::LocationType Type, Metadata *Val, MDNode *Variable, |
172 | MDNode *Expression, MDNode *AssignID, Metadata *Address, |
173 | MDNode *AddressExpression, MDNode *DI) { |
174 | return new DbgVariableRecord(Type, Val, Variable, Expression, AssignID, |
175 | Address, AddressExpression, DI); |
176 | } |
177 | |
178 | DbgVariableRecord * |
179 | DbgVariableRecord::createDbgVariableRecord(Value *Location, DILocalVariable *DV, |
180 | DIExpression *Expr, |
181 | const DILocation *DI) { |
182 | return new DbgVariableRecord(ValueAsMetadata::get(V: Location), DV, Expr, DI, |
183 | LocationType::Value); |
184 | } |
185 | |
186 | DbgVariableRecord *DbgVariableRecord::createDbgVariableRecord( |
187 | Value *Location, DILocalVariable *DV, DIExpression *Expr, |
188 | const DILocation *DI, DbgVariableRecord &InsertBefore) { |
189 | auto *NewDbgVariableRecord = createDbgVariableRecord(Location, DV, Expr, DI); |
190 | NewDbgVariableRecord->insertBefore(InsertBefore: &InsertBefore); |
191 | return NewDbgVariableRecord; |
192 | } |
193 | |
194 | DbgVariableRecord *DbgVariableRecord::createDVRDeclare(Value *Address, |
195 | DILocalVariable *DV, |
196 | DIExpression *Expr, |
197 | const DILocation *DI) { |
198 | return new DbgVariableRecord(ValueAsMetadata::get(V: Address), DV, Expr, DI, |
199 | LocationType::Declare); |
200 | } |
201 | |
202 | DbgVariableRecord * |
203 | DbgVariableRecord::createDVRDeclare(Value *Address, DILocalVariable *DV, |
204 | DIExpression *Expr, const DILocation *DI, |
205 | DbgVariableRecord &InsertBefore) { |
206 | auto *NewDVRDeclare = createDVRDeclare(Address, DV, Expr, DI); |
207 | NewDVRDeclare->insertBefore(InsertBefore: &InsertBefore); |
208 | return NewDVRDeclare; |
209 | } |
210 | |
211 | DbgVariableRecord *DbgVariableRecord::createDVRAssign( |
212 | Value *Val, DILocalVariable *Variable, DIExpression *Expression, |
213 | DIAssignID *AssignID, Value *Address, DIExpression *AddressExpression, |
214 | const DILocation *DI) { |
215 | return new DbgVariableRecord(ValueAsMetadata::get(V: Val), Variable, Expression, |
216 | AssignID, ValueAsMetadata::get(V: Address), |
217 | AddressExpression, DI); |
218 | } |
219 | |
220 | DbgVariableRecord *DbgVariableRecord::createLinkedDVRAssign( |
221 | Instruction *LinkedInstr, Value *Val, DILocalVariable *Variable, |
222 | DIExpression *Expression, Value *Address, DIExpression *AddressExpression, |
223 | const DILocation *DI) { |
224 | auto *Link = LinkedInstr->getMetadata(KindID: LLVMContext::MD_DIAssignID); |
225 | assert(Link && "Linked instruction must have DIAssign metadata attached" ); |
226 | auto *NewDVRAssign = DbgVariableRecord::createDVRAssign( |
227 | Val, Variable, Expression, AssignID: cast<DIAssignID>(Val: Link), Address, |
228 | AddressExpression, DI); |
229 | LinkedInstr->getParent()->insertDbgRecordAfter(DR: NewDVRAssign, I: LinkedInstr); |
230 | return NewDVRAssign; |
231 | } |
232 | |
233 | iterator_range<DbgVariableRecord::location_op_iterator> |
234 | DbgVariableRecord::location_ops() const { |
235 | auto *MD = getRawLocation(); |
236 | // If a Value has been deleted, the "location" for this DbgVariableRecord will |
237 | // be replaced by nullptr. Return an empty range. |
238 | if (!MD) |
239 | return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)), |
240 | location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))}; |
241 | |
242 | // If operand is ValueAsMetadata, return a range over just that operand. |
243 | if (auto *VAM = dyn_cast<ValueAsMetadata>(Val: MD)) |
244 | return {location_op_iterator(VAM), location_op_iterator(VAM + 1)}; |
245 | |
246 | // If operand is DIArgList, return a range over its args. |
247 | if (auto *AL = dyn_cast<DIArgList>(Val: MD)) |
248 | return {location_op_iterator(AL->args_begin()), |
249 | location_op_iterator(AL->args_end())}; |
250 | |
251 | // Operand is an empty metadata tuple, so return empty iterator. |
252 | assert(cast<MDNode>(MD)->getNumOperands() == 0); |
253 | return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)), |
254 | location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))}; |
255 | } |
256 | |
257 | unsigned DbgVariableRecord::getNumVariableLocationOps() const { |
258 | if (hasArgList()) |
259 | return cast<DIArgList>(Val: getRawLocation())->getArgs().size(); |
260 | return 1; |
261 | } |
262 | |
263 | Value *DbgVariableRecord::getVariableLocationOp(unsigned OpIdx) const { |
264 | auto *MD = getRawLocation(); |
265 | if (!MD) |
266 | return nullptr; |
267 | |
268 | if (auto *AL = dyn_cast<DIArgList>(Val: MD)) |
269 | return AL->getArgs()[OpIdx]->getValue(); |
270 | if (isa<MDNode>(Val: MD)) |
271 | return nullptr; |
272 | assert(isa<ValueAsMetadata>(MD) && |
273 | "Attempted to get location operand from DbgVariableRecord with none." ); |
274 | auto *V = cast<ValueAsMetadata>(Val: MD); |
275 | assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a " |
276 | "single location operand." ); |
277 | return V->getValue(); |
278 | } |
279 | |
280 | static ValueAsMetadata *getAsMetadata(Value *V) { |
281 | return isa<MetadataAsValue>(Val: V) ? dyn_cast<ValueAsMetadata>( |
282 | Val: cast<MetadataAsValue>(Val: V)->getMetadata()) |
283 | : ValueAsMetadata::get(V); |
284 | } |
285 | |
286 | void DbgVariableRecord::replaceVariableLocationOp(Value *OldValue, |
287 | Value *NewValue, |
288 | bool AllowEmpty) { |
289 | assert(NewValue && "Values must be non-null" ); |
290 | |
291 | bool DbgAssignAddrReplaced = isDbgAssign() && OldValue == getAddress(); |
292 | if (DbgAssignAddrReplaced) |
293 | setAddress(NewValue); |
294 | |
295 | auto Locations = location_ops(); |
296 | auto OldIt = find(Range&: Locations, Val: OldValue); |
297 | if (OldIt == Locations.end()) { |
298 | if (AllowEmpty || DbgAssignAddrReplaced) |
299 | return; |
300 | llvm_unreachable("OldValue must be a current location" ); |
301 | } |
302 | |
303 | if (!hasArgList()) { |
304 | // Set our location to be the MAV wrapping the new Value. |
305 | setRawLocation(isa<MetadataAsValue>(Val: NewValue) |
306 | ? cast<MetadataAsValue>(Val: NewValue)->getMetadata() |
307 | : ValueAsMetadata::get(V: NewValue)); |
308 | return; |
309 | } |
310 | |
311 | // We must be referring to a DIArgList, produce a new operands vector with the |
312 | // old value replaced, generate a new DIArgList and set it as our location. |
313 | SmallVector<ValueAsMetadata *, 4> MDs; |
314 | ValueAsMetadata *NewOperand = getAsMetadata(V: NewValue); |
315 | for (auto *VMD : Locations) |
316 | MDs.push_back(Elt: VMD == *OldIt ? NewOperand : getAsMetadata(V: VMD)); |
317 | setRawLocation(DIArgList::get(Context&: getVariableLocationOp(OpIdx: 0)->getContext(), Args: MDs)); |
318 | } |
319 | |
320 | void DbgVariableRecord::replaceVariableLocationOp(unsigned OpIdx, |
321 | Value *NewValue) { |
322 | assert(OpIdx < getNumVariableLocationOps() && "Invalid Operand Index" ); |
323 | |
324 | if (!hasArgList()) { |
325 | setRawLocation(isa<MetadataAsValue>(Val: NewValue) |
326 | ? cast<MetadataAsValue>(Val: NewValue)->getMetadata() |
327 | : ValueAsMetadata::get(V: NewValue)); |
328 | return; |
329 | } |
330 | |
331 | SmallVector<ValueAsMetadata *, 4> MDs; |
332 | ValueAsMetadata *NewOperand = getAsMetadata(V: NewValue); |
333 | for (unsigned Idx = 0; Idx < getNumVariableLocationOps(); ++Idx) |
334 | MDs.push_back(Elt: Idx == OpIdx ? NewOperand |
335 | : getAsMetadata(V: getVariableLocationOp(OpIdx: Idx))); |
336 | |
337 | setRawLocation(DIArgList::get(Context&: getVariableLocationOp(OpIdx: 0)->getContext(), Args: MDs)); |
338 | } |
339 | |
340 | void DbgVariableRecord::addVariableLocationOps(ArrayRef<Value *> NewValues, |
341 | DIExpression *NewExpr) { |
342 | assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() + |
343 | NewValues.size()) && |
344 | "NewExpr for debug variable intrinsic does not reference every " |
345 | "location operand." ); |
346 | assert(!is_contained(NewValues, nullptr) && "New values must be non-null" ); |
347 | setExpression(NewExpr); |
348 | SmallVector<ValueAsMetadata *, 4> MDs; |
349 | for (auto *VMD : location_ops()) |
350 | MDs.push_back(Elt: getAsMetadata(V: VMD)); |
351 | for (auto *VMD : NewValues) |
352 | MDs.push_back(Elt: getAsMetadata(V: VMD)); |
353 | setRawLocation(DIArgList::get(Context&: getVariableLocationOp(OpIdx: 0)->getContext(), Args: MDs)); |
354 | } |
355 | |
356 | void DbgVariableRecord::setKillLocation() { |
357 | // TODO: When/if we remove duplicate values from DIArgLists, we don't need |
358 | // this set anymore. |
359 | SmallPtrSet<Value *, 4> RemovedValues; |
360 | for (Value *OldValue : location_ops()) { |
361 | if (!RemovedValues.insert(Ptr: OldValue).second) |
362 | continue; |
363 | Value *Poison = PoisonValue::get(T: OldValue->getType()); |
364 | replaceVariableLocationOp(OldValue, NewValue: Poison); |
365 | } |
366 | } |
367 | |
368 | bool DbgVariableRecord::isKillLocation() const { |
369 | return (!hasArgList() && isa<MDNode>(Val: getRawLocation())) || |
370 | (getNumVariableLocationOps() == 0 && !getExpression()->isComplex()) || |
371 | any_of(Range: location_ops(), P: [](Value *V) { return isa<UndefValue>(Val: V); }); |
372 | } |
373 | |
374 | std::optional<DbgVariableFragmentInfo> DbgVariableRecord::getFragment() const { |
375 | return getExpression()->getFragmentInfo(); |
376 | } |
377 | |
378 | std::optional<uint64_t> DbgVariableRecord::getFragmentSizeInBits() const { |
379 | if (auto Fragment = getExpression()->getFragmentInfo()) |
380 | return Fragment->SizeInBits; |
381 | return getVariable()->getSizeInBits(); |
382 | } |
383 | |
384 | DbgRecord *DbgRecord::clone() const { |
385 | switch (RecordKind) { |
386 | case ValueKind: |
387 | return cast<DbgVariableRecord>(Val: this)->clone(); |
388 | case LabelKind: |
389 | return cast<DbgLabelRecord>(Val: this)->clone(); |
390 | }; |
391 | llvm_unreachable("unsupported DbgRecord kind" ); |
392 | } |
393 | |
394 | DbgVariableRecord *DbgVariableRecord::clone() const { |
395 | return new DbgVariableRecord(*this); |
396 | } |
397 | |
398 | DbgLabelRecord *DbgLabelRecord::clone() const { |
399 | return new DbgLabelRecord(getLabel(), getDebugLoc()); |
400 | } |
401 | |
402 | DbgVariableIntrinsic * |
403 | DbgVariableRecord::createDebugIntrinsic(Module *M, |
404 | Instruction *InsertBefore) const { |
405 | [[maybe_unused]] DICompileUnit *Unit = |
406 | getDebugLoc()->getScope()->getSubprogram()->getUnit(); |
407 | assert(M && Unit && |
408 | "Cannot clone from BasicBlock that is not part of a Module or " |
409 | "DICompileUnit!" ); |
410 | LLVMContext &Context = getDebugLoc()->getContext(); |
411 | Function *IntrinsicFn; |
412 | |
413 | // Work out what sort of intrinsic we're going to produce. |
414 | switch (getType()) { |
415 | case DbgVariableRecord::LocationType::Declare: |
416 | IntrinsicFn = Intrinsic::getDeclaration(M, id: Intrinsic::dbg_declare); |
417 | break; |
418 | case DbgVariableRecord::LocationType::Value: |
419 | IntrinsicFn = Intrinsic::getDeclaration(M, id: Intrinsic::dbg_value); |
420 | break; |
421 | case DbgVariableRecord::LocationType::Assign: |
422 | IntrinsicFn = Intrinsic::getDeclaration(M, id: Intrinsic::dbg_assign); |
423 | break; |
424 | case DbgVariableRecord::LocationType::End: |
425 | case DbgVariableRecord::LocationType::Any: |
426 | llvm_unreachable("Invalid LocationType" ); |
427 | } |
428 | |
429 | // Create the intrinsic from this DbgVariableRecord's information, optionally |
430 | // insert into the target location. |
431 | DbgVariableIntrinsic *DVI; |
432 | assert(getRawLocation() && |
433 | "DbgVariableRecord's RawLocation should be non-null." ); |
434 | if (isDbgAssign()) { |
435 | Value *AssignArgs[] = { |
436 | MetadataAsValue::get(Context, MD: getRawLocation()), |
437 | MetadataAsValue::get(Context, MD: getVariable()), |
438 | MetadataAsValue::get(Context, MD: getExpression()), |
439 | MetadataAsValue::get(Context, MD: getAssignID()), |
440 | MetadataAsValue::get(Context, MD: getRawAddress()), |
441 | MetadataAsValue::get(Context, MD: getAddressExpression())}; |
442 | DVI = cast<DbgVariableIntrinsic>(Val: CallInst::Create( |
443 | Ty: IntrinsicFn->getFunctionType(), Func: IntrinsicFn, Args: AssignArgs)); |
444 | } else { |
445 | Value *Args[] = {MetadataAsValue::get(Context, MD: getRawLocation()), |
446 | MetadataAsValue::get(Context, MD: getVariable()), |
447 | MetadataAsValue::get(Context, MD: getExpression())}; |
448 | DVI = cast<DbgVariableIntrinsic>( |
449 | Val: CallInst::Create(Ty: IntrinsicFn->getFunctionType(), Func: IntrinsicFn, Args)); |
450 | } |
451 | DVI->setTailCall(); |
452 | DVI->setDebugLoc(getDebugLoc()); |
453 | if (InsertBefore) |
454 | DVI->insertBefore(InsertPos: InsertBefore); |
455 | |
456 | return DVI; |
457 | } |
458 | |
459 | DbgLabelInst * |
460 | DbgLabelRecord::createDebugIntrinsic(Module *M, |
461 | Instruction *InsertBefore) const { |
462 | auto *LabelFn = Intrinsic::getDeclaration(M, id: Intrinsic::dbg_label); |
463 | Value *Args[] = { |
464 | MetadataAsValue::get(Context&: getDebugLoc()->getContext(), MD: getLabel())}; |
465 | DbgLabelInst *DbgLabel = cast<DbgLabelInst>( |
466 | Val: CallInst::Create(Ty: LabelFn->getFunctionType(), Func: LabelFn, Args)); |
467 | DbgLabel->setTailCall(); |
468 | DbgLabel->setDebugLoc(getDebugLoc()); |
469 | if (InsertBefore) |
470 | DbgLabel->insertBefore(InsertPos: InsertBefore); |
471 | return DbgLabel; |
472 | } |
473 | |
474 | Value *DbgVariableRecord::getAddress() const { |
475 | auto *MD = getRawAddress(); |
476 | if (auto *V = dyn_cast_or_null<ValueAsMetadata>(Val: MD)) |
477 | return V->getValue(); |
478 | |
479 | // When the value goes to null, it gets replaced by an empty MDNode. |
480 | assert(!MD || |
481 | !cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode" ); |
482 | return nullptr; |
483 | } |
484 | |
485 | DIAssignID *DbgVariableRecord::getAssignID() const { |
486 | return cast<DIAssignID>(Val: DebugValues[2]); |
487 | } |
488 | |
489 | void DbgVariableRecord::setAssignId(DIAssignID *New) { |
490 | resetDebugValue(Idx: 2, DebugValue: New); |
491 | } |
492 | |
493 | void DbgVariableRecord::setKillAddress() { |
494 | resetDebugValue( |
495 | Idx: 1, DebugValue: ValueAsMetadata::get(V: UndefValue::get(T: getAddress()->getType()))); |
496 | } |
497 | |
498 | bool DbgVariableRecord::isKillAddress() const { |
499 | Value *Addr = getAddress(); |
500 | return !Addr || isa<UndefValue>(Val: Addr); |
501 | } |
502 | |
503 | const Instruction *DbgRecord::getInstruction() const { |
504 | return Marker->MarkedInstr; |
505 | } |
506 | |
507 | const BasicBlock *DbgRecord::getParent() const { |
508 | return Marker->MarkedInstr->getParent(); |
509 | } |
510 | |
511 | BasicBlock *DbgRecord::getParent() { return Marker->MarkedInstr->getParent(); } |
512 | |
513 | BasicBlock *DbgRecord::getBlock() { return Marker->getParent(); } |
514 | |
515 | const BasicBlock *DbgRecord::getBlock() const { return Marker->getParent(); } |
516 | |
517 | Function *DbgRecord::getFunction() { return getBlock()->getParent(); } |
518 | |
519 | const Function *DbgRecord::getFunction() const { |
520 | return getBlock()->getParent(); |
521 | } |
522 | |
523 | Module *DbgRecord::getModule() { return getFunction()->getParent(); } |
524 | |
525 | const Module *DbgRecord::getModule() const { |
526 | return getFunction()->getParent(); |
527 | } |
528 | |
529 | LLVMContext &DbgRecord::getContext() { return getBlock()->getContext(); } |
530 | |
531 | const LLVMContext &DbgRecord::getContext() const { |
532 | return getBlock()->getContext(); |
533 | } |
534 | |
535 | void DbgRecord::insertBefore(DbgRecord *InsertBefore) { |
536 | assert(!getMarker() && |
537 | "Cannot insert a DbgRecord that is already has a DbgMarker!" ); |
538 | assert(InsertBefore->getMarker() && |
539 | "Cannot insert a DbgRecord before a DbgRecord that does not have a " |
540 | "DbgMarker!" ); |
541 | InsertBefore->getMarker()->insertDbgRecord(New: this, InsertBefore); |
542 | } |
543 | void DbgRecord::insertAfter(DbgRecord *InsertAfter) { |
544 | assert(!getMarker() && |
545 | "Cannot insert a DbgRecord that is already has a DbgMarker!" ); |
546 | assert(InsertAfter->getMarker() && |
547 | "Cannot insert a DbgRecord after a DbgRecord that does not have a " |
548 | "DbgMarker!" ); |
549 | InsertAfter->getMarker()->insertDbgRecordAfter(New: this, InsertAfter); |
550 | } |
551 | void DbgRecord::moveBefore(DbgRecord *MoveBefore) { |
552 | assert(getMarker() && |
553 | "Canot move a DbgRecord that does not currently have a DbgMarker!" ); |
554 | removeFromParent(); |
555 | insertBefore(InsertBefore: MoveBefore); |
556 | } |
557 | void DbgRecord::moveAfter(DbgRecord *MoveAfter) { |
558 | assert(getMarker() && |
559 | "Canot move a DbgRecord that does not currently have a DbgMarker!" ); |
560 | removeFromParent(); |
561 | insertAfter(InsertAfter: MoveAfter); |
562 | } |
563 | |
564 | /////////////////////////////////////////////////////////////////////////////// |
565 | |
566 | // An empty, global, DbgMarker for the purpose of describing empty ranges of |
567 | // DbgRecords. |
568 | DbgMarker DbgMarker::EmptyDbgMarker; |
569 | |
570 | void DbgMarker::dropDbgRecords() { |
571 | while (!StoredDbgRecords.empty()) { |
572 | auto It = StoredDbgRecords.begin(); |
573 | DbgRecord *DR = &*It; |
574 | StoredDbgRecords.erase(I: It); |
575 | DR->deleteRecord(); |
576 | } |
577 | } |
578 | |
579 | void DbgMarker::dropOneDbgRecord(DbgRecord *DR) { |
580 | assert(DR->getMarker() == this); |
581 | StoredDbgRecords.erase(I: DR->getIterator()); |
582 | DR->deleteRecord(); |
583 | } |
584 | |
585 | const BasicBlock *DbgMarker::getParent() const { |
586 | return MarkedInstr->getParent(); |
587 | } |
588 | |
589 | BasicBlock *DbgMarker::getParent() { return MarkedInstr->getParent(); } |
590 | |
591 | void DbgMarker::removeMarker() { |
592 | // Are there any DbgRecords in this DbgMarker? If not, nothing to preserve. |
593 | Instruction *Owner = MarkedInstr; |
594 | if (StoredDbgRecords.empty()) { |
595 | eraseFromParent(); |
596 | Owner->DebugMarker = nullptr; |
597 | return; |
598 | } |
599 | |
600 | // The attached DbgRecords need to be preserved; attach them to the next |
601 | // instruction. If there isn't a next instruction, put them on the |
602 | // "trailing" list. |
603 | DbgMarker *NextMarker = Owner->getParent()->getNextMarker(I: Owner); |
604 | if (NextMarker) { |
605 | NextMarker->absorbDebugValues(Src&: *this, InsertAtHead: true); |
606 | eraseFromParent(); |
607 | } else { |
608 | // We can avoid a deallocation -- just store this marker onto the next |
609 | // instruction. Unless we're at the end of the block, in which case this |
610 | // marker becomes the trailing marker of a degenerate block. |
611 | BasicBlock::iterator NextIt = std::next(x: Owner->getIterator()); |
612 | if (NextIt == getParent()->end()) { |
613 | getParent()->setTrailingDbgRecords(this); |
614 | MarkedInstr = nullptr; |
615 | } else { |
616 | NextIt->DebugMarker = this; |
617 | MarkedInstr = &*NextIt; |
618 | } |
619 | } |
620 | Owner->DebugMarker = nullptr; |
621 | } |
622 | |
623 | void DbgMarker::removeFromParent() { |
624 | MarkedInstr->DebugMarker = nullptr; |
625 | MarkedInstr = nullptr; |
626 | } |
627 | |
628 | void DbgMarker::eraseFromParent() { |
629 | if (MarkedInstr) |
630 | removeFromParent(); |
631 | dropDbgRecords(); |
632 | delete this; |
633 | } |
634 | |
635 | iterator_range<DbgRecord::self_iterator> DbgMarker::getDbgRecordRange() { |
636 | return make_range(x: StoredDbgRecords.begin(), y: StoredDbgRecords.end()); |
637 | } |
638 | iterator_range<DbgRecord::const_self_iterator> |
639 | DbgMarker::getDbgRecordRange() const { |
640 | return make_range(x: StoredDbgRecords.begin(), y: StoredDbgRecords.end()); |
641 | } |
642 | |
643 | void DbgRecord::removeFromParent() { |
644 | getMarker()->StoredDbgRecords.erase(I: getIterator()); |
645 | Marker = nullptr; |
646 | } |
647 | |
648 | void DbgRecord::eraseFromParent() { |
649 | removeFromParent(); |
650 | deleteRecord(); |
651 | } |
652 | |
653 | void DbgMarker::insertDbgRecord(DbgRecord *New, bool InsertAtHead) { |
654 | auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end(); |
655 | StoredDbgRecords.insert(I: It, Node&: *New); |
656 | New->setMarker(this); |
657 | } |
658 | void DbgMarker::insertDbgRecord(DbgRecord *New, DbgRecord *InsertBefore) { |
659 | assert(InsertBefore->getMarker() == this && |
660 | "DbgRecord 'InsertBefore' must be contained in this DbgMarker!" ); |
661 | StoredDbgRecords.insert(I: InsertBefore->getIterator(), Node&: *New); |
662 | New->setMarker(this); |
663 | } |
664 | void DbgMarker::insertDbgRecordAfter(DbgRecord *New, DbgRecord *InsertAfter) { |
665 | assert(InsertAfter->getMarker() == this && |
666 | "DbgRecord 'InsertAfter' must be contained in this DbgMarker!" ); |
667 | StoredDbgRecords.insert(I: ++(InsertAfter->getIterator()), Node&: *New); |
668 | New->setMarker(this); |
669 | } |
670 | |
671 | void DbgMarker::absorbDebugValues(DbgMarker &Src, bool InsertAtHead) { |
672 | auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end(); |
673 | for (DbgRecord &DVR : Src.StoredDbgRecords) |
674 | DVR.setMarker(this); |
675 | |
676 | StoredDbgRecords.splice(I: It, L2&: Src.StoredDbgRecords); |
677 | } |
678 | |
679 | void DbgMarker::absorbDebugValues( |
680 | iterator_range<DbgRecord::self_iterator> Range, DbgMarker &Src, |
681 | bool InsertAtHead) { |
682 | for (DbgRecord &DR : Range) |
683 | DR.setMarker(this); |
684 | |
685 | auto InsertPos = |
686 | (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end(); |
687 | |
688 | StoredDbgRecords.splice(I: InsertPos, Src.StoredDbgRecords, First: Range.begin(), |
689 | Last: Range.end()); |
690 | } |
691 | |
692 | iterator_range<simple_ilist<DbgRecord>::iterator> DbgMarker::cloneDebugInfoFrom( |
693 | DbgMarker *From, std::optional<simple_ilist<DbgRecord>::iterator> from_here, |
694 | bool InsertAtHead) { |
695 | DbgRecord *First = nullptr; |
696 | // Work out what range of DbgRecords to clone: normally all the contents of |
697 | // the "From" marker, optionally we can start from the from_here position down |
698 | // to end(). |
699 | auto Range = |
700 | make_range(x: From->StoredDbgRecords.begin(), y: From->StoredDbgRecords.end()); |
701 | if (from_here.has_value()) |
702 | Range = make_range(x: *from_here, y: From->StoredDbgRecords.end()); |
703 | |
704 | // Clone each DbgVariableRecord and insert into StoreDbgVariableRecords; |
705 | // optionally place them at the start or the end of the list. |
706 | auto Pos = (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end(); |
707 | for (DbgRecord &DR : Range) { |
708 | DbgRecord *New = DR.clone(); |
709 | New->setMarker(this); |
710 | StoredDbgRecords.insert(I: Pos, Node&: *New); |
711 | if (!First) |
712 | First = New; |
713 | } |
714 | |
715 | if (!First) |
716 | return {StoredDbgRecords.end(), StoredDbgRecords.end()}; |
717 | |
718 | if (InsertAtHead) |
719 | // If InsertAtHead is set, we cloned a range onto the front of of the |
720 | // StoredDbgRecords collection, return that range. |
721 | return {StoredDbgRecords.begin(), Pos}; |
722 | else |
723 | // We inserted a block at the end, return that range. |
724 | return {First->getIterator(), StoredDbgRecords.end()}; |
725 | } |
726 | |
727 | } // end namespace llvm |
728 | |