1 //===-- llvm/IntrinsicInst.h - Intrinsic Instruction Wrappers ---*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines classes that make it really easy to deal with intrinsic 11 // functions with the isa/dyncast family of functions. In particular, this 12 // allows you to do things like: 13 // 14 // if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(Inst)) 15 // ... MCI->getDest() ... MCI->getSource() ... 16 // 17 // All intrinsic function calls are instances of the call instruction, so these 18 // are all subclasses of the CallInst class. Note that none of these classes 19 // has state or virtual methods, which is an important part of this gross/neat 20 // hack working. 21 // 22 //===----------------------------------------------------------------------===// 23 24 #ifndef LLVM_IR_INTRINSICINST_H 25 #define LLVM_IR_INTRINSICINST_H 26 27 #include "llvm/IR/Constants.h" 28 #include "llvm/IR/DerivedTypes.h" 29 #include "llvm/IR/Function.h" 30 #include "llvm/IR/GlobalVariable.h" 31 #include "llvm/IR/Instructions.h" 32 #include "llvm/IR/Intrinsics.h" 33 #include "llvm/IR/Metadata.h" 34 #include "llvm/IR/Value.h" 35 #include "llvm/Support/Casting.h" 36 #include <cassert> 37 #include <cstdint> 38 39 namespace llvm { 40 41 /// A wrapper class for inspecting calls to intrinsic functions. 42 /// This allows the standard isa/dyncast/cast functionality to work with calls 43 /// to intrinsic functions. 44 class IntrinsicInst : public CallInst { 45 public: 46 IntrinsicInst() = delete; 47 IntrinsicInst(const IntrinsicInst &) = delete; 48 IntrinsicInst &operator=(const IntrinsicInst &) = delete; 49 50 /// Return the intrinsic ID of this intrinsic. 51 Intrinsic::ID getIntrinsicID() const { 52 return getCalledFunction()->getIntrinsicID(); 53 } 54 55 // Methods for support type inquiry through isa, cast, and dyn_cast: 56 static inline bool classof(const CallInst *I) { 57 if (const Function *CF = I->getCalledFunction()) 58 return CF->isIntrinsic(); 59 return false; 60 } 61 static inline bool classof(const Value *V) { 62 return isa<CallInst>(V) && classof(cast<CallInst>(V)); 63 } 64 }; 65 66 /// This is the common base class for debug info intrinsics. 67 class DbgInfoIntrinsic : public IntrinsicInst { 68 public: 69 /// Get the location corresponding to the variable referenced by the debug 70 /// info intrinsic. Depending on the intrinsic, this could be the 71 /// variable's value or its address. 72 Value *getVariableLocation(bool AllowNullOp = true) const; 73 74 // Methods for support type inquiry through isa, cast, and dyn_cast: 75 static inline bool classof(const IntrinsicInst *I) { 76 switch (I->getIntrinsicID()) { 77 case Intrinsic::dbg_declare: 78 case Intrinsic::dbg_value: 79 return true; 80 default: return false; 81 } 82 } 83 static inline bool classof(const Value *V) { 84 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 85 } 86 }; 87 88 /// This represents the llvm.dbg.declare instruction. 89 class DbgDeclareInst : public DbgInfoIntrinsic { 90 public: 91 Value *getAddress() const { return getVariableLocation(); } 92 93 DILocalVariable *getVariable() const { 94 return cast<DILocalVariable>(getRawVariable()); 95 } 96 97 DIExpression *getExpression() const { 98 return cast<DIExpression>(getRawExpression()); 99 } 100 101 Metadata *getRawVariable() const { 102 return cast<MetadataAsValue>(getArgOperand(1))->getMetadata(); 103 } 104 105 Metadata *getRawExpression() const { 106 return cast<MetadataAsValue>(getArgOperand(2))->getMetadata(); 107 } 108 109 // Methods for support type inquiry through isa, cast, and dyn_cast: 110 static inline bool classof(const IntrinsicInst *I) { 111 return I->getIntrinsicID() == Intrinsic::dbg_declare; 112 } 113 static inline bool classof(const Value *V) { 114 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 115 } 116 }; 117 118 /// This represents the llvm.dbg.value instruction. 119 class DbgValueInst : public DbgInfoIntrinsic { 120 public: 121 Value *getValue() const { 122 return getVariableLocation(/* AllowNullOp = */ false); 123 } 124 125 uint64_t getOffset() const { 126 return cast<ConstantInt>( 127 const_cast<Value*>(getArgOperand(1)))->getZExtValue(); 128 } 129 130 DILocalVariable *getVariable() const { 131 return cast<DILocalVariable>(getRawVariable()); 132 } 133 134 DIExpression *getExpression() const { 135 return cast<DIExpression>(getRawExpression()); 136 } 137 138 Metadata *getRawVariable() const { 139 return cast<MetadataAsValue>(getArgOperand(2))->getMetadata(); 140 } 141 142 Metadata *getRawExpression() const { 143 return cast<MetadataAsValue>(getArgOperand(3))->getMetadata(); 144 } 145 146 // Methods for support type inquiry through isa, cast, and dyn_cast: 147 static inline bool classof(const IntrinsicInst *I) { 148 return I->getIntrinsicID() == Intrinsic::dbg_value; 149 } 150 static inline bool classof(const Value *V) { 151 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 152 } 153 }; 154 155 /// This is the common base class for constrained floating point intrinsics. 156 class ConstrainedFPIntrinsic : public IntrinsicInst { 157 public: 158 enum RoundingMode { 159 rmInvalid, 160 rmDynamic, 161 rmToNearest, 162 rmDownward, 163 rmUpward, 164 rmTowardZero 165 }; 166 167 enum ExceptionBehavior { 168 ebInvalid, 169 ebIgnore, 170 ebMayTrap, 171 ebStrict 172 }; 173 174 RoundingMode getRoundingMode() const; 175 ExceptionBehavior getExceptionBehavior() const; 176 177 // Methods for support type inquiry through isa, cast, and dyn_cast: 178 static inline bool classof(const IntrinsicInst *I) { 179 switch (I->getIntrinsicID()) { 180 case Intrinsic::experimental_constrained_fadd: 181 case Intrinsic::experimental_constrained_fsub: 182 case Intrinsic::experimental_constrained_fmul: 183 case Intrinsic::experimental_constrained_fdiv: 184 case Intrinsic::experimental_constrained_frem: 185 return true; 186 default: return false; 187 } 188 } 189 static inline bool classof(const Value *V) { 190 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 191 } 192 }; 193 194 /// This class represents atomic memcpy intrinsic 195 /// TODO: Integrate this class into MemIntrinsic hierarchy. 196 class ElementAtomicMemCpyInst : public IntrinsicInst { 197 public: 198 Value *getRawDest() const { return getArgOperand(0); } 199 Value *getRawSource() const { return getArgOperand(1); } 200 201 Value *getNumElements() const { return getArgOperand(2); } 202 void setNumElements(Value *V) { setArgOperand(2, V); } 203 204 uint64_t getSrcAlignment() const { return getParamAlignment(1); } 205 uint64_t getDstAlignment() const { return getParamAlignment(2); } 206 207 uint64_t getElementSizeInBytes() const { 208 Value *Arg = getArgOperand(3); 209 return cast<ConstantInt>(Arg)->getZExtValue(); 210 } 211 212 static inline bool classof(const IntrinsicInst *I) { 213 return I->getIntrinsicID() == Intrinsic::memcpy_element_atomic; 214 } 215 static inline bool classof(const Value *V) { 216 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 217 } 218 }; 219 220 /// This is the common base class for memset/memcpy/memmove. 221 class MemIntrinsic : public IntrinsicInst { 222 public: 223 Value *getRawDest() const { return const_cast<Value*>(getArgOperand(0)); } 224 const Use &getRawDestUse() const { return getArgOperandUse(0); } 225 Use &getRawDestUse() { return getArgOperandUse(0); } 226 227 Value *getLength() const { return const_cast<Value*>(getArgOperand(2)); } 228 const Use &getLengthUse() const { return getArgOperandUse(2); } 229 Use &getLengthUse() { return getArgOperandUse(2); } 230 231 ConstantInt *getAlignmentCst() const { 232 return cast<ConstantInt>(const_cast<Value*>(getArgOperand(3))); 233 } 234 235 unsigned getAlignment() const { 236 return getAlignmentCst()->getZExtValue(); 237 } 238 239 ConstantInt *getVolatileCst() const { 240 return cast<ConstantInt>(const_cast<Value*>(getArgOperand(4))); 241 } 242 243 bool isVolatile() const { 244 return !getVolatileCst()->isZero(); 245 } 246 247 unsigned getDestAddressSpace() const { 248 return cast<PointerType>(getRawDest()->getType())->getAddressSpace(); 249 } 250 251 /// This is just like getRawDest, but it strips off any cast 252 /// instructions that feed it, giving the original input. The returned 253 /// value is guaranteed to be a pointer. 254 Value *getDest() const { return getRawDest()->stripPointerCasts(); } 255 256 /// Set the specified arguments of the instruction. 257 void setDest(Value *Ptr) { 258 assert(getRawDest()->getType() == Ptr->getType() && 259 "setDest called with pointer of wrong type!"); 260 setArgOperand(0, Ptr); 261 } 262 263 void setLength(Value *L) { 264 assert(getLength()->getType() == L->getType() && 265 "setLength called with value of wrong type!"); 266 setArgOperand(2, L); 267 } 268 269 void setAlignment(Constant* A) { 270 setArgOperand(3, A); 271 } 272 273 void setVolatile(Constant* V) { 274 setArgOperand(4, V); 275 } 276 277 Type *getAlignmentType() const { 278 return getArgOperand(3)->getType(); 279 } 280 281 // Methods for support type inquiry through isa, cast, and dyn_cast: 282 static inline bool classof(const IntrinsicInst *I) { 283 switch (I->getIntrinsicID()) { 284 case Intrinsic::memcpy: 285 case Intrinsic::memmove: 286 case Intrinsic::memset: 287 return true; 288 default: return false; 289 } 290 } 291 static inline bool classof(const Value *V) { 292 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 293 } 294 }; 295 296 /// This class wraps the llvm.memset intrinsic. 297 class MemSetInst : public MemIntrinsic { 298 public: 299 /// Return the arguments to the instruction. 300 Value *getValue() const { return const_cast<Value*>(getArgOperand(1)); } 301 const Use &getValueUse() const { return getArgOperandUse(1); } 302 Use &getValueUse() { return getArgOperandUse(1); } 303 304 void setValue(Value *Val) { 305 assert(getValue()->getType() == Val->getType() && 306 "setValue called with value of wrong type!"); 307 setArgOperand(1, Val); 308 } 309 310 // Methods for support type inquiry through isa, cast, and dyn_cast: 311 static inline bool classof(const IntrinsicInst *I) { 312 return I->getIntrinsicID() == Intrinsic::memset; 313 } 314 static inline bool classof(const Value *V) { 315 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 316 } 317 }; 318 319 /// This class wraps the llvm.memcpy/memmove intrinsics. 320 class MemTransferInst : public MemIntrinsic { 321 public: 322 /// Return the arguments to the instruction. 323 Value *getRawSource() const { return const_cast<Value*>(getArgOperand(1)); } 324 const Use &getRawSourceUse() const { return getArgOperandUse(1); } 325 Use &getRawSourceUse() { return getArgOperandUse(1); } 326 327 /// This is just like getRawSource, but it strips off any cast 328 /// instructions that feed it, giving the original input. The returned 329 /// value is guaranteed to be a pointer. 330 Value *getSource() const { return getRawSource()->stripPointerCasts(); } 331 332 unsigned getSourceAddressSpace() const { 333 return cast<PointerType>(getRawSource()->getType())->getAddressSpace(); 334 } 335 336 void setSource(Value *Ptr) { 337 assert(getRawSource()->getType() == Ptr->getType() && 338 "setSource called with pointer of wrong type!"); 339 setArgOperand(1, Ptr); 340 } 341 342 // Methods for support type inquiry through isa, cast, and dyn_cast: 343 static inline bool classof(const IntrinsicInst *I) { 344 return I->getIntrinsicID() == Intrinsic::memcpy || 345 I->getIntrinsicID() == Intrinsic::memmove; 346 } 347 static inline bool classof(const Value *V) { 348 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 349 } 350 }; 351 352 /// This class wraps the llvm.memcpy intrinsic. 353 class MemCpyInst : public MemTransferInst { 354 public: 355 // Methods for support type inquiry through isa, cast, and dyn_cast: 356 static inline bool classof(const IntrinsicInst *I) { 357 return I->getIntrinsicID() == Intrinsic::memcpy; 358 } 359 static inline bool classof(const Value *V) { 360 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 361 } 362 }; 363 364 /// This class wraps the llvm.memmove intrinsic. 365 class MemMoveInst : public MemTransferInst { 366 public: 367 // Methods for support type inquiry through isa, cast, and dyn_cast: 368 static inline bool classof(const IntrinsicInst *I) { 369 return I->getIntrinsicID() == Intrinsic::memmove; 370 } 371 static inline bool classof(const Value *V) { 372 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 373 } 374 }; 375 376 /// This represents the llvm.va_start intrinsic. 377 class VAStartInst : public IntrinsicInst { 378 public: 379 static inline bool classof(const IntrinsicInst *I) { 380 return I->getIntrinsicID() == Intrinsic::vastart; 381 } 382 static inline bool classof(const Value *V) { 383 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 384 } 385 386 Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); } 387 }; 388 389 /// This represents the llvm.va_end intrinsic. 390 class VAEndInst : public IntrinsicInst { 391 public: 392 static inline bool classof(const IntrinsicInst *I) { 393 return I->getIntrinsicID() == Intrinsic::vaend; 394 } 395 static inline bool classof(const Value *V) { 396 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 397 } 398 399 Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); } 400 }; 401 402 /// This represents the llvm.va_copy intrinsic. 403 class VACopyInst : public IntrinsicInst { 404 public: 405 static inline bool classof(const IntrinsicInst *I) { 406 return I->getIntrinsicID() == Intrinsic::vacopy; 407 } 408 static inline bool classof(const Value *V) { 409 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 410 } 411 412 Value *getDest() const { return const_cast<Value*>(getArgOperand(0)); } 413 Value *getSrc() const { return const_cast<Value*>(getArgOperand(1)); } 414 }; 415 416 /// This represents the llvm.instrprof_increment intrinsic. 417 class InstrProfIncrementInst : public IntrinsicInst { 418 public: 419 static inline bool classof(const IntrinsicInst *I) { 420 return I->getIntrinsicID() == Intrinsic::instrprof_increment; 421 } 422 static inline bool classof(const Value *V) { 423 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 424 } 425 426 GlobalVariable *getName() const { 427 return cast<GlobalVariable>( 428 const_cast<Value *>(getArgOperand(0))->stripPointerCasts()); 429 } 430 431 ConstantInt *getHash() const { 432 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); 433 } 434 435 ConstantInt *getNumCounters() const { 436 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2))); 437 } 438 439 ConstantInt *getIndex() const { 440 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 441 } 442 443 Value *getStep() const; 444 }; 445 446 class InstrProfIncrementInstStep : public InstrProfIncrementInst { 447 public: 448 static inline bool classof(const IntrinsicInst *I) { 449 return I->getIntrinsicID() == Intrinsic::instrprof_increment_step; 450 } 451 static inline bool classof(const Value *V) { 452 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 453 } 454 }; 455 456 /// This represents the llvm.instrprof_value_profile intrinsic. 457 class InstrProfValueProfileInst : public IntrinsicInst { 458 public: 459 static inline bool classof(const IntrinsicInst *I) { 460 return I->getIntrinsicID() == Intrinsic::instrprof_value_profile; 461 } 462 static inline bool classof(const Value *V) { 463 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 464 } 465 466 GlobalVariable *getName() const { 467 return cast<GlobalVariable>( 468 const_cast<Value *>(getArgOperand(0))->stripPointerCasts()); 469 } 470 471 ConstantInt *getHash() const { 472 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); 473 } 474 475 Value *getTargetValue() const { 476 return cast<Value>(const_cast<Value *>(getArgOperand(2))); 477 } 478 479 ConstantInt *getValueKind() const { 480 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 481 } 482 483 // Returns the value site index. 484 ConstantInt *getIndex() const { 485 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4))); 486 } 487 }; 488 489 } // end namespace llvm 490 491 #endif // LLVM_IR_INTRINSICINST_H 492