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/Function.h" 29 #include "llvm/IR/Instructions.h" 30 #include "llvm/IR/Intrinsics.h" 31 32 namespace llvm { 33 /// IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic 34 /// functions. This allows the standard isa/dyncast/cast functionality to 35 /// work with calls to intrinsic functions. 36 class IntrinsicInst : public CallInst { 37 IntrinsicInst() LLVM_DELETED_FUNCTION; 38 IntrinsicInst(const IntrinsicInst&) LLVM_DELETED_FUNCTION; 39 void operator=(const IntrinsicInst&) LLVM_DELETED_FUNCTION; 40 public: 41 /// getIntrinsicID - Return the intrinsic ID of this intrinsic. 42 /// getIntrinsicID()43 Intrinsic::ID getIntrinsicID() const { 44 return (Intrinsic::ID)getCalledFunction()->getIntrinsicID(); 45 } 46 47 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const CallInst * I)48 static inline bool classof(const CallInst *I) { 49 if (const Function *CF = I->getCalledFunction()) 50 return CF->isIntrinsic(); 51 return false; 52 } classof(const Value * V)53 static inline bool classof(const Value *V) { 54 return isa<CallInst>(V) && classof(cast<CallInst>(V)); 55 } 56 }; 57 58 /// DbgInfoIntrinsic - This is the common base class for debug info intrinsics 59 /// 60 class DbgInfoIntrinsic : public IntrinsicInst { 61 public: 62 63 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const IntrinsicInst * I)64 static inline bool classof(const IntrinsicInst *I) { 65 switch (I->getIntrinsicID()) { 66 case Intrinsic::dbg_declare: 67 case Intrinsic::dbg_value: 68 return true; 69 default: return false; 70 } 71 } classof(const Value * V)72 static inline bool classof(const Value *V) { 73 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 74 } 75 76 static Value *StripCast(Value *C); 77 }; 78 79 /// DbgDeclareInst - This represents the llvm.dbg.declare instruction. 80 /// 81 class DbgDeclareInst : public DbgInfoIntrinsic { 82 public: 83 Value *getAddress() const; getVariable()84 MDNode *getVariable() const { return cast<MDNode>(getArgOperand(1)); } 85 86 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const IntrinsicInst * I)87 static inline bool classof(const IntrinsicInst *I) { 88 return I->getIntrinsicID() == Intrinsic::dbg_declare; 89 } classof(const Value * V)90 static inline bool classof(const Value *V) { 91 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 92 } 93 }; 94 95 /// DbgValueInst - This represents the llvm.dbg.value instruction. 96 /// 97 class DbgValueInst : public DbgInfoIntrinsic { 98 public: 99 const Value *getValue() const; 100 Value *getValue(); getOffset()101 uint64_t getOffset() const { 102 return cast<ConstantInt>( 103 const_cast<Value*>(getArgOperand(1)))->getZExtValue(); 104 } getVariable()105 MDNode *getVariable() const { return cast<MDNode>(getArgOperand(2)); } 106 107 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const IntrinsicInst * I)108 static inline bool classof(const IntrinsicInst *I) { 109 return I->getIntrinsicID() == Intrinsic::dbg_value; 110 } classof(const Value * V)111 static inline bool classof(const Value *V) { 112 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 113 } 114 }; 115 116 /// MemIntrinsic - This is the common base class for memset/memcpy/memmove. 117 /// 118 class MemIntrinsic : public IntrinsicInst { 119 public: getRawDest()120 Value *getRawDest() const { return const_cast<Value*>(getArgOperand(0)); } getRawDestUse()121 const Use &getRawDestUse() const { return getArgOperandUse(0); } getRawDestUse()122 Use &getRawDestUse() { return getArgOperandUse(0); } 123 getLength()124 Value *getLength() const { return const_cast<Value*>(getArgOperand(2)); } getLengthUse()125 const Use &getLengthUse() const { return getArgOperandUse(2); } getLengthUse()126 Use &getLengthUse() { return getArgOperandUse(2); } 127 getAlignmentCst()128 ConstantInt *getAlignmentCst() const { 129 return cast<ConstantInt>(const_cast<Value*>(getArgOperand(3))); 130 } 131 getAlignment()132 unsigned getAlignment() const { 133 return getAlignmentCst()->getZExtValue(); 134 } 135 getVolatileCst()136 ConstantInt *getVolatileCst() const { 137 return cast<ConstantInt>(const_cast<Value*>(getArgOperand(4))); 138 } isVolatile()139 bool isVolatile() const { 140 return !getVolatileCst()->isZero(); 141 } 142 getDestAddressSpace()143 unsigned getDestAddressSpace() const { 144 return cast<PointerType>(getRawDest()->getType())->getAddressSpace(); 145 } 146 147 /// getDest - This is just like getRawDest, but it strips off any cast 148 /// instructions that feed it, giving the original input. The returned 149 /// value is guaranteed to be a pointer. getDest()150 Value *getDest() const { return getRawDest()->stripPointerCasts(); } 151 152 /// set* - Set the specified arguments of the instruction. 153 /// setDest(Value * Ptr)154 void setDest(Value *Ptr) { 155 assert(getRawDest()->getType() == Ptr->getType() && 156 "setDest called with pointer of wrong type!"); 157 setArgOperand(0, Ptr); 158 } 159 setLength(Value * L)160 void setLength(Value *L) { 161 assert(getLength()->getType() == L->getType() && 162 "setLength called with value of wrong type!"); 163 setArgOperand(2, L); 164 } 165 setAlignment(Constant * A)166 void setAlignment(Constant* A) { 167 setArgOperand(3, A); 168 } 169 setVolatile(Constant * V)170 void setVolatile(Constant* V) { 171 setArgOperand(4, V); 172 } 173 getAlignmentType()174 Type *getAlignmentType() const { 175 return getArgOperand(3)->getType(); 176 } 177 178 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const IntrinsicInst * I)179 static inline bool classof(const IntrinsicInst *I) { 180 switch (I->getIntrinsicID()) { 181 case Intrinsic::memcpy: 182 case Intrinsic::memmove: 183 case Intrinsic::memset: 184 return true; 185 default: return false; 186 } 187 } classof(const Value * V)188 static inline bool classof(const Value *V) { 189 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 190 } 191 }; 192 193 /// MemSetInst - This class wraps the llvm.memset intrinsic. 194 /// 195 class MemSetInst : public MemIntrinsic { 196 public: 197 /// get* - Return the arguments to the instruction. 198 /// getValue()199 Value *getValue() const { return const_cast<Value*>(getArgOperand(1)); } getValueUse()200 const Use &getValueUse() const { return getArgOperandUse(1); } getValueUse()201 Use &getValueUse() { return getArgOperandUse(1); } 202 setValue(Value * Val)203 void setValue(Value *Val) { 204 assert(getValue()->getType() == Val->getType() && 205 "setValue called with value of wrong type!"); 206 setArgOperand(1, Val); 207 } 208 209 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const IntrinsicInst * I)210 static inline bool classof(const IntrinsicInst *I) { 211 return I->getIntrinsicID() == Intrinsic::memset; 212 } classof(const Value * V)213 static inline bool classof(const Value *V) { 214 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 215 } 216 }; 217 218 /// MemTransferInst - This class wraps the llvm.memcpy/memmove intrinsics. 219 /// 220 class MemTransferInst : public MemIntrinsic { 221 public: 222 /// get* - Return the arguments to the instruction. 223 /// getRawSource()224 Value *getRawSource() const { return const_cast<Value*>(getArgOperand(1)); } getRawSourceUse()225 const Use &getRawSourceUse() const { return getArgOperandUse(1); } getRawSourceUse()226 Use &getRawSourceUse() { return getArgOperandUse(1); } 227 228 /// getSource - This is just like getRawSource, but it strips off any cast 229 /// instructions that feed it, giving the original input. The returned 230 /// value is guaranteed to be a pointer. getSource()231 Value *getSource() const { return getRawSource()->stripPointerCasts(); } 232 getSourceAddressSpace()233 unsigned getSourceAddressSpace() const { 234 return cast<PointerType>(getRawSource()->getType())->getAddressSpace(); 235 } 236 setSource(Value * Ptr)237 void setSource(Value *Ptr) { 238 assert(getRawSource()->getType() == Ptr->getType() && 239 "setSource called with pointer of wrong type!"); 240 setArgOperand(1, Ptr); 241 } 242 243 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const IntrinsicInst * I)244 static inline bool classof(const IntrinsicInst *I) { 245 return I->getIntrinsicID() == Intrinsic::memcpy || 246 I->getIntrinsicID() == Intrinsic::memmove; 247 } classof(const Value * V)248 static inline bool classof(const Value *V) { 249 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 250 } 251 }; 252 253 254 /// MemCpyInst - This class wraps the llvm.memcpy intrinsic. 255 /// 256 class MemCpyInst : public MemTransferInst { 257 public: 258 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const IntrinsicInst * I)259 static inline bool classof(const IntrinsicInst *I) { 260 return I->getIntrinsicID() == Intrinsic::memcpy; 261 } classof(const Value * V)262 static inline bool classof(const Value *V) { 263 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 264 } 265 }; 266 267 /// MemMoveInst - This class wraps the llvm.memmove intrinsic. 268 /// 269 class MemMoveInst : public MemTransferInst { 270 public: 271 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const IntrinsicInst * I)272 static inline bool classof(const IntrinsicInst *I) { 273 return I->getIntrinsicID() == Intrinsic::memmove; 274 } classof(const Value * V)275 static inline bool classof(const Value *V) { 276 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 277 } 278 }; 279 280 /// VAStartInst - This represents the llvm.va_start intrinsic. 281 /// 282 class VAStartInst : public IntrinsicInst { 283 public: classof(const IntrinsicInst * I)284 static inline bool classof(const IntrinsicInst *I) { 285 return I->getIntrinsicID() == Intrinsic::vastart; 286 } classof(const Value * V)287 static inline bool classof(const Value *V) { 288 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 289 } 290 getArgList()291 Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); } 292 }; 293 294 /// VAEndInst - This represents the llvm.va_end intrinsic. 295 /// 296 class VAEndInst : public IntrinsicInst { 297 public: classof(const IntrinsicInst * I)298 static inline bool classof(const IntrinsicInst *I) { 299 return I->getIntrinsicID() == Intrinsic::vaend; 300 } classof(const Value * V)301 static inline bool classof(const Value *V) { 302 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 303 } 304 getArgList()305 Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); } 306 }; 307 308 /// VACopyInst - This represents the llvm.va_copy intrinsic. 309 /// 310 class VACopyInst : public IntrinsicInst { 311 public: classof(const IntrinsicInst * I)312 static inline bool classof(const IntrinsicInst *I) { 313 return I->getIntrinsicID() == Intrinsic::vacopy; 314 } classof(const Value * V)315 static inline bool classof(const Value *V) { 316 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 317 } 318 getDest()319 Value *getDest() const { return const_cast<Value*>(getArgOperand(0)); } getSrc()320 Value *getSrc() const { return const_cast<Value*>(getArgOperand(1)); } 321 }; 322 323 } 324 325 #endif 326