Line data Source code
1 : //===-- 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 :
39 : namespace llvm {
40 :
41 : /// A wrapper class for inspecting calls to intrinsic functions.
42 : /// This allows the standard isa/dyncast/cast functionality to work with calls
43 : /// to intrinsic functions.
44 : class IntrinsicInst : public CallInst {
45 : public:
46 : IntrinsicInst() = delete;
47 : IntrinsicInst(const IntrinsicInst &) = delete;
48 : IntrinsicInst &operator=(const IntrinsicInst &) = delete;
49 :
50 : /// Return the intrinsic ID of this intrinsic.
51 : Intrinsic::ID getIntrinsicID() const {
52 44282029 : 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 135301440 : 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:
69 : /// \name Casting methods
70 : /// @{
71 : static bool classof(const IntrinsicInst *I) {
72 15243049 : 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 0 : 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:
90 : /// 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 315314 : return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
111 : }
112 :
113 : Metadata *getRawExpression() const {
114 287687 : return cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
115 : }
116 :
117 : /// Get the size (in bits) of the variable, or fragment of the variable that
118 : /// is described.
119 : Optional<uint64_t> getFragmentSizeInBits() const;
120 :
121 : /// \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 7255661 : static bool classof(const Value *V) {
133 7255661 : return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
134 : }
135 : /// @}
136 : };
137 :
138 : /// This represents the llvm.dbg.declare instruction.
139 : class DbgDeclareInst : public DbgVariableIntrinsic {
140 : public:
141 15774 : Value *getAddress() const { return getVariableLocation(); }
142 :
143 : /// \name Casting methods
144 : /// @{
145 : static bool classof(const IntrinsicInst *I) {
146 0 : return I->getIntrinsicID() == Intrinsic::dbg_declare;
147 : }
148 : static bool classof(const Value *V) {
149 7454359 : return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
150 : }
151 : /// @}
152 : };
153 :
154 : /// This represents the llvm.dbg.addr instruction.
155 : class DbgAddrIntrinsic : public DbgVariableIntrinsic {
156 : public:
157 : Value *getAddress() const { return getVariableLocation(); }
158 :
159 : /// \name Casting methods
160 : /// @{
161 : static bool classof(const IntrinsicInst *I) {
162 0 : 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.
170 : class DbgValueInst : public DbgVariableIntrinsic {
171 : public:
172 : Value *getValue() const {
173 2612951 : return getVariableLocation(/* AllowNullOp = */ false);
174 : }
175 :
176 : /// \name Casting methods
177 : /// @{
178 : static bool classof(const IntrinsicInst *I) {
179 0 : return I->getIntrinsicID() == Intrinsic::dbg_value;
180 : }
181 : static bool classof(const Value *V) {
182 4806093 : return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
183 : }
184 : /// @}
185 : };
186 :
187 : /// 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 87 : 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 2272246 : return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
205 : }
206 : /// @}
207 : };
208 :
209 : /// 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 200977 : 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 599926 : 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 45728 : 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 17 : setArgOperand(ARG_DEST, Ptr);
300 : }
301 :
302 209779 : void setDestAlignment(unsigned Align) {
303 209779 : removeParamAttr(ARG_DEST, Attribute::Alignment);
304 209779 : if (Align > 0)
305 209776 : addParamAttr(ARG_DEST,
306 : Attribute::getWithAlignment(getContext(), Align));
307 209779 : }
308 7 :
309 7 : void setLength(Value *L) {
310 7 : assert(getLength()->getType() == L->getType() &&
311 7 : "setLength called with value of wrong type!");
312 : setArgOperand(ARG_LENGTH, L);
313 7 : }
314 195188 : };
315 195188 :
316 195188 : /// Common base class for all memory transfer intrinsics. Simply provides
317 195188 : /// common methods.
318 : template <class BaseCL> class MemTransferBase : public BaseCL {
319 195188 : private:
320 : enum { ARG_SOURCE = 1 };
321 :
322 : public:
323 : /// Return the arguments to the instruction.
324 : Value *getRawSource() const {
325 291557 : 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 4308 : 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 13 : BaseCL::setArgOperand(ARG_SOURCE, Ptr);
349 : }
350 :
351 618 : void setSourceAlignment(unsigned Align) {
352 618 : BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
353 618 : if (Align > 0)
354 616 : BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment(
355 : BaseCL::getContext(), Align));
356 618 : }
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 162372 : enum { ARG_VALUE = 1 };
364 162372 :
365 162372 : public:
366 162372 : Value *getValue() const {
367 239440 : return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE));
368 162372 : }
369 7 : const Use &getValueUse() const {
370 7 : return BaseCL::getArgOperandUse(ARG_VALUE);
371 7 : }
372 7 : Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); }
373 :
374 7 : void setValue(Value *Val) {
375 162365 : assert(getValue()->getType() == Val->getType() &&
376 162365 : "setValue called with value of wrong type!");
377 162365 : BaseCL::setArgOperand(ARG_VALUE, Val);
378 162365 : }
379 : };
380 162365 :
381 : // 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 433 : 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 18 : 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 42 : static bool classof(const Value *V) {
417 42 : 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
423 : class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> {
424 : public:
425 : static bool classof(const IntrinsicInst *I) {
426 0 : 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
435 : class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> {
436 : public:
437 : static bool classof(const IntrinsicInst *I) {
438 1510 : switch (I->getIntrinsicID()) {
439 : case Intrinsic::memcpy_element_unordered_atomic:
440 : case Intrinsic::memmove_element_unordered_atomic:
441 : return true;
442 0 : 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 0 : 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 1000643 : return cast<ConstantInt>(
483 : const_cast<Value *>(getArgOperand(ARG_VOLATILE)));
484 : }
485 :
486 1000643 : bool isVolatile() const {
487 1000643 : 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 9662160 : static bool classof(const Value *V) {
503 9662160 : return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
504 : }
505 : };
506 :
507 : /// This class wraps the llvm.memset intrinsic.
508 : class MemSetInst : public MemSetBase<MemIntrinsic> {
509 : public:
510 : // Methods for support type inquiry through isa, cast, and dyn_cast:
511 : static bool classof(const IntrinsicInst *I) {
512 0 : return I->getIntrinsicID() == Intrinsic::memset;
513 : }
514 : static bool classof(const Value *V) {
515 497756 : return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
516 : }
517 : };
518 :
519 : /// This class wraps the llvm.memcpy/memmove intrinsics.
520 : class MemTransferInst : public MemTransferBase<MemIntrinsic> {
521 : public:
522 : // Methods for support type inquiry through isa, cast, and dyn_cast:
523 : static bool classof(const IntrinsicInst *I) {
524 133434 : 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 0 : return I->getIntrinsicID() == Intrinsic::memcpy;
538 : }
539 : static bool classof(const Value *V) {
540 288825 : 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 0 : return I->getIntrinsicID() == Intrinsic::memmove;
550 : }
551 : static bool classof(const Value *V) {
552 286784 : 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 135 : bool isVolatile() const {
563 : // Only the non-atomic intrinsics can be volatile
564 : if (auto *MI = dyn_cast<MemIntrinsic>(this))
565 125 : return MI->isVolatile();
566 : return false;
567 : }
568 :
569 : static bool classof(const IntrinsicInst *I) {
570 1048702 : 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 0 : 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
590 : class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> {
591 : public:
592 : static bool classof(const IntrinsicInst *I) {
593 317321 : switch (I->getIntrinsicID()) {
594 : case Intrinsic::memset:
595 : case Intrinsic::memset_element_unordered_atomic:
596 : return true;
597 0 : 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
609 : class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> {
610 : public:
611 : static bool classof(const IntrinsicInst *I) {
612 527682 : 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 0 : 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 3124950 : 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 193342 : switch (I->getIntrinsicID()) {
653 : case Intrinsic::memmove:
654 : case Intrinsic::memmove_element_unordered_atomic:
655 : return true;
656 0 : 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 1264 : return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
713 : }
714 :
715 : GlobalVariable *getName() const {
716 2079 : 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 844 : 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 882 : 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 920 : return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
753 : }
754 :
755 : GlobalVariable *getName() const {
756 36 : 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
|