1 //===-- llvm/IntrinsicInst.h - Intrinsic Instruction Wrappers ---*- C++ -*-===// 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 // This file defines classes that make it really easy to deal with intrinsic 10 // functions with the isa/dyncast family of functions. In particular, this 11 // allows you to do things like: 12 // 13 // if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(Inst)) 14 // ... MCI->getDest() ... MCI->getSource() ... 15 // 16 // All intrinsic function calls are instances of the call instruction, so these 17 // are all subclasses of the CallInst class. Note that none of these classes 18 // has state or virtual methods, which is an important part of this gross/neat 19 // hack working. 20 // 21 //===----------------------------------------------------------------------===// 22 23 #ifndef LLVM_IR_INTRINSICINST_H 24 #define LLVM_IR_INTRINSICINST_H 25 26 #include "llvm/IR/Constants.h" 27 #include "llvm/IR/DerivedTypes.h" 28 #include "llvm/IR/FPEnv.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 bool classof(const CallInst *I) { 57 if (const Function *CF = I->getCalledFunction()) 58 return CF->isIntrinsic(); 59 return false; 60 } 61 static bool classof(const Value *V) { 62 return isa<CallInst>(V) && classof(cast<CallInst>(V)); 63 } 64 }; 65 66 /// Check if \p ID corresponds to a debug info intrinsic. 67 static inline bool isDbgInfoIntrinsic(Intrinsic::ID ID) { 68 switch (ID) { 69 case Intrinsic::dbg_declare: 70 case Intrinsic::dbg_value: 71 case Intrinsic::dbg_addr: 72 case Intrinsic::dbg_label: 73 return true; 74 default: 75 return false; 76 } 77 } 78 79 /// This is the common base class for debug info intrinsics. 80 class DbgInfoIntrinsic : public IntrinsicInst { 81 public: 82 /// \name Casting methods 83 /// @{ 84 static bool classof(const IntrinsicInst *I) { 85 return isDbgInfoIntrinsic(I->getIntrinsicID()); 86 } 87 static bool classof(const Value *V) { 88 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 89 } 90 /// @} 91 }; 92 93 /// This is the common base class for debug info intrinsics for variables. 94 class DbgVariableIntrinsic : public DbgInfoIntrinsic { 95 public: 96 /// Get the location corresponding to the variable referenced by the debug 97 /// info intrinsic. Depending on the intrinsic, this could be the 98 /// variable's value or its address. 99 Value *getVariableLocation(bool AllowNullOp = true) const; 100 101 /// Does this describe the address of a local variable. True for dbg.addr 102 /// and dbg.declare, but not dbg.value, which describes its value. 103 bool isAddressOfVariable() const { 104 return getIntrinsicID() != Intrinsic::dbg_value; 105 } 106 107 DILocalVariable *getVariable() const { 108 return cast<DILocalVariable>(getRawVariable()); 109 } 110 111 DIExpression *getExpression() const { 112 return cast<DIExpression>(getRawExpression()); 113 } 114 115 Metadata *getRawVariable() const { 116 return cast<MetadataAsValue>(getArgOperand(1))->getMetadata(); 117 } 118 119 Metadata *getRawExpression() const { 120 return cast<MetadataAsValue>(getArgOperand(2))->getMetadata(); 121 } 122 123 /// Get the size (in bits) of the variable, or fragment of the variable that 124 /// is described. 125 Optional<uint64_t> getFragmentSizeInBits() const; 126 127 /// \name Casting methods 128 /// @{ 129 static bool classof(const IntrinsicInst *I) { 130 switch (I->getIntrinsicID()) { 131 case Intrinsic::dbg_declare: 132 case Intrinsic::dbg_value: 133 case Intrinsic::dbg_addr: 134 return true; 135 default: 136 return false; 137 } 138 } 139 static bool classof(const Value *V) { 140 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 141 } 142 /// @} 143 }; 144 145 /// This represents the llvm.dbg.declare instruction. 146 class DbgDeclareInst : public DbgVariableIntrinsic { 147 public: 148 Value *getAddress() const { return getVariableLocation(); } 149 150 /// \name Casting methods 151 /// @{ 152 static bool classof(const IntrinsicInst *I) { 153 return I->getIntrinsicID() == Intrinsic::dbg_declare; 154 } 155 static bool classof(const Value *V) { 156 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 157 } 158 /// @} 159 }; 160 161 /// This represents the llvm.dbg.addr instruction. 162 class DbgAddrIntrinsic : public DbgVariableIntrinsic { 163 public: 164 Value *getAddress() const { return getVariableLocation(); } 165 166 /// \name Casting methods 167 /// @{ 168 static bool classof(const IntrinsicInst *I) { 169 return I->getIntrinsicID() == Intrinsic::dbg_addr; 170 } 171 static bool classof(const Value *V) { 172 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 173 } 174 }; 175 176 /// This represents the llvm.dbg.value instruction. 177 class DbgValueInst : public DbgVariableIntrinsic { 178 public: 179 Value *getValue() const { 180 return getVariableLocation(/* AllowNullOp = */ false); 181 } 182 183 /// \name Casting methods 184 /// @{ 185 static bool classof(const IntrinsicInst *I) { 186 return I->getIntrinsicID() == Intrinsic::dbg_value; 187 } 188 static bool classof(const Value *V) { 189 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 190 } 191 /// @} 192 }; 193 194 /// This represents the llvm.dbg.label instruction. 195 class DbgLabelInst : public DbgInfoIntrinsic { 196 public: 197 DILabel *getLabel() const { return cast<DILabel>(getRawLabel()); } 198 199 Metadata *getRawLabel() const { 200 return cast<MetadataAsValue>(getArgOperand(0))->getMetadata(); 201 } 202 203 /// Methods for support type inquiry through isa, cast, and dyn_cast: 204 /// @{ 205 static bool classof(const IntrinsicInst *I) { 206 return I->getIntrinsicID() == Intrinsic::dbg_label; 207 } 208 static bool classof(const Value *V) { 209 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 210 } 211 /// @} 212 }; 213 214 /// This is the common base class for vector predication intrinsics. 215 class VPIntrinsic : public IntrinsicInst { 216 public: 217 static Optional<int> GetMaskParamPos(Intrinsic::ID IntrinsicID); 218 static Optional<int> GetVectorLengthParamPos(Intrinsic::ID IntrinsicID); 219 220 /// The llvm.vp.* intrinsics for this instruction Opcode 221 static Intrinsic::ID GetForOpcode(unsigned OC); 222 223 // Whether \p ID is a VP intrinsic ID. 224 static bool IsVPIntrinsic(Intrinsic::ID); 225 226 /// \return the mask parameter or nullptr. 227 Value *getMaskParam() const; 228 229 /// \return the vector length parameter or nullptr. 230 Value *getVectorLengthParam() const; 231 232 /// \return whether the vector length param can be ignored. 233 bool canIgnoreVectorLengthParam() const; 234 235 /// \return the static element count (vector number of elements) the vector 236 /// length parameter applies to. 237 ElementCount getStaticVectorLength() const; 238 239 // Methods for support type inquiry through isa, cast, and dyn_cast: 240 static bool classof(const IntrinsicInst *I) { 241 return IsVPIntrinsic(I->getIntrinsicID()); 242 } 243 static bool classof(const Value *V) { 244 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 245 } 246 247 // Equivalent non-predicated opcode 248 unsigned getFunctionalOpcode() const { 249 return GetFunctionalOpcodeForVP(getIntrinsicID()); 250 } 251 252 // Equivalent non-predicated opcode 253 static unsigned GetFunctionalOpcodeForVP(Intrinsic::ID ID); 254 }; 255 256 /// This is the common base class for constrained floating point intrinsics. 257 class ConstrainedFPIntrinsic : public IntrinsicInst { 258 public: 259 bool isUnaryOp() const; 260 bool isTernaryOp() const; 261 Optional<RoundingMode> getRoundingMode() const; 262 Optional<fp::ExceptionBehavior> getExceptionBehavior() const; 263 264 // Methods for support type inquiry through isa, cast, and dyn_cast: 265 static bool classof(const IntrinsicInst *I); 266 static bool classof(const Value *V) { 267 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 268 } 269 }; 270 271 /// Constrained floating point compare intrinsics. 272 class ConstrainedFPCmpIntrinsic : public ConstrainedFPIntrinsic { 273 public: 274 FCmpInst::Predicate getPredicate() const; 275 276 // Methods for support type inquiry through isa, cast, and dyn_cast: 277 static bool classof(const IntrinsicInst *I) { 278 switch (I->getIntrinsicID()) { 279 case Intrinsic::experimental_constrained_fcmp: 280 case Intrinsic::experimental_constrained_fcmps: 281 return true; 282 default: 283 return false; 284 } 285 } 286 static bool classof(const Value *V) { 287 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 288 } 289 }; 290 291 /// This class represents an intrinsic that is based on a binary operation. 292 /// This includes op.with.overflow and saturating add/sub intrinsics. 293 class BinaryOpIntrinsic : public IntrinsicInst { 294 public: 295 static bool classof(const IntrinsicInst *I) { 296 switch (I->getIntrinsicID()) { 297 case Intrinsic::uadd_with_overflow: 298 case Intrinsic::sadd_with_overflow: 299 case Intrinsic::usub_with_overflow: 300 case Intrinsic::ssub_with_overflow: 301 case Intrinsic::umul_with_overflow: 302 case Intrinsic::smul_with_overflow: 303 case Intrinsic::uadd_sat: 304 case Intrinsic::sadd_sat: 305 case Intrinsic::usub_sat: 306 case Intrinsic::ssub_sat: 307 return true; 308 default: 309 return false; 310 } 311 } 312 static bool classof(const Value *V) { 313 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 314 } 315 316 Value *getLHS() const { return const_cast<Value *>(getArgOperand(0)); } 317 Value *getRHS() const { return const_cast<Value *>(getArgOperand(1)); } 318 319 /// Returns the binary operation underlying the intrinsic. 320 Instruction::BinaryOps getBinaryOp() const; 321 322 /// Whether the intrinsic is signed or unsigned. 323 bool isSigned() const; 324 325 /// Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap. 326 unsigned getNoWrapKind() const; 327 }; 328 329 /// Represents an op.with.overflow intrinsic. 330 class WithOverflowInst : public BinaryOpIntrinsic { 331 public: 332 static bool classof(const IntrinsicInst *I) { 333 switch (I->getIntrinsicID()) { 334 case Intrinsic::uadd_with_overflow: 335 case Intrinsic::sadd_with_overflow: 336 case Intrinsic::usub_with_overflow: 337 case Intrinsic::ssub_with_overflow: 338 case Intrinsic::umul_with_overflow: 339 case Intrinsic::smul_with_overflow: 340 return true; 341 default: 342 return false; 343 } 344 } 345 static bool classof(const Value *V) { 346 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 347 } 348 }; 349 350 /// Represents a saturating add/sub intrinsic. 351 class SaturatingInst : public BinaryOpIntrinsic { 352 public: 353 static bool classof(const IntrinsicInst *I) { 354 switch (I->getIntrinsicID()) { 355 case Intrinsic::uadd_sat: 356 case Intrinsic::sadd_sat: 357 case Intrinsic::usub_sat: 358 case Intrinsic::ssub_sat: 359 return true; 360 default: 361 return false; 362 } 363 } 364 static bool classof(const Value *V) { 365 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 366 } 367 }; 368 369 /// Common base class for all memory intrinsics. Simply provides 370 /// common methods. 371 /// Written as CRTP to avoid a common base class amongst the 372 /// three atomicity hierarchies. 373 template <typename Derived> class MemIntrinsicBase : public IntrinsicInst { 374 private: 375 enum { ARG_DEST = 0, ARG_LENGTH = 2 }; 376 377 public: 378 Value *getRawDest() const { 379 return const_cast<Value *>(getArgOperand(ARG_DEST)); 380 } 381 const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); } 382 Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); } 383 384 Value *getLength() const { 385 return const_cast<Value *>(getArgOperand(ARG_LENGTH)); 386 } 387 const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); } 388 Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); } 389 390 /// This is just like getRawDest, but it strips off any cast 391 /// instructions (including addrspacecast) that feed it, giving the 392 /// original input. The returned value is guaranteed to be a pointer. 393 Value *getDest() const { return getRawDest()->stripPointerCasts(); } 394 395 unsigned getDestAddressSpace() const { 396 return cast<PointerType>(getRawDest()->getType())->getAddressSpace(); 397 } 398 399 /// FIXME: Remove this function once transition to Align is over. 400 /// Use getDestAlign() instead. 401 unsigned getDestAlignment() const { 402 if (auto MA = getParamAlign(ARG_DEST)) 403 return MA->value(); 404 return 0; 405 } 406 MaybeAlign getDestAlign() const { return getParamAlign(ARG_DEST); } 407 408 /// Set the specified arguments of the instruction. 409 void setDest(Value *Ptr) { 410 assert(getRawDest()->getType() == Ptr->getType() && 411 "setDest called with pointer of wrong type!"); 412 setArgOperand(ARG_DEST, Ptr); 413 } 414 415 /// FIXME: Remove this function once transition to Align is over. 416 /// Use the version that takes MaybeAlign instead of this one. 417 void setDestAlignment(unsigned Alignment) { 418 setDestAlignment(MaybeAlign(Alignment)); 419 } 420 void setDestAlignment(MaybeAlign Alignment) { 421 removeParamAttr(ARG_DEST, Attribute::Alignment); 422 if (Alignment) 423 addParamAttr(ARG_DEST, 424 Attribute::getWithAlignment(getContext(), *Alignment)); 425 } 426 void setDestAlignment(Align Alignment) { 427 removeParamAttr(ARG_DEST, Attribute::Alignment); 428 addParamAttr(ARG_DEST, 429 Attribute::getWithAlignment(getContext(), Alignment)); 430 } 431 432 void setLength(Value *L) { 433 assert(getLength()->getType() == L->getType() && 434 "setLength called with value of wrong type!"); 435 setArgOperand(ARG_LENGTH, L); 436 } 437 }; 438 439 /// Common base class for all memory transfer intrinsics. Simply provides 440 /// common methods. 441 template <class BaseCL> class MemTransferBase : public BaseCL { 442 private: 443 enum { ARG_SOURCE = 1 }; 444 445 public: 446 /// Return the arguments to the instruction. 447 Value *getRawSource() const { 448 return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE)); 449 } 450 const Use &getRawSourceUse() const { 451 return BaseCL::getArgOperandUse(ARG_SOURCE); 452 } 453 Use &getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE); } 454 455 /// This is just like getRawSource, but it strips off any cast 456 /// instructions that feed it, giving the original input. The returned 457 /// value is guaranteed to be a pointer. 458 Value *getSource() const { return getRawSource()->stripPointerCasts(); } 459 460 unsigned getSourceAddressSpace() const { 461 return cast<PointerType>(getRawSource()->getType())->getAddressSpace(); 462 } 463 464 /// FIXME: Remove this function once transition to Align is over. 465 /// Use getSourceAlign() instead. 466 unsigned getSourceAlignment() const { 467 if (auto MA = BaseCL::getParamAlign(ARG_SOURCE)) 468 return MA->value(); 469 return 0; 470 } 471 472 MaybeAlign getSourceAlign() const { 473 return BaseCL::getParamAlign(ARG_SOURCE); 474 } 475 476 void setSource(Value *Ptr) { 477 assert(getRawSource()->getType() == Ptr->getType() && 478 "setSource called with pointer of wrong type!"); 479 BaseCL::setArgOperand(ARG_SOURCE, Ptr); 480 } 481 482 /// FIXME: Remove this function once transition to Align is over. 483 /// Use the version that takes MaybeAlign instead of this one. 484 void setSourceAlignment(unsigned Alignment) { 485 setSourceAlignment(MaybeAlign(Alignment)); 486 } 487 void setSourceAlignment(MaybeAlign Alignment) { 488 BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment); 489 if (Alignment) 490 BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment( 491 BaseCL::getContext(), *Alignment)); 492 } 493 void setSourceAlignment(Align Alignment) { 494 BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment); 495 BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment( 496 BaseCL::getContext(), Alignment)); 497 } 498 }; 499 500 /// Common base class for all memset intrinsics. Simply provides 501 /// common methods. 502 template <class BaseCL> class MemSetBase : public BaseCL { 503 private: 504 enum { ARG_VALUE = 1 }; 505 506 public: 507 Value *getValue() const { 508 return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE)); 509 } 510 const Use &getValueUse() const { return BaseCL::getArgOperandUse(ARG_VALUE); } 511 Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); } 512 513 void setValue(Value *Val) { 514 assert(getValue()->getType() == Val->getType() && 515 "setValue called with value of wrong type!"); 516 BaseCL::setArgOperand(ARG_VALUE, Val); 517 } 518 }; 519 520 // The common base class for the atomic memset/memmove/memcpy intrinsics 521 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove 522 class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> { 523 private: 524 enum { ARG_ELEMENTSIZE = 3 }; 525 526 public: 527 Value *getRawElementSizeInBytes() const { 528 return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE)); 529 } 530 531 ConstantInt *getElementSizeInBytesCst() const { 532 return cast<ConstantInt>(getRawElementSizeInBytes()); 533 } 534 535 uint32_t getElementSizeInBytes() const { 536 return getElementSizeInBytesCst()->getZExtValue(); 537 } 538 539 void setElementSizeInBytes(Constant *V) { 540 assert(V->getType() == Type::getInt8Ty(getContext()) && 541 "setElementSizeInBytes called with value of wrong type!"); 542 setArgOperand(ARG_ELEMENTSIZE, V); 543 } 544 545 static bool classof(const IntrinsicInst *I) { 546 switch (I->getIntrinsicID()) { 547 case Intrinsic::memcpy_element_unordered_atomic: 548 case Intrinsic::memmove_element_unordered_atomic: 549 case Intrinsic::memset_element_unordered_atomic: 550 return true; 551 default: 552 return false; 553 } 554 } 555 static bool classof(const Value *V) { 556 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 557 } 558 }; 559 560 /// This class represents atomic memset intrinsic 561 // i.e. llvm.element.unordered.atomic.memset 562 class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> { 563 public: 564 static bool classof(const IntrinsicInst *I) { 565 return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic; 566 } 567 static bool classof(const Value *V) { 568 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 569 } 570 }; 571 572 // This class wraps the atomic memcpy/memmove intrinsics 573 // i.e. llvm.element.unordered.atomic.memcpy/memmove 574 class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> { 575 public: 576 static bool classof(const IntrinsicInst *I) { 577 switch (I->getIntrinsicID()) { 578 case Intrinsic::memcpy_element_unordered_atomic: 579 case Intrinsic::memmove_element_unordered_atomic: 580 return true; 581 default: 582 return false; 583 } 584 } 585 static bool classof(const Value *V) { 586 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 587 } 588 }; 589 590 /// This class represents the atomic memcpy intrinsic 591 /// i.e. llvm.element.unordered.atomic.memcpy 592 class AtomicMemCpyInst : public AtomicMemTransferInst { 593 public: 594 static bool classof(const IntrinsicInst *I) { 595 return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic; 596 } 597 static bool classof(const Value *V) { 598 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 599 } 600 }; 601 602 /// This class represents the atomic memmove intrinsic 603 /// i.e. llvm.element.unordered.atomic.memmove 604 class AtomicMemMoveInst : public AtomicMemTransferInst { 605 public: 606 static bool classof(const IntrinsicInst *I) { 607 return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic; 608 } 609 static bool classof(const Value *V) { 610 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 611 } 612 }; 613 614 /// This is the common base class for memset/memcpy/memmove. 615 class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> { 616 private: 617 enum { ARG_VOLATILE = 3 }; 618 619 public: 620 ConstantInt *getVolatileCst() const { 621 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(ARG_VOLATILE))); 622 } 623 624 bool isVolatile() const { return !getVolatileCst()->isZero(); } 625 626 void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); } 627 628 // Methods for support type inquiry through isa, cast, and dyn_cast: 629 static bool classof(const IntrinsicInst *I) { 630 switch (I->getIntrinsicID()) { 631 case Intrinsic::memcpy: 632 case Intrinsic::memmove: 633 case Intrinsic::memset: 634 case Intrinsic::memcpy_inline: 635 return true; 636 default: 637 return false; 638 } 639 } 640 static bool classof(const Value *V) { 641 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 642 } 643 }; 644 645 /// This class wraps the llvm.memset intrinsic. 646 class MemSetInst : public MemSetBase<MemIntrinsic> { 647 public: 648 // Methods for support type inquiry through isa, cast, and dyn_cast: 649 static bool classof(const IntrinsicInst *I) { 650 return I->getIntrinsicID() == Intrinsic::memset; 651 } 652 static bool classof(const Value *V) { 653 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 654 } 655 }; 656 657 /// This class wraps the llvm.memcpy/memmove intrinsics. 658 class MemTransferInst : public MemTransferBase<MemIntrinsic> { 659 public: 660 // Methods for support type inquiry through isa, cast, and dyn_cast: 661 static bool classof(const IntrinsicInst *I) { 662 switch (I->getIntrinsicID()) { 663 case Intrinsic::memcpy: 664 case Intrinsic::memmove: 665 case Intrinsic::memcpy_inline: 666 return true; 667 default: 668 return false; 669 } 670 } 671 static bool classof(const Value *V) { 672 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 673 } 674 }; 675 676 /// This class wraps the llvm.memcpy intrinsic. 677 class MemCpyInst : public MemTransferInst { 678 public: 679 // Methods for support type inquiry through isa, cast, and dyn_cast: 680 static bool classof(const IntrinsicInst *I) { 681 return I->getIntrinsicID() == Intrinsic::memcpy; 682 } 683 static bool classof(const Value *V) { 684 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 685 } 686 }; 687 688 /// This class wraps the llvm.memmove intrinsic. 689 class MemMoveInst : public MemTransferInst { 690 public: 691 // Methods for support type inquiry through isa, cast, and dyn_cast: 692 static bool classof(const IntrinsicInst *I) { 693 return I->getIntrinsicID() == Intrinsic::memmove; 694 } 695 static bool classof(const Value *V) { 696 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 697 } 698 }; 699 700 /// This class wraps the llvm.memcpy.inline intrinsic. 701 class MemCpyInlineInst : public MemTransferInst { 702 public: 703 ConstantInt *getLength() const { 704 return cast<ConstantInt>(MemTransferInst::getLength()); 705 } 706 // Methods for support type inquiry through isa, cast, and dyn_cast: 707 static bool classof(const IntrinsicInst *I) { 708 return I->getIntrinsicID() == Intrinsic::memcpy_inline; 709 } 710 static bool classof(const Value *V) { 711 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 712 } 713 }; 714 715 // The common base class for any memset/memmove/memcpy intrinsics; 716 // whether they be atomic or non-atomic. 717 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove 718 // and llvm.memset/memcpy/memmove 719 class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> { 720 public: 721 bool isVolatile() const { 722 // Only the non-atomic intrinsics can be volatile 723 if (auto *MI = dyn_cast<MemIntrinsic>(this)) 724 return MI->isVolatile(); 725 return false; 726 } 727 728 static bool classof(const IntrinsicInst *I) { 729 switch (I->getIntrinsicID()) { 730 case Intrinsic::memcpy: 731 case Intrinsic::memcpy_inline: 732 case Intrinsic::memmove: 733 case Intrinsic::memset: 734 case Intrinsic::memcpy_element_unordered_atomic: 735 case Intrinsic::memmove_element_unordered_atomic: 736 case Intrinsic::memset_element_unordered_atomic: 737 return true; 738 default: 739 return false; 740 } 741 } 742 static bool classof(const Value *V) { 743 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 744 } 745 }; 746 747 /// This class represents any memset intrinsic 748 // i.e. llvm.element.unordered.atomic.memset 749 // and llvm.memset 750 class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> { 751 public: 752 static bool classof(const IntrinsicInst *I) { 753 switch (I->getIntrinsicID()) { 754 case Intrinsic::memset: 755 case Intrinsic::memset_element_unordered_atomic: 756 return true; 757 default: 758 return false; 759 } 760 } 761 static bool classof(const Value *V) { 762 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 763 } 764 }; 765 766 // This class wraps any memcpy/memmove intrinsics 767 // i.e. llvm.element.unordered.atomic.memcpy/memmove 768 // and llvm.memcpy/memmove 769 class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> { 770 public: 771 static bool classof(const IntrinsicInst *I) { 772 switch (I->getIntrinsicID()) { 773 case Intrinsic::memcpy: 774 case Intrinsic::memcpy_inline: 775 case Intrinsic::memmove: 776 case Intrinsic::memcpy_element_unordered_atomic: 777 case Intrinsic::memmove_element_unordered_atomic: 778 return true; 779 default: 780 return false; 781 } 782 } 783 static bool classof(const Value *V) { 784 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 785 } 786 }; 787 788 /// This class represents any memcpy intrinsic 789 /// i.e. llvm.element.unordered.atomic.memcpy 790 /// and llvm.memcpy 791 class AnyMemCpyInst : public AnyMemTransferInst { 792 public: 793 static bool classof(const IntrinsicInst *I) { 794 switch (I->getIntrinsicID()) { 795 case Intrinsic::memcpy: 796 case Intrinsic::memcpy_inline: 797 case Intrinsic::memcpy_element_unordered_atomic: 798 return true; 799 default: 800 return false; 801 } 802 } 803 static bool classof(const Value *V) { 804 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 805 } 806 }; 807 808 /// This class represents any memmove intrinsic 809 /// i.e. llvm.element.unordered.atomic.memmove 810 /// and llvm.memmove 811 class AnyMemMoveInst : public AnyMemTransferInst { 812 public: 813 static bool classof(const IntrinsicInst *I) { 814 switch (I->getIntrinsicID()) { 815 case Intrinsic::memmove: 816 case Intrinsic::memmove_element_unordered_atomic: 817 return true; 818 default: 819 return false; 820 } 821 } 822 static bool classof(const Value *V) { 823 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 824 } 825 }; 826 827 /// This represents the llvm.va_start intrinsic. 828 class VAStartInst : public IntrinsicInst { 829 public: 830 static bool classof(const IntrinsicInst *I) { 831 return I->getIntrinsicID() == Intrinsic::vastart; 832 } 833 static bool classof(const Value *V) { 834 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 835 } 836 837 Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); } 838 }; 839 840 /// This represents the llvm.va_end intrinsic. 841 class VAEndInst : public IntrinsicInst { 842 public: 843 static bool classof(const IntrinsicInst *I) { 844 return I->getIntrinsicID() == Intrinsic::vaend; 845 } 846 static bool classof(const Value *V) { 847 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 848 } 849 850 Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); } 851 }; 852 853 /// This represents the llvm.va_copy intrinsic. 854 class VACopyInst : public IntrinsicInst { 855 public: 856 static bool classof(const IntrinsicInst *I) { 857 return I->getIntrinsicID() == Intrinsic::vacopy; 858 } 859 static bool classof(const Value *V) { 860 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 861 } 862 863 Value *getDest() const { return const_cast<Value *>(getArgOperand(0)); } 864 Value *getSrc() const { return const_cast<Value *>(getArgOperand(1)); } 865 }; 866 867 /// This represents the llvm.instrprof_increment intrinsic. 868 class InstrProfIncrementInst : public IntrinsicInst { 869 public: 870 static bool classof(const IntrinsicInst *I) { 871 return I->getIntrinsicID() == Intrinsic::instrprof_increment; 872 } 873 static bool classof(const Value *V) { 874 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 875 } 876 877 GlobalVariable *getName() const { 878 return cast<GlobalVariable>( 879 const_cast<Value *>(getArgOperand(0))->stripPointerCasts()); 880 } 881 882 ConstantInt *getHash() const { 883 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); 884 } 885 886 ConstantInt *getNumCounters() const { 887 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2))); 888 } 889 890 ConstantInt *getIndex() const { 891 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 892 } 893 894 Value *getStep() const; 895 }; 896 897 class InstrProfIncrementInstStep : public InstrProfIncrementInst { 898 public: 899 static bool classof(const IntrinsicInst *I) { 900 return I->getIntrinsicID() == Intrinsic::instrprof_increment_step; 901 } 902 static bool classof(const Value *V) { 903 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 904 } 905 }; 906 907 /// This represents the llvm.instrprof_value_profile intrinsic. 908 class InstrProfValueProfileInst : public IntrinsicInst { 909 public: 910 static bool classof(const IntrinsicInst *I) { 911 return I->getIntrinsicID() == Intrinsic::instrprof_value_profile; 912 } 913 static bool classof(const Value *V) { 914 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 915 } 916 917 GlobalVariable *getName() const { 918 return cast<GlobalVariable>( 919 const_cast<Value *>(getArgOperand(0))->stripPointerCasts()); 920 } 921 922 ConstantInt *getHash() const { 923 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); 924 } 925 926 Value *getTargetValue() const { 927 return cast<Value>(const_cast<Value *>(getArgOperand(2))); 928 } 929 930 ConstantInt *getValueKind() const { 931 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 932 } 933 934 // Returns the value site index. 935 ConstantInt *getIndex() const { 936 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4))); 937 } 938 }; 939 940 } // end namespace llvm 941 942 #endif // LLVM_IR_INTRINSICINST_H 943