1249259Sdim//===-- llvm/IntrinsicInst.h - Intrinsic Instruction Wrappers ---*- C++ -*-===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file defines classes that make it really easy to deal with intrinsic 11249259Sdim// functions with the isa/dyncast family of functions. In particular, this 12249259Sdim// allows you to do things like: 13249259Sdim// 14249259Sdim// if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(Inst)) 15249259Sdim// ... MCI->getDest() ... MCI->getSource() ... 16249259Sdim// 17249259Sdim// All intrinsic function calls are instances of the call instruction, so these 18249259Sdim// are all subclasses of the CallInst class. Note that none of these classes 19249259Sdim// has state or virtual methods, which is an important part of this gross/neat 20249259Sdim// hack working. 21249259Sdim// 22249259Sdim//===----------------------------------------------------------------------===// 23249259Sdim 24249259Sdim#ifndef LLVM_IR_INTRINSICINST_H 25249259Sdim#define LLVM_IR_INTRINSICINST_H 26249259Sdim 27249259Sdim#include "llvm/IR/Constants.h" 28249259Sdim#include "llvm/IR/Function.h" 29249259Sdim#include "llvm/IR/Instructions.h" 30249259Sdim#include "llvm/IR/Intrinsics.h" 31249259Sdim 32249259Sdimnamespace llvm { 33249259Sdim /// IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic 34249259Sdim /// functions. This allows the standard isa/dyncast/cast functionality to 35249259Sdim /// work with calls to intrinsic functions. 36249259Sdim class IntrinsicInst : public CallInst { 37249259Sdim IntrinsicInst() LLVM_DELETED_FUNCTION; 38249259Sdim IntrinsicInst(const IntrinsicInst&) LLVM_DELETED_FUNCTION; 39249259Sdim void operator=(const IntrinsicInst&) LLVM_DELETED_FUNCTION; 40249259Sdim public: 41249259Sdim /// getIntrinsicID - Return the intrinsic ID of this intrinsic. 42249259Sdim /// 43249259Sdim Intrinsic::ID getIntrinsicID() const { 44249259Sdim return (Intrinsic::ID)getCalledFunction()->getIntrinsicID(); 45249259Sdim } 46249259Sdim 47249259Sdim // Methods for support type inquiry through isa, cast, and dyn_cast: 48249259Sdim static inline bool classof(const CallInst *I) { 49249259Sdim if (const Function *CF = I->getCalledFunction()) 50249259Sdim return CF->isIntrinsic(); 51249259Sdim return false; 52249259Sdim } 53249259Sdim static inline bool classof(const Value *V) { 54249259Sdim return isa<CallInst>(V) && classof(cast<CallInst>(V)); 55249259Sdim } 56249259Sdim }; 57249259Sdim 58249259Sdim /// DbgInfoIntrinsic - This is the common base class for debug info intrinsics 59249259Sdim /// 60249259Sdim class DbgInfoIntrinsic : public IntrinsicInst { 61249259Sdim public: 62249259Sdim 63249259Sdim // Methods for support type inquiry through isa, cast, and dyn_cast: 64249259Sdim static inline bool classof(const IntrinsicInst *I) { 65249259Sdim switch (I->getIntrinsicID()) { 66249259Sdim case Intrinsic::dbg_declare: 67249259Sdim case Intrinsic::dbg_value: 68249259Sdim return true; 69249259Sdim default: return false; 70249259Sdim } 71249259Sdim } 72249259Sdim static inline bool classof(const Value *V) { 73249259Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 74249259Sdim } 75249259Sdim 76249259Sdim static Value *StripCast(Value *C); 77249259Sdim }; 78249259Sdim 79249259Sdim /// DbgDeclareInst - This represents the llvm.dbg.declare instruction. 80249259Sdim /// 81249259Sdim class DbgDeclareInst : public DbgInfoIntrinsic { 82249259Sdim public: 83249259Sdim Value *getAddress() const; 84249259Sdim MDNode *getVariable() const { return cast<MDNode>(getArgOperand(1)); } 85249259Sdim 86249259Sdim // Methods for support type inquiry through isa, cast, and dyn_cast: 87249259Sdim static inline bool classof(const IntrinsicInst *I) { 88249259Sdim return I->getIntrinsicID() == Intrinsic::dbg_declare; 89249259Sdim } 90249259Sdim static inline bool classof(const Value *V) { 91249259Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 92249259Sdim } 93249259Sdim }; 94249259Sdim 95249259Sdim /// DbgValueInst - This represents the llvm.dbg.value instruction. 96249259Sdim /// 97249259Sdim class DbgValueInst : public DbgInfoIntrinsic { 98249259Sdim public: 99249259Sdim const Value *getValue() const; 100249259Sdim Value *getValue(); 101249259Sdim uint64_t getOffset() const { 102249259Sdim return cast<ConstantInt>( 103249259Sdim const_cast<Value*>(getArgOperand(1)))->getZExtValue(); 104249259Sdim } 105249259Sdim MDNode *getVariable() const { return cast<MDNode>(getArgOperand(2)); } 106249259Sdim 107249259Sdim // Methods for support type inquiry through isa, cast, and dyn_cast: 108249259Sdim static inline bool classof(const IntrinsicInst *I) { 109249259Sdim return I->getIntrinsicID() == Intrinsic::dbg_value; 110249259Sdim } 111249259Sdim static inline bool classof(const Value *V) { 112249259Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 113249259Sdim } 114249259Sdim }; 115249259Sdim 116249259Sdim /// MemIntrinsic - This is the common base class for memset/memcpy/memmove. 117249259Sdim /// 118249259Sdim class MemIntrinsic : public IntrinsicInst { 119249259Sdim public: 120249259Sdim Value *getRawDest() const { return const_cast<Value*>(getArgOperand(0)); } 121249259Sdim 122249259Sdim Value *getLength() const { return const_cast<Value*>(getArgOperand(2)); } 123249259Sdim ConstantInt *getAlignmentCst() const { 124249259Sdim return cast<ConstantInt>(const_cast<Value*>(getArgOperand(3))); 125249259Sdim } 126249259Sdim 127249259Sdim unsigned getAlignment() const { 128249259Sdim return getAlignmentCst()->getZExtValue(); 129249259Sdim } 130249259Sdim 131249259Sdim ConstantInt *getVolatileCst() const { 132249259Sdim return cast<ConstantInt>(const_cast<Value*>(getArgOperand(4))); 133249259Sdim } 134249259Sdim bool isVolatile() const { 135249259Sdim return !getVolatileCst()->isZero(); 136249259Sdim } 137249259Sdim 138249259Sdim unsigned getDestAddressSpace() const { 139249259Sdim return cast<PointerType>(getRawDest()->getType())->getAddressSpace(); 140249259Sdim } 141249259Sdim 142249259Sdim /// getDest - This is just like getRawDest, but it strips off any cast 143249259Sdim /// instructions that feed it, giving the original input. The returned 144249259Sdim /// value is guaranteed to be a pointer. 145249259Sdim Value *getDest() const { return getRawDest()->stripPointerCasts(); } 146249259Sdim 147249259Sdim /// set* - Set the specified arguments of the instruction. 148249259Sdim /// 149249259Sdim void setDest(Value *Ptr) { 150249259Sdim assert(getRawDest()->getType() == Ptr->getType() && 151249259Sdim "setDest called with pointer of wrong type!"); 152249259Sdim setArgOperand(0, Ptr); 153249259Sdim } 154249259Sdim 155249259Sdim void setLength(Value *L) { 156249259Sdim assert(getLength()->getType() == L->getType() && 157249259Sdim "setLength called with value of wrong type!"); 158249259Sdim setArgOperand(2, L); 159249259Sdim } 160249259Sdim 161249259Sdim void setAlignment(Constant* A) { 162249259Sdim setArgOperand(3, A); 163249259Sdim } 164249259Sdim 165249259Sdim void setVolatile(Constant* V) { 166249259Sdim setArgOperand(4, V); 167249259Sdim } 168249259Sdim 169249259Sdim Type *getAlignmentType() const { 170249259Sdim return getArgOperand(3)->getType(); 171249259Sdim } 172249259Sdim 173249259Sdim // Methods for support type inquiry through isa, cast, and dyn_cast: 174249259Sdim static inline bool classof(const IntrinsicInst *I) { 175249259Sdim switch (I->getIntrinsicID()) { 176249259Sdim case Intrinsic::memcpy: 177249259Sdim case Intrinsic::memmove: 178249259Sdim case Intrinsic::memset: 179249259Sdim return true; 180249259Sdim default: return false; 181249259Sdim } 182249259Sdim } 183249259Sdim static inline bool classof(const Value *V) { 184249259Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 185249259Sdim } 186249259Sdim }; 187249259Sdim 188249259Sdim /// MemSetInst - This class wraps the llvm.memset intrinsic. 189249259Sdim /// 190249259Sdim class MemSetInst : public MemIntrinsic { 191249259Sdim public: 192249259Sdim /// get* - Return the arguments to the instruction. 193249259Sdim /// 194249259Sdim Value *getValue() const { return const_cast<Value*>(getArgOperand(1)); } 195249259Sdim 196249259Sdim void setValue(Value *Val) { 197249259Sdim assert(getValue()->getType() == Val->getType() && 198249259Sdim "setValue called with value of wrong type!"); 199249259Sdim setArgOperand(1, Val); 200249259Sdim } 201249259Sdim 202249259Sdim // Methods for support type inquiry through isa, cast, and dyn_cast: 203249259Sdim static inline bool classof(const IntrinsicInst *I) { 204249259Sdim return I->getIntrinsicID() == Intrinsic::memset; 205249259Sdim } 206249259Sdim static inline bool classof(const Value *V) { 207249259Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 208249259Sdim } 209249259Sdim }; 210249259Sdim 211249259Sdim /// MemTransferInst - This class wraps the llvm.memcpy/memmove intrinsics. 212249259Sdim /// 213249259Sdim class MemTransferInst : public MemIntrinsic { 214249259Sdim public: 215249259Sdim /// get* - Return the arguments to the instruction. 216249259Sdim /// 217249259Sdim Value *getRawSource() const { return const_cast<Value*>(getArgOperand(1)); } 218249259Sdim 219249259Sdim /// getSource - This is just like getRawSource, but it strips off any cast 220249259Sdim /// instructions that feed it, giving the original input. The returned 221249259Sdim /// value is guaranteed to be a pointer. 222249259Sdim Value *getSource() const { return getRawSource()->stripPointerCasts(); } 223249259Sdim 224249259Sdim unsigned getSourceAddressSpace() const { 225249259Sdim return cast<PointerType>(getRawSource()->getType())->getAddressSpace(); 226249259Sdim } 227249259Sdim 228249259Sdim void setSource(Value *Ptr) { 229249259Sdim assert(getRawSource()->getType() == Ptr->getType() && 230249259Sdim "setSource called with pointer of wrong type!"); 231249259Sdim setArgOperand(1, Ptr); 232249259Sdim } 233249259Sdim 234249259Sdim // Methods for support type inquiry through isa, cast, and dyn_cast: 235249259Sdim static inline bool classof(const IntrinsicInst *I) { 236249259Sdim return I->getIntrinsicID() == Intrinsic::memcpy || 237249259Sdim I->getIntrinsicID() == Intrinsic::memmove; 238249259Sdim } 239249259Sdim static inline bool classof(const Value *V) { 240249259Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 241249259Sdim } 242249259Sdim }; 243249259Sdim 244249259Sdim 245249259Sdim /// MemCpyInst - This class wraps the llvm.memcpy intrinsic. 246249259Sdim /// 247249259Sdim class MemCpyInst : public MemTransferInst { 248249259Sdim public: 249249259Sdim // Methods for support type inquiry through isa, cast, and dyn_cast: 250249259Sdim static inline bool classof(const IntrinsicInst *I) { 251249259Sdim return I->getIntrinsicID() == Intrinsic::memcpy; 252249259Sdim } 253249259Sdim static inline bool classof(const Value *V) { 254249259Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 255249259Sdim } 256249259Sdim }; 257249259Sdim 258249259Sdim /// MemMoveInst - This class wraps the llvm.memmove intrinsic. 259249259Sdim /// 260249259Sdim class MemMoveInst : public MemTransferInst { 261249259Sdim public: 262249259Sdim // Methods for support type inquiry through isa, cast, and dyn_cast: 263249259Sdim static inline bool classof(const IntrinsicInst *I) { 264249259Sdim return I->getIntrinsicID() == Intrinsic::memmove; 265249259Sdim } 266249259Sdim static inline bool classof(const Value *V) { 267249259Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 268249259Sdim } 269249259Sdim }; 270249259Sdim 271249259Sdim /// VAStartInst - This represents the llvm.va_start intrinsic. 272249259Sdim /// 273249259Sdim class VAStartInst : public IntrinsicInst { 274249259Sdim public: 275249259Sdim static inline bool classof(const IntrinsicInst *I) { 276249259Sdim return I->getIntrinsicID() == Intrinsic::vastart; 277249259Sdim } 278249259Sdim static inline bool classof(const Value *V) { 279249259Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 280249259Sdim } 281249259Sdim 282249259Sdim Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); } 283249259Sdim }; 284249259Sdim 285249259Sdim /// VAEndInst - This represents the llvm.va_end intrinsic. 286249259Sdim /// 287249259Sdim class VAEndInst : public IntrinsicInst { 288249259Sdim public: 289249259Sdim static inline bool classof(const IntrinsicInst *I) { 290249259Sdim return I->getIntrinsicID() == Intrinsic::vaend; 291249259Sdim } 292249259Sdim static inline bool classof(const Value *V) { 293249259Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 294249259Sdim } 295249259Sdim 296249259Sdim Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); } 297249259Sdim }; 298249259Sdim 299249259Sdim /// VACopyInst - This represents the llvm.va_copy intrinsic. 300249259Sdim /// 301249259Sdim class VACopyInst : public IntrinsicInst { 302249259Sdim public: 303249259Sdim static inline bool classof(const IntrinsicInst *I) { 304249259Sdim return I->getIntrinsicID() == Intrinsic::vacopy; 305249259Sdim } 306249259Sdim static inline bool classof(const Value *V) { 307249259Sdim return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 308249259Sdim } 309249259Sdim 310249259Sdim Value *getDest() const { return const_cast<Value*>(getArgOperand(0)); } 311249259Sdim Value *getSrc() const { return const_cast<Value*>(getArgOperand(1)); } 312249259Sdim }; 313249259Sdim 314249259Sdim} 315249259Sdim 316249259Sdim#endif 317