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