1 //===-- llvm/IntrinsicInst.h - Intrinsic Instruction Wrappers ---*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines classes that make it really easy to deal with intrinsic
10 // functions with the isa/dyncast family of functions.  In particular, this
11 // allows you to do things like:
12 //
13 //     if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(Inst))
14 //        ... MCI->getDest() ... MCI->getSource() ...
15 //
16 // All intrinsic function calls are instances of the call instruction, so these
17 // are all subclasses of the CallInst class.  Note that none of these classes
18 // has state or virtual methods, which is an important part of this gross/neat
19 // hack working.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 #ifndef LLVM_IR_INTRINSICINST_H
24 #define LLVM_IR_INTRINSICINST_H
25 
26 #include "llvm/IR/Constants.h"
27 #include "llvm/IR/DerivedTypes.h"
28 #include "llvm/IR/Function.h"
29 #include "llvm/IR/GlobalVariable.h"
30 #include "llvm/IR/Instructions.h"
31 #include "llvm/IR/Intrinsics.h"
32 #include "llvm/IR/Metadata.h"
33 #include "llvm/IR/Value.h"
34 #include "llvm/Support/Casting.h"
35 #include <cassert>
36 #include <cstdint>
37 
38 namespace llvm {
39 
40   /// A wrapper class for inspecting calls to intrinsic functions.
41   /// This allows the standard isa/dyncast/cast functionality to work with calls
42   /// to intrinsic functions.
43   class IntrinsicInst : public CallInst {
44   public:
45     IntrinsicInst() = delete;
46     IntrinsicInst(const IntrinsicInst &) = delete;
47     IntrinsicInst &operator=(const IntrinsicInst &) = delete;
48 
49     /// Return the intrinsic ID of this intrinsic.
getIntrinsicID()50     Intrinsic::ID getIntrinsicID() const {
51       return getCalledFunction()->getIntrinsicID();
52     }
53 
54     // Methods for support type inquiry through isa, cast, and dyn_cast:
classof(const CallInst * I)55     static bool classof(const CallInst *I) {
56       if (const Function *CF = I->getCalledFunction())
57         return CF->isIntrinsic();
58       return false;
59     }
classof(const Value * V)60     static bool classof(const Value *V) {
61       return isa<CallInst>(V) && classof(cast<CallInst>(V));
62     }
63   };
64 
65   /// This is the common base class for debug info intrinsics.
66   class DbgInfoIntrinsic : public IntrinsicInst {
67   public:
68     /// \name Casting methods
69     /// @{
classof(const IntrinsicInst * I)70     static bool classof(const IntrinsicInst *I) {
71       switch (I->getIntrinsicID()) {
72       case Intrinsic::dbg_declare:
73       case Intrinsic::dbg_value:
74       case Intrinsic::dbg_addr:
75       case Intrinsic::dbg_label:
76         return true;
77       default: return false;
78       }
79     }
classof(const Value * V)80     static bool classof(const Value *V) {
81       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
82     }
83     /// @}
84   };
85 
86   /// This is the common base class for debug info intrinsics for variables.
87   class DbgVariableIntrinsic : public DbgInfoIntrinsic {
88   public:
89     /// Get the location corresponding to the variable referenced by the debug
90     /// info intrinsic.  Depending on the intrinsic, this could be the
91     /// variable's value or its address.
92     Value *getVariableLocation(bool AllowNullOp = true) const;
93 
94     /// Does this describe the address of a local variable. True for dbg.addr
95     /// and dbg.declare, but not dbg.value, which describes its value.
isAddressOfVariable()96     bool isAddressOfVariable() const {
97       return getIntrinsicID() != Intrinsic::dbg_value;
98     }
99 
getVariable()100     DILocalVariable *getVariable() const {
101       return cast<DILocalVariable>(getRawVariable());
102     }
103 
getExpression()104     DIExpression *getExpression() const {
105       return cast<DIExpression>(getRawExpression());
106     }
107 
getRawVariable()108     Metadata *getRawVariable() const {
109       return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
110     }
111 
getRawExpression()112     Metadata *getRawExpression() const {
113       return cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
114     }
115 
116     /// Get the size (in bits) of the variable, or fragment of the variable that
117     /// is described.
118     Optional<uint64_t> getFragmentSizeInBits() const;
119 
120     /// \name Casting methods
121     /// @{
classof(const IntrinsicInst * I)122     static bool classof(const IntrinsicInst *I) {
123       switch (I->getIntrinsicID()) {
124       case Intrinsic::dbg_declare:
125       case Intrinsic::dbg_value:
126       case Intrinsic::dbg_addr:
127         return true;
128       default: return false;
129       }
130     }
classof(const Value * V)131     static bool classof(const Value *V) {
132       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
133     }
134     /// @}
135   };
136 
137   /// This represents the llvm.dbg.declare instruction.
138   class DbgDeclareInst : public DbgVariableIntrinsic {
139   public:
getAddress()140     Value *getAddress() const { return getVariableLocation(); }
141 
142     /// \name Casting methods
143     /// @{
classof(const IntrinsicInst * I)144     static bool classof(const IntrinsicInst *I) {
145       return I->getIntrinsicID() == Intrinsic::dbg_declare;
146     }
classof(const Value * V)147     static bool classof(const Value *V) {
148       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
149     }
150     /// @}
151   };
152 
153   /// This represents the llvm.dbg.addr instruction.
154   class DbgAddrIntrinsic : public DbgVariableIntrinsic {
155   public:
getAddress()156     Value *getAddress() const { return getVariableLocation(); }
157 
158     /// \name Casting methods
159     /// @{
classof(const IntrinsicInst * I)160     static bool classof(const IntrinsicInst *I) {
161       return I->getIntrinsicID() == Intrinsic::dbg_addr;
162     }
classof(const Value * V)163     static bool classof(const Value *V) {
164       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
165     }
166   };
167 
168   /// This represents the llvm.dbg.value instruction.
169   class DbgValueInst : public DbgVariableIntrinsic {
170   public:
getValue()171     Value *getValue() const {
172       return getVariableLocation(/* AllowNullOp = */ false);
173     }
174 
175     /// \name Casting methods
176     /// @{
classof(const IntrinsicInst * I)177     static bool classof(const IntrinsicInst *I) {
178       return I->getIntrinsicID() == Intrinsic::dbg_value;
179     }
classof(const Value * V)180     static bool classof(const Value *V) {
181       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
182     }
183     /// @}
184   };
185 
186   /// This represents the llvm.dbg.label instruction.
187   class DbgLabelInst : public DbgInfoIntrinsic {
188   public:
getLabel()189     DILabel *getLabel() const {
190       return cast<DILabel>(getRawLabel());
191     }
192 
getRawLabel()193     Metadata *getRawLabel() const {
194       return cast<MetadataAsValue>(getArgOperand(0))->getMetadata();
195     }
196 
197     /// Methods for support type inquiry through isa, cast, and dyn_cast:
198     /// @{
classof(const IntrinsicInst * I)199     static bool classof(const IntrinsicInst *I) {
200       return I->getIntrinsicID() == Intrinsic::dbg_label;
201     }
classof(const Value * V)202     static bool classof(const Value *V) {
203       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
204     }
205     /// @}
206   };
207 
208   /// This is the common base class for constrained floating point intrinsics.
209   class ConstrainedFPIntrinsic : public IntrinsicInst {
210   public:
211     /// Specifies the rounding mode to be assumed. This is only used when
212     /// when constrained floating point is enabled. See the LLVM Language
213     /// Reference Manual for details.
214     enum RoundingMode : uint8_t {
215       rmDynamic,         ///< This corresponds to "fpround.dynamic".
216       rmToNearest,       ///< This corresponds to "fpround.tonearest".
217       rmDownward,        ///< This corresponds to "fpround.downward".
218       rmUpward,          ///< This corresponds to "fpround.upward".
219       rmTowardZero       ///< This corresponds to "fpround.tozero".
220     };
221 
222     /// Specifies the required exception behavior. This is only used when
223     /// when constrained floating point is used. See the LLVM Language
224     /// Reference Manual for details.
225     enum ExceptionBehavior : uint8_t {
226       ebIgnore,          ///< This corresponds to "fpexcept.ignore".
227       ebMayTrap,         ///< This corresponds to "fpexcept.maytrap".
228       ebStrict           ///< This corresponds to "fpexcept.strict".
229     };
230 
231     bool isUnaryOp() const;
232     bool isTernaryOp() const;
233     Optional<RoundingMode> getRoundingMode() const;
234     Optional<ExceptionBehavior> getExceptionBehavior() const;
235 
236     /// Returns a valid RoundingMode enumerator when given a string
237     /// that is valid as input in constrained intrinsic rounding mode
238     /// metadata.
239     static Optional<RoundingMode> StrToRoundingMode(StringRef);
240 
241     /// For any RoundingMode enumerator, returns a string valid as input in
242     /// constrained intrinsic rounding mode metadata.
243     static Optional<StringRef> RoundingModeToStr(RoundingMode);
244 
245     /// Returns a valid ExceptionBehavior enumerator when given a string
246     /// valid as input in constrained intrinsic exception behavior metadata.
247     static Optional<ExceptionBehavior> StrToExceptionBehavior(StringRef);
248 
249     /// For any ExceptionBehavior enumerator, returns a string valid as
250     /// input in constrained intrinsic exception behavior metadata.
251     static Optional<StringRef> ExceptionBehaviorToStr(ExceptionBehavior);
252 
253     // Methods for support type inquiry through isa, cast, and dyn_cast:
classof(const IntrinsicInst * I)254     static bool classof(const IntrinsicInst *I) {
255       switch (I->getIntrinsicID()) {
256       case Intrinsic::experimental_constrained_fadd:
257       case Intrinsic::experimental_constrained_fsub:
258       case Intrinsic::experimental_constrained_fmul:
259       case Intrinsic::experimental_constrained_fdiv:
260       case Intrinsic::experimental_constrained_frem:
261       case Intrinsic::experimental_constrained_fma:
262       case Intrinsic::experimental_constrained_fptrunc:
263       case Intrinsic::experimental_constrained_fpext:
264       case Intrinsic::experimental_constrained_sqrt:
265       case Intrinsic::experimental_constrained_pow:
266       case Intrinsic::experimental_constrained_powi:
267       case Intrinsic::experimental_constrained_sin:
268       case Intrinsic::experimental_constrained_cos:
269       case Intrinsic::experimental_constrained_exp:
270       case Intrinsic::experimental_constrained_exp2:
271       case Intrinsic::experimental_constrained_log:
272       case Intrinsic::experimental_constrained_log10:
273       case Intrinsic::experimental_constrained_log2:
274       case Intrinsic::experimental_constrained_rint:
275       case Intrinsic::experimental_constrained_nearbyint:
276       case Intrinsic::experimental_constrained_maxnum:
277       case Intrinsic::experimental_constrained_minnum:
278       case Intrinsic::experimental_constrained_ceil:
279       case Intrinsic::experimental_constrained_floor:
280       case Intrinsic::experimental_constrained_round:
281       case Intrinsic::experimental_constrained_trunc:
282         return true;
283       default: return false;
284       }
285     }
classof(const Value * V)286     static bool classof(const Value *V) {
287       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
288     }
289   };
290 
291   /// This class represents an intrinsic that is based on a binary operation.
292   /// This includes op.with.overflow and saturating add/sub intrinsics.
293   class BinaryOpIntrinsic : public IntrinsicInst {
294   public:
classof(const IntrinsicInst * I)295     static bool classof(const IntrinsicInst *I) {
296       switch (I->getIntrinsicID()) {
297       case Intrinsic::uadd_with_overflow:
298       case Intrinsic::sadd_with_overflow:
299       case Intrinsic::usub_with_overflow:
300       case Intrinsic::ssub_with_overflow:
301       case Intrinsic::umul_with_overflow:
302       case Intrinsic::smul_with_overflow:
303       case Intrinsic::uadd_sat:
304       case Intrinsic::sadd_sat:
305       case Intrinsic::usub_sat:
306       case Intrinsic::ssub_sat:
307         return true;
308       default:
309         return false;
310       }
311     }
classof(const Value * V)312     static bool classof(const Value *V) {
313       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
314     }
315 
getLHS()316     Value *getLHS() const { return const_cast<Value*>(getArgOperand(0)); }
getRHS()317     Value *getRHS() const { return const_cast<Value*>(getArgOperand(1)); }
318 
319     /// Returns the binary operation underlying the intrinsic.
320     Instruction::BinaryOps getBinaryOp() const;
321 
322     /// Whether the intrinsic is signed or unsigned.
323     bool isSigned() const;
324 
325     /// Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap.
326     unsigned getNoWrapKind() const;
327   };
328 
329   /// Represents an op.with.overflow intrinsic.
330   class WithOverflowInst : public BinaryOpIntrinsic {
331   public:
classof(const IntrinsicInst * I)332     static bool classof(const IntrinsicInst *I) {
333       switch (I->getIntrinsicID()) {
334       case Intrinsic::uadd_with_overflow:
335       case Intrinsic::sadd_with_overflow:
336       case Intrinsic::usub_with_overflow:
337       case Intrinsic::ssub_with_overflow:
338       case Intrinsic::umul_with_overflow:
339       case Intrinsic::smul_with_overflow:
340         return true;
341       default:
342         return false;
343       }
344     }
classof(const Value * V)345     static bool classof(const Value *V) {
346       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
347     }
348   };
349 
350   /// Represents a saturating add/sub intrinsic.
351   class SaturatingInst : public BinaryOpIntrinsic {
352   public:
classof(const IntrinsicInst * I)353     static bool classof(const IntrinsicInst *I) {
354       switch (I->getIntrinsicID()) {
355       case Intrinsic::uadd_sat:
356       case Intrinsic::sadd_sat:
357       case Intrinsic::usub_sat:
358       case Intrinsic::ssub_sat:
359         return true;
360       default:
361         return false;
362       }
363     }
classof(const Value * V)364     static bool classof(const Value *V) {
365       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
366     }
367   };
368 
369   /// Common base class for all memory intrinsics. Simply provides
370   /// common methods.
371   /// Written as CRTP to avoid a common base class amongst the
372   /// three atomicity hierarchies.
373   template <typename Derived> class MemIntrinsicBase : public IntrinsicInst {
374   private:
375     enum { ARG_DEST = 0, ARG_LENGTH = 2 };
376 
377   public:
getRawDest()378     Value *getRawDest() const {
379       return const_cast<Value *>(getArgOperand(ARG_DEST));
380     }
getRawDestUse()381     const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
getRawDestUse()382     Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
383 
getLength()384     Value *getLength() const {
385       return const_cast<Value *>(getArgOperand(ARG_LENGTH));
386     }
getLengthUse()387     const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
getLengthUse()388     Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
389 
390     /// This is just like getRawDest, but it strips off any cast
391     /// instructions (including addrspacecast) that feed it, giving the
392     /// original input.  The returned value is guaranteed to be a pointer.
getDest()393     Value *getDest() const { return getRawDest()->stripPointerCasts(); }
394 
getDestAddressSpace()395     unsigned getDestAddressSpace() const {
396       return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
397     }
398 
getDestAlignment()399     unsigned getDestAlignment() const { return getParamAlignment(ARG_DEST); }
400 
401     /// Set the specified arguments of the instruction.
setDest(Value * Ptr)402     void setDest(Value *Ptr) {
403       assert(getRawDest()->getType() == Ptr->getType() &&
404              "setDest called with pointer of wrong type!");
405       setArgOperand(ARG_DEST, Ptr);
406     }
407 
setDestAlignment(unsigned Align)408     void setDestAlignment(unsigned Align) {
409       removeParamAttr(ARG_DEST, Attribute::Alignment);
410       if (Align > 0)
411         addParamAttr(ARG_DEST,
412                      Attribute::getWithAlignment(getContext(), Align));
413     }
414 
setLength(Value * L)415     void setLength(Value *L) {
416       assert(getLength()->getType() == L->getType() &&
417              "setLength called with value of wrong type!");
418       setArgOperand(ARG_LENGTH, L);
419     }
420   };
421 
422   /// Common base class for all memory transfer intrinsics. Simply provides
423   /// common methods.
424   template <class BaseCL> class MemTransferBase : public BaseCL {
425   private:
426     enum { ARG_SOURCE = 1 };
427 
428   public:
429     /// Return the arguments to the instruction.
getRawSource()430     Value *getRawSource() const {
431       return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE));
432     }
getRawSourceUse()433     const Use &getRawSourceUse() const {
434       return BaseCL::getArgOperandUse(ARG_SOURCE);
435     }
getRawSourceUse()436     Use &getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE); }
437 
438     /// This is just like getRawSource, but it strips off any cast
439     /// instructions that feed it, giving the original input.  The returned
440     /// value is guaranteed to be a pointer.
getSource()441     Value *getSource() const { return getRawSource()->stripPointerCasts(); }
442 
getSourceAddressSpace()443     unsigned getSourceAddressSpace() const {
444       return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
445     }
446 
getSourceAlignment()447     unsigned getSourceAlignment() const {
448       return BaseCL::getParamAlignment(ARG_SOURCE);
449     }
450 
setSource(Value * Ptr)451     void setSource(Value *Ptr) {
452       assert(getRawSource()->getType() == Ptr->getType() &&
453              "setSource called with pointer of wrong type!");
454       BaseCL::setArgOperand(ARG_SOURCE, Ptr);
455     }
456 
setSourceAlignment(unsigned Align)457     void setSourceAlignment(unsigned Align) {
458       BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
459       if (Align > 0)
460         BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment(
461                                              BaseCL::getContext(), Align));
462     }
463   };
464 
465   /// Common base class for all memset intrinsics. Simply provides
466   /// common methods.
467   template <class BaseCL> class MemSetBase : public BaseCL {
468   private:
469     enum { ARG_VALUE = 1 };
470 
471   public:
getValue()472     Value *getValue() const {
473       return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE));
474     }
getValueUse()475     const Use &getValueUse() const {
476       return BaseCL::getArgOperandUse(ARG_VALUE);
477     }
getValueUse()478     Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); }
479 
setValue(Value * Val)480     void setValue(Value *Val) {
481       assert(getValue()->getType() == Val->getType() &&
482              "setValue called with value of wrong type!");
483       BaseCL::setArgOperand(ARG_VALUE, Val);
484     }
485   };
486 
487   // The common base class for the atomic memset/memmove/memcpy intrinsics
488   // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
489   class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> {
490   private:
491     enum { ARG_ELEMENTSIZE = 3 };
492 
493   public:
getRawElementSizeInBytes()494     Value *getRawElementSizeInBytes() const {
495       return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
496     }
497 
getElementSizeInBytesCst()498     ConstantInt *getElementSizeInBytesCst() const {
499       return cast<ConstantInt>(getRawElementSizeInBytes());
500     }
501 
getElementSizeInBytes()502     uint32_t getElementSizeInBytes() const {
503       return getElementSizeInBytesCst()->getZExtValue();
504     }
505 
setElementSizeInBytes(Constant * V)506     void setElementSizeInBytes(Constant *V) {
507       assert(V->getType() == Type::getInt8Ty(getContext()) &&
508              "setElementSizeInBytes called with value of wrong type!");
509       setArgOperand(ARG_ELEMENTSIZE, V);
510     }
511 
classof(const IntrinsicInst * I)512     static bool classof(const IntrinsicInst *I) {
513       switch (I->getIntrinsicID()) {
514       case Intrinsic::memcpy_element_unordered_atomic:
515       case Intrinsic::memmove_element_unordered_atomic:
516       case Intrinsic::memset_element_unordered_atomic:
517         return true;
518       default:
519         return false;
520       }
521     }
classof(const Value * V)522     static bool classof(const Value *V) {
523       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
524     }
525   };
526 
527   /// This class represents atomic memset intrinsic
528   // i.e. llvm.element.unordered.atomic.memset
529   class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> {
530   public:
classof(const IntrinsicInst * I)531     static bool classof(const IntrinsicInst *I) {
532       return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic;
533     }
classof(const Value * V)534     static bool classof(const Value *V) {
535       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
536     }
537   };
538 
539   // This class wraps the atomic memcpy/memmove intrinsics
540   // i.e. llvm.element.unordered.atomic.memcpy/memmove
541   class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> {
542   public:
classof(const IntrinsicInst * I)543     static bool classof(const IntrinsicInst *I) {
544       switch (I->getIntrinsicID()) {
545       case Intrinsic::memcpy_element_unordered_atomic:
546       case Intrinsic::memmove_element_unordered_atomic:
547         return true;
548       default:
549         return false;
550       }
551     }
classof(const Value * V)552     static bool classof(const Value *V) {
553       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
554     }
555   };
556 
557   /// This class represents the atomic memcpy intrinsic
558   /// i.e. llvm.element.unordered.atomic.memcpy
559   class AtomicMemCpyInst : public AtomicMemTransferInst {
560   public:
classof(const IntrinsicInst * I)561     static bool classof(const IntrinsicInst *I) {
562       return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
563     }
classof(const Value * V)564     static bool classof(const Value *V) {
565       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
566     }
567   };
568 
569   /// This class represents the atomic memmove intrinsic
570   /// i.e. llvm.element.unordered.atomic.memmove
571   class AtomicMemMoveInst : public AtomicMemTransferInst {
572   public:
classof(const IntrinsicInst * I)573     static bool classof(const IntrinsicInst *I) {
574       return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic;
575     }
classof(const Value * V)576     static bool classof(const Value *V) {
577       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
578     }
579   };
580 
581   /// This is the common base class for memset/memcpy/memmove.
582   class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> {
583   private:
584     enum { ARG_VOLATILE = 3 };
585 
586   public:
getVolatileCst()587     ConstantInt *getVolatileCst() const {
588       return cast<ConstantInt>(
589           const_cast<Value *>(getArgOperand(ARG_VOLATILE)));
590     }
591 
isVolatile()592     bool isVolatile() const {
593       return !getVolatileCst()->isZero();
594     }
595 
setVolatile(Constant * V)596     void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); }
597 
598     // Methods for support type inquiry through isa, cast, and dyn_cast:
classof(const IntrinsicInst * I)599     static bool classof(const IntrinsicInst *I) {
600       switch (I->getIntrinsicID()) {
601       case Intrinsic::memcpy:
602       case Intrinsic::memmove:
603       case Intrinsic::memset:
604         return true;
605       default: return false;
606       }
607     }
classof(const Value * V)608     static bool classof(const Value *V) {
609       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
610     }
611   };
612 
613   /// This class wraps the llvm.memset intrinsic.
614   class MemSetInst : public MemSetBase<MemIntrinsic> {
615   public:
616     // Methods for support type inquiry through isa, cast, and dyn_cast:
classof(const IntrinsicInst * I)617     static bool classof(const IntrinsicInst *I) {
618       return I->getIntrinsicID() == Intrinsic::memset;
619     }
classof(const Value * V)620     static bool classof(const Value *V) {
621       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
622     }
623   };
624 
625   /// This class wraps the llvm.memcpy/memmove intrinsics.
626   class MemTransferInst : public MemTransferBase<MemIntrinsic> {
627   public:
628     // Methods for support type inquiry through isa, cast, and dyn_cast:
classof(const IntrinsicInst * I)629     static bool classof(const IntrinsicInst *I) {
630       return I->getIntrinsicID() == Intrinsic::memcpy ||
631              I->getIntrinsicID() == Intrinsic::memmove;
632     }
classof(const Value * V)633     static bool classof(const Value *V) {
634       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
635     }
636   };
637 
638   /// This class wraps the llvm.memcpy intrinsic.
639   class MemCpyInst : public MemTransferInst {
640   public:
641     // Methods for support type inquiry through isa, cast, and dyn_cast:
classof(const IntrinsicInst * I)642     static bool classof(const IntrinsicInst *I) {
643       return I->getIntrinsicID() == Intrinsic::memcpy;
644     }
classof(const Value * V)645     static bool classof(const Value *V) {
646       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
647     }
648   };
649 
650   /// This class wraps the llvm.memmove intrinsic.
651   class MemMoveInst : public MemTransferInst {
652   public:
653     // Methods for support type inquiry through isa, cast, and dyn_cast:
classof(const IntrinsicInst * I)654     static bool classof(const IntrinsicInst *I) {
655       return I->getIntrinsicID() == Intrinsic::memmove;
656     }
classof(const Value * V)657     static bool classof(const Value *V) {
658       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
659     }
660   };
661 
662   // The common base class for any memset/memmove/memcpy intrinsics;
663   // whether they be atomic or non-atomic.
664   // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
665   //  and llvm.memset/memcpy/memmove
666   class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> {
667   public:
isVolatile()668     bool isVolatile() const {
669       // Only the non-atomic intrinsics can be volatile
670       if (auto *MI = dyn_cast<MemIntrinsic>(this))
671         return MI->isVolatile();
672       return false;
673     }
674 
classof(const IntrinsicInst * I)675     static bool classof(const IntrinsicInst *I) {
676       switch (I->getIntrinsicID()) {
677       case Intrinsic::memcpy:
678       case Intrinsic::memmove:
679       case Intrinsic::memset:
680       case Intrinsic::memcpy_element_unordered_atomic:
681       case Intrinsic::memmove_element_unordered_atomic:
682       case Intrinsic::memset_element_unordered_atomic:
683         return true;
684       default:
685         return false;
686       }
687     }
classof(const Value * V)688     static bool classof(const Value *V) {
689       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
690     }
691   };
692 
693   /// This class represents any memset intrinsic
694   // i.e. llvm.element.unordered.atomic.memset
695   // and  llvm.memset
696   class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> {
697   public:
classof(const IntrinsicInst * I)698     static bool classof(const IntrinsicInst *I) {
699       switch (I->getIntrinsicID()) {
700       case Intrinsic::memset:
701       case Intrinsic::memset_element_unordered_atomic:
702         return true;
703       default:
704         return false;
705       }
706     }
classof(const Value * V)707     static bool classof(const Value *V) {
708       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
709     }
710   };
711 
712   // This class wraps any memcpy/memmove intrinsics
713   // i.e. llvm.element.unordered.atomic.memcpy/memmove
714   // and  llvm.memcpy/memmove
715   class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> {
716   public:
classof(const IntrinsicInst * I)717     static bool classof(const IntrinsicInst *I) {
718       switch (I->getIntrinsicID()) {
719       case Intrinsic::memcpy:
720       case Intrinsic::memmove:
721       case Intrinsic::memcpy_element_unordered_atomic:
722       case Intrinsic::memmove_element_unordered_atomic:
723         return true;
724       default:
725         return false;
726       }
727     }
classof(const Value * V)728     static bool classof(const Value *V) {
729       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
730     }
731   };
732 
733   /// This class represents any memcpy intrinsic
734   /// i.e. llvm.element.unordered.atomic.memcpy
735   ///  and llvm.memcpy
736   class AnyMemCpyInst : public AnyMemTransferInst {
737   public:
classof(const IntrinsicInst * I)738     static bool classof(const IntrinsicInst *I) {
739       switch (I->getIntrinsicID()) {
740       case Intrinsic::memcpy:
741       case Intrinsic::memcpy_element_unordered_atomic:
742         return true;
743       default:
744         return false;
745       }
746     }
classof(const Value * V)747     static bool classof(const Value *V) {
748       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
749     }
750   };
751 
752   /// This class represents any memmove intrinsic
753   /// i.e. llvm.element.unordered.atomic.memmove
754   ///  and llvm.memmove
755   class AnyMemMoveInst : public AnyMemTransferInst {
756   public:
classof(const IntrinsicInst * I)757     static bool classof(const IntrinsicInst *I) {
758       switch (I->getIntrinsicID()) {
759       case Intrinsic::memmove:
760       case Intrinsic::memmove_element_unordered_atomic:
761         return true;
762       default:
763         return false;
764       }
765     }
classof(const Value * V)766     static bool classof(const Value *V) {
767       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
768     }
769   };
770 
771   /// This represents the llvm.va_start intrinsic.
772   class VAStartInst : public IntrinsicInst {
773   public:
classof(const IntrinsicInst * I)774     static bool classof(const IntrinsicInst *I) {
775       return I->getIntrinsicID() == Intrinsic::vastart;
776     }
classof(const Value * V)777     static bool classof(const Value *V) {
778       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
779     }
780 
getArgList()781     Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); }
782   };
783 
784   /// This represents the llvm.va_end intrinsic.
785   class VAEndInst : public IntrinsicInst {
786   public:
classof(const IntrinsicInst * I)787     static bool classof(const IntrinsicInst *I) {
788       return I->getIntrinsicID() == Intrinsic::vaend;
789     }
classof(const Value * V)790     static bool classof(const Value *V) {
791       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
792     }
793 
getArgList()794     Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); }
795   };
796 
797   /// This represents the llvm.va_copy intrinsic.
798   class VACopyInst : public IntrinsicInst {
799   public:
classof(const IntrinsicInst * I)800     static bool classof(const IntrinsicInst *I) {
801       return I->getIntrinsicID() == Intrinsic::vacopy;
802     }
classof(const Value * V)803     static bool classof(const Value *V) {
804       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
805     }
806 
getDest()807     Value *getDest() const { return const_cast<Value*>(getArgOperand(0)); }
getSrc()808     Value *getSrc() const { return const_cast<Value*>(getArgOperand(1)); }
809   };
810 
811   /// This represents the llvm.instrprof_increment intrinsic.
812   class InstrProfIncrementInst : public IntrinsicInst {
813   public:
classof(const IntrinsicInst * I)814     static bool classof(const IntrinsicInst *I) {
815       return I->getIntrinsicID() == Intrinsic::instrprof_increment;
816     }
classof(const Value * V)817     static bool classof(const Value *V) {
818       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
819     }
820 
getName()821     GlobalVariable *getName() const {
822       return cast<GlobalVariable>(
823           const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
824     }
825 
getHash()826     ConstantInt *getHash() const {
827       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
828     }
829 
getNumCounters()830     ConstantInt *getNumCounters() const {
831       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
832     }
833 
getIndex()834     ConstantInt *getIndex() const {
835       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
836     }
837 
838     Value *getStep() const;
839   };
840 
841   class InstrProfIncrementInstStep : public InstrProfIncrementInst {
842   public:
classof(const IntrinsicInst * I)843     static bool classof(const IntrinsicInst *I) {
844       return I->getIntrinsicID() == Intrinsic::instrprof_increment_step;
845     }
classof(const Value * V)846     static bool classof(const Value *V) {
847       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
848     }
849   };
850 
851   /// This represents the llvm.instrprof_value_profile intrinsic.
852   class InstrProfValueProfileInst : public IntrinsicInst {
853   public:
classof(const IntrinsicInst * I)854     static bool classof(const IntrinsicInst *I) {
855       return I->getIntrinsicID() == Intrinsic::instrprof_value_profile;
856     }
classof(const Value * V)857     static bool classof(const Value *V) {
858       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
859     }
860 
getName()861     GlobalVariable *getName() const {
862       return cast<GlobalVariable>(
863           const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
864     }
865 
getHash()866     ConstantInt *getHash() const {
867       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
868     }
869 
getTargetValue()870     Value *getTargetValue() const {
871       return cast<Value>(const_cast<Value *>(getArgOperand(2)));
872     }
873 
getValueKind()874     ConstantInt *getValueKind() const {
875       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
876     }
877 
878     // Returns the value site index.
getIndex()879     ConstantInt *getIndex() const {
880       return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4)));
881     }
882   };
883 
884 } // end namespace llvm
885 
886 #endif // LLVM_IR_INTRINSICINST_H
887