LCOV - code coverage report
Current view: top level - include/llvm/IR - IntrinsicInst.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 57 57 100.0 %
Date: 2018-07-13 00:08:38 Functions: 10 10 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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    59476395 :       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   111062800 :       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      458780 :       return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
      90             :     }
      91             : 
      92             :     Metadata *getRawExpression() const {
      93      348969 :       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     8732883 :       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      103320 :     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     3915119 :       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     1081191 :       return getVariableLocation(/* AllowNullOp = */ false);
     154             :     }
     155             : 
     156             :     /// \name Casting methods
     157             :     /// @{
     158             :     static bool classof(const IntrinsicInst *I) {
     159        2341 :       return I->getIntrinsicID() == Intrinsic::dbg_value;
     160             :     }
     161             :     static bool classof(const Value *V) {
     162     2890112 :       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         114 :       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     1763516 :       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      178384 :       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      283253 :       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        1104 :       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          17 :       setArgOperand(ARG_DEST, Ptr);
     284             :     }
     285             : 
     286       53468 :     void setDestAlignment(unsigned Align) {
     287       53468 :       removeParamAttr(ARG_DEST, Attribute::Alignment);
     288       53468 :       if (Align > 0)
     289       53465 :         addParamAttr(ARG_DEST,
     290             :                      Attribute::getWithAlignment(getContext(), Align));
     291       53468 :     }
     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       41303 :       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         552 :       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          13 :       BaseCL::setArgOperand(ARG_SOURCE, Ptr);
     333             :     }
     334             : 
     335       13897 :     void setSourceAlignment(unsigned Align) {
     336       13897 :       BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
     337       13897 :       if (Align > 0)
     338       13895 :         BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment(
     339             :                                              BaseCL::getContext(), Align));
     340       13897 :     }
     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      221873 :       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         411 :       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          18 :       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          36 :     static bool classof(const Value *V) {
     401          36 :       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        1251 :       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      420385 :       return cast<ConstantInt>(
     467             :           const_cast<Value *>(getArgOperand(ARG_VOLATILE)));
     468             :     }
     469             : 
     470      420385 :     bool isVolatile() const {
     471      420385 :       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     7087602 :     static bool classof(const Value *V) {
     487     7087602 :       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      329009 :       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      126934 :       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      135595 :       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      134346 :       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         120 :     bool isVolatile() const {
     547             :       // Only the non-atomic intrinsics can be volatile
     548             :       if (auto *MI = dyn_cast<MemIntrinsic>(this))
     549         110 :         return MI->isVolatile();
     550             :       return false;
     551             :     }
     552             : 
     553             :     static bool classof(const IntrinsicInst *I) {
     554      837576 :       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      259683 :       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      443947 :       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     2747124 :       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      172853 :       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        1251 :       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
     697             :     }
     698             : 
     699             :     GlobalVariable *getName() const {
     700        2052 :       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         837 :       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         875 :       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         913 :       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
     737             :     }
     738             : 
     739             :     GlobalVariable *getName() const {
     740          36 :       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

Generated by: LCOV version 1.13