1c9157d92SDimitry Andric //======-- DebugProgramInstruction.cpp - Implement DPValues/DPMarkers --======//
2c9157d92SDimitry Andric //
3c9157d92SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c9157d92SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5c9157d92SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c9157d92SDimitry Andric //
7c9157d92SDimitry Andric //===----------------------------------------------------------------------===//
8c9157d92SDimitry Andric
9c9157d92SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
10c9157d92SDimitry Andric #include "llvm/IR/DebugProgramInstruction.h"
11c9157d92SDimitry Andric #include "llvm/IR/DIBuilder.h"
12c9157d92SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
13c9157d92SDimitry Andric
14c9157d92SDimitry Andric namespace llvm {
15c9157d92SDimitry Andric
DPValue(const DbgVariableIntrinsic * DVI)16c9157d92SDimitry Andric DPValue::DPValue(const DbgVariableIntrinsic *DVI)
17*a58f00eaSDimitry Andric : DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}),
18*a58f00eaSDimitry Andric Variable(DVI->getVariable()), Expression(DVI->getExpression()),
19*a58f00eaSDimitry Andric DbgLoc(DVI->getDebugLoc()), AddressExpression(nullptr) {
20c9157d92SDimitry Andric switch (DVI->getIntrinsicID()) {
21c9157d92SDimitry Andric case Intrinsic::dbg_value:
22c9157d92SDimitry Andric Type = LocationType::Value;
23c9157d92SDimitry Andric break;
24c9157d92SDimitry Andric case Intrinsic::dbg_declare:
25c9157d92SDimitry Andric Type = LocationType::Declare;
26c9157d92SDimitry Andric break;
27*a58f00eaSDimitry Andric case Intrinsic::dbg_assign: {
28*a58f00eaSDimitry Andric Type = LocationType::Assign;
29*a58f00eaSDimitry Andric const DbgAssignIntrinsic *Assign =
30*a58f00eaSDimitry Andric static_cast<const DbgAssignIntrinsic *>(DVI);
31*a58f00eaSDimitry Andric resetDebugValue(1, Assign->getRawAddress());
32*a58f00eaSDimitry Andric AddressExpression = Assign->getAddressExpression();
33*a58f00eaSDimitry Andric setAssignId(Assign->getAssignID());
34*a58f00eaSDimitry Andric break;
35*a58f00eaSDimitry Andric }
36c9157d92SDimitry Andric default:
37c9157d92SDimitry Andric llvm_unreachable(
38c9157d92SDimitry Andric "Trying to create a DPValue with an invalid intrinsic type!");
39c9157d92SDimitry Andric }
40c9157d92SDimitry Andric }
41c9157d92SDimitry Andric
DPValue(const DPValue & DPV)42c9157d92SDimitry Andric DPValue::DPValue(const DPValue &DPV)
43*a58f00eaSDimitry Andric : DebugValueUser(DPV.DebugValues), Variable(DPV.getVariable()),
44*a58f00eaSDimitry Andric Expression(DPV.getExpression()), DbgLoc(DPV.getDebugLoc()),
45*a58f00eaSDimitry Andric AddressExpression(DPV.AddressExpression), Type(DPV.getType()) {}
46c9157d92SDimitry Andric
DPValue(Metadata * Location,DILocalVariable * DV,DIExpression * Expr,const DILocation * DI,LocationType Type)47c9157d92SDimitry Andric DPValue::DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
48c9157d92SDimitry Andric const DILocation *DI, LocationType Type)
49*a58f00eaSDimitry Andric : DebugValueUser({Location, nullptr, nullptr}), Variable(DV),
50*a58f00eaSDimitry Andric Expression(Expr), DbgLoc(DI), Type(Type) {}
51*a58f00eaSDimitry Andric
DPValue(Metadata * Value,DILocalVariable * Variable,DIExpression * Expression,DIAssignID * AssignID,Metadata * Address,DIExpression * AddressExpression,const DILocation * DI)52*a58f00eaSDimitry Andric DPValue::DPValue(Metadata *Value, DILocalVariable *Variable,
53*a58f00eaSDimitry Andric DIExpression *Expression, DIAssignID *AssignID,
54*a58f00eaSDimitry Andric Metadata *Address, DIExpression *AddressExpression,
55*a58f00eaSDimitry Andric const DILocation *DI)
56*a58f00eaSDimitry Andric : DebugValueUser({Value, Address, AssignID}), Variable(Variable),
57*a58f00eaSDimitry Andric Expression(Expression), DbgLoc(DI), AddressExpression(AddressExpression),
58*a58f00eaSDimitry Andric Type(LocationType::Assign) {}
59c9157d92SDimitry Andric
deleteInstr()60c9157d92SDimitry Andric void DPValue::deleteInstr() { delete this; }
61c9157d92SDimitry Andric
createDPValue(Value * Location,DILocalVariable * DV,DIExpression * Expr,const DILocation * DI)62*a58f00eaSDimitry Andric DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV,
63*a58f00eaSDimitry Andric DIExpression *Expr, const DILocation *DI) {
64*a58f00eaSDimitry Andric return new DPValue(ValueAsMetadata::get(Location), DV, Expr, DI,
65*a58f00eaSDimitry Andric LocationType::Value);
66*a58f00eaSDimitry Andric }
67*a58f00eaSDimitry Andric
createDPValue(Value * Location,DILocalVariable * DV,DIExpression * Expr,const DILocation * DI,DPValue & InsertBefore)68*a58f00eaSDimitry Andric DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV,
69*a58f00eaSDimitry Andric DIExpression *Expr, const DILocation *DI,
70*a58f00eaSDimitry Andric DPValue &InsertBefore) {
71*a58f00eaSDimitry Andric auto *NewDPValue = createDPValue(Location, DV, Expr, DI);
72*a58f00eaSDimitry Andric NewDPValue->insertBefore(&InsertBefore);
73*a58f00eaSDimitry Andric return NewDPValue;
74*a58f00eaSDimitry Andric }
75*a58f00eaSDimitry Andric
createDPVDeclare(Value * Address,DILocalVariable * DV,DIExpression * Expr,const DILocation * DI)76*a58f00eaSDimitry Andric DPValue *DPValue::createDPVDeclare(Value *Address, DILocalVariable *DV,
77*a58f00eaSDimitry Andric DIExpression *Expr, const DILocation *DI) {
78*a58f00eaSDimitry Andric return new DPValue(ValueAsMetadata::get(Address), DV, Expr, DI,
79*a58f00eaSDimitry Andric LocationType::Declare);
80*a58f00eaSDimitry Andric }
81*a58f00eaSDimitry Andric
createDPVDeclare(Value * Address,DILocalVariable * DV,DIExpression * Expr,const DILocation * DI,DPValue & InsertBefore)82*a58f00eaSDimitry Andric DPValue *DPValue::createDPVDeclare(Value *Address, DILocalVariable *DV,
83*a58f00eaSDimitry Andric DIExpression *Expr, const DILocation *DI,
84*a58f00eaSDimitry Andric DPValue &InsertBefore) {
85*a58f00eaSDimitry Andric auto *NewDPVDeclare = createDPVDeclare(Address, DV, Expr, DI);
86*a58f00eaSDimitry Andric NewDPVDeclare->insertBefore(&InsertBefore);
87*a58f00eaSDimitry Andric return NewDPVDeclare;
88*a58f00eaSDimitry Andric }
89*a58f00eaSDimitry Andric
createDPVAssign(Value * Val,DILocalVariable * Variable,DIExpression * Expression,DIAssignID * AssignID,Value * Address,DIExpression * AddressExpression,const DILocation * DI)90*a58f00eaSDimitry Andric DPValue *DPValue::createDPVAssign(Value *Val, DILocalVariable *Variable,
91*a58f00eaSDimitry Andric DIExpression *Expression,
92*a58f00eaSDimitry Andric DIAssignID *AssignID, Value *Address,
93*a58f00eaSDimitry Andric DIExpression *AddressExpression,
94*a58f00eaSDimitry Andric const DILocation *DI) {
95*a58f00eaSDimitry Andric return new DPValue(ValueAsMetadata::get(Val), Variable, Expression, AssignID,
96*a58f00eaSDimitry Andric ValueAsMetadata::get(Address), AddressExpression, DI);
97*a58f00eaSDimitry Andric }
98*a58f00eaSDimitry Andric
createLinkedDPVAssign(Instruction * LinkedInstr,Value * Val,DILocalVariable * Variable,DIExpression * Expression,Value * Address,DIExpression * AddressExpression,const DILocation * DI)99*a58f00eaSDimitry Andric DPValue *DPValue::createLinkedDPVAssign(Instruction *LinkedInstr, Value *Val,
100*a58f00eaSDimitry Andric DILocalVariable *Variable,
101*a58f00eaSDimitry Andric DIExpression *Expression,
102*a58f00eaSDimitry Andric Value *Address,
103*a58f00eaSDimitry Andric DIExpression *AddressExpression,
104*a58f00eaSDimitry Andric const DILocation *DI) {
105*a58f00eaSDimitry Andric auto *Link = LinkedInstr->getMetadata(LLVMContext::MD_DIAssignID);
106*a58f00eaSDimitry Andric assert(Link && "Linked instruction must have DIAssign metadata attached");
107*a58f00eaSDimitry Andric auto *NewDPVAssign = DPValue::createDPVAssign(Val, Variable, Expression,
108*a58f00eaSDimitry Andric cast<DIAssignID>(Link), Address,
109*a58f00eaSDimitry Andric AddressExpression, DI);
110*a58f00eaSDimitry Andric LinkedInstr->getParent()->insertDPValueAfter(NewDPVAssign, LinkedInstr);
111*a58f00eaSDimitry Andric return NewDPVAssign;
112*a58f00eaSDimitry Andric }
113*a58f00eaSDimitry Andric
location_ops() const114c9157d92SDimitry Andric iterator_range<DPValue::location_op_iterator> DPValue::location_ops() const {
115c9157d92SDimitry Andric auto *MD = getRawLocation();
116c9157d92SDimitry Andric // If a Value has been deleted, the "location" for this DPValue will be
117c9157d92SDimitry Andric // replaced by nullptr. Return an empty range.
118c9157d92SDimitry Andric if (!MD)
119c9157d92SDimitry Andric return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
120c9157d92SDimitry Andric location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
121c9157d92SDimitry Andric
122c9157d92SDimitry Andric // If operand is ValueAsMetadata, return a range over just that operand.
123c9157d92SDimitry Andric if (auto *VAM = dyn_cast<ValueAsMetadata>(MD))
124c9157d92SDimitry Andric return {location_op_iterator(VAM), location_op_iterator(VAM + 1)};
125c9157d92SDimitry Andric
126c9157d92SDimitry Andric // If operand is DIArgList, return a range over its args.
127c9157d92SDimitry Andric if (auto *AL = dyn_cast<DIArgList>(MD))
128c9157d92SDimitry Andric return {location_op_iterator(AL->args_begin()),
129c9157d92SDimitry Andric location_op_iterator(AL->args_end())};
130c9157d92SDimitry Andric
131c9157d92SDimitry Andric // Operand is an empty metadata tuple, so return empty iterator.
132c9157d92SDimitry Andric assert(cast<MDNode>(MD)->getNumOperands() == 0);
133c9157d92SDimitry Andric return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
134c9157d92SDimitry Andric location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
135c9157d92SDimitry Andric }
136c9157d92SDimitry Andric
getNumVariableLocationOps() const137c9157d92SDimitry Andric unsigned DPValue::getNumVariableLocationOps() const {
138c9157d92SDimitry Andric if (hasArgList())
139c9157d92SDimitry Andric return cast<DIArgList>(getRawLocation())->getArgs().size();
140c9157d92SDimitry Andric return 1;
141c9157d92SDimitry Andric }
142c9157d92SDimitry Andric
getVariableLocationOp(unsigned OpIdx) const143c9157d92SDimitry Andric Value *DPValue::getVariableLocationOp(unsigned OpIdx) const {
144c9157d92SDimitry Andric auto *MD = getRawLocation();
145c9157d92SDimitry Andric if (!MD)
146c9157d92SDimitry Andric return nullptr;
147c9157d92SDimitry Andric
148c9157d92SDimitry Andric if (auto *AL = dyn_cast<DIArgList>(MD))
149c9157d92SDimitry Andric return AL->getArgs()[OpIdx]->getValue();
150c9157d92SDimitry Andric if (isa<MDNode>(MD))
151c9157d92SDimitry Andric return nullptr;
152c9157d92SDimitry Andric assert(isa<ValueAsMetadata>(MD) &&
153c9157d92SDimitry Andric "Attempted to get location operand from DPValue with none.");
154c9157d92SDimitry Andric auto *V = cast<ValueAsMetadata>(MD);
155c9157d92SDimitry Andric assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a "
156c9157d92SDimitry Andric "single location operand.");
157c9157d92SDimitry Andric return V->getValue();
158c9157d92SDimitry Andric }
159c9157d92SDimitry Andric
getAsMetadata(Value * V)160c9157d92SDimitry Andric static ValueAsMetadata *getAsMetadata(Value *V) {
161c9157d92SDimitry Andric return isa<MetadataAsValue>(V) ? dyn_cast<ValueAsMetadata>(
162c9157d92SDimitry Andric cast<MetadataAsValue>(V)->getMetadata())
163c9157d92SDimitry Andric : ValueAsMetadata::get(V);
164c9157d92SDimitry Andric }
165c9157d92SDimitry Andric
replaceVariableLocationOp(Value * OldValue,Value * NewValue,bool AllowEmpty)166c9157d92SDimitry Andric void DPValue::replaceVariableLocationOp(Value *OldValue, Value *NewValue,
167c9157d92SDimitry Andric bool AllowEmpty) {
168c9157d92SDimitry Andric assert(NewValue && "Values must be non-null");
169*a58f00eaSDimitry Andric
170*a58f00eaSDimitry Andric bool DbgAssignAddrReplaced = isDbgAssign() && OldValue == getAddress();
171*a58f00eaSDimitry Andric if (DbgAssignAddrReplaced)
172*a58f00eaSDimitry Andric setAddress(NewValue);
173*a58f00eaSDimitry Andric
174c9157d92SDimitry Andric auto Locations = location_ops();
175c9157d92SDimitry Andric auto OldIt = find(Locations, OldValue);
176c9157d92SDimitry Andric if (OldIt == Locations.end()) {
177*a58f00eaSDimitry Andric if (AllowEmpty || DbgAssignAddrReplaced)
178c9157d92SDimitry Andric return;
179c9157d92SDimitry Andric llvm_unreachable("OldValue must be a current location");
180c9157d92SDimitry Andric }
181c9157d92SDimitry Andric
182c9157d92SDimitry Andric if (!hasArgList()) {
183c9157d92SDimitry Andric // Set our location to be the MAV wrapping the new Value.
184c9157d92SDimitry Andric setRawLocation(isa<MetadataAsValue>(NewValue)
185c9157d92SDimitry Andric ? cast<MetadataAsValue>(NewValue)->getMetadata()
186c9157d92SDimitry Andric : ValueAsMetadata::get(NewValue));
187c9157d92SDimitry Andric return;
188c9157d92SDimitry Andric }
189c9157d92SDimitry Andric
190c9157d92SDimitry Andric // We must be referring to a DIArgList, produce a new operands vector with the
191c9157d92SDimitry Andric // old value replaced, generate a new DIArgList and set it as our location.
192c9157d92SDimitry Andric SmallVector<ValueAsMetadata *, 4> MDs;
193c9157d92SDimitry Andric ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
194c9157d92SDimitry Andric for (auto *VMD : Locations)
195c9157d92SDimitry Andric MDs.push_back(VMD == *OldIt ? NewOperand : getAsMetadata(VMD));
196c9157d92SDimitry Andric setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
197c9157d92SDimitry Andric }
198c9157d92SDimitry Andric
replaceVariableLocationOp(unsigned OpIdx,Value * NewValue)199c9157d92SDimitry Andric void DPValue::replaceVariableLocationOp(unsigned OpIdx, Value *NewValue) {
200c9157d92SDimitry Andric assert(OpIdx < getNumVariableLocationOps() && "Invalid Operand Index");
201c9157d92SDimitry Andric
202c9157d92SDimitry Andric if (!hasArgList()) {
203c9157d92SDimitry Andric setRawLocation(isa<MetadataAsValue>(NewValue)
204c9157d92SDimitry Andric ? cast<MetadataAsValue>(NewValue)->getMetadata()
205c9157d92SDimitry Andric : ValueAsMetadata::get(NewValue));
206c9157d92SDimitry Andric return;
207c9157d92SDimitry Andric }
208c9157d92SDimitry Andric
209c9157d92SDimitry Andric SmallVector<ValueAsMetadata *, 4> MDs;
210c9157d92SDimitry Andric ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
211c9157d92SDimitry Andric for (unsigned Idx = 0; Idx < getNumVariableLocationOps(); ++Idx)
212c9157d92SDimitry Andric MDs.push_back(Idx == OpIdx ? NewOperand
213c9157d92SDimitry Andric : getAsMetadata(getVariableLocationOp(Idx)));
214c9157d92SDimitry Andric
215c9157d92SDimitry Andric setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
216c9157d92SDimitry Andric }
217c9157d92SDimitry Andric
addVariableLocationOps(ArrayRef<Value * > NewValues,DIExpression * NewExpr)218c9157d92SDimitry Andric void DPValue::addVariableLocationOps(ArrayRef<Value *> NewValues,
219c9157d92SDimitry Andric DIExpression *NewExpr) {
220c9157d92SDimitry Andric assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() +
221c9157d92SDimitry Andric NewValues.size()) &&
222c9157d92SDimitry Andric "NewExpr for debug variable intrinsic does not reference every "
223c9157d92SDimitry Andric "location operand.");
224c9157d92SDimitry Andric assert(!is_contained(NewValues, nullptr) && "New values must be non-null");
225c9157d92SDimitry Andric setExpression(NewExpr);
226c9157d92SDimitry Andric SmallVector<ValueAsMetadata *, 4> MDs;
227c9157d92SDimitry Andric for (auto *VMD : location_ops())
228c9157d92SDimitry Andric MDs.push_back(getAsMetadata(VMD));
229c9157d92SDimitry Andric for (auto *VMD : NewValues)
230c9157d92SDimitry Andric MDs.push_back(getAsMetadata(VMD));
231c9157d92SDimitry Andric setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
232c9157d92SDimitry Andric }
233c9157d92SDimitry Andric
setKillLocation()234c9157d92SDimitry Andric void DPValue::setKillLocation() {
235c9157d92SDimitry Andric // TODO: When/if we remove duplicate values from DIArgLists, we don't need
236c9157d92SDimitry Andric // this set anymore.
237c9157d92SDimitry Andric SmallPtrSet<Value *, 4> RemovedValues;
238c9157d92SDimitry Andric for (Value *OldValue : location_ops()) {
239c9157d92SDimitry Andric if (!RemovedValues.insert(OldValue).second)
240c9157d92SDimitry Andric continue;
241c9157d92SDimitry Andric Value *Poison = PoisonValue::get(OldValue->getType());
242c9157d92SDimitry Andric replaceVariableLocationOp(OldValue, Poison);
243c9157d92SDimitry Andric }
244c9157d92SDimitry Andric }
245c9157d92SDimitry Andric
isKillLocation() const246c9157d92SDimitry Andric bool DPValue::isKillLocation() const {
247c9157d92SDimitry Andric return (getNumVariableLocationOps() == 0 &&
248c9157d92SDimitry Andric !getExpression()->isComplex()) ||
249c9157d92SDimitry Andric any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); });
250c9157d92SDimitry Andric }
251c9157d92SDimitry Andric
getFragmentSizeInBits() const252c9157d92SDimitry Andric std::optional<uint64_t> DPValue::getFragmentSizeInBits() const {
253c9157d92SDimitry Andric if (auto Fragment = getExpression()->getFragmentInfo())
254c9157d92SDimitry Andric return Fragment->SizeInBits;
255c9157d92SDimitry Andric return getVariable()->getSizeInBits();
256c9157d92SDimitry Andric }
257c9157d92SDimitry Andric
clone() const258c9157d92SDimitry Andric DPValue *DPValue::clone() const { return new DPValue(*this); }
259c9157d92SDimitry Andric
260c9157d92SDimitry Andric DbgVariableIntrinsic *
createDebugIntrinsic(Module * M,Instruction * InsertBefore) const261c9157d92SDimitry Andric DPValue::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
262c9157d92SDimitry Andric [[maybe_unused]] DICompileUnit *Unit =
263c9157d92SDimitry Andric getDebugLoc().get()->getScope()->getSubprogram()->getUnit();
264c9157d92SDimitry Andric assert(M && Unit &&
265c9157d92SDimitry Andric "Cannot clone from BasicBlock that is not part of a Module or "
266c9157d92SDimitry Andric "DICompileUnit!");
267c9157d92SDimitry Andric LLVMContext &Context = getDebugLoc()->getContext();
268c9157d92SDimitry Andric Function *IntrinsicFn;
269c9157d92SDimitry Andric
270c9157d92SDimitry Andric // Work out what sort of intrinsic we're going to produce.
271c9157d92SDimitry Andric switch (getType()) {
272c9157d92SDimitry Andric case DPValue::LocationType::Declare:
273c9157d92SDimitry Andric IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_declare);
274c9157d92SDimitry Andric break;
275c9157d92SDimitry Andric case DPValue::LocationType::Value:
276c9157d92SDimitry Andric IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_value);
277c9157d92SDimitry Andric break;
278*a58f00eaSDimitry Andric case DPValue::LocationType::Assign:
279*a58f00eaSDimitry Andric IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_assign);
280*a58f00eaSDimitry Andric break;
281c9157d92SDimitry Andric case DPValue::LocationType::End:
282c9157d92SDimitry Andric case DPValue::LocationType::Any:
283c9157d92SDimitry Andric llvm_unreachable("Invalid LocationType");
284c9157d92SDimitry Andric }
285c9157d92SDimitry Andric
286c9157d92SDimitry Andric // Create the intrinsic from this DPValue's information, optionally insert
287c9157d92SDimitry Andric // into the target location.
288*a58f00eaSDimitry Andric DbgVariableIntrinsic *DVI;
289*a58f00eaSDimitry Andric if (isDbgAssign()) {
290*a58f00eaSDimitry Andric Value *AssignArgs[] = {
291*a58f00eaSDimitry Andric MetadataAsValue::get(Context, getRawLocation()),
292*a58f00eaSDimitry Andric MetadataAsValue::get(Context, getVariable()),
293*a58f00eaSDimitry Andric MetadataAsValue::get(Context, getExpression()),
294*a58f00eaSDimitry Andric MetadataAsValue::get(Context, getAssignID()),
295*a58f00eaSDimitry Andric MetadataAsValue::get(Context, getRawAddress()),
296*a58f00eaSDimitry Andric MetadataAsValue::get(Context, getAddressExpression())};
297*a58f00eaSDimitry Andric DVI = cast<DbgVariableIntrinsic>(CallInst::Create(
298*a58f00eaSDimitry Andric IntrinsicFn->getFunctionType(), IntrinsicFn, AssignArgs));
299*a58f00eaSDimitry Andric } else {
300*a58f00eaSDimitry Andric Value *Args[] = {MetadataAsValue::get(Context, getRawLocation()),
301*a58f00eaSDimitry Andric MetadataAsValue::get(Context, getVariable()),
302*a58f00eaSDimitry Andric MetadataAsValue::get(Context, getExpression())};
303*a58f00eaSDimitry Andric DVI = cast<DbgVariableIntrinsic>(
304c9157d92SDimitry Andric CallInst::Create(IntrinsicFn->getFunctionType(), IntrinsicFn, Args));
305*a58f00eaSDimitry Andric }
306c9157d92SDimitry Andric DVI->setTailCall();
307c9157d92SDimitry Andric DVI->setDebugLoc(getDebugLoc());
308c9157d92SDimitry Andric if (InsertBefore)
309c9157d92SDimitry Andric DVI->insertBefore(InsertBefore);
310c9157d92SDimitry Andric
311c9157d92SDimitry Andric return DVI;
312c9157d92SDimitry Andric }
313c9157d92SDimitry Andric
getAddress() const314*a58f00eaSDimitry Andric Value *DPValue::getAddress() const {
315*a58f00eaSDimitry Andric auto *MD = getRawAddress();
316*a58f00eaSDimitry Andric if (auto *V = dyn_cast<ValueAsMetadata>(MD))
317*a58f00eaSDimitry Andric return V->getValue();
318*a58f00eaSDimitry Andric
319*a58f00eaSDimitry Andric // When the value goes to null, it gets replaced by an empty MDNode.
320*a58f00eaSDimitry Andric assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");
321*a58f00eaSDimitry Andric return nullptr;
322*a58f00eaSDimitry Andric }
323*a58f00eaSDimitry Andric
getAssignID() const324*a58f00eaSDimitry Andric DIAssignID *DPValue::getAssignID() const {
325*a58f00eaSDimitry Andric return cast<DIAssignID>(DebugValues[2]);
326*a58f00eaSDimitry Andric }
327*a58f00eaSDimitry Andric
setAssignId(DIAssignID * New)328*a58f00eaSDimitry Andric void DPValue::setAssignId(DIAssignID *New) { resetDebugValue(2, New); }
329*a58f00eaSDimitry Andric
setKillAddress()330*a58f00eaSDimitry Andric void DPValue::setKillAddress() {
331*a58f00eaSDimitry Andric resetDebugValue(
332*a58f00eaSDimitry Andric 1, ValueAsMetadata::get(UndefValue::get(getAddress()->getType())));
333*a58f00eaSDimitry Andric }
334*a58f00eaSDimitry Andric
isKillAddress() const335*a58f00eaSDimitry Andric bool DPValue::isKillAddress() const {
336*a58f00eaSDimitry Andric Value *Addr = getAddress();
337*a58f00eaSDimitry Andric return !Addr || isa<UndefValue>(Addr);
338c9157d92SDimitry Andric }
339c9157d92SDimitry Andric
getParent() const340c9157d92SDimitry Andric const BasicBlock *DPValue::getParent() const {
341c9157d92SDimitry Andric return Marker->MarkedInstr->getParent();
342c9157d92SDimitry Andric }
343c9157d92SDimitry Andric
getParent()344c9157d92SDimitry Andric BasicBlock *DPValue::getParent() { return Marker->MarkedInstr->getParent(); }
345c9157d92SDimitry Andric
getBlock()346c9157d92SDimitry Andric BasicBlock *DPValue::getBlock() { return Marker->getParent(); }
347c9157d92SDimitry Andric
getBlock() const348c9157d92SDimitry Andric const BasicBlock *DPValue::getBlock() const { return Marker->getParent(); }
349c9157d92SDimitry Andric
getFunction()350c9157d92SDimitry Andric Function *DPValue::getFunction() { return getBlock()->getParent(); }
351c9157d92SDimitry Andric
getFunction() const352c9157d92SDimitry Andric const Function *DPValue::getFunction() const { return getBlock()->getParent(); }
353c9157d92SDimitry Andric
getModule()354c9157d92SDimitry Andric Module *DPValue::getModule() { return getFunction()->getParent(); }
355c9157d92SDimitry Andric
getModule() const356c9157d92SDimitry Andric const Module *DPValue::getModule() const { return getFunction()->getParent(); }
357c9157d92SDimitry Andric
getContext()358c9157d92SDimitry Andric LLVMContext &DPValue::getContext() { return getBlock()->getContext(); }
359c9157d92SDimitry Andric
getContext() const360c9157d92SDimitry Andric const LLVMContext &DPValue::getContext() const {
361c9157d92SDimitry Andric return getBlock()->getContext();
362c9157d92SDimitry Andric }
363c9157d92SDimitry Andric
insertBefore(DPValue * InsertBefore)364*a58f00eaSDimitry Andric void DPValue::insertBefore(DPValue *InsertBefore) {
365*a58f00eaSDimitry Andric assert(!getMarker() &&
366*a58f00eaSDimitry Andric "Cannot insert a DPValue that is already has a DPMarker!");
367*a58f00eaSDimitry Andric assert(InsertBefore->getMarker() &&
368*a58f00eaSDimitry Andric "Cannot insert a DPValue before a DPValue that does not have a "
369*a58f00eaSDimitry Andric "DPMarker!");
370*a58f00eaSDimitry Andric InsertBefore->getMarker()->insertDPValue(this, InsertBefore);
371*a58f00eaSDimitry Andric }
insertAfter(DPValue * InsertAfter)372*a58f00eaSDimitry Andric void DPValue::insertAfter(DPValue *InsertAfter) {
373*a58f00eaSDimitry Andric assert(!getMarker() &&
374*a58f00eaSDimitry Andric "Cannot insert a DPValue that is already has a DPMarker!");
375*a58f00eaSDimitry Andric assert(InsertAfter->getMarker() &&
376*a58f00eaSDimitry Andric "Cannot insert a DPValue after a DPValue that does not have a "
377*a58f00eaSDimitry Andric "DPMarker!");
378*a58f00eaSDimitry Andric InsertAfter->getMarker()->insertDPValueAfter(this, InsertAfter);
379*a58f00eaSDimitry Andric }
moveBefore(DPValue * MoveBefore)380*a58f00eaSDimitry Andric void DPValue::moveBefore(DPValue *MoveBefore) {
381*a58f00eaSDimitry Andric assert(getMarker() &&
382*a58f00eaSDimitry Andric "Canot move a DPValue that does not currently have a DPMarker!");
383*a58f00eaSDimitry Andric removeFromParent();
384*a58f00eaSDimitry Andric insertBefore(MoveBefore);
385*a58f00eaSDimitry Andric }
moveAfter(DPValue * MoveAfter)386*a58f00eaSDimitry Andric void DPValue::moveAfter(DPValue *MoveAfter) {
387*a58f00eaSDimitry Andric assert(getMarker() &&
388*a58f00eaSDimitry Andric "Canot move a DPValue that does not currently have a DPMarker!");
389*a58f00eaSDimitry Andric removeFromParent();
390*a58f00eaSDimitry Andric insertAfter(MoveAfter);
391*a58f00eaSDimitry Andric }
392*a58f00eaSDimitry Andric
393c9157d92SDimitry Andric ///////////////////////////////////////////////////////////////////////////////
394c9157d92SDimitry Andric
395c9157d92SDimitry Andric // An empty, global, DPMarker for the purpose of describing empty ranges of
396c9157d92SDimitry Andric // DPValues.
397c9157d92SDimitry Andric DPMarker DPMarker::EmptyDPMarker;
398c9157d92SDimitry Andric
dropDPValues()399c9157d92SDimitry Andric void DPMarker::dropDPValues() {
400c9157d92SDimitry Andric while (!StoredDPValues.empty()) {
401c9157d92SDimitry Andric auto It = StoredDPValues.begin();
402c9157d92SDimitry Andric DPValue *DPV = &*It;
403c9157d92SDimitry Andric StoredDPValues.erase(It);
404c9157d92SDimitry Andric DPV->deleteInstr();
405c9157d92SDimitry Andric }
406c9157d92SDimitry Andric }
407c9157d92SDimitry Andric
dropOneDPValue(DPValue * DPV)408c9157d92SDimitry Andric void DPMarker::dropOneDPValue(DPValue *DPV) {
409c9157d92SDimitry Andric assert(DPV->getMarker() == this);
410c9157d92SDimitry Andric StoredDPValues.erase(DPV->getIterator());
411c9157d92SDimitry Andric DPV->deleteInstr();
412c9157d92SDimitry Andric }
413c9157d92SDimitry Andric
getParent() const414c9157d92SDimitry Andric const BasicBlock *DPMarker::getParent() const {
415c9157d92SDimitry Andric return MarkedInstr->getParent();
416c9157d92SDimitry Andric }
417c9157d92SDimitry Andric
getParent()418c9157d92SDimitry Andric BasicBlock *DPMarker::getParent() { return MarkedInstr->getParent(); }
419c9157d92SDimitry Andric
removeMarker()420c9157d92SDimitry Andric void DPMarker::removeMarker() {
421c9157d92SDimitry Andric // Are there any DPValues in this DPMarker? If not, nothing to preserve.
422c9157d92SDimitry Andric Instruction *Owner = MarkedInstr;
423c9157d92SDimitry Andric if (StoredDPValues.empty()) {
424c9157d92SDimitry Andric eraseFromParent();
425c9157d92SDimitry Andric Owner->DbgMarker = nullptr;
426c9157d92SDimitry Andric return;
427c9157d92SDimitry Andric }
428c9157d92SDimitry Andric
429c9157d92SDimitry Andric // The attached DPValues need to be preserved; attach them to the next
430c9157d92SDimitry Andric // instruction. If there isn't a next instruction, put them on the
431c9157d92SDimitry Andric // "trailing" list.
432c9157d92SDimitry Andric DPMarker *NextMarker = Owner->getParent()->getNextMarker(Owner);
433c9157d92SDimitry Andric if (NextMarker == nullptr) {
434c9157d92SDimitry Andric NextMarker = new DPMarker();
435c9157d92SDimitry Andric Owner->getParent()->setTrailingDPValues(NextMarker);
436c9157d92SDimitry Andric }
437c9157d92SDimitry Andric NextMarker->absorbDebugValues(*this, true);
438c9157d92SDimitry Andric
439c9157d92SDimitry Andric eraseFromParent();
440c9157d92SDimitry Andric }
441c9157d92SDimitry Andric
removeFromParent()442c9157d92SDimitry Andric void DPMarker::removeFromParent() {
443c9157d92SDimitry Andric MarkedInstr->DbgMarker = nullptr;
444c9157d92SDimitry Andric MarkedInstr = nullptr;
445c9157d92SDimitry Andric }
446c9157d92SDimitry Andric
eraseFromParent()447c9157d92SDimitry Andric void DPMarker::eraseFromParent() {
448c9157d92SDimitry Andric if (MarkedInstr)
449c9157d92SDimitry Andric removeFromParent();
450c9157d92SDimitry Andric dropDPValues();
451c9157d92SDimitry Andric delete this;
452c9157d92SDimitry Andric }
453c9157d92SDimitry Andric
getDbgValueRange()454c9157d92SDimitry Andric iterator_range<DPValue::self_iterator> DPMarker::getDbgValueRange() {
455c9157d92SDimitry Andric return make_range(StoredDPValues.begin(), StoredDPValues.end());
456c9157d92SDimitry Andric }
457*a58f00eaSDimitry Andric iterator_range<DPValue::const_self_iterator>
getDbgValueRange() const458*a58f00eaSDimitry Andric DPMarker::getDbgValueRange() const {
459*a58f00eaSDimitry Andric return make_range(StoredDPValues.begin(), StoredDPValues.end());
460*a58f00eaSDimitry Andric }
461c9157d92SDimitry Andric
removeFromParent()462c9157d92SDimitry Andric void DPValue::removeFromParent() {
463c9157d92SDimitry Andric getMarker()->StoredDPValues.erase(getIterator());
464*a58f00eaSDimitry Andric Marker = nullptr;
465c9157d92SDimitry Andric }
466c9157d92SDimitry Andric
eraseFromParent()467c9157d92SDimitry Andric void DPValue::eraseFromParent() {
468c9157d92SDimitry Andric removeFromParent();
469c9157d92SDimitry Andric deleteInstr();
470c9157d92SDimitry Andric }
471c9157d92SDimitry Andric
insertDPValue(DPValue * New,bool InsertAtHead)472c9157d92SDimitry Andric void DPMarker::insertDPValue(DPValue *New, bool InsertAtHead) {
473c9157d92SDimitry Andric auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end();
474c9157d92SDimitry Andric StoredDPValues.insert(It, *New);
475c9157d92SDimitry Andric New->setMarker(this);
476c9157d92SDimitry Andric }
insertDPValue(DPValue * New,DPValue * InsertBefore)477*a58f00eaSDimitry Andric void DPMarker::insertDPValue(DPValue *New, DPValue *InsertBefore) {
478*a58f00eaSDimitry Andric assert(InsertBefore->getMarker() == this &&
479*a58f00eaSDimitry Andric "DPValue 'InsertBefore' must be contained in this DPMarker!");
480*a58f00eaSDimitry Andric StoredDPValues.insert(InsertBefore->getIterator(), *New);
481*a58f00eaSDimitry Andric New->setMarker(this);
482*a58f00eaSDimitry Andric }
insertDPValueAfter(DPValue * New,DPValue * InsertAfter)483*a58f00eaSDimitry Andric void DPMarker::insertDPValueAfter(DPValue *New, DPValue *InsertAfter) {
484*a58f00eaSDimitry Andric assert(InsertAfter->getMarker() == this &&
485*a58f00eaSDimitry Andric "DPValue 'InsertAfter' must be contained in this DPMarker!");
486*a58f00eaSDimitry Andric StoredDPValues.insert(++(InsertAfter->getIterator()), *New);
487*a58f00eaSDimitry Andric New->setMarker(this);
488*a58f00eaSDimitry Andric }
489c9157d92SDimitry Andric
absorbDebugValues(DPMarker & Src,bool InsertAtHead)490c9157d92SDimitry Andric void DPMarker::absorbDebugValues(DPMarker &Src, bool InsertAtHead) {
491c9157d92SDimitry Andric auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end();
492c9157d92SDimitry Andric for (DPValue &DPV : Src.StoredDPValues)
493c9157d92SDimitry Andric DPV.setMarker(this);
494c9157d92SDimitry Andric
495c9157d92SDimitry Andric StoredDPValues.splice(It, Src.StoredDPValues);
496c9157d92SDimitry Andric }
497c9157d92SDimitry Andric
absorbDebugValues(iterator_range<DPValue::self_iterator> Range,DPMarker & Src,bool InsertAtHead)498c9157d92SDimitry Andric void DPMarker::absorbDebugValues(iterator_range<DPValue::self_iterator> Range,
499c9157d92SDimitry Andric DPMarker &Src, bool InsertAtHead) {
500c9157d92SDimitry Andric for (DPValue &DPV : Range)
501c9157d92SDimitry Andric DPV.setMarker(this);
502c9157d92SDimitry Andric
503c9157d92SDimitry Andric auto InsertPos =
504c9157d92SDimitry Andric (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end();
505c9157d92SDimitry Andric
506c9157d92SDimitry Andric StoredDPValues.splice(InsertPos, Src.StoredDPValues, Range.begin(),
507c9157d92SDimitry Andric Range.end());
508c9157d92SDimitry Andric }
509c9157d92SDimitry Andric
cloneDebugInfoFrom(DPMarker * From,std::optional<simple_ilist<DPValue>::iterator> from_here,bool InsertAtHead)510c9157d92SDimitry Andric iterator_range<simple_ilist<DPValue>::iterator> DPMarker::cloneDebugInfoFrom(
511c9157d92SDimitry Andric DPMarker *From, std::optional<simple_ilist<DPValue>::iterator> from_here,
512c9157d92SDimitry Andric bool InsertAtHead) {
513c9157d92SDimitry Andric DPValue *First = nullptr;
514c9157d92SDimitry Andric // Work out what range of DPValues to clone: normally all the contents of the
515c9157d92SDimitry Andric // "From" marker, optionally we can start from the from_here position down to
516c9157d92SDimitry Andric // end().
517c9157d92SDimitry Andric auto Range =
518c9157d92SDimitry Andric make_range(From->StoredDPValues.begin(), From->StoredDPValues.end());
519c9157d92SDimitry Andric if (from_here.has_value())
520c9157d92SDimitry Andric Range = make_range(*from_here, From->StoredDPValues.end());
521c9157d92SDimitry Andric
522c9157d92SDimitry Andric // Clone each DPValue and insert into StoreDPValues; optionally place them at
523c9157d92SDimitry Andric // the start or the end of the list.
524c9157d92SDimitry Andric auto Pos = (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end();
525c9157d92SDimitry Andric for (DPValue &DPV : Range) {
526c9157d92SDimitry Andric DPValue *New = DPV.clone();
527c9157d92SDimitry Andric New->setMarker(this);
528c9157d92SDimitry Andric StoredDPValues.insert(Pos, *New);
529c9157d92SDimitry Andric if (!First)
530c9157d92SDimitry Andric First = New;
531c9157d92SDimitry Andric }
532c9157d92SDimitry Andric
533c9157d92SDimitry Andric if (!First)
534c9157d92SDimitry Andric return {StoredDPValues.end(), StoredDPValues.end()};
535c9157d92SDimitry Andric
536c9157d92SDimitry Andric if (InsertAtHead)
537c9157d92SDimitry Andric // If InsertAtHead is set, we cloned a range onto the front of of the
538c9157d92SDimitry Andric // StoredDPValues collection, return that range.
539c9157d92SDimitry Andric return {StoredDPValues.begin(), Pos};
540c9157d92SDimitry Andric else
541c9157d92SDimitry Andric // We inserted a block at the end, return that range.
542c9157d92SDimitry Andric return {First->getIterator(), StoredDPValues.end()};
543c9157d92SDimitry Andric }
544c9157d92SDimitry Andric
545c9157d92SDimitry Andric } // end namespace llvm
546c9157d92SDimitry Andric
547