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