xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicInst.h (revision c66ec88fed842fbaad62c30d510644ceb7bd2d71)
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/FPEnv.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.
51   Intrinsic::ID getIntrinsicID() const {
52     return getCalledFunction()->getIntrinsicID();
53   }
54 
55   // Methods for support type inquiry through isa, cast, and dyn_cast:
56   static bool classof(const CallInst *I) {
57     if (const Function *CF = I->getCalledFunction())
58       return CF->isIntrinsic();
59     return false;
60   }
61   static bool classof(const Value *V) {
62     return isa<CallInst>(V) && classof(cast<CallInst>(V));
63   }
64 };
65 
66 /// Check if \p ID corresponds to a debug info intrinsic.
67 static inline bool isDbgInfoIntrinsic(Intrinsic::ID ID) {
68   switch (ID) {
69   case Intrinsic::dbg_declare:
70   case Intrinsic::dbg_value:
71   case Intrinsic::dbg_addr:
72   case Intrinsic::dbg_label:
73     return true;
74   default:
75     return false;
76   }
77 }
78 
79 /// This is the common base class for debug info intrinsics.
80 class DbgInfoIntrinsic : public IntrinsicInst {
81 public:
82   /// \name Casting methods
83   /// @{
84   static bool classof(const IntrinsicInst *I) {
85     return isDbgInfoIntrinsic(I->getIntrinsicID());
86   }
87   static bool classof(const Value *V) {
88     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
89   }
90   /// @}
91 };
92 
93 /// This is the common base class for debug info intrinsics for variables.
94 class DbgVariableIntrinsic : public DbgInfoIntrinsic {
95 public:
96   /// Get the location corresponding to the variable referenced by the debug
97   /// info intrinsic.  Depending on the intrinsic, this could be the
98   /// variable's value or its address.
99   Value *getVariableLocation(bool AllowNullOp = true) const;
100 
101   /// Does this describe the address of a local variable. True for dbg.addr
102   /// and dbg.declare, but not dbg.value, which describes its value.
103   bool isAddressOfVariable() const {
104     return getIntrinsicID() != Intrinsic::dbg_value;
105   }
106 
107   DILocalVariable *getVariable() const {
108     return cast<DILocalVariable>(getRawVariable());
109   }
110 
111   DIExpression *getExpression() const {
112     return cast<DIExpression>(getRawExpression());
113   }
114 
115   Metadata *getRawVariable() const {
116     return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
117   }
118 
119   Metadata *getRawExpression() const {
120     return cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
121   }
122 
123   /// Get the size (in bits) of the variable, or fragment of the variable that
124   /// is described.
125   Optional<uint64_t> getFragmentSizeInBits() const;
126 
127   /// \name Casting methods
128   /// @{
129   static bool classof(const IntrinsicInst *I) {
130     switch (I->getIntrinsicID()) {
131     case Intrinsic::dbg_declare:
132     case Intrinsic::dbg_value:
133     case Intrinsic::dbg_addr:
134       return true;
135     default:
136       return false;
137     }
138   }
139   static bool classof(const Value *V) {
140     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
141   }
142   /// @}
143 };
144 
145 /// This represents the llvm.dbg.declare instruction.
146 class DbgDeclareInst : public DbgVariableIntrinsic {
147 public:
148   Value *getAddress() const { return getVariableLocation(); }
149 
150   /// \name Casting methods
151   /// @{
152   static bool classof(const IntrinsicInst *I) {
153     return I->getIntrinsicID() == Intrinsic::dbg_declare;
154   }
155   static bool classof(const Value *V) {
156     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
157   }
158   /// @}
159 };
160 
161 /// This represents the llvm.dbg.addr instruction.
162 class DbgAddrIntrinsic : public DbgVariableIntrinsic {
163 public:
164   Value *getAddress() const { return getVariableLocation(); }
165 
166   /// \name Casting methods
167   /// @{
168   static bool classof(const IntrinsicInst *I) {
169     return I->getIntrinsicID() == Intrinsic::dbg_addr;
170   }
171   static bool classof(const Value *V) {
172     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
173   }
174 };
175 
176 /// This represents the llvm.dbg.value instruction.
177 class DbgValueInst : public DbgVariableIntrinsic {
178 public:
179   Value *getValue() const {
180     return getVariableLocation(/* AllowNullOp = */ false);
181   }
182 
183   /// \name Casting methods
184   /// @{
185   static bool classof(const IntrinsicInst *I) {
186     return I->getIntrinsicID() == Intrinsic::dbg_value;
187   }
188   static bool classof(const Value *V) {
189     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
190   }
191   /// @}
192 };
193 
194 /// This represents the llvm.dbg.label instruction.
195 class DbgLabelInst : public DbgInfoIntrinsic {
196 public:
197   DILabel *getLabel() const { return cast<DILabel>(getRawLabel()); }
198 
199   Metadata *getRawLabel() const {
200     return cast<MetadataAsValue>(getArgOperand(0))->getMetadata();
201   }
202 
203   /// Methods for support type inquiry through isa, cast, and dyn_cast:
204   /// @{
205   static bool classof(const IntrinsicInst *I) {
206     return I->getIntrinsicID() == Intrinsic::dbg_label;
207   }
208   static bool classof(const Value *V) {
209     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
210   }
211   /// @}
212 };
213 
214 /// This is the common base class for vector predication intrinsics.
215 class VPIntrinsic : public IntrinsicInst {
216 public:
217   static Optional<int> GetMaskParamPos(Intrinsic::ID IntrinsicID);
218   static Optional<int> GetVectorLengthParamPos(Intrinsic::ID IntrinsicID);
219 
220   /// The llvm.vp.* intrinsics for this instruction Opcode
221   static Intrinsic::ID GetForOpcode(unsigned OC);
222 
223   // Whether \p ID is a VP intrinsic ID.
224   static bool IsVPIntrinsic(Intrinsic::ID);
225 
226   /// \return the mask parameter or nullptr.
227   Value *getMaskParam() const;
228 
229   /// \return the vector length parameter or nullptr.
230   Value *getVectorLengthParam() const;
231 
232   /// \return whether the vector length param can be ignored.
233   bool canIgnoreVectorLengthParam() const;
234 
235   /// \return the static element count (vector number of elements) the vector
236   /// length parameter applies to.
237   ElementCount getStaticVectorLength() const;
238 
239   // Methods for support type inquiry through isa, cast, and dyn_cast:
240   static bool classof(const IntrinsicInst *I) {
241     return IsVPIntrinsic(I->getIntrinsicID());
242   }
243   static bool classof(const Value *V) {
244     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
245   }
246 
247   // Equivalent non-predicated opcode
248   unsigned getFunctionalOpcode() const {
249     return GetFunctionalOpcodeForVP(getIntrinsicID());
250   }
251 
252   // Equivalent non-predicated opcode
253   static unsigned GetFunctionalOpcodeForVP(Intrinsic::ID ID);
254 };
255 
256 /// This is the common base class for constrained floating point intrinsics.
257 class ConstrainedFPIntrinsic : public IntrinsicInst {
258 public:
259   bool isUnaryOp() const;
260   bool isTernaryOp() const;
261   Optional<RoundingMode> getRoundingMode() const;
262   Optional<fp::ExceptionBehavior> getExceptionBehavior() const;
263 
264   // Methods for support type inquiry through isa, cast, and dyn_cast:
265   static bool classof(const IntrinsicInst *I);
266   static bool classof(const Value *V) {
267     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
268   }
269 };
270 
271 /// Constrained floating point compare intrinsics.
272 class ConstrainedFPCmpIntrinsic : public ConstrainedFPIntrinsic {
273 public:
274   FCmpInst::Predicate getPredicate() const;
275 
276   // Methods for support type inquiry through isa, cast, and dyn_cast:
277   static bool classof(const IntrinsicInst *I) {
278     switch (I->getIntrinsicID()) {
279     case Intrinsic::experimental_constrained_fcmp:
280     case Intrinsic::experimental_constrained_fcmps:
281       return true;
282     default:
283       return false;
284     }
285   }
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:
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   }
312   static bool classof(const Value *V) {
313     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
314   }
315 
316   Value *getLHS() const { return const_cast<Value *>(getArgOperand(0)); }
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:
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   }
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:
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   }
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:
378   Value *getRawDest() const {
379     return const_cast<Value *>(getArgOperand(ARG_DEST));
380   }
381   const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
382   Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
383 
384   Value *getLength() const {
385     return const_cast<Value *>(getArgOperand(ARG_LENGTH));
386   }
387   const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
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.
393   Value *getDest() const { return getRawDest()->stripPointerCasts(); }
394 
395   unsigned getDestAddressSpace() const {
396     return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
397   }
398 
399   /// FIXME: Remove this function once transition to Align is over.
400   /// Use getDestAlign() instead.
401   unsigned getDestAlignment() const {
402     if (auto MA = getParamAlign(ARG_DEST))
403       return MA->value();
404     return 0;
405   }
406   MaybeAlign getDestAlign() const { return getParamAlign(ARG_DEST); }
407 
408   /// Set the specified arguments of the instruction.
409   void setDest(Value *Ptr) {
410     assert(getRawDest()->getType() == Ptr->getType() &&
411            "setDest called with pointer of wrong type!");
412     setArgOperand(ARG_DEST, Ptr);
413   }
414 
415   /// FIXME: Remove this function once transition to Align is over.
416   /// Use the version that takes MaybeAlign instead of this one.
417   void setDestAlignment(unsigned Alignment) {
418     setDestAlignment(MaybeAlign(Alignment));
419   }
420   void setDestAlignment(MaybeAlign Alignment) {
421     removeParamAttr(ARG_DEST, Attribute::Alignment);
422     if (Alignment)
423       addParamAttr(ARG_DEST,
424                    Attribute::getWithAlignment(getContext(), *Alignment));
425   }
426   void setDestAlignment(Align Alignment) {
427     removeParamAttr(ARG_DEST, Attribute::Alignment);
428     addParamAttr(ARG_DEST,
429                  Attribute::getWithAlignment(getContext(), Alignment));
430   }
431 
432   void setLength(Value *L) {
433     assert(getLength()->getType() == L->getType() &&
434            "setLength called with value of wrong type!");
435     setArgOperand(ARG_LENGTH, L);
436   }
437 };
438 
439 /// Common base class for all memory transfer intrinsics. Simply provides
440 /// common methods.
441 template <class BaseCL> class MemTransferBase : public BaseCL {
442 private:
443   enum { ARG_SOURCE = 1 };
444 
445 public:
446   /// Return the arguments to the instruction.
447   Value *getRawSource() const {
448     return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE));
449   }
450   const Use &getRawSourceUse() const {
451     return BaseCL::getArgOperandUse(ARG_SOURCE);
452   }
453   Use &getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE); }
454 
455   /// This is just like getRawSource, but it strips off any cast
456   /// instructions that feed it, giving the original input.  The returned
457   /// value is guaranteed to be a pointer.
458   Value *getSource() const { return getRawSource()->stripPointerCasts(); }
459 
460   unsigned getSourceAddressSpace() const {
461     return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
462   }
463 
464   /// FIXME: Remove this function once transition to Align is over.
465   /// Use getSourceAlign() instead.
466   unsigned getSourceAlignment() const {
467     if (auto MA = BaseCL::getParamAlign(ARG_SOURCE))
468       return MA->value();
469     return 0;
470   }
471 
472   MaybeAlign getSourceAlign() const {
473     return BaseCL::getParamAlign(ARG_SOURCE);
474   }
475 
476   void setSource(Value *Ptr) {
477     assert(getRawSource()->getType() == Ptr->getType() &&
478            "setSource called with pointer of wrong type!");
479     BaseCL::setArgOperand(ARG_SOURCE, Ptr);
480   }
481 
482   /// FIXME: Remove this function once transition to Align is over.
483   /// Use the version that takes MaybeAlign instead of this one.
484   void setSourceAlignment(unsigned Alignment) {
485     setSourceAlignment(MaybeAlign(Alignment));
486   }
487   void setSourceAlignment(MaybeAlign Alignment) {
488     BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
489     if (Alignment)
490       BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment(
491                                            BaseCL::getContext(), *Alignment));
492   }
493   void setSourceAlignment(Align Alignment) {
494     BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
495     BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment(
496                                          BaseCL::getContext(), Alignment));
497   }
498 };
499 
500 /// Common base class for all memset intrinsics. Simply provides
501 /// common methods.
502 template <class BaseCL> class MemSetBase : public BaseCL {
503 private:
504   enum { ARG_VALUE = 1 };
505 
506 public:
507   Value *getValue() const {
508     return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE));
509   }
510   const Use &getValueUse() const { return BaseCL::getArgOperandUse(ARG_VALUE); }
511   Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); }
512 
513   void setValue(Value *Val) {
514     assert(getValue()->getType() == Val->getType() &&
515            "setValue called with value of wrong type!");
516     BaseCL::setArgOperand(ARG_VALUE, Val);
517   }
518 };
519 
520 // The common base class for the atomic memset/memmove/memcpy intrinsics
521 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
522 class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> {
523 private:
524   enum { ARG_ELEMENTSIZE = 3 };
525 
526 public:
527   Value *getRawElementSizeInBytes() const {
528     return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
529   }
530 
531   ConstantInt *getElementSizeInBytesCst() const {
532     return cast<ConstantInt>(getRawElementSizeInBytes());
533   }
534 
535   uint32_t getElementSizeInBytes() const {
536     return getElementSizeInBytesCst()->getZExtValue();
537   }
538 
539   void setElementSizeInBytes(Constant *V) {
540     assert(V->getType() == Type::getInt8Ty(getContext()) &&
541            "setElementSizeInBytes called with value of wrong type!");
542     setArgOperand(ARG_ELEMENTSIZE, V);
543   }
544 
545   static bool classof(const IntrinsicInst *I) {
546     switch (I->getIntrinsicID()) {
547     case Intrinsic::memcpy_element_unordered_atomic:
548     case Intrinsic::memmove_element_unordered_atomic:
549     case Intrinsic::memset_element_unordered_atomic:
550       return true;
551     default:
552       return false;
553     }
554   }
555   static bool classof(const Value *V) {
556     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
557   }
558 };
559 
560 /// This class represents atomic memset intrinsic
561 // i.e. llvm.element.unordered.atomic.memset
562 class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> {
563 public:
564   static bool classof(const IntrinsicInst *I) {
565     return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic;
566   }
567   static bool classof(const Value *V) {
568     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
569   }
570 };
571 
572 // This class wraps the atomic memcpy/memmove intrinsics
573 // i.e. llvm.element.unordered.atomic.memcpy/memmove
574 class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> {
575 public:
576   static bool classof(const IntrinsicInst *I) {
577     switch (I->getIntrinsicID()) {
578     case Intrinsic::memcpy_element_unordered_atomic:
579     case Intrinsic::memmove_element_unordered_atomic:
580       return true;
581     default:
582       return false;
583     }
584   }
585   static bool classof(const Value *V) {
586     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
587   }
588 };
589 
590 /// This class represents the atomic memcpy intrinsic
591 /// i.e. llvm.element.unordered.atomic.memcpy
592 class AtomicMemCpyInst : public AtomicMemTransferInst {
593 public:
594   static bool classof(const IntrinsicInst *I) {
595     return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
596   }
597   static bool classof(const Value *V) {
598     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
599   }
600 };
601 
602 /// This class represents the atomic memmove intrinsic
603 /// i.e. llvm.element.unordered.atomic.memmove
604 class AtomicMemMoveInst : public AtomicMemTransferInst {
605 public:
606   static bool classof(const IntrinsicInst *I) {
607     return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic;
608   }
609   static bool classof(const Value *V) {
610     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
611   }
612 };
613 
614 /// This is the common base class for memset/memcpy/memmove.
615 class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> {
616 private:
617   enum { ARG_VOLATILE = 3 };
618 
619 public:
620   ConstantInt *getVolatileCst() const {
621     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(ARG_VOLATILE)));
622   }
623 
624   bool isVolatile() const { return !getVolatileCst()->isZero(); }
625 
626   void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); }
627 
628   // Methods for support type inquiry through isa, cast, and dyn_cast:
629   static bool classof(const IntrinsicInst *I) {
630     switch (I->getIntrinsicID()) {
631     case Intrinsic::memcpy:
632     case Intrinsic::memmove:
633     case Intrinsic::memset:
634     case Intrinsic::memcpy_inline:
635       return true;
636     default:
637       return false;
638     }
639   }
640   static bool classof(const Value *V) {
641     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
642   }
643 };
644 
645 /// This class wraps the llvm.memset intrinsic.
646 class MemSetInst : public MemSetBase<MemIntrinsic> {
647 public:
648   // Methods for support type inquiry through isa, cast, and dyn_cast:
649   static bool classof(const IntrinsicInst *I) {
650     return I->getIntrinsicID() == Intrinsic::memset;
651   }
652   static bool classof(const Value *V) {
653     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
654   }
655 };
656 
657 /// This class wraps the llvm.memcpy/memmove intrinsics.
658 class MemTransferInst : public MemTransferBase<MemIntrinsic> {
659 public:
660   // Methods for support type inquiry through isa, cast, and dyn_cast:
661   static bool classof(const IntrinsicInst *I) {
662     switch (I->getIntrinsicID()) {
663     case Intrinsic::memcpy:
664     case Intrinsic::memmove:
665     case Intrinsic::memcpy_inline:
666       return true;
667     default:
668       return false;
669     }
670   }
671   static bool classof(const Value *V) {
672     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
673   }
674 };
675 
676 /// This class wraps the llvm.memcpy intrinsic.
677 class MemCpyInst : public MemTransferInst {
678 public:
679   // Methods for support type inquiry through isa, cast, and dyn_cast:
680   static bool classof(const IntrinsicInst *I) {
681     return I->getIntrinsicID() == Intrinsic::memcpy;
682   }
683   static bool classof(const Value *V) {
684     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
685   }
686 };
687 
688 /// This class wraps the llvm.memmove intrinsic.
689 class MemMoveInst : public MemTransferInst {
690 public:
691   // Methods for support type inquiry through isa, cast, and dyn_cast:
692   static bool classof(const IntrinsicInst *I) {
693     return I->getIntrinsicID() == Intrinsic::memmove;
694   }
695   static bool classof(const Value *V) {
696     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
697   }
698 };
699 
700 /// This class wraps the llvm.memcpy.inline intrinsic.
701 class MemCpyInlineInst : public MemTransferInst {
702 public:
703   ConstantInt *getLength() const {
704     return cast<ConstantInt>(MemTransferInst::getLength());
705   }
706   // Methods for support type inquiry through isa, cast, and dyn_cast:
707   static bool classof(const IntrinsicInst *I) {
708     return I->getIntrinsicID() == Intrinsic::memcpy_inline;
709   }
710   static bool classof(const Value *V) {
711     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
712   }
713 };
714 
715 // The common base class for any memset/memmove/memcpy intrinsics;
716 // whether they be atomic or non-atomic.
717 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
718 //  and llvm.memset/memcpy/memmove
719 class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> {
720 public:
721   bool isVolatile() const {
722     // Only the non-atomic intrinsics can be volatile
723     if (auto *MI = dyn_cast<MemIntrinsic>(this))
724       return MI->isVolatile();
725     return false;
726   }
727 
728   static bool classof(const IntrinsicInst *I) {
729     switch (I->getIntrinsicID()) {
730     case Intrinsic::memcpy:
731     case Intrinsic::memcpy_inline:
732     case Intrinsic::memmove:
733     case Intrinsic::memset:
734     case Intrinsic::memcpy_element_unordered_atomic:
735     case Intrinsic::memmove_element_unordered_atomic:
736     case Intrinsic::memset_element_unordered_atomic:
737       return true;
738     default:
739       return false;
740     }
741   }
742   static bool classof(const Value *V) {
743     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
744   }
745 };
746 
747 /// This class represents any memset intrinsic
748 // i.e. llvm.element.unordered.atomic.memset
749 // and  llvm.memset
750 class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> {
751 public:
752   static bool classof(const IntrinsicInst *I) {
753     switch (I->getIntrinsicID()) {
754     case Intrinsic::memset:
755     case Intrinsic::memset_element_unordered_atomic:
756       return true;
757     default:
758       return false;
759     }
760   }
761   static bool classof(const Value *V) {
762     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
763   }
764 };
765 
766 // This class wraps any memcpy/memmove intrinsics
767 // i.e. llvm.element.unordered.atomic.memcpy/memmove
768 // and  llvm.memcpy/memmove
769 class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> {
770 public:
771   static bool classof(const IntrinsicInst *I) {
772     switch (I->getIntrinsicID()) {
773     case Intrinsic::memcpy:
774     case Intrinsic::memcpy_inline:
775     case Intrinsic::memmove:
776     case Intrinsic::memcpy_element_unordered_atomic:
777     case Intrinsic::memmove_element_unordered_atomic:
778       return true;
779     default:
780       return false;
781     }
782   }
783   static bool classof(const Value *V) {
784     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
785   }
786 };
787 
788 /// This class represents any memcpy intrinsic
789 /// i.e. llvm.element.unordered.atomic.memcpy
790 ///  and llvm.memcpy
791 class AnyMemCpyInst : public AnyMemTransferInst {
792 public:
793   static bool classof(const IntrinsicInst *I) {
794     switch (I->getIntrinsicID()) {
795     case Intrinsic::memcpy:
796     case Intrinsic::memcpy_inline:
797     case Intrinsic::memcpy_element_unordered_atomic:
798       return true;
799     default:
800       return false;
801     }
802   }
803   static bool classof(const Value *V) {
804     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
805   }
806 };
807 
808 /// This class represents any memmove intrinsic
809 /// i.e. llvm.element.unordered.atomic.memmove
810 ///  and llvm.memmove
811 class AnyMemMoveInst : public AnyMemTransferInst {
812 public:
813   static bool classof(const IntrinsicInst *I) {
814     switch (I->getIntrinsicID()) {
815     case Intrinsic::memmove:
816     case Intrinsic::memmove_element_unordered_atomic:
817       return true;
818     default:
819       return false;
820     }
821   }
822   static bool classof(const Value *V) {
823     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
824   }
825 };
826 
827 /// This represents the llvm.va_start intrinsic.
828 class VAStartInst : public IntrinsicInst {
829 public:
830   static bool classof(const IntrinsicInst *I) {
831     return I->getIntrinsicID() == Intrinsic::vastart;
832   }
833   static bool classof(const Value *V) {
834     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
835   }
836 
837   Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); }
838 };
839 
840 /// This represents the llvm.va_end intrinsic.
841 class VAEndInst : public IntrinsicInst {
842 public:
843   static bool classof(const IntrinsicInst *I) {
844     return I->getIntrinsicID() == Intrinsic::vaend;
845   }
846   static bool classof(const Value *V) {
847     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
848   }
849 
850   Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); }
851 };
852 
853 /// This represents the llvm.va_copy intrinsic.
854 class VACopyInst : public IntrinsicInst {
855 public:
856   static bool classof(const IntrinsicInst *I) {
857     return I->getIntrinsicID() == Intrinsic::vacopy;
858   }
859   static bool classof(const Value *V) {
860     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
861   }
862 
863   Value *getDest() const { return const_cast<Value *>(getArgOperand(0)); }
864   Value *getSrc() const { return const_cast<Value *>(getArgOperand(1)); }
865 };
866 
867 /// This represents the llvm.instrprof_increment intrinsic.
868 class InstrProfIncrementInst : public IntrinsicInst {
869 public:
870   static bool classof(const IntrinsicInst *I) {
871     return I->getIntrinsicID() == Intrinsic::instrprof_increment;
872   }
873   static bool classof(const Value *V) {
874     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
875   }
876 
877   GlobalVariable *getName() const {
878     return cast<GlobalVariable>(
879         const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
880   }
881 
882   ConstantInt *getHash() const {
883     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
884   }
885 
886   ConstantInt *getNumCounters() const {
887     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
888   }
889 
890   ConstantInt *getIndex() const {
891     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
892   }
893 
894   Value *getStep() const;
895 };
896 
897 class InstrProfIncrementInstStep : public InstrProfIncrementInst {
898 public:
899   static bool classof(const IntrinsicInst *I) {
900     return I->getIntrinsicID() == Intrinsic::instrprof_increment_step;
901   }
902   static bool classof(const Value *V) {
903     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
904   }
905 };
906 
907 /// This represents the llvm.instrprof_value_profile intrinsic.
908 class InstrProfValueProfileInst : public IntrinsicInst {
909 public:
910   static bool classof(const IntrinsicInst *I) {
911     return I->getIntrinsicID() == Intrinsic::instrprof_value_profile;
912   }
913   static bool classof(const Value *V) {
914     return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
915   }
916 
917   GlobalVariable *getName() const {
918     return cast<GlobalVariable>(
919         const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
920   }
921 
922   ConstantInt *getHash() const {
923     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
924   }
925 
926   Value *getTargetValue() const {
927     return cast<Value>(const_cast<Value *>(getArgOperand(2)));
928   }
929 
930   ConstantInt *getValueKind() const {
931     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
932   }
933 
934   // Returns the value site index.
935   ConstantInt *getIndex() const {
936     return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4)));
937   }
938 };
939 
940 } // end namespace llvm
941 
942 #endif // LLVM_IR_INTRINSICINST_H
943