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. getIntrinsicID()51 Intrinsic::ID getIntrinsicID() const { 52 return getCalledFunction()->getIntrinsicID(); 53 } 54 55 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const CallInst * I)56 static bool classof(const CallInst *I) { 57 if (const Function *CF = I->getCalledFunction()) 58 return CF->isIntrinsic(); 59 return false; 60 } classof(const Value * V)61 static 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 /// Does this describe the address of a local variable. True for dbg.addr 75 /// and dbg.declare, but not dbg.value, which describes its value. isAddressOfVariable()76 bool isAddressOfVariable() const { 77 return getIntrinsicID() != Intrinsic::dbg_value; 78 } 79 getVariable()80 DILocalVariable *getVariable() const { 81 return cast<DILocalVariable>(getRawVariable()); 82 } 83 getExpression()84 DIExpression *getExpression() const { 85 return cast<DIExpression>(getRawExpression()); 86 } 87 getRawVariable()88 Metadata *getRawVariable() const { 89 return cast<MetadataAsValue>(getArgOperand(1))->getMetadata(); 90 } 91 getRawExpression()92 Metadata *getRawExpression() const { 93 return cast<MetadataAsValue>(getArgOperand(2))->getMetadata(); 94 } 95 96 /// Get the size (in bits) of the variable, or fragment of the variable that 97 /// is described. 98 Optional<uint64_t> getFragmentSizeInBits() const; 99 100 /// \name Casting methods 101 /// @{ classof(const IntrinsicInst * I)102 static bool classof(const IntrinsicInst *I) { 103 switch (I->getIntrinsicID()) { 104 case Intrinsic::dbg_declare: 105 case Intrinsic::dbg_value: 106 case Intrinsic::dbg_addr: 107 case Intrinsic::dbg_label: 108 return true; 109 default: return false; 110 } 111 } classof(const Value * V)112 static bool classof(const Value *V) { 113 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 114 } 115 /// @} 116 }; 117 118 /// This represents the llvm.dbg.declare instruction. 119 class DbgDeclareInst : public DbgInfoIntrinsic { 120 public: getAddress()121 Value *getAddress() const { return getVariableLocation(); } 122 123 /// \name Casting methods 124 /// @{ classof(const IntrinsicInst * I)125 static bool classof(const IntrinsicInst *I) { 126 return I->getIntrinsicID() == Intrinsic::dbg_declare; 127 } classof(const Value * V)128 static bool classof(const Value *V) { 129 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 130 } 131 /// @} 132 }; 133 134 /// This represents the llvm.dbg.addr instruction. 135 class DbgAddrIntrinsic : public DbgInfoIntrinsic { 136 public: getAddress()137 Value *getAddress() const { return getVariableLocation(); } 138 139 /// \name Casting methods 140 /// @{ classof(const IntrinsicInst * I)141 static bool classof(const IntrinsicInst *I) { 142 return I->getIntrinsicID() == Intrinsic::dbg_addr; 143 } classof(const Value * V)144 static bool classof(const Value *V) { 145 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 146 } 147 }; 148 149 /// This represents the llvm.dbg.value instruction. 150 class DbgValueInst : public DbgInfoIntrinsic { 151 public: getValue()152 Value *getValue() const { 153 return getVariableLocation(/* AllowNullOp = */ false); 154 } 155 156 /// \name Casting methods 157 /// @{ classof(const IntrinsicInst * I)158 static bool classof(const IntrinsicInst *I) { 159 return I->getIntrinsicID() == Intrinsic::dbg_value; 160 } classof(const Value * V)161 static bool classof(const Value *V) { 162 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 163 } 164 /// @} 165 }; 166 167 /// This represents the llvm.dbg.label instruction. 168 class DbgLabelInst : public DbgInfoIntrinsic { 169 public: getLabel()170 DILabel *getLabel() const { 171 return cast<DILabel>(getRawVariable()); 172 } 173 getRawVariable()174 Metadata *getRawVariable() const { 175 return cast<MetadataAsValue>(getArgOperand(0))->getMetadata(); 176 } 177 getRawExpression()178 Metadata *getRawExpression() const { 179 return nullptr; 180 } 181 182 /// Methods for support type inquiry through isa, cast, and dyn_cast: 183 /// @{ classof(const IntrinsicInst * I)184 static bool classof(const IntrinsicInst *I) { 185 return I->getIntrinsicID() == Intrinsic::dbg_label; 186 } classof(const Value * V)187 static bool classof(const Value *V) { 188 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 189 } 190 /// @} 191 }; 192 193 /// This is the common base class for constrained floating point intrinsics. 194 class ConstrainedFPIntrinsic : public IntrinsicInst { 195 public: 196 enum RoundingMode { 197 rmInvalid, 198 rmDynamic, 199 rmToNearest, 200 rmDownward, 201 rmUpward, 202 rmTowardZero 203 }; 204 205 enum ExceptionBehavior { 206 ebInvalid, 207 ebIgnore, 208 ebMayTrap, 209 ebStrict 210 }; 211 212 bool isUnaryOp() const; 213 bool isTernaryOp() const; 214 RoundingMode getRoundingMode() const; 215 ExceptionBehavior getExceptionBehavior() const; 216 217 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const IntrinsicInst * I)218 static bool classof(const IntrinsicInst *I) { 219 switch (I->getIntrinsicID()) { 220 case Intrinsic::experimental_constrained_fadd: 221 case Intrinsic::experimental_constrained_fsub: 222 case Intrinsic::experimental_constrained_fmul: 223 case Intrinsic::experimental_constrained_fdiv: 224 case Intrinsic::experimental_constrained_frem: 225 case Intrinsic::experimental_constrained_fma: 226 case Intrinsic::experimental_constrained_sqrt: 227 case Intrinsic::experimental_constrained_pow: 228 case Intrinsic::experimental_constrained_powi: 229 case Intrinsic::experimental_constrained_sin: 230 case Intrinsic::experimental_constrained_cos: 231 case Intrinsic::experimental_constrained_exp: 232 case Intrinsic::experimental_constrained_exp2: 233 case Intrinsic::experimental_constrained_log: 234 case Intrinsic::experimental_constrained_log10: 235 case Intrinsic::experimental_constrained_log2: 236 case Intrinsic::experimental_constrained_rint: 237 case Intrinsic::experimental_constrained_nearbyint: 238 return true; 239 default: return false; 240 } 241 } classof(const Value * V)242 static bool classof(const Value *V) { 243 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 244 } 245 }; 246 247 /// Common base class for all memory intrinsics. Simply provides 248 /// common methods. 249 /// Written as CRTP to avoid a common base class amongst the 250 /// three atomicity hierarchies. 251 template <typename Derived> class MemIntrinsicBase : public IntrinsicInst { 252 private: 253 enum { ARG_DEST = 0, ARG_LENGTH = 2 }; 254 255 public: getRawDest()256 Value *getRawDest() const { 257 return const_cast<Value *>(getArgOperand(ARG_DEST)); 258 } getRawDestUse()259 const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); } getRawDestUse()260 Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); } 261 getLength()262 Value *getLength() const { 263 return const_cast<Value *>(getArgOperand(ARG_LENGTH)); 264 } getLengthUse()265 const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); } getLengthUse()266 Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); } 267 268 /// This is just like getRawDest, but it strips off any cast 269 /// instructions (including addrspacecast) that feed it, giving the 270 /// original input. The returned value is guaranteed to be a pointer. getDest()271 Value *getDest() const { return getRawDest()->stripPointerCasts(); } 272 getDestAddressSpace()273 unsigned getDestAddressSpace() const { 274 return cast<PointerType>(getRawDest()->getType())->getAddressSpace(); 275 } 276 getDestAlignment()277 unsigned getDestAlignment() const { return getParamAlignment(ARG_DEST); } 278 279 /// Set the specified arguments of the instruction. setDest(Value * Ptr)280 void setDest(Value *Ptr) { 281 assert(getRawDest()->getType() == Ptr->getType() && 282 "setDest called with pointer of wrong type!"); 283 setArgOperand(ARG_DEST, Ptr); 284 } 285 setDestAlignment(unsigned Align)286 void setDestAlignment(unsigned Align) { 287 removeParamAttr(ARG_DEST, Attribute::Alignment); 288 if (Align > 0) 289 addParamAttr(ARG_DEST, 290 Attribute::getWithAlignment(getContext(), Align)); 291 } 292 setLength(Value * L)293 void setLength(Value *L) { 294 assert(getLength()->getType() == L->getType() && 295 "setLength called with value of wrong type!"); 296 setArgOperand(ARG_LENGTH, L); 297 } 298 }; 299 300 /// Common base class for all memory transfer intrinsics. Simply provides 301 /// common methods. 302 template <class BaseCL> class MemTransferBase : public BaseCL { 303 private: 304 enum { ARG_SOURCE = 1 }; 305 306 public: 307 /// Return the arguments to the instruction. getRawSource()308 Value *getRawSource() const { 309 return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE)); 310 } getRawSourceUse()311 const Use &getRawSourceUse() const { 312 return BaseCL::getArgOperandUse(ARG_SOURCE); 313 } getRawSourceUse()314 Use &getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE); } 315 316 /// This is just like getRawSource, but it strips off any cast 317 /// instructions that feed it, giving the original input. The returned 318 /// value is guaranteed to be a pointer. getSource()319 Value *getSource() const { return getRawSource()->stripPointerCasts(); } 320 getSourceAddressSpace()321 unsigned getSourceAddressSpace() const { 322 return cast<PointerType>(getRawSource()->getType())->getAddressSpace(); 323 } 324 getSourceAlignment()325 unsigned getSourceAlignment() const { 326 return BaseCL::getParamAlignment(ARG_SOURCE); 327 } 328 setSource(Value * Ptr)329 void setSource(Value *Ptr) { 330 assert(getRawSource()->getType() == Ptr->getType() && 331 "setSource called with pointer of wrong type!"); 332 BaseCL::setArgOperand(ARG_SOURCE, Ptr); 333 } 334 setSourceAlignment(unsigned Align)335 void setSourceAlignment(unsigned Align) { 336 BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment); 337 if (Align > 0) 338 BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment( 339 BaseCL::getContext(), Align)); 340 } 341 }; 342 343 /// Common base class for all memset intrinsics. Simply provides 344 /// common methods. 345 template <class BaseCL> class MemSetBase : public BaseCL { 346 private: 347 enum { ARG_VALUE = 1 }; 348 349 public: getValue()350 Value *getValue() const { 351 return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE)); 352 } getValueUse()353 const Use &getValueUse() const { 354 return BaseCL::getArgOperandUse(ARG_VALUE); 355 } getValueUse()356 Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); } 357 setValue(Value * Val)358 void setValue(Value *Val) { 359 assert(getValue()->getType() == Val->getType() && 360 "setValue called with value of wrong type!"); 361 BaseCL::setArgOperand(ARG_VALUE, Val); 362 } 363 }; 364 365 // The common base class for the atomic memset/memmove/memcpy intrinsics 366 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove 367 class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> { 368 private: 369 enum { ARG_ELEMENTSIZE = 3 }; 370 371 public: getRawElementSizeInBytes()372 Value *getRawElementSizeInBytes() const { 373 return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE)); 374 } 375 getElementSizeInBytesCst()376 ConstantInt *getElementSizeInBytesCst() const { 377 return cast<ConstantInt>(getRawElementSizeInBytes()); 378 } 379 getElementSizeInBytes()380 uint32_t getElementSizeInBytes() const { 381 return getElementSizeInBytesCst()->getZExtValue(); 382 } 383 setElementSizeInBytes(Constant * V)384 void setElementSizeInBytes(Constant *V) { 385 assert(V->getType() == Type::getInt8Ty(getContext()) && 386 "setElementSizeInBytes called with value of wrong type!"); 387 setArgOperand(ARG_ELEMENTSIZE, V); 388 } 389 classof(const IntrinsicInst * I)390 static bool classof(const IntrinsicInst *I) { 391 switch (I->getIntrinsicID()) { 392 case Intrinsic::memcpy_element_unordered_atomic: 393 case Intrinsic::memmove_element_unordered_atomic: 394 case Intrinsic::memset_element_unordered_atomic: 395 return true; 396 default: 397 return false; 398 } 399 } classof(const Value * V)400 static bool classof(const Value *V) { 401 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 402 } 403 }; 404 405 /// This class represents atomic memset intrinsic 406 // i.e. llvm.element.unordered.atomic.memset 407 class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> { 408 public: classof(const IntrinsicInst * I)409 static bool classof(const IntrinsicInst *I) { 410 return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic; 411 } classof(const Value * V)412 static bool classof(const Value *V) { 413 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 414 } 415 }; 416 417 // This class wraps the atomic memcpy/memmove intrinsics 418 // i.e. llvm.element.unordered.atomic.memcpy/memmove 419 class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> { 420 public: classof(const IntrinsicInst * I)421 static bool classof(const IntrinsicInst *I) { 422 switch (I->getIntrinsicID()) { 423 case Intrinsic::memcpy_element_unordered_atomic: 424 case Intrinsic::memmove_element_unordered_atomic: 425 return true; 426 default: 427 return false; 428 } 429 } classof(const Value * V)430 static bool classof(const Value *V) { 431 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 432 } 433 }; 434 435 /// This class represents the atomic memcpy intrinsic 436 /// i.e. llvm.element.unordered.atomic.memcpy 437 class AtomicMemCpyInst : public AtomicMemTransferInst { 438 public: classof(const IntrinsicInst * I)439 static bool classof(const IntrinsicInst *I) { 440 return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic; 441 } classof(const Value * V)442 static bool classof(const Value *V) { 443 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 444 } 445 }; 446 447 /// This class represents the atomic memmove intrinsic 448 /// i.e. llvm.element.unordered.atomic.memmove 449 class AtomicMemMoveInst : public AtomicMemTransferInst { 450 public: classof(const IntrinsicInst * I)451 static bool classof(const IntrinsicInst *I) { 452 return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic; 453 } classof(const Value * V)454 static bool classof(const Value *V) { 455 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 456 } 457 }; 458 459 /// This is the common base class for memset/memcpy/memmove. 460 class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> { 461 private: 462 enum { ARG_VOLATILE = 3 }; 463 464 public: getVolatileCst()465 ConstantInt *getVolatileCst() const { 466 return cast<ConstantInt>( 467 const_cast<Value *>(getArgOperand(ARG_VOLATILE))); 468 } 469 isVolatile()470 bool isVolatile() const { 471 return !getVolatileCst()->isZero(); 472 } 473 setVolatile(Constant * V)474 void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); } 475 476 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const IntrinsicInst * I)477 static bool classof(const IntrinsicInst *I) { 478 switch (I->getIntrinsicID()) { 479 case Intrinsic::memcpy: 480 case Intrinsic::memmove: 481 case Intrinsic::memset: 482 return true; 483 default: return false; 484 } 485 } classof(const Value * V)486 static bool classof(const Value *V) { 487 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 488 } 489 }; 490 491 /// This class wraps the llvm.memset intrinsic. 492 class MemSetInst : public MemSetBase<MemIntrinsic> { 493 public: 494 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const IntrinsicInst * I)495 static bool classof(const IntrinsicInst *I) { 496 return I->getIntrinsicID() == Intrinsic::memset; 497 } classof(const Value * V)498 static bool classof(const Value *V) { 499 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 500 } 501 }; 502 503 /// This class wraps the llvm.memcpy/memmove intrinsics. 504 class MemTransferInst : public MemTransferBase<MemIntrinsic> { 505 public: 506 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const IntrinsicInst * I)507 static bool classof(const IntrinsicInst *I) { 508 return I->getIntrinsicID() == Intrinsic::memcpy || 509 I->getIntrinsicID() == Intrinsic::memmove; 510 } classof(const Value * V)511 static bool classof(const Value *V) { 512 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 513 } 514 }; 515 516 /// This class wraps the llvm.memcpy intrinsic. 517 class MemCpyInst : public MemTransferInst { 518 public: 519 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const IntrinsicInst * I)520 static bool classof(const IntrinsicInst *I) { 521 return I->getIntrinsicID() == Intrinsic::memcpy; 522 } classof(const Value * V)523 static bool classof(const Value *V) { 524 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 525 } 526 }; 527 528 /// This class wraps the llvm.memmove intrinsic. 529 class MemMoveInst : public MemTransferInst { 530 public: 531 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const IntrinsicInst * I)532 static bool classof(const IntrinsicInst *I) { 533 return I->getIntrinsicID() == Intrinsic::memmove; 534 } classof(const Value * V)535 static bool classof(const Value *V) { 536 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 537 } 538 }; 539 540 // The common base class for any memset/memmove/memcpy intrinsics; 541 // whether they be atomic or non-atomic. 542 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove 543 // and llvm.memset/memcpy/memmove 544 class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> { 545 public: isVolatile()546 bool isVolatile() const { 547 // Only the non-atomic intrinsics can be volatile 548 if (auto *MI = dyn_cast<MemIntrinsic>(this)) 549 return MI->isVolatile(); 550 return false; 551 } 552 classof(const IntrinsicInst * I)553 static bool classof(const IntrinsicInst *I) { 554 switch (I->getIntrinsicID()) { 555 case Intrinsic::memcpy: 556 case Intrinsic::memmove: 557 case Intrinsic::memset: 558 case Intrinsic::memcpy_element_unordered_atomic: 559 case Intrinsic::memmove_element_unordered_atomic: 560 case Intrinsic::memset_element_unordered_atomic: 561 return true; 562 default: 563 return false; 564 } 565 } classof(const Value * V)566 static bool classof(const Value *V) { 567 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 568 } 569 }; 570 571 /// This class represents any memset intrinsic 572 // i.e. llvm.element.unordered.atomic.memset 573 // and llvm.memset 574 class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> { 575 public: classof(const IntrinsicInst * I)576 static bool classof(const IntrinsicInst *I) { 577 switch (I->getIntrinsicID()) { 578 case Intrinsic::memset: 579 case Intrinsic::memset_element_unordered_atomic: 580 return true; 581 default: 582 return false; 583 } 584 } classof(const Value * V)585 static bool classof(const Value *V) { 586 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 587 } 588 }; 589 590 // This class wraps any memcpy/memmove intrinsics 591 // i.e. llvm.element.unordered.atomic.memcpy/memmove 592 // and llvm.memcpy/memmove 593 class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> { 594 public: classof(const IntrinsicInst * I)595 static bool classof(const IntrinsicInst *I) { 596 switch (I->getIntrinsicID()) { 597 case Intrinsic::memcpy: 598 case Intrinsic::memmove: 599 case Intrinsic::memcpy_element_unordered_atomic: 600 case Intrinsic::memmove_element_unordered_atomic: 601 return true; 602 default: 603 return false; 604 } 605 } classof(const Value * V)606 static bool classof(const Value *V) { 607 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 608 } 609 }; 610 611 /// This class represents any memcpy intrinsic 612 /// i.e. llvm.element.unordered.atomic.memcpy 613 /// and llvm.memcpy 614 class AnyMemCpyInst : public AnyMemTransferInst { 615 public: classof(const IntrinsicInst * I)616 static bool classof(const IntrinsicInst *I) { 617 switch (I->getIntrinsicID()) { 618 case Intrinsic::memcpy: 619 case Intrinsic::memcpy_element_unordered_atomic: 620 return true; 621 default: 622 return false; 623 } 624 } classof(const Value * V)625 static bool classof(const Value *V) { 626 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 627 } 628 }; 629 630 /// This class represents any memmove intrinsic 631 /// i.e. llvm.element.unordered.atomic.memmove 632 /// and llvm.memmove 633 class AnyMemMoveInst : public AnyMemTransferInst { 634 public: classof(const IntrinsicInst * I)635 static bool classof(const IntrinsicInst *I) { 636 switch (I->getIntrinsicID()) { 637 case Intrinsic::memmove: 638 case Intrinsic::memmove_element_unordered_atomic: 639 return true; 640 default: 641 return false; 642 } 643 } classof(const Value * V)644 static bool classof(const Value *V) { 645 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 646 } 647 }; 648 649 /// This represents the llvm.va_start intrinsic. 650 class VAStartInst : public IntrinsicInst { 651 public: classof(const IntrinsicInst * I)652 static bool classof(const IntrinsicInst *I) { 653 return I->getIntrinsicID() == Intrinsic::vastart; 654 } classof(const Value * V)655 static bool classof(const Value *V) { 656 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 657 } 658 getArgList()659 Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); } 660 }; 661 662 /// This represents the llvm.va_end intrinsic. 663 class VAEndInst : public IntrinsicInst { 664 public: classof(const IntrinsicInst * I)665 static bool classof(const IntrinsicInst *I) { 666 return I->getIntrinsicID() == Intrinsic::vaend; 667 } classof(const Value * V)668 static bool classof(const Value *V) { 669 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 670 } 671 getArgList()672 Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); } 673 }; 674 675 /// This represents the llvm.va_copy intrinsic. 676 class VACopyInst : public IntrinsicInst { 677 public: classof(const IntrinsicInst * I)678 static bool classof(const IntrinsicInst *I) { 679 return I->getIntrinsicID() == Intrinsic::vacopy; 680 } classof(const Value * V)681 static bool classof(const Value *V) { 682 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 683 } 684 getDest()685 Value *getDest() const { return const_cast<Value*>(getArgOperand(0)); } getSrc()686 Value *getSrc() const { return const_cast<Value*>(getArgOperand(1)); } 687 }; 688 689 /// This represents the llvm.instrprof_increment intrinsic. 690 class InstrProfIncrementInst : public IntrinsicInst { 691 public: classof(const IntrinsicInst * I)692 static bool classof(const IntrinsicInst *I) { 693 return I->getIntrinsicID() == Intrinsic::instrprof_increment; 694 } classof(const Value * V)695 static bool classof(const Value *V) { 696 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 697 } 698 getName()699 GlobalVariable *getName() const { 700 return cast<GlobalVariable>( 701 const_cast<Value *>(getArgOperand(0))->stripPointerCasts()); 702 } 703 getHash()704 ConstantInt *getHash() const { 705 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); 706 } 707 getNumCounters()708 ConstantInt *getNumCounters() const { 709 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2))); 710 } 711 getIndex()712 ConstantInt *getIndex() const { 713 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 714 } 715 716 Value *getStep() const; 717 }; 718 719 class InstrProfIncrementInstStep : public InstrProfIncrementInst { 720 public: classof(const IntrinsicInst * I)721 static bool classof(const IntrinsicInst *I) { 722 return I->getIntrinsicID() == Intrinsic::instrprof_increment_step; 723 } classof(const Value * V)724 static bool classof(const Value *V) { 725 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 726 } 727 }; 728 729 /// This represents the llvm.instrprof_value_profile intrinsic. 730 class InstrProfValueProfileInst : public IntrinsicInst { 731 public: classof(const IntrinsicInst * I)732 static bool classof(const IntrinsicInst *I) { 733 return I->getIntrinsicID() == Intrinsic::instrprof_value_profile; 734 } classof(const Value * V)735 static bool classof(const Value *V) { 736 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 737 } 738 getName()739 GlobalVariable *getName() const { 740 return cast<GlobalVariable>( 741 const_cast<Value *>(getArgOperand(0))->stripPointerCasts()); 742 } 743 getHash()744 ConstantInt *getHash() const { 745 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); 746 } 747 getTargetValue()748 Value *getTargetValue() const { 749 return cast<Value>(const_cast<Value *>(getArgOperand(2))); 750 } 751 getValueKind()752 ConstantInt *getValueKind() const { 753 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 754 } 755 756 // Returns the value site index. getIndex()757 ConstantInt *getIndex() const { 758 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4))); 759 } 760 }; 761 762 } // end namespace llvm 763 764 #endif // LLVM_IR_INTRINSICINST_H 765