blob: 52504582dd1d3eb4091a434fd6954af3d59d53ff [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===-- llvm/IntrinsicInst.h - Intrinsic Instruction Wrappers ---*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
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"
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020028#include "llvm/IR/FPEnv.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010029#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
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020041/// 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;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010049
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020050 /// Return the intrinsic ID of this intrinsic.
51 Intrinsic::ID getIntrinsicID() const {
52 return getCalledFunction()->getIntrinsicID();
53 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010054
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020055 /// Return true if swapping the first two arguments to the intrinsic produces
56 /// the same result.
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:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010081 return false;
82 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020083 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010084
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020085 // Methods for support type inquiry through isa, cast, and dyn_cast:
86 static bool classof(const CallInst *I) {
87 if (const Function *CF = I->getCalledFunction())
88 return CF->isIntrinsic();
89 return false;
90 }
91 static bool classof(const Value *V) {
92 return isa<CallInst>(V) && classof(cast<CallInst>(V));
93 }
94};
Andrew Scullcdfcccc2018-10-05 20:58:37 +010095
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020096/// Check if \p ID corresponds to a debug info intrinsic.
97static 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}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100108
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200109/// This is the common base class for debug info intrinsics.
110class DbgInfoIntrinsic : public IntrinsicInst {
111public:
112 /// \name Casting methods
113 /// @{
114 static bool classof(const IntrinsicInst *I) {
115 return isDbgInfoIntrinsic(I->getIntrinsicID());
116 }
117 static bool classof(const Value *V) {
118 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
119 }
120 /// @}
121};
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100122
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200123/// This is the common base class for debug info intrinsics for variables.
124class DbgVariableIntrinsic : public DbgInfoIntrinsic {
125public:
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;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100130
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200131 /// 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.
133 bool isAddressOfVariable() const {
134 return getIntrinsicID() != Intrinsic::dbg_value;
135 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100136
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200137 DILocalVariable *getVariable() const {
138 return cast<DILocalVariable>(getRawVariable());
139 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100140
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200141 DIExpression *getExpression() const {
142 return cast<DIExpression>(getRawExpression());
143 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100144
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200145 Metadata *getRawVariable() const {
146 return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
147 }
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100148
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200149 Metadata *getRawExpression() const {
150 return cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
151 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100152
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200153 /// Get the size (in bits) of the variable, or fragment of the variable that
154 /// is described.
155 Optional<uint64_t> getFragmentSizeInBits() const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100156
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200157 /// \name Casting methods
158 /// @{
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:
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100166 return false;
167 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200168 }
169 static bool classof(const Value *V) {
170 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
171 }
172 /// @}
173};
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100174
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200175/// This represents the llvm.dbg.declare instruction.
176class DbgDeclareInst : public DbgVariableIntrinsic {
177public:
178 Value *getAddress() const { return getVariableLocation(); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100179
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200180 /// \name Casting methods
181 /// @{
182 static bool classof(const IntrinsicInst *I) {
183 return I->getIntrinsicID() == Intrinsic::dbg_declare;
184 }
185 static bool classof(const Value *V) {
186 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
187 }
188 /// @}
189};
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100190
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200191/// This represents the llvm.dbg.addr instruction.
192class DbgAddrIntrinsic : public DbgVariableIntrinsic {
193public:
194 Value *getAddress() const { return getVariableLocation(); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100195
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200196 /// \name Casting methods
197 /// @{
198 static bool classof(const IntrinsicInst *I) {
199 return I->getIntrinsicID() == Intrinsic::dbg_addr;
200 }
201 static bool classof(const Value *V) {
202 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
203 }
204};
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100205
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200206/// This represents the llvm.dbg.value instruction.
207class DbgValueInst : public DbgVariableIntrinsic {
208public:
209 Value *getValue() const {
210 return getVariableLocation(/* AllowNullOp = */ false);
211 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100212
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200213 /// \name Casting methods
214 /// @{
215 static bool classof(const IntrinsicInst *I) {
216 return I->getIntrinsicID() == Intrinsic::dbg_value;
217 }
218 static bool classof(const Value *V) {
219 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
220 }
221 /// @}
222};
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100223
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200224/// This represents the llvm.dbg.label instruction.
225class DbgLabelInst : public DbgInfoIntrinsic {
226public:
227 DILabel *getLabel() const { return cast<DILabel>(getRawLabel()); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100228
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200229 Metadata *getRawLabel() const {
230 return cast<MetadataAsValue>(getArgOperand(0))->getMetadata();
231 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100232
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200233 /// Methods for support type inquiry through isa, cast, and dyn_cast:
234 /// @{
235 static bool classof(const IntrinsicInst *I) {
236 return I->getIntrinsicID() == Intrinsic::dbg_label;
237 }
238 static bool classof(const Value *V) {
239 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
240 }
241 /// @}
242};
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100243
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200244/// This is the common base class for vector predication intrinsics.
245class VPIntrinsic : public IntrinsicInst {
246public:
247 static Optional<int> GetMaskParamPos(Intrinsic::ID IntrinsicID);
248 static Optional<int> GetVectorLengthParamPos(Intrinsic::ID IntrinsicID);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100249
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200250 /// The llvm.vp.* intrinsics for this instruction Opcode
251 static Intrinsic::ID GetForOpcode(unsigned OC);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100252
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200253 // Whether \p ID is a VP intrinsic ID.
254 static bool IsVPIntrinsic(Intrinsic::ID);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100255
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200256 /// \return the mask parameter or nullptr.
257 Value *getMaskParam() const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100258
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200259 /// \return the vector length parameter or nullptr.
260 Value *getVectorLengthParam() const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100261
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200262 /// \return whether the vector length param can be ignored.
263 bool canIgnoreVectorLengthParam() const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100264
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200265 /// \return the static element count (vector number of elements) the vector
266 /// length parameter applies to.
267 ElementCount getStaticVectorLength() const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100268
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200269 // Methods for support type inquiry through isa, cast, and dyn_cast:
270 static bool classof(const IntrinsicInst *I) {
271 return IsVPIntrinsic(I->getIntrinsicID());
272 }
273 static bool classof(const Value *V) {
274 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
275 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100276
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200277 // Equivalent non-predicated opcode
278 unsigned getFunctionalOpcode() const {
279 return GetFunctionalOpcodeForVP(getIntrinsicID());
280 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100281
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200282 // Equivalent non-predicated opcode
283 static unsigned GetFunctionalOpcodeForVP(Intrinsic::ID ID);
284};
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100285
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200286/// This is the common base class for constrained floating point intrinsics.
287class ConstrainedFPIntrinsic : public IntrinsicInst {
288public:
289 bool isUnaryOp() const;
290 bool isTernaryOp() const;
291 Optional<RoundingMode> getRoundingMode() const;
292 Optional<fp::ExceptionBehavior> getExceptionBehavior() const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100293
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200294 // Methods for support type inquiry through isa, cast, and dyn_cast:
295 static bool classof(const IntrinsicInst *I);
296 static bool classof(const Value *V) {
297 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
298 }
299};
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100300
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200301/// Constrained floating point compare intrinsics.
302class ConstrainedFPCmpIntrinsic : public ConstrainedFPIntrinsic {
303public:
304 FCmpInst::Predicate getPredicate() const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100305
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200306 // Methods for support type inquiry through isa, cast, and dyn_cast:
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;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100314 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200315 }
316 static bool classof(const Value *V) {
317 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
318 }
319};
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100320
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200321/// This class represents an intrinsic that is based on a binary operation.
322/// This includes op.with.overflow and saturating add/sub intrinsics.
323class BinaryOpIntrinsic : public IntrinsicInst {
324public:
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;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100340 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200341 }
342 static bool classof(const Value *V) {
343 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
344 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100345
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200346 Value *getLHS() const { return const_cast<Value *>(getArgOperand(0)); }
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.
360class WithOverflowInst : public BinaryOpIntrinsic {
361public:
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 }
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.
381class SaturatingInst : public BinaryOpIntrinsic {
382public:
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 }
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.
403template <typename Derived> class MemIntrinsicBase : public IntrinsicInst {
404private:
405 enum { ARG_DEST = 0, ARG_LENGTH = 2 };
406
407public:
408 Value *getRawDest() const {
409 return const_cast<Value *>(getArgOperand(ARG_DEST));
410 }
411 const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
412 Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
413
414 Value *getLength() const {
415 return const_cast<Value *>(getArgOperand(ARG_LENGTH));
416 }
417 const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
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.
423 Value *getDest() const { return getRawDest()->stripPointerCasts(); }
424
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.
431 unsigned getDestAlignment() const {
432 if (auto MA = getParamAlign(ARG_DEST))
433 return MA->value();
434 return 0;
435 }
436 MaybeAlign getDestAlign() const { return getParamAlign(ARG_DEST); }
437
438 /// Set the specified arguments of the instruction.
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.
447 void setDestAlignment(unsigned Alignment) {
448 setDestAlignment(MaybeAlign(Alignment));
449 }
450 void setDestAlignment(MaybeAlign Alignment) {
451 removeParamAttr(ARG_DEST, Attribute::Alignment);
452 if (Alignment)
453 addParamAttr(ARG_DEST,
454 Attribute::getWithAlignment(getContext(), *Alignment));
455 }
456 void setDestAlignment(Align Alignment) {
457 removeParamAttr(ARG_DEST, Attribute::Alignment);
458 addParamAttr(ARG_DEST,
459 Attribute::getWithAlignment(getContext(), Alignment));
460 }
461
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.
471template <class BaseCL> class MemTransferBase : public BaseCL {
472private:
473 enum { ARG_SOURCE = 1 };
474
475public:
476 /// Return the arguments to the instruction.
477 Value *getRawSource() const {
478 return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE));
479 }
480 const Use &getRawSourceUse() const {
481 return BaseCL::getArgOperandUse(ARG_SOURCE);
482 }
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.
488 Value *getSource() const { return getRawSource()->stripPointerCasts(); }
489
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.
496 unsigned getSourceAlignment() const {
497 if (auto MA = BaseCL::getParamAlign(ARG_SOURCE))
498 return MA->value();
499 return 0;
500 }
501
502 MaybeAlign getSourceAlign() const {
503 return BaseCL::getParamAlign(ARG_SOURCE);
504 }
505
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.
514 void setSourceAlignment(unsigned Alignment) {
515 setSourceAlignment(MaybeAlign(Alignment));
516 }
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 }
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.
532template <class BaseCL> class MemSetBase : public BaseCL {
533private:
534 enum { ARG_VALUE = 1 };
535
536public:
537 Value *getValue() const {
538 return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE));
539 }
540 const Use &getValueUse() const { return BaseCL::getArgOperandUse(ARG_VALUE); }
541 Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); }
542
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
552class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> {
553private:
554 enum { ARG_ELEMENTSIZE = 3 };
555
556public:
557 Value *getRawElementSizeInBytes() const {
558 return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
559 }
560
561 ConstantInt *getElementSizeInBytesCst() const {
562 return cast<ConstantInt>(getRawElementSizeInBytes());
563 }
564
565 uint32_t getElementSizeInBytes() const {
566 return getElementSizeInBytesCst()->getZExtValue();
567 }
568
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
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 }
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
592class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> {
593public:
594 static bool classof(const IntrinsicInst *I) {
595 return I->getIntrinsicID() == Intrinsic::memset_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 wraps the atomic memcpy/memmove intrinsics
603// i.e. llvm.element.unordered.atomic.memcpy/memmove
604class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> {
605public:
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 }
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
622class AtomicMemCpyInst : public AtomicMemTransferInst {
623public:
624 static bool classof(const IntrinsicInst *I) {
625 return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
626 }
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
634class AtomicMemMoveInst : public AtomicMemTransferInst {
635public:
636 static bool classof(const IntrinsicInst *I) {
637 return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic;
638 }
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.
645class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> {
646private:
647 enum { ARG_VOLATILE = 3 };
648
649public:
650 ConstantInt *getVolatileCst() const {
651 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(ARG_VOLATILE)));
652 }
653
654 bool isVolatile() const { return !getVolatileCst()->isZero(); }
655
656 void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); }
657
658 // Methods for support type inquiry through isa, cast, and dyn_cast:
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 }
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.
676class MemSetInst : public MemSetBase<MemIntrinsic> {
677public:
678 // Methods for support type inquiry through isa, cast, and dyn_cast:
679 static bool classof(const IntrinsicInst *I) {
680 return I->getIntrinsicID() == Intrinsic::memset;
681 }
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.
688class MemTransferInst : public MemTransferBase<MemIntrinsic> {
689public:
690 // Methods for support type inquiry through isa, cast, and dyn_cast:
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 }
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.
707class MemCpyInst : public MemTransferInst {
708public:
709 // Methods for support type inquiry through isa, cast, and dyn_cast:
710 static bool classof(const IntrinsicInst *I) {
711 return I->getIntrinsicID() == Intrinsic::memcpy;
712 }
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.
719class MemMoveInst : public MemTransferInst {
720public:
721 // Methods for support type inquiry through isa, cast, and dyn_cast:
722 static bool classof(const IntrinsicInst *I) {
723 return I->getIntrinsicID() == Intrinsic::memmove;
724 }
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.
731class MemCpyInlineInst : public MemTransferInst {
732public:
733 ConstantInt *getLength() const {
734 return cast<ConstantInt>(MemTransferInst::getLength());
735 }
736 // Methods for support type inquiry through isa, cast, and dyn_cast:
737 static bool classof(const IntrinsicInst *I) {
738 return I->getIntrinsicID() == Intrinsic::memcpy_inline;
739 }
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
749class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> {
750public:
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
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 }
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
780class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> {
781public:
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 }
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
799class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> {
800public:
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 }
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
821class AnyMemCpyInst : public AnyMemTransferInst {
822public:
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 }
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
841class AnyMemMoveInst : public AnyMemTransferInst {
842public:
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 }
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.
858class VAStartInst : public IntrinsicInst {
859public:
860 static bool classof(const IntrinsicInst *I) {
861 return I->getIntrinsicID() == Intrinsic::vastart;
862 }
863 static bool classof(const Value *V) {
864 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
865 }
866
867 Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); }
868};
869
870/// This represents the llvm.va_end intrinsic.
871class VAEndInst : public IntrinsicInst {
872public:
873 static bool classof(const IntrinsicInst *I) {
874 return I->getIntrinsicID() == Intrinsic::vaend;
875 }
876 static bool classof(const Value *V) {
877 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
878 }
879
880 Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); }
881};
882
883/// This represents the llvm.va_copy intrinsic.
884class VACopyInst : public IntrinsicInst {
885public:
886 static bool classof(const IntrinsicInst *I) {
887 return I->getIntrinsicID() == Intrinsic::vacopy;
888 }
889 static bool classof(const Value *V) {
890 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
891 }
892
893 Value *getDest() const { return const_cast<Value *>(getArgOperand(0)); }
894 Value *getSrc() const { return const_cast<Value *>(getArgOperand(1)); }
895};
896
897/// This represents the llvm.instrprof_increment intrinsic.
898class InstrProfIncrementInst : public IntrinsicInst {
899public:
900 static bool classof(const IntrinsicInst *I) {
901 return I->getIntrinsicID() == Intrinsic::instrprof_increment;
902 }
903 static bool classof(const Value *V) {
904 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
905 }
906
907 GlobalVariable *getName() const {
908 return cast<GlobalVariable>(
909 const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
910 }
911
912 ConstantInt *getHash() const {
913 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
914 }
915
916 ConstantInt *getNumCounters() const {
917 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
918 }
919
920 ConstantInt *getIndex() const {
921 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
922 }
923
924 Value *getStep() const;
925};
926
927class InstrProfIncrementInstStep : public InstrProfIncrementInst {
928public:
929 static bool classof(const IntrinsicInst *I) {
930 return I->getIntrinsicID() == Intrinsic::instrprof_increment_step;
931 }
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.
938class InstrProfValueProfileInst : public IntrinsicInst {
939public:
940 static bool classof(const IntrinsicInst *I) {
941 return I->getIntrinsicID() == Intrinsic::instrprof_value_profile;
942 }
943 static bool classof(const Value *V) {
944 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
945 }
946
947 GlobalVariable *getName() const {
948 return cast<GlobalVariable>(
949 const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
950 }
951
952 ConstantInt *getHash() const {
953 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
954 }
955
956 Value *getTargetValue() const {
957 return cast<Value>(const_cast<Value *>(getArgOperand(2)));
958 }
959
960 ConstantInt *getValueKind() const {
961 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
962 }
963
964 // Returns the value site index.
965 ConstantInt *getIndex() const {
966 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4)));
967 }
968};
969
970class PseudoProbeInst : public IntrinsicInst {
971public:
972 static bool classof(const IntrinsicInst *I) {
973 return I->getIntrinsicID() == Intrinsic::pseudoprobe;
974 }
975
976 static bool classof(const Value *V) {
977 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
978 }
979
980 ConstantInt *getFuncGuid() const {
981 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(0)));
982 }
983
984 ConstantInt *getAttributes() const {
985 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
986 }
987
988 ConstantInt *getIndex() const {
989 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
990 }
991};
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100992} // end namespace llvm
993
994#endif // LLVM_IR_INTRINSICINST_H