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
39namespace 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.
44class IntrinsicInst : public CallInst {
45public:
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.
67static 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.
80class DbgInfoIntrinsic : public IntrinsicInst {
81public:
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.
94class DbgVariableIntrinsic : public DbgInfoIntrinsic {
95public:
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.
146class DbgDeclareInst : public DbgVariableIntrinsic {
147public:
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.
162class DbgAddrIntrinsic : public DbgVariableIntrinsic {
163public:
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.
177class DbgValueInst : public DbgVariableIntrinsic {
178public:
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.
195class DbgLabelInst : public DbgInfoIntrinsic {
196public:
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.
215class VPIntrinsic : public IntrinsicInst {
216public:
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.
257class ConstrainedFPIntrinsic : public IntrinsicInst {
258public:
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.
272class ConstrainedFPCmpIntrinsic : public ConstrainedFPIntrinsic {
273public:
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.
293class BinaryOpIntrinsic : public IntrinsicInst {
294public:
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.
330class WithOverflowInst : public BinaryOpIntrinsic {
331public:
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.
351class SaturatingInst : public BinaryOpIntrinsic {
352public:
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.
373template <typename Derived> class MemIntrinsicBase : public IntrinsicInst {
374private:
375  enum { ARG_DEST = 0, ARG_LENGTH = 2 };
376
377public:
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.
441template <class BaseCL> class MemTransferBase : public BaseCL {
442private:
443  enum { ARG_SOURCE = 1 };
444
445public:
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.
502template <class BaseCL> class MemSetBase : public BaseCL {
503private:
504  enum { ARG_VALUE = 1 };
505
506public:
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
522class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> {
523private:
524  enum { ARG_ELEMENTSIZE = 3 };
525
526public:
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
562class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> {
563public:
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
574class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> {
575public:
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
592class AtomicMemCpyInst : public AtomicMemTransferInst {
593public:
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
604class AtomicMemMoveInst : public AtomicMemTransferInst {
605public:
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.
615class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> {
616private:
617  enum { ARG_VOLATILE = 3 };
618
619public:
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.
646class MemSetInst : public MemSetBase<MemIntrinsic> {
647public:
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.
658class MemTransferInst : public MemTransferBase<MemIntrinsic> {
659public:
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.
677class MemCpyInst : public MemTransferInst {
678public:
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.
689class MemMoveInst : public MemTransferInst {
690public:
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.
701class MemCpyInlineInst : public MemTransferInst {
702public:
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
719class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> {
720public:
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
750class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> {
751public:
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
769class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> {
770public:
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
791class AnyMemCpyInst : public AnyMemTransferInst {
792public:
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
811class AnyMemMoveInst : public AnyMemTransferInst {
812public:
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.
828class VAStartInst : public IntrinsicInst {
829public:
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.
841class VAEndInst : public IntrinsicInst {
842public:
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.
854class VACopyInst : public IntrinsicInst {
855public:
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.
868class InstrProfIncrementInst : public IntrinsicInst {
869public:
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
897class InstrProfIncrementInstStep : public InstrProfIncrementInst {
898public:
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.
908class InstrProfValueProfileInst : public IntrinsicInst {
909public:
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