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