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

Generated by: LCOV version 1.13