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