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