|  | //===-- llvm/IntrinsicInst.h - Intrinsic Instruction Wrappers ---*- C++ -*-===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This file defines classes that make it really easy to deal with intrinsic | 
|  | // functions with the isa/dyncast family of functions.  In particular, this | 
|  | // allows you to do things like: | 
|  | // | 
|  | //     if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(Inst)) | 
|  | //        ... MCI->getDest() ... MCI->getSource() ... | 
|  | // | 
|  | // All intrinsic function calls are instances of the call instruction, so these | 
|  | // are all subclasses of the CallInst class.  Note that none of these classes | 
|  | // has state or virtual methods, which is an important part of this gross/neat | 
|  | // hack working. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef LLVM_INTRINSICINST_H | 
|  | #define LLVM_INTRINSICINST_H | 
|  |  | 
|  | #include "llvm/Constants.h" | 
|  | #include "llvm/Function.h" | 
|  | #include "llvm/Instructions.h" | 
|  | #include "llvm/Intrinsics.h" | 
|  |  | 
|  | namespace llvm { | 
|  | /// IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic | 
|  | /// functions.  This allows the standard isa/dyncast/cast functionality to | 
|  | /// work with calls to intrinsic functions. | 
|  | class IntrinsicInst : public CallInst { | 
|  | IntrinsicInst();                      // DO NOT IMPLEMENT | 
|  | IntrinsicInst(const IntrinsicInst&);  // DO NOT IMPLEMENT | 
|  | void operator=(const IntrinsicInst&); // DO NOT IMPLEMENT | 
|  | public: | 
|  | /// getIntrinsicID - Return the intrinsic ID of this intrinsic. | 
|  | /// | 
|  | Intrinsic::ID getIntrinsicID() const { | 
|  | return (Intrinsic::ID)getCalledFunction()->getIntrinsicID(); | 
|  | } | 
|  |  | 
|  | // Methods for support type inquiry through isa, cast, and dyn_cast: | 
|  | static inline bool classof(const IntrinsicInst *) { return true; } | 
|  | static inline bool classof(const CallInst *I) { | 
|  | if (const Function *CF = I->getCalledFunction()) | 
|  | return CF->getIntrinsicID() != 0; | 
|  | return false; | 
|  | } | 
|  | static inline bool classof(const Value *V) { | 
|  | return isa<CallInst>(V) && classof(cast<CallInst>(V)); | 
|  | } | 
|  | }; | 
|  |  | 
|  | /// DbgInfoIntrinsic - This is the common base class for debug info intrinsics | 
|  | /// | 
|  | class DbgInfoIntrinsic : public IntrinsicInst { | 
|  | public: | 
|  |  | 
|  | // Methods for support type inquiry through isa, cast, and dyn_cast: | 
|  | static inline bool classof(const DbgInfoIntrinsic *) { return true; } | 
|  | static inline bool classof(const IntrinsicInst *I) { | 
|  | switch (I->getIntrinsicID()) { | 
|  | case Intrinsic::dbg_declare: | 
|  | case Intrinsic::dbg_value: | 
|  | return true; | 
|  | default: return false; | 
|  | } | 
|  | } | 
|  | static inline bool classof(const Value *V) { | 
|  | return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); | 
|  | } | 
|  |  | 
|  | static Value *StripCast(Value *C); | 
|  | }; | 
|  |  | 
|  | /// DbgDeclareInst - This represents the llvm.dbg.declare instruction. | 
|  | /// | 
|  | class DbgDeclareInst : public DbgInfoIntrinsic { | 
|  | public: | 
|  | Value *getAddress() const; | 
|  | MDNode *getVariable() const { return cast<MDNode>(getArgOperand(1)); } | 
|  |  | 
|  | // Methods for support type inquiry through isa, cast, and dyn_cast: | 
|  | static inline bool classof(const DbgDeclareInst *) { return true; } | 
|  | static inline bool classof(const IntrinsicInst *I) { | 
|  | return I->getIntrinsicID() == Intrinsic::dbg_declare; | 
|  | } | 
|  | static inline bool classof(const Value *V) { | 
|  | return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); | 
|  | } | 
|  | }; | 
|  |  | 
|  | /// DbgValueInst - This represents the llvm.dbg.value instruction. | 
|  | /// | 
|  | class DbgValueInst : public DbgInfoIntrinsic { | 
|  | public: | 
|  | const Value *getValue() const; | 
|  | Value *getValue(); | 
|  | uint64_t getOffset() const { | 
|  | return cast<ConstantInt>( | 
|  | const_cast<Value*>(getArgOperand(1)))->getZExtValue(); | 
|  | } | 
|  | MDNode *getVariable() const { return cast<MDNode>(getArgOperand(2)); } | 
|  |  | 
|  | // Methods for support type inquiry through isa, cast, and dyn_cast: | 
|  | static inline bool classof(const DbgValueInst *) { return true; } | 
|  | static inline bool classof(const IntrinsicInst *I) { | 
|  | return I->getIntrinsicID() == Intrinsic::dbg_value; | 
|  | } | 
|  | static inline bool classof(const Value *V) { | 
|  | return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); | 
|  | } | 
|  | }; | 
|  |  | 
|  | /// MemIntrinsic - This is the common base class for memset/memcpy/memmove. | 
|  | /// | 
|  | class MemIntrinsic : public IntrinsicInst { | 
|  | public: | 
|  | Value *getRawDest() const { return const_cast<Value*>(getArgOperand(0)); } | 
|  |  | 
|  | Value *getLength() const { return const_cast<Value*>(getArgOperand(2)); } | 
|  | ConstantInt *getAlignmentCst() const { | 
|  | return cast<ConstantInt>(const_cast<Value*>(getArgOperand(3))); | 
|  | } | 
|  |  | 
|  | unsigned getAlignment() const { | 
|  | return getAlignmentCst()->getZExtValue(); | 
|  | } | 
|  |  | 
|  | ConstantInt *getVolatileCst() const { | 
|  | return cast<ConstantInt>(const_cast<Value*>(getArgOperand(4))); | 
|  | } | 
|  | bool isVolatile() const { | 
|  | return !getVolatileCst()->isZero(); | 
|  | } | 
|  |  | 
|  | unsigned getDestAddressSpace() const { | 
|  | return cast<PointerType>(getRawDest()->getType())->getAddressSpace(); | 
|  | } | 
|  |  | 
|  | /// getDest - This is just like getRawDest, but it strips off any cast | 
|  | /// instructions that feed it, giving the original input.  The returned | 
|  | /// value is guaranteed to be a pointer. | 
|  | Value *getDest() const { return getRawDest()->stripPointerCasts(); } | 
|  |  | 
|  | /// set* - Set the specified arguments of the instruction. | 
|  | /// | 
|  | void setDest(Value *Ptr) { | 
|  | assert(getRawDest()->getType() == Ptr->getType() && | 
|  | "setDest called with pointer of wrong type!"); | 
|  | setArgOperand(0, Ptr); | 
|  | } | 
|  |  | 
|  | void setLength(Value *L) { | 
|  | assert(getLength()->getType() == L->getType() && | 
|  | "setLength called with value of wrong type!"); | 
|  | setArgOperand(2, L); | 
|  | } | 
|  |  | 
|  | void setAlignment(Constant* A) { | 
|  | setArgOperand(3, A); | 
|  | } | 
|  |  | 
|  | void setVolatile(Constant* V) { | 
|  | setArgOperand(4, V); | 
|  | } | 
|  |  | 
|  | Type *getAlignmentType() const { | 
|  | return getArgOperand(3)->getType(); | 
|  | } | 
|  |  | 
|  | // Methods for support type inquiry through isa, cast, and dyn_cast: | 
|  | static inline bool classof(const MemIntrinsic *) { return true; } | 
|  | static inline bool classof(const IntrinsicInst *I) { | 
|  | switch (I->getIntrinsicID()) { | 
|  | case Intrinsic::memcpy: | 
|  | case Intrinsic::memmove: | 
|  | case Intrinsic::memset: | 
|  | return true; | 
|  | default: return false; | 
|  | } | 
|  | } | 
|  | static inline bool classof(const Value *V) { | 
|  | return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); | 
|  | } | 
|  | }; | 
|  |  | 
|  | /// MemSetInst - This class wraps the llvm.memset intrinsic. | 
|  | /// | 
|  | class MemSetInst : public MemIntrinsic { | 
|  | public: | 
|  | /// get* - Return the arguments to the instruction. | 
|  | /// | 
|  | Value *getValue() const { return const_cast<Value*>(getArgOperand(1)); } | 
|  |  | 
|  | void setValue(Value *Val) { | 
|  | assert(getValue()->getType() == Val->getType() && | 
|  | "setValue called with value of wrong type!"); | 
|  | setArgOperand(1, Val); | 
|  | } | 
|  |  | 
|  | // Methods for support type inquiry through isa, cast, and dyn_cast: | 
|  | static inline bool classof(const MemSetInst *) { return true; } | 
|  | static inline bool classof(const IntrinsicInst *I) { | 
|  | return I->getIntrinsicID() == Intrinsic::memset; | 
|  | } | 
|  | static inline bool classof(const Value *V) { | 
|  | return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); | 
|  | } | 
|  | }; | 
|  |  | 
|  | /// MemTransferInst - This class wraps the llvm.memcpy/memmove intrinsics. | 
|  | /// | 
|  | class MemTransferInst : public MemIntrinsic { | 
|  | public: | 
|  | /// get* - Return the arguments to the instruction. | 
|  | /// | 
|  | Value *getRawSource() const { return const_cast<Value*>(getArgOperand(1)); } | 
|  |  | 
|  | /// getSource - This is just like getRawSource, but it strips off any cast | 
|  | /// instructions that feed it, giving the original input.  The returned | 
|  | /// value is guaranteed to be a pointer. | 
|  | Value *getSource() const { return getRawSource()->stripPointerCasts(); } | 
|  |  | 
|  | unsigned getSourceAddressSpace() const { | 
|  | return cast<PointerType>(getRawSource()->getType())->getAddressSpace(); | 
|  | } | 
|  |  | 
|  | void setSource(Value *Ptr) { | 
|  | assert(getRawSource()->getType() == Ptr->getType() && | 
|  | "setSource called with pointer of wrong type!"); | 
|  | setArgOperand(1, Ptr); | 
|  | } | 
|  |  | 
|  | // Methods for support type inquiry through isa, cast, and dyn_cast: | 
|  | static inline bool classof(const MemTransferInst *) { return true; } | 
|  | static inline bool classof(const IntrinsicInst *I) { | 
|  | return I->getIntrinsicID() == Intrinsic::memcpy || | 
|  | I->getIntrinsicID() == Intrinsic::memmove; | 
|  | } | 
|  | static inline bool classof(const Value *V) { | 
|  | return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); | 
|  | } | 
|  | }; | 
|  |  | 
|  |  | 
|  | /// MemCpyInst - This class wraps the llvm.memcpy intrinsic. | 
|  | /// | 
|  | class MemCpyInst : public MemTransferInst { | 
|  | public: | 
|  | // Methods for support type inquiry through isa, cast, and dyn_cast: | 
|  | static inline bool classof(const MemCpyInst *) { return true; } | 
|  | static inline bool classof(const IntrinsicInst *I) { | 
|  | return I->getIntrinsicID() == Intrinsic::memcpy; | 
|  | } | 
|  | static inline bool classof(const Value *V) { | 
|  | return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); | 
|  | } | 
|  | }; | 
|  |  | 
|  | /// MemMoveInst - This class wraps the llvm.memmove intrinsic. | 
|  | /// | 
|  | class MemMoveInst : public MemTransferInst { | 
|  | public: | 
|  | // Methods for support type inquiry through isa, cast, and dyn_cast: | 
|  | static inline bool classof(const MemMoveInst *) { return true; } | 
|  | static inline bool classof(const IntrinsicInst *I) { | 
|  | return I->getIntrinsicID() == Intrinsic::memmove; | 
|  | } | 
|  | static inline bool classof(const Value *V) { | 
|  | return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); | 
|  | } | 
|  | }; | 
|  |  | 
|  | /// EHExceptionInst - This represents the llvm.eh.exception instruction. | 
|  | /// | 
|  | class EHExceptionInst : public IntrinsicInst { | 
|  | public: | 
|  | // Methods for support type inquiry through isa, cast, and dyn_cast: | 
|  | static inline bool classof(const EHExceptionInst *) { return true; } | 
|  | static inline bool classof(const IntrinsicInst *I) { | 
|  | return I->getIntrinsicID() == Intrinsic::eh_exception; | 
|  | } | 
|  | static inline bool classof(const Value *V) { | 
|  | return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); | 
|  | } | 
|  | }; | 
|  |  | 
|  | /// EHSelectorInst - This represents the llvm.eh.selector instruction. | 
|  | /// | 
|  | class EHSelectorInst : public IntrinsicInst { | 
|  | public: | 
|  | // Methods for support type inquiry through isa, cast, and dyn_cast: | 
|  | static inline bool classof(const EHSelectorInst *) { return true; } | 
|  | static inline bool classof(const IntrinsicInst *I) { | 
|  | return I->getIntrinsicID() == Intrinsic::eh_selector; | 
|  | } | 
|  | static inline bool classof(const Value *V) { | 
|  | return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); | 
|  | } | 
|  | }; | 
|  |  | 
|  | } | 
|  |  | 
|  | #endif |