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