xref: /freebsd-src/contrib/llvm-project/llvm/lib/IR/DebugProgramInstruction.cpp (revision 7a6dacaca14b62ca4b74406814becb87a3fefac0)
15f757f3fSDimitry Andric //======-- DebugProgramInstruction.cpp - Implement DPValues/DPMarkers --======//
25f757f3fSDimitry Andric //
35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65f757f3fSDimitry Andric //
75f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
85f757f3fSDimitry Andric 
95f757f3fSDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
105f757f3fSDimitry Andric #include "llvm/IR/DebugProgramInstruction.h"
115f757f3fSDimitry Andric #include "llvm/IR/DIBuilder.h"
125f757f3fSDimitry Andric #include "llvm/IR/IntrinsicInst.h"
135f757f3fSDimitry Andric 
145f757f3fSDimitry Andric namespace llvm {
155f757f3fSDimitry Andric 
165f757f3fSDimitry Andric DPValue::DPValue(const DbgVariableIntrinsic *DVI)
17*7a6dacacSDimitry Andric     : DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}),
18*7a6dacacSDimitry Andric       Variable(DVI->getVariable()), Expression(DVI->getExpression()),
19*7a6dacacSDimitry Andric       DbgLoc(DVI->getDebugLoc()), AddressExpression(nullptr) {
205f757f3fSDimitry Andric   switch (DVI->getIntrinsicID()) {
215f757f3fSDimitry Andric   case Intrinsic::dbg_value:
225f757f3fSDimitry Andric     Type = LocationType::Value;
235f757f3fSDimitry Andric     break;
245f757f3fSDimitry Andric   case Intrinsic::dbg_declare:
255f757f3fSDimitry Andric     Type = LocationType::Declare;
265f757f3fSDimitry Andric     break;
27*7a6dacacSDimitry Andric   case Intrinsic::dbg_assign: {
28*7a6dacacSDimitry Andric     Type = LocationType::Assign;
29*7a6dacacSDimitry Andric     const DbgAssignIntrinsic *Assign =
30*7a6dacacSDimitry Andric         static_cast<const DbgAssignIntrinsic *>(DVI);
31*7a6dacacSDimitry Andric     resetDebugValue(1, Assign->getRawAddress());
32*7a6dacacSDimitry Andric     AddressExpression = Assign->getAddressExpression();
33*7a6dacacSDimitry Andric     setAssignId(Assign->getAssignID());
34*7a6dacacSDimitry Andric     break;
35*7a6dacacSDimitry Andric   }
365f757f3fSDimitry Andric   default:
375f757f3fSDimitry Andric     llvm_unreachable(
385f757f3fSDimitry Andric         "Trying to create a DPValue with an invalid intrinsic type!");
395f757f3fSDimitry Andric   }
405f757f3fSDimitry Andric }
415f757f3fSDimitry Andric 
425f757f3fSDimitry Andric DPValue::DPValue(const DPValue &DPV)
43*7a6dacacSDimitry Andric     : DebugValueUser(DPV.DebugValues), Variable(DPV.getVariable()),
44*7a6dacacSDimitry Andric       Expression(DPV.getExpression()), DbgLoc(DPV.getDebugLoc()),
45*7a6dacacSDimitry Andric       AddressExpression(DPV.AddressExpression), Type(DPV.getType()) {}
465f757f3fSDimitry Andric 
475f757f3fSDimitry Andric DPValue::DPValue(Metadata *Location, DILocalVariable *DV, DIExpression *Expr,
485f757f3fSDimitry Andric                  const DILocation *DI, LocationType Type)
49*7a6dacacSDimitry Andric     : DebugValueUser({Location, nullptr, nullptr}), Variable(DV),
50*7a6dacacSDimitry Andric       Expression(Expr), DbgLoc(DI), Type(Type) {}
51*7a6dacacSDimitry Andric 
52*7a6dacacSDimitry Andric DPValue::DPValue(Metadata *Value, DILocalVariable *Variable,
53*7a6dacacSDimitry Andric                  DIExpression *Expression, DIAssignID *AssignID,
54*7a6dacacSDimitry Andric                  Metadata *Address, DIExpression *AddressExpression,
55*7a6dacacSDimitry Andric                  const DILocation *DI)
56*7a6dacacSDimitry Andric     : DebugValueUser({Value, Address, AssignID}), Variable(Variable),
57*7a6dacacSDimitry Andric       Expression(Expression), DbgLoc(DI), AddressExpression(AddressExpression),
58*7a6dacacSDimitry Andric       Type(LocationType::Assign) {}
595f757f3fSDimitry Andric 
605f757f3fSDimitry Andric void DPValue::deleteInstr() { delete this; }
615f757f3fSDimitry Andric 
62*7a6dacacSDimitry Andric DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV,
63*7a6dacacSDimitry Andric                                 DIExpression *Expr, const DILocation *DI) {
64*7a6dacacSDimitry Andric   return new DPValue(ValueAsMetadata::get(Location), DV, Expr, DI,
65*7a6dacacSDimitry Andric                      LocationType::Value);
66*7a6dacacSDimitry Andric }
67*7a6dacacSDimitry Andric 
68*7a6dacacSDimitry Andric DPValue *DPValue::createDPValue(Value *Location, DILocalVariable *DV,
69*7a6dacacSDimitry Andric                                 DIExpression *Expr, const DILocation *DI,
70*7a6dacacSDimitry Andric                                 DPValue &InsertBefore) {
71*7a6dacacSDimitry Andric   auto *NewDPValue = createDPValue(Location, DV, Expr, DI);
72*7a6dacacSDimitry Andric   NewDPValue->insertBefore(&InsertBefore);
73*7a6dacacSDimitry Andric   return NewDPValue;
74*7a6dacacSDimitry Andric }
75*7a6dacacSDimitry Andric 
76*7a6dacacSDimitry Andric DPValue *DPValue::createDPVDeclare(Value *Address, DILocalVariable *DV,
77*7a6dacacSDimitry Andric                                    DIExpression *Expr, const DILocation *DI) {
78*7a6dacacSDimitry Andric   return new DPValue(ValueAsMetadata::get(Address), DV, Expr, DI,
79*7a6dacacSDimitry Andric                      LocationType::Declare);
80*7a6dacacSDimitry Andric }
81*7a6dacacSDimitry Andric 
82*7a6dacacSDimitry Andric DPValue *DPValue::createDPVDeclare(Value *Address, DILocalVariable *DV,
83*7a6dacacSDimitry Andric                                    DIExpression *Expr, const DILocation *DI,
84*7a6dacacSDimitry Andric                                    DPValue &InsertBefore) {
85*7a6dacacSDimitry Andric   auto *NewDPVDeclare = createDPVDeclare(Address, DV, Expr, DI);
86*7a6dacacSDimitry Andric   NewDPVDeclare->insertBefore(&InsertBefore);
87*7a6dacacSDimitry Andric   return NewDPVDeclare;
88*7a6dacacSDimitry Andric }
89*7a6dacacSDimitry Andric 
90*7a6dacacSDimitry Andric DPValue *DPValue::createDPVAssign(Value *Val, DILocalVariable *Variable,
91*7a6dacacSDimitry Andric                                   DIExpression *Expression,
92*7a6dacacSDimitry Andric                                   DIAssignID *AssignID, Value *Address,
93*7a6dacacSDimitry Andric                                   DIExpression *AddressExpression,
94*7a6dacacSDimitry Andric                                   const DILocation *DI) {
95*7a6dacacSDimitry Andric   return new DPValue(ValueAsMetadata::get(Val), Variable, Expression, AssignID,
96*7a6dacacSDimitry Andric                      ValueAsMetadata::get(Address), AddressExpression, DI);
97*7a6dacacSDimitry Andric }
98*7a6dacacSDimitry Andric 
99*7a6dacacSDimitry Andric DPValue *DPValue::createLinkedDPVAssign(Instruction *LinkedInstr, Value *Val,
100*7a6dacacSDimitry Andric                                         DILocalVariable *Variable,
101*7a6dacacSDimitry Andric                                         DIExpression *Expression,
102*7a6dacacSDimitry Andric                                         Value *Address,
103*7a6dacacSDimitry Andric                                         DIExpression *AddressExpression,
104*7a6dacacSDimitry Andric                                         const DILocation *DI) {
105*7a6dacacSDimitry Andric   auto *Link = LinkedInstr->getMetadata(LLVMContext::MD_DIAssignID);
106*7a6dacacSDimitry Andric   assert(Link && "Linked instruction must have DIAssign metadata attached");
107*7a6dacacSDimitry Andric   auto *NewDPVAssign = DPValue::createDPVAssign(Val, Variable, Expression,
108*7a6dacacSDimitry Andric                                                 cast<DIAssignID>(Link), Address,
109*7a6dacacSDimitry Andric                                                 AddressExpression, DI);
110*7a6dacacSDimitry Andric   LinkedInstr->getParent()->insertDPValueAfter(NewDPVAssign, LinkedInstr);
111*7a6dacacSDimitry Andric   return NewDPVAssign;
112*7a6dacacSDimitry Andric }
113*7a6dacacSDimitry Andric 
1145f757f3fSDimitry Andric iterator_range<DPValue::location_op_iterator> DPValue::location_ops() const {
1155f757f3fSDimitry Andric   auto *MD = getRawLocation();
1165f757f3fSDimitry Andric   // If a Value has been deleted, the "location" for this DPValue will be
1175f757f3fSDimitry Andric   // replaced by nullptr. Return an empty range.
1185f757f3fSDimitry Andric   if (!MD)
1195f757f3fSDimitry Andric     return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
1205f757f3fSDimitry Andric             location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
1215f757f3fSDimitry Andric 
1225f757f3fSDimitry Andric   // If operand is ValueAsMetadata, return a range over just that operand.
1235f757f3fSDimitry Andric   if (auto *VAM = dyn_cast<ValueAsMetadata>(MD))
1245f757f3fSDimitry Andric     return {location_op_iterator(VAM), location_op_iterator(VAM + 1)};
1255f757f3fSDimitry Andric 
1265f757f3fSDimitry Andric   // If operand is DIArgList, return a range over its args.
1275f757f3fSDimitry Andric   if (auto *AL = dyn_cast<DIArgList>(MD))
1285f757f3fSDimitry Andric     return {location_op_iterator(AL->args_begin()),
1295f757f3fSDimitry Andric             location_op_iterator(AL->args_end())};
1305f757f3fSDimitry Andric 
1315f757f3fSDimitry Andric   // Operand is an empty metadata tuple, so return empty iterator.
1325f757f3fSDimitry Andric   assert(cast<MDNode>(MD)->getNumOperands() == 0);
1335f757f3fSDimitry Andric   return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
1345f757f3fSDimitry Andric           location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
1355f757f3fSDimitry Andric }
1365f757f3fSDimitry Andric 
1375f757f3fSDimitry Andric unsigned DPValue::getNumVariableLocationOps() const {
1385f757f3fSDimitry Andric   if (hasArgList())
1395f757f3fSDimitry Andric     return cast<DIArgList>(getRawLocation())->getArgs().size();
1405f757f3fSDimitry Andric   return 1;
1415f757f3fSDimitry Andric }
1425f757f3fSDimitry Andric 
1435f757f3fSDimitry Andric Value *DPValue::getVariableLocationOp(unsigned OpIdx) const {
1445f757f3fSDimitry Andric   auto *MD = getRawLocation();
1455f757f3fSDimitry Andric   if (!MD)
1465f757f3fSDimitry Andric     return nullptr;
1475f757f3fSDimitry Andric 
1485f757f3fSDimitry Andric   if (auto *AL = dyn_cast<DIArgList>(MD))
1495f757f3fSDimitry Andric     return AL->getArgs()[OpIdx]->getValue();
1505f757f3fSDimitry Andric   if (isa<MDNode>(MD))
1515f757f3fSDimitry Andric     return nullptr;
1525f757f3fSDimitry Andric   assert(isa<ValueAsMetadata>(MD) &&
1535f757f3fSDimitry Andric          "Attempted to get location operand from DPValue with none.");
1545f757f3fSDimitry Andric   auto *V = cast<ValueAsMetadata>(MD);
1555f757f3fSDimitry Andric   assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a "
1565f757f3fSDimitry Andric                        "single location operand.");
1575f757f3fSDimitry Andric   return V->getValue();
1585f757f3fSDimitry Andric }
1595f757f3fSDimitry Andric 
1605f757f3fSDimitry Andric static ValueAsMetadata *getAsMetadata(Value *V) {
1615f757f3fSDimitry Andric   return isa<MetadataAsValue>(V) ? dyn_cast<ValueAsMetadata>(
1625f757f3fSDimitry Andric                                        cast<MetadataAsValue>(V)->getMetadata())
1635f757f3fSDimitry Andric                                  : ValueAsMetadata::get(V);
1645f757f3fSDimitry Andric }
1655f757f3fSDimitry Andric 
1665f757f3fSDimitry Andric void DPValue::replaceVariableLocationOp(Value *OldValue, Value *NewValue,
1675f757f3fSDimitry Andric                                         bool AllowEmpty) {
1685f757f3fSDimitry Andric   assert(NewValue && "Values must be non-null");
169*7a6dacacSDimitry Andric 
170*7a6dacacSDimitry Andric   bool DbgAssignAddrReplaced = isDbgAssign() && OldValue == getAddress();
171*7a6dacacSDimitry Andric   if (DbgAssignAddrReplaced)
172*7a6dacacSDimitry Andric     setAddress(NewValue);
173*7a6dacacSDimitry Andric 
1745f757f3fSDimitry Andric   auto Locations = location_ops();
1755f757f3fSDimitry Andric   auto OldIt = find(Locations, OldValue);
1765f757f3fSDimitry Andric   if (OldIt == Locations.end()) {
177*7a6dacacSDimitry Andric     if (AllowEmpty || DbgAssignAddrReplaced)
1785f757f3fSDimitry Andric       return;
1795f757f3fSDimitry Andric     llvm_unreachable("OldValue must be a current location");
1805f757f3fSDimitry Andric   }
1815f757f3fSDimitry Andric 
1825f757f3fSDimitry Andric   if (!hasArgList()) {
1835f757f3fSDimitry Andric     // Set our location to be the MAV wrapping the new Value.
1845f757f3fSDimitry Andric     setRawLocation(isa<MetadataAsValue>(NewValue)
1855f757f3fSDimitry Andric                        ? cast<MetadataAsValue>(NewValue)->getMetadata()
1865f757f3fSDimitry Andric                        : ValueAsMetadata::get(NewValue));
1875f757f3fSDimitry Andric     return;
1885f757f3fSDimitry Andric   }
1895f757f3fSDimitry Andric 
1905f757f3fSDimitry Andric   // We must be referring to a DIArgList, produce a new operands vector with the
1915f757f3fSDimitry Andric   // old value replaced, generate a new DIArgList and set it as our location.
1925f757f3fSDimitry Andric   SmallVector<ValueAsMetadata *, 4> MDs;
1935f757f3fSDimitry Andric   ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
1945f757f3fSDimitry Andric   for (auto *VMD : Locations)
1955f757f3fSDimitry Andric     MDs.push_back(VMD == *OldIt ? NewOperand : getAsMetadata(VMD));
1965f757f3fSDimitry Andric   setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
1975f757f3fSDimitry Andric }
1985f757f3fSDimitry Andric 
1995f757f3fSDimitry Andric void DPValue::replaceVariableLocationOp(unsigned OpIdx, Value *NewValue) {
2005f757f3fSDimitry Andric   assert(OpIdx < getNumVariableLocationOps() && "Invalid Operand Index");
2015f757f3fSDimitry Andric 
2025f757f3fSDimitry Andric   if (!hasArgList()) {
2035f757f3fSDimitry Andric     setRawLocation(isa<MetadataAsValue>(NewValue)
2045f757f3fSDimitry Andric                        ? cast<MetadataAsValue>(NewValue)->getMetadata()
2055f757f3fSDimitry Andric                        : ValueAsMetadata::get(NewValue));
2065f757f3fSDimitry Andric     return;
2075f757f3fSDimitry Andric   }
2085f757f3fSDimitry Andric 
2095f757f3fSDimitry Andric   SmallVector<ValueAsMetadata *, 4> MDs;
2105f757f3fSDimitry Andric   ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
2115f757f3fSDimitry Andric   for (unsigned Idx = 0; Idx < getNumVariableLocationOps(); ++Idx)
2125f757f3fSDimitry Andric     MDs.push_back(Idx == OpIdx ? NewOperand
2135f757f3fSDimitry Andric                                : getAsMetadata(getVariableLocationOp(Idx)));
2145f757f3fSDimitry Andric 
2155f757f3fSDimitry Andric   setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
2165f757f3fSDimitry Andric }
2175f757f3fSDimitry Andric 
2185f757f3fSDimitry Andric void DPValue::addVariableLocationOps(ArrayRef<Value *> NewValues,
2195f757f3fSDimitry Andric                                      DIExpression *NewExpr) {
2205f757f3fSDimitry Andric   assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() +
2215f757f3fSDimitry Andric                                     NewValues.size()) &&
2225f757f3fSDimitry Andric          "NewExpr for debug variable intrinsic does not reference every "
2235f757f3fSDimitry Andric          "location operand.");
2245f757f3fSDimitry Andric   assert(!is_contained(NewValues, nullptr) && "New values must be non-null");
2255f757f3fSDimitry Andric   setExpression(NewExpr);
2265f757f3fSDimitry Andric   SmallVector<ValueAsMetadata *, 4> MDs;
2275f757f3fSDimitry Andric   for (auto *VMD : location_ops())
2285f757f3fSDimitry Andric     MDs.push_back(getAsMetadata(VMD));
2295f757f3fSDimitry Andric   for (auto *VMD : NewValues)
2305f757f3fSDimitry Andric     MDs.push_back(getAsMetadata(VMD));
2315f757f3fSDimitry Andric   setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));
2325f757f3fSDimitry Andric }
2335f757f3fSDimitry Andric 
2345f757f3fSDimitry Andric void DPValue::setKillLocation() {
2355f757f3fSDimitry Andric   // TODO: When/if we remove duplicate values from DIArgLists, we don't need
2365f757f3fSDimitry Andric   // this set anymore.
2375f757f3fSDimitry Andric   SmallPtrSet<Value *, 4> RemovedValues;
2385f757f3fSDimitry Andric   for (Value *OldValue : location_ops()) {
2395f757f3fSDimitry Andric     if (!RemovedValues.insert(OldValue).second)
2405f757f3fSDimitry Andric       continue;
2415f757f3fSDimitry Andric     Value *Poison = PoisonValue::get(OldValue->getType());
2425f757f3fSDimitry Andric     replaceVariableLocationOp(OldValue, Poison);
2435f757f3fSDimitry Andric   }
2445f757f3fSDimitry Andric }
2455f757f3fSDimitry Andric 
2465f757f3fSDimitry Andric bool DPValue::isKillLocation() const {
2475f757f3fSDimitry Andric   return (getNumVariableLocationOps() == 0 &&
2485f757f3fSDimitry Andric           !getExpression()->isComplex()) ||
2495f757f3fSDimitry Andric          any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); });
2505f757f3fSDimitry Andric }
2515f757f3fSDimitry Andric 
2525f757f3fSDimitry Andric std::optional<uint64_t> DPValue::getFragmentSizeInBits() const {
2535f757f3fSDimitry Andric   if (auto Fragment = getExpression()->getFragmentInfo())
2545f757f3fSDimitry Andric     return Fragment->SizeInBits;
2555f757f3fSDimitry Andric   return getVariable()->getSizeInBits();
2565f757f3fSDimitry Andric }
2575f757f3fSDimitry Andric 
2585f757f3fSDimitry Andric DPValue *DPValue::clone() const { return new DPValue(*this); }
2595f757f3fSDimitry Andric 
2605f757f3fSDimitry Andric DbgVariableIntrinsic *
2615f757f3fSDimitry Andric DPValue::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {
2625f757f3fSDimitry Andric   [[maybe_unused]] DICompileUnit *Unit =
2635f757f3fSDimitry Andric       getDebugLoc().get()->getScope()->getSubprogram()->getUnit();
2645f757f3fSDimitry Andric   assert(M && Unit &&
2655f757f3fSDimitry Andric          "Cannot clone from BasicBlock that is not part of a Module or "
2665f757f3fSDimitry Andric          "DICompileUnit!");
2675f757f3fSDimitry Andric   LLVMContext &Context = getDebugLoc()->getContext();
2685f757f3fSDimitry Andric   Function *IntrinsicFn;
2695f757f3fSDimitry Andric 
2705f757f3fSDimitry Andric   // Work out what sort of intrinsic we're going to produce.
2715f757f3fSDimitry Andric   switch (getType()) {
2725f757f3fSDimitry Andric   case DPValue::LocationType::Declare:
2735f757f3fSDimitry Andric     IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_declare);
2745f757f3fSDimitry Andric     break;
2755f757f3fSDimitry Andric   case DPValue::LocationType::Value:
2765f757f3fSDimitry Andric     IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_value);
2775f757f3fSDimitry Andric     break;
278*7a6dacacSDimitry Andric   case DPValue::LocationType::Assign:
279*7a6dacacSDimitry Andric     IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_assign);
280*7a6dacacSDimitry Andric     break;
2815f757f3fSDimitry Andric   case DPValue::LocationType::End:
2825f757f3fSDimitry Andric   case DPValue::LocationType::Any:
2835f757f3fSDimitry Andric     llvm_unreachable("Invalid LocationType");
2845f757f3fSDimitry Andric   }
2855f757f3fSDimitry Andric 
2865f757f3fSDimitry Andric   // Create the intrinsic from this DPValue's information, optionally insert
2875f757f3fSDimitry Andric   // into the target location.
288*7a6dacacSDimitry Andric   DbgVariableIntrinsic *DVI;
289*7a6dacacSDimitry Andric   if (isDbgAssign()) {
290*7a6dacacSDimitry Andric     Value *AssignArgs[] = {
291*7a6dacacSDimitry Andric         MetadataAsValue::get(Context, getRawLocation()),
292*7a6dacacSDimitry Andric         MetadataAsValue::get(Context, getVariable()),
293*7a6dacacSDimitry Andric         MetadataAsValue::get(Context, getExpression()),
294*7a6dacacSDimitry Andric         MetadataAsValue::get(Context, getAssignID()),
295*7a6dacacSDimitry Andric         MetadataAsValue::get(Context, getRawAddress()),
296*7a6dacacSDimitry Andric         MetadataAsValue::get(Context, getAddressExpression())};
297*7a6dacacSDimitry Andric     DVI = cast<DbgVariableIntrinsic>(CallInst::Create(
298*7a6dacacSDimitry Andric         IntrinsicFn->getFunctionType(), IntrinsicFn, AssignArgs));
299*7a6dacacSDimitry Andric   } else {
300*7a6dacacSDimitry Andric     Value *Args[] = {MetadataAsValue::get(Context, getRawLocation()),
301*7a6dacacSDimitry Andric                      MetadataAsValue::get(Context, getVariable()),
302*7a6dacacSDimitry Andric                      MetadataAsValue::get(Context, getExpression())};
303*7a6dacacSDimitry Andric     DVI = cast<DbgVariableIntrinsic>(
3045f757f3fSDimitry Andric         CallInst::Create(IntrinsicFn->getFunctionType(), IntrinsicFn, Args));
305*7a6dacacSDimitry Andric   }
3065f757f3fSDimitry Andric   DVI->setTailCall();
3075f757f3fSDimitry Andric   DVI->setDebugLoc(getDebugLoc());
3085f757f3fSDimitry Andric   if (InsertBefore)
3095f757f3fSDimitry Andric     DVI->insertBefore(InsertBefore);
3105f757f3fSDimitry Andric 
3115f757f3fSDimitry Andric   return DVI;
3125f757f3fSDimitry Andric }
3135f757f3fSDimitry Andric 
314*7a6dacacSDimitry Andric Value *DPValue::getAddress() const {
315*7a6dacacSDimitry Andric   auto *MD = getRawAddress();
316*7a6dacacSDimitry Andric   if (auto *V = dyn_cast<ValueAsMetadata>(MD))
317*7a6dacacSDimitry Andric     return V->getValue();
318*7a6dacacSDimitry Andric 
319*7a6dacacSDimitry Andric   // When the value goes to null, it gets replaced by an empty MDNode.
320*7a6dacacSDimitry Andric   assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");
321*7a6dacacSDimitry Andric   return nullptr;
322*7a6dacacSDimitry Andric }
323*7a6dacacSDimitry Andric 
324*7a6dacacSDimitry Andric DIAssignID *DPValue::getAssignID() const {
325*7a6dacacSDimitry Andric   return cast<DIAssignID>(DebugValues[2]);
326*7a6dacacSDimitry Andric }
327*7a6dacacSDimitry Andric 
328*7a6dacacSDimitry Andric void DPValue::setAssignId(DIAssignID *New) { resetDebugValue(2, New); }
329*7a6dacacSDimitry Andric 
330*7a6dacacSDimitry Andric void DPValue::setKillAddress() {
331*7a6dacacSDimitry Andric   resetDebugValue(
332*7a6dacacSDimitry Andric       1, ValueAsMetadata::get(UndefValue::get(getAddress()->getType())));
333*7a6dacacSDimitry Andric }
334*7a6dacacSDimitry Andric 
335*7a6dacacSDimitry Andric bool DPValue::isKillAddress() const {
336*7a6dacacSDimitry Andric   Value *Addr = getAddress();
337*7a6dacacSDimitry Andric   return !Addr || isa<UndefValue>(Addr);
3385f757f3fSDimitry Andric }
3395f757f3fSDimitry Andric 
3405f757f3fSDimitry Andric const BasicBlock *DPValue::getParent() const {
3415f757f3fSDimitry Andric   return Marker->MarkedInstr->getParent();
3425f757f3fSDimitry Andric }
3435f757f3fSDimitry Andric 
3445f757f3fSDimitry Andric BasicBlock *DPValue::getParent() { return Marker->MarkedInstr->getParent(); }
3455f757f3fSDimitry Andric 
3465f757f3fSDimitry Andric BasicBlock *DPValue::getBlock() { return Marker->getParent(); }
3475f757f3fSDimitry Andric 
3485f757f3fSDimitry Andric const BasicBlock *DPValue::getBlock() const { return Marker->getParent(); }
3495f757f3fSDimitry Andric 
3505f757f3fSDimitry Andric Function *DPValue::getFunction() { return getBlock()->getParent(); }
3515f757f3fSDimitry Andric 
3525f757f3fSDimitry Andric const Function *DPValue::getFunction() const { return getBlock()->getParent(); }
3535f757f3fSDimitry Andric 
3545f757f3fSDimitry Andric Module *DPValue::getModule() { return getFunction()->getParent(); }
3555f757f3fSDimitry Andric 
3565f757f3fSDimitry Andric const Module *DPValue::getModule() const { return getFunction()->getParent(); }
3575f757f3fSDimitry Andric 
3585f757f3fSDimitry Andric LLVMContext &DPValue::getContext() { return getBlock()->getContext(); }
3595f757f3fSDimitry Andric 
3605f757f3fSDimitry Andric const LLVMContext &DPValue::getContext() const {
3615f757f3fSDimitry Andric   return getBlock()->getContext();
3625f757f3fSDimitry Andric }
3635f757f3fSDimitry Andric 
364*7a6dacacSDimitry Andric void DPValue::insertBefore(DPValue *InsertBefore) {
365*7a6dacacSDimitry Andric   assert(!getMarker() &&
366*7a6dacacSDimitry Andric          "Cannot insert a DPValue that is already has a DPMarker!");
367*7a6dacacSDimitry Andric   assert(InsertBefore->getMarker() &&
368*7a6dacacSDimitry Andric          "Cannot insert a DPValue before a DPValue that does not have a "
369*7a6dacacSDimitry Andric          "DPMarker!");
370*7a6dacacSDimitry Andric   InsertBefore->getMarker()->insertDPValue(this, InsertBefore);
371*7a6dacacSDimitry Andric }
372*7a6dacacSDimitry Andric void DPValue::insertAfter(DPValue *InsertAfter) {
373*7a6dacacSDimitry Andric   assert(!getMarker() &&
374*7a6dacacSDimitry Andric          "Cannot insert a DPValue that is already has a DPMarker!");
375*7a6dacacSDimitry Andric   assert(InsertAfter->getMarker() &&
376*7a6dacacSDimitry Andric          "Cannot insert a DPValue after a DPValue that does not have a "
377*7a6dacacSDimitry Andric          "DPMarker!");
378*7a6dacacSDimitry Andric   InsertAfter->getMarker()->insertDPValueAfter(this, InsertAfter);
379*7a6dacacSDimitry Andric }
380*7a6dacacSDimitry Andric void DPValue::moveBefore(DPValue *MoveBefore) {
381*7a6dacacSDimitry Andric   assert(getMarker() &&
382*7a6dacacSDimitry Andric          "Canot move a DPValue that does not currently have a DPMarker!");
383*7a6dacacSDimitry Andric   removeFromParent();
384*7a6dacacSDimitry Andric   insertBefore(MoveBefore);
385*7a6dacacSDimitry Andric }
386*7a6dacacSDimitry Andric void DPValue::moveAfter(DPValue *MoveAfter) {
387*7a6dacacSDimitry Andric   assert(getMarker() &&
388*7a6dacacSDimitry Andric          "Canot move a DPValue that does not currently have a DPMarker!");
389*7a6dacacSDimitry Andric   removeFromParent();
390*7a6dacacSDimitry Andric   insertAfter(MoveAfter);
391*7a6dacacSDimitry Andric }
392*7a6dacacSDimitry Andric 
3935f757f3fSDimitry Andric ///////////////////////////////////////////////////////////////////////////////
3945f757f3fSDimitry Andric 
3955f757f3fSDimitry Andric // An empty, global, DPMarker for the purpose of describing empty ranges of
3965f757f3fSDimitry Andric // DPValues.
3975f757f3fSDimitry Andric DPMarker DPMarker::EmptyDPMarker;
3985f757f3fSDimitry Andric 
3995f757f3fSDimitry Andric void DPMarker::dropDPValues() {
4005f757f3fSDimitry Andric   while (!StoredDPValues.empty()) {
4015f757f3fSDimitry Andric     auto It = StoredDPValues.begin();
4025f757f3fSDimitry Andric     DPValue *DPV = &*It;
4035f757f3fSDimitry Andric     StoredDPValues.erase(It);
4045f757f3fSDimitry Andric     DPV->deleteInstr();
4055f757f3fSDimitry Andric   }
4065f757f3fSDimitry Andric }
4075f757f3fSDimitry Andric 
4085f757f3fSDimitry Andric void DPMarker::dropOneDPValue(DPValue *DPV) {
4095f757f3fSDimitry Andric   assert(DPV->getMarker() == this);
4105f757f3fSDimitry Andric   StoredDPValues.erase(DPV->getIterator());
4115f757f3fSDimitry Andric   DPV->deleteInstr();
4125f757f3fSDimitry Andric }
4135f757f3fSDimitry Andric 
4145f757f3fSDimitry Andric const BasicBlock *DPMarker::getParent() const {
4155f757f3fSDimitry Andric   return MarkedInstr->getParent();
4165f757f3fSDimitry Andric }
4175f757f3fSDimitry Andric 
4185f757f3fSDimitry Andric BasicBlock *DPMarker::getParent() { return MarkedInstr->getParent(); }
4195f757f3fSDimitry Andric 
4205f757f3fSDimitry Andric void DPMarker::removeMarker() {
4215f757f3fSDimitry Andric   // Are there any DPValues in this DPMarker? If not, nothing to preserve.
4225f757f3fSDimitry Andric   Instruction *Owner = MarkedInstr;
4235f757f3fSDimitry Andric   if (StoredDPValues.empty()) {
4245f757f3fSDimitry Andric     eraseFromParent();
4255f757f3fSDimitry Andric     Owner->DbgMarker = nullptr;
4265f757f3fSDimitry Andric     return;
4275f757f3fSDimitry Andric   }
4285f757f3fSDimitry Andric 
4295f757f3fSDimitry Andric   // The attached DPValues need to be preserved; attach them to the next
4305f757f3fSDimitry Andric   // instruction. If there isn't a next instruction, put them on the
4315f757f3fSDimitry Andric   // "trailing" list.
4325f757f3fSDimitry Andric   DPMarker *NextMarker = Owner->getParent()->getNextMarker(Owner);
4335f757f3fSDimitry Andric   if (NextMarker == nullptr) {
4345f757f3fSDimitry Andric     NextMarker = new DPMarker();
4355f757f3fSDimitry Andric     Owner->getParent()->setTrailingDPValues(NextMarker);
4365f757f3fSDimitry Andric   }
4375f757f3fSDimitry Andric   NextMarker->absorbDebugValues(*this, true);
4385f757f3fSDimitry Andric 
4395f757f3fSDimitry Andric   eraseFromParent();
4405f757f3fSDimitry Andric }
4415f757f3fSDimitry Andric 
4425f757f3fSDimitry Andric void DPMarker::removeFromParent() {
4435f757f3fSDimitry Andric   MarkedInstr->DbgMarker = nullptr;
4445f757f3fSDimitry Andric   MarkedInstr = nullptr;
4455f757f3fSDimitry Andric }
4465f757f3fSDimitry Andric 
4475f757f3fSDimitry Andric void DPMarker::eraseFromParent() {
4485f757f3fSDimitry Andric   if (MarkedInstr)
4495f757f3fSDimitry Andric     removeFromParent();
4505f757f3fSDimitry Andric   dropDPValues();
4515f757f3fSDimitry Andric   delete this;
4525f757f3fSDimitry Andric }
4535f757f3fSDimitry Andric 
4545f757f3fSDimitry Andric iterator_range<DPValue::self_iterator> DPMarker::getDbgValueRange() {
4555f757f3fSDimitry Andric   return make_range(StoredDPValues.begin(), StoredDPValues.end());
4565f757f3fSDimitry Andric }
457*7a6dacacSDimitry Andric iterator_range<DPValue::const_self_iterator>
458*7a6dacacSDimitry Andric DPMarker::getDbgValueRange() const {
459*7a6dacacSDimitry Andric   return make_range(StoredDPValues.begin(), StoredDPValues.end());
460*7a6dacacSDimitry Andric }
4615f757f3fSDimitry Andric 
4625f757f3fSDimitry Andric void DPValue::removeFromParent() {
4635f757f3fSDimitry Andric   getMarker()->StoredDPValues.erase(getIterator());
464*7a6dacacSDimitry Andric   Marker = nullptr;
4655f757f3fSDimitry Andric }
4665f757f3fSDimitry Andric 
4675f757f3fSDimitry Andric void DPValue::eraseFromParent() {
4685f757f3fSDimitry Andric   removeFromParent();
4695f757f3fSDimitry Andric   deleteInstr();
4705f757f3fSDimitry Andric }
4715f757f3fSDimitry Andric 
4725f757f3fSDimitry Andric void DPMarker::insertDPValue(DPValue *New, bool InsertAtHead) {
4735f757f3fSDimitry Andric   auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end();
4745f757f3fSDimitry Andric   StoredDPValues.insert(It, *New);
4755f757f3fSDimitry Andric   New->setMarker(this);
4765f757f3fSDimitry Andric }
477*7a6dacacSDimitry Andric void DPMarker::insertDPValue(DPValue *New, DPValue *InsertBefore) {
478*7a6dacacSDimitry Andric   assert(InsertBefore->getMarker() == this &&
479*7a6dacacSDimitry Andric          "DPValue 'InsertBefore' must be contained in this DPMarker!");
480*7a6dacacSDimitry Andric   StoredDPValues.insert(InsertBefore->getIterator(), *New);
481*7a6dacacSDimitry Andric   New->setMarker(this);
482*7a6dacacSDimitry Andric }
483*7a6dacacSDimitry Andric void DPMarker::insertDPValueAfter(DPValue *New, DPValue *InsertAfter) {
484*7a6dacacSDimitry Andric   assert(InsertAfter->getMarker() == this &&
485*7a6dacacSDimitry Andric          "DPValue 'InsertAfter' must be contained in this DPMarker!");
486*7a6dacacSDimitry Andric   StoredDPValues.insert(++(InsertAfter->getIterator()), *New);
487*7a6dacacSDimitry Andric   New->setMarker(this);
488*7a6dacacSDimitry Andric }
4895f757f3fSDimitry Andric 
4905f757f3fSDimitry Andric void DPMarker::absorbDebugValues(DPMarker &Src, bool InsertAtHead) {
4915f757f3fSDimitry Andric   auto It = InsertAtHead ? StoredDPValues.begin() : StoredDPValues.end();
4925f757f3fSDimitry Andric   for (DPValue &DPV : Src.StoredDPValues)
4935f757f3fSDimitry Andric     DPV.setMarker(this);
4945f757f3fSDimitry Andric 
4955f757f3fSDimitry Andric   StoredDPValues.splice(It, Src.StoredDPValues);
4965f757f3fSDimitry Andric }
4975f757f3fSDimitry Andric 
4985f757f3fSDimitry Andric void DPMarker::absorbDebugValues(iterator_range<DPValue::self_iterator> Range,
4995f757f3fSDimitry Andric                                  DPMarker &Src, bool InsertAtHead) {
5005f757f3fSDimitry Andric   for (DPValue &DPV : Range)
5015f757f3fSDimitry Andric     DPV.setMarker(this);
5025f757f3fSDimitry Andric 
5035f757f3fSDimitry Andric   auto InsertPos =
5045f757f3fSDimitry Andric       (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end();
5055f757f3fSDimitry Andric 
5065f757f3fSDimitry Andric   StoredDPValues.splice(InsertPos, Src.StoredDPValues, Range.begin(),
5075f757f3fSDimitry Andric                         Range.end());
5085f757f3fSDimitry Andric }
5095f757f3fSDimitry Andric 
5105f757f3fSDimitry Andric iterator_range<simple_ilist<DPValue>::iterator> DPMarker::cloneDebugInfoFrom(
5115f757f3fSDimitry Andric     DPMarker *From, std::optional<simple_ilist<DPValue>::iterator> from_here,
5125f757f3fSDimitry Andric     bool InsertAtHead) {
5135f757f3fSDimitry Andric   DPValue *First = nullptr;
5145f757f3fSDimitry Andric   // Work out what range of DPValues to clone: normally all the contents of the
5155f757f3fSDimitry Andric   // "From" marker, optionally we can start from the from_here position down to
5165f757f3fSDimitry Andric   // end().
5175f757f3fSDimitry Andric   auto Range =
5185f757f3fSDimitry Andric       make_range(From->StoredDPValues.begin(), From->StoredDPValues.end());
5195f757f3fSDimitry Andric   if (from_here.has_value())
5205f757f3fSDimitry Andric     Range = make_range(*from_here, From->StoredDPValues.end());
5215f757f3fSDimitry Andric 
5225f757f3fSDimitry Andric   // Clone each DPValue and insert into StoreDPValues; optionally place them at
5235f757f3fSDimitry Andric   // the start or the end of the list.
5245f757f3fSDimitry Andric   auto Pos = (InsertAtHead) ? StoredDPValues.begin() : StoredDPValues.end();
5255f757f3fSDimitry Andric   for (DPValue &DPV : Range) {
5265f757f3fSDimitry Andric     DPValue *New = DPV.clone();
5275f757f3fSDimitry Andric     New->setMarker(this);
5285f757f3fSDimitry Andric     StoredDPValues.insert(Pos, *New);
5295f757f3fSDimitry Andric     if (!First)
5305f757f3fSDimitry Andric       First = New;
5315f757f3fSDimitry Andric   }
5325f757f3fSDimitry Andric 
5335f757f3fSDimitry Andric   if (!First)
5345f757f3fSDimitry Andric     return {StoredDPValues.end(), StoredDPValues.end()};
5355f757f3fSDimitry Andric 
5365f757f3fSDimitry Andric   if (InsertAtHead)
5375f757f3fSDimitry Andric     // If InsertAtHead is set, we cloned a range onto the front of of the
5385f757f3fSDimitry Andric     // StoredDPValues collection, return that range.
5395f757f3fSDimitry Andric     return {StoredDPValues.begin(), Pos};
5405f757f3fSDimitry Andric   else
5415f757f3fSDimitry Andric     // We inserted a block at the end, return that range.
5425f757f3fSDimitry Andric     return {First->getIterator(), StoredDPValues.end()};
5435f757f3fSDimitry Andric }
5445f757f3fSDimitry Andric 
5455f757f3fSDimitry Andric } // end namespace llvm
5465f757f3fSDimitry Andric 
547