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