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

Generated by: LCOV version 1.13