Home | History | Annotate | Download | only in IR
      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 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   /// 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.
     76     bool isAddressOfVariable() const {
     77       return getIntrinsicID() != Intrinsic::dbg_value;
     78     }
     79 
     80     DILocalVariable *getVariable() const {
     81       return cast<DILocalVariable>(getRawVariable());
     82     }
     83 
     84     DIExpression *getExpression() const {
     85       return cast<DIExpression>(getRawExpression());
     86     }
     87 
     88     Metadata *getRawVariable() const {
     89       return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
     90     }
     91 
     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     /// @{
    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     }
    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:
    121     Value *getAddress() const { return getVariableLocation(); }
    122 
    123     /// \name Casting methods
    124     /// @{
    125     static bool classof(const IntrinsicInst *I) {
    126       return I->getIntrinsicID() == Intrinsic::dbg_declare;
    127     }
    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:
    137     Value *getAddress() const { return getVariableLocation(); }
    138 
    139     /// \name Casting methods
    140     /// @{
    141     static bool classof(const IntrinsicInst *I) {
    142       return I->getIntrinsicID() == Intrinsic::dbg_addr;
    143     }
    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:
    152     Value *getValue() const {
    153       return getVariableLocation(/* AllowNullOp = */ false);
    154     }
    155 
    156     /// \name Casting methods
    157     /// @{
    158     static bool classof(const IntrinsicInst *I) {
    159       return I->getIntrinsicID() == Intrinsic::dbg_value;
    160     }
    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:
    170     DILabel *getLabel() const {
    171       return cast<DILabel>(getRawVariable());
    172     }
    173 
    174     Metadata *getRawVariable() const {
    175       return cast<MetadataAsValue>(getArgOperand(0))->getMetadata();
    176     }
    177 
    178     Metadata *getRawExpression() const {
    179       return nullptr;
    180     }
    181 
    182     /// Methods for support type inquiry through isa, cast, and dyn_cast:
    183     /// @{
    184     static bool classof(const IntrinsicInst *I) {
    185       return I->getIntrinsicID() == Intrinsic::dbg_label;
    186     }
    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:
    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     }
    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:
    256     Value *getRawDest() const {
    257       return const_cast<Value *>(getArgOperand(ARG_DEST));
    258     }
    259     const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
    260     Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
    261 
    262     Value *getLength() const {
    263       return const_cast<Value *>(getArgOperand(ARG_LENGTH));
    264     }
    265     const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
    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.
    271     Value *getDest() const { return getRawDest()->stripPointerCasts(); }
    272 
    273     unsigned getDestAddressSpace() const {
    274       return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
    275     }
    276 
    277     unsigned getDestAlignment() const { return getParamAlignment(ARG_DEST); }
    278 
    279     /// Set the specified arguments of the instruction.
    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 
    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 
    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.
    308     Value *getRawSource() const {
    309       return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE));
    310     }
    311     const Use &getRawSourceUse() const {
    312       return BaseCL::getArgOperandUse(ARG_SOURCE);
    313     }
    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.
    319     Value *getSource() const { return getRawSource()->stripPointerCasts(); }
    320 
    321     unsigned getSourceAddressSpace() const {
    322       return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
    323     }
    324 
    325     unsigned getSourceAlignment() const {
    326       return BaseCL::getParamAlignment(ARG_SOURCE);
    327     }
    328 
    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 
    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:
    350     Value *getValue() const {
    351       return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE));
    352     }
    353     const Use &getValueUse() const {
    354       return BaseCL::getArgOperandUse(ARG_VALUE);
    355     }
    356     Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); }
    357 
    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:
    372     Value *getRawElementSizeInBytes() const {
    373       return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
    374     }
    375 
    376     ConstantInt *getElementSizeInBytesCst() const {
    377       return cast<ConstantInt>(getRawElementSizeInBytes());
    378     }
    379 
    380     uint32_t getElementSizeInBytes() const {
    381       return getElementSizeInBytesCst()->getZExtValue();
    382     }
    383 
    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 
    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     }
    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:
    409     static bool classof(const IntrinsicInst *I) {
    410       return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic;
    411     }
    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:
    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     }
    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:
    439     static bool classof(const IntrinsicInst *I) {
    440       return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
    441     }
    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:
    451     static bool classof(const IntrinsicInst *I) {
    452       return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic;
    453     }
    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:
    465     ConstantInt *getVolatileCst() const {
    466       return cast<ConstantInt>(
    467           const_cast<Value *>(getArgOperand(ARG_VOLATILE)));
    468     }
    469 
    470     bool isVolatile() const {
    471       return !getVolatileCst()->isZero();
    472     }
    473 
    474     void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); }
    475 
    476     // Methods for support type inquiry through isa, cast, and dyn_cast:
    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     }
    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:
    495     static bool classof(const IntrinsicInst *I) {
    496       return I->getIntrinsicID() == Intrinsic::memset;
    497     }
    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:
    507     static bool classof(const IntrinsicInst *I) {
    508       return I->getIntrinsicID() == Intrinsic::memcpy ||
    509              I->getIntrinsicID() == Intrinsic::memmove;
    510     }
    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:
    520     static bool classof(const IntrinsicInst *I) {
    521       return I->getIntrinsicID() == Intrinsic::memcpy;
    522     }
    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:
    532     static bool classof(const IntrinsicInst *I) {
    533       return I->getIntrinsicID() == Intrinsic::memmove;
    534     }
    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:
    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 
    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     }
    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:
    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     }
    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:
    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     }
    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:
    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     }
    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:
    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     }
    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:
    652     static bool classof(const IntrinsicInst *I) {
    653       return I->getIntrinsicID() == Intrinsic::vastart;
    654     }
    655     static bool classof(const Value *V) {
    656       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
    657     }
    658 
    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:
    665     static bool classof(const IntrinsicInst *I) {
    666       return I->getIntrinsicID() == Intrinsic::vaend;
    667     }
    668     static bool classof(const Value *V) {
    669       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
    670     }
    671 
    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:
    678     static bool classof(const IntrinsicInst *I) {
    679       return I->getIntrinsicID() == Intrinsic::vacopy;
    680     }
    681     static bool classof(const Value *V) {
    682       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
    683     }
    684 
    685     Value *getDest() const { return const_cast<Value*>(getArgOperand(0)); }
    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:
    692     static bool classof(const IntrinsicInst *I) {
    693       return I->getIntrinsicID() == Intrinsic::instrprof_increment;
    694     }
    695     static bool classof(const Value *V) {
    696       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
    697     }
    698 
    699     GlobalVariable *getName() const {
    700       return cast<GlobalVariable>(
    701           const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
    702     }
    703 
    704     ConstantInt *getHash() const {
    705       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
    706     }
    707 
    708     ConstantInt *getNumCounters() const {
    709       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
    710     }
    711 
    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:
    721     static bool classof(const IntrinsicInst *I) {
    722       return I->getIntrinsicID() == Intrinsic::instrprof_increment_step;
    723     }
    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:
    732     static bool classof(const IntrinsicInst *I) {
    733       return I->getIntrinsicID() == Intrinsic::instrprof_value_profile;
    734     }
    735     static bool classof(const Value *V) {
    736       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
    737     }
    738 
    739     GlobalVariable *getName() const {
    740       return cast<GlobalVariable>(
    741           const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
    742     }
    743 
    744     ConstantInt *getHash() const {
    745       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
    746     }
    747 
    748     Value *getTargetValue() const {
    749       return cast<Value>(const_cast<Value *>(getArgOperand(2)));
    750     }
    751 
    752     ConstantInt *getValueKind() const {
    753       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
    754     }
    755 
    756     // Returns the value site index.
    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