1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===-- llvm/IntrinsicInst.h - Intrinsic Instruction Wrappers ---*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines classes that make it really easy to deal with intrinsic
- // functions with the isa/dyncast family of functions. In particular, this
- // allows you to do things like:
- //
- // if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(Inst))
- // ... MCI->getDest() ... MCI->getSource() ...
- //
- // All intrinsic function calls are instances of the call instruction, so these
- // are all subclasses of the CallInst class. Note that none of these classes
- // has state or virtual methods, which is an important part of this gross/neat
- // hack working.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_IR_INTRINSICINST_H
- #define LLVM_IR_INTRINSICINST_H
- #include "llvm/IR/Constants.h"
- #include "llvm/IR/DebugInfoMetadata.h"
- #include "llvm/IR/DerivedTypes.h"
- #include "llvm/IR/FPEnv.h"
- #include "llvm/IR/Function.h"
- #include "llvm/IR/GlobalVariable.h"
- #include "llvm/IR/Instructions.h"
- #include "llvm/IR/Intrinsics.h"
- #include "llvm/IR/Value.h"
- #include "llvm/Support/Casting.h"
- #include <cassert>
- #include <cstdint>
- #include <optional>
- namespace llvm {
- class Metadata;
- /// A wrapper class for inspecting calls to intrinsic functions.
- /// This allows the standard isa/dyncast/cast functionality to work with calls
- /// to intrinsic functions.
- class IntrinsicInst : public CallInst {
- public:
- IntrinsicInst() = delete;
- IntrinsicInst(const IntrinsicInst &) = delete;
- IntrinsicInst &operator=(const IntrinsicInst &) = delete;
- /// Return the intrinsic ID of this intrinsic.
- Intrinsic::ID getIntrinsicID() const {
- return getCalledFunction()->getIntrinsicID();
- }
- /// Return true if swapping the first two arguments to the intrinsic produces
- /// the same result.
- bool isCommutative() const {
- switch (getIntrinsicID()) {
- case Intrinsic::maxnum:
- case Intrinsic::minnum:
- case Intrinsic::maximum:
- case Intrinsic::minimum:
- case Intrinsic::smax:
- case Intrinsic::smin:
- case Intrinsic::umax:
- case Intrinsic::umin:
- case Intrinsic::sadd_sat:
- case Intrinsic::uadd_sat:
- case Intrinsic::sadd_with_overflow:
- case Intrinsic::uadd_with_overflow:
- case Intrinsic::smul_with_overflow:
- case Intrinsic::umul_with_overflow:
- case Intrinsic::smul_fix:
- case Intrinsic::umul_fix:
- case Intrinsic::smul_fix_sat:
- case Intrinsic::umul_fix_sat:
- case Intrinsic::fma:
- case Intrinsic::fmuladd:
- return true;
- default:
- return false;
- }
- }
- /// Checks if the intrinsic is an annotation.
- bool isAssumeLikeIntrinsic() const {
- switch (getIntrinsicID()) {
- default: break;
- case Intrinsic::assume:
- case Intrinsic::sideeffect:
- case Intrinsic::pseudoprobe:
- case Intrinsic::dbg_assign:
- case Intrinsic::dbg_declare:
- case Intrinsic::dbg_value:
- case Intrinsic::dbg_label:
- case Intrinsic::invariant_start:
- case Intrinsic::invariant_end:
- case Intrinsic::lifetime_start:
- case Intrinsic::lifetime_end:
- case Intrinsic::experimental_noalias_scope_decl:
- case Intrinsic::objectsize:
- case Intrinsic::ptr_annotation:
- case Intrinsic::var_annotation:
- return true;
- }
- return false;
- }
- /// Check if the intrinsic might lower into a regular function call in the
- /// course of IR transformations
- static bool mayLowerToFunctionCall(Intrinsic::ID IID);
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const CallInst *I) {
- if (const Function *CF = I->getCalledFunction())
- return CF->isIntrinsic();
- return false;
- }
- static bool classof(const Value *V) {
- return isa<CallInst>(V) && classof(cast<CallInst>(V));
- }
- };
- /// Check if \p ID corresponds to a lifetime intrinsic.
- static inline bool isLifetimeIntrinsic(Intrinsic::ID ID) {
- switch (ID) {
- case Intrinsic::lifetime_start:
- case Intrinsic::lifetime_end:
- return true;
- default:
- return false;
- }
- }
- /// This is the common base class for lifetime intrinsics.
- class LifetimeIntrinsic : public IntrinsicInst {
- public:
- /// \name Casting methods
- /// @{
- static bool classof(const IntrinsicInst *I) {
- return isLifetimeIntrinsic(I->getIntrinsicID());
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// @}
- };
- /// Check if \p ID corresponds to a debug info intrinsic.
- static inline bool isDbgInfoIntrinsic(Intrinsic::ID ID) {
- switch (ID) {
- case Intrinsic::dbg_declare:
- case Intrinsic::dbg_value:
- case Intrinsic::dbg_addr:
- case Intrinsic::dbg_label:
- case Intrinsic::dbg_assign:
- return true;
- default:
- return false;
- }
- }
- /// This is the common base class for debug info intrinsics.
- class DbgInfoIntrinsic : public IntrinsicInst {
- public:
- /// \name Casting methods
- /// @{
- static bool classof(const IntrinsicInst *I) {
- return isDbgInfoIntrinsic(I->getIntrinsicID());
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// @}
- };
- /// This is the common base class for debug info intrinsics for variables.
- class DbgVariableIntrinsic : public DbgInfoIntrinsic {
- public:
- // Iterator for ValueAsMetadata that internally uses direct pointer iteration
- // over either a ValueAsMetadata* or a ValueAsMetadata**, dereferencing to the
- // ValueAsMetadata .
- class location_op_iterator
- : public iterator_facade_base<location_op_iterator,
- std::bidirectional_iterator_tag, Value *> {
- PointerUnion<ValueAsMetadata *, ValueAsMetadata **> I;
- public:
- location_op_iterator(ValueAsMetadata *SingleIter) : I(SingleIter) {}
- location_op_iterator(ValueAsMetadata **MultiIter) : I(MultiIter) {}
- location_op_iterator(const location_op_iterator &R) : I(R.I) {}
- location_op_iterator &operator=(const location_op_iterator &R) {
- I = R.I;
- return *this;
- }
- bool operator==(const location_op_iterator &RHS) const {
- return I == RHS.I;
- }
- const Value *operator*() const {
- ValueAsMetadata *VAM = I.is<ValueAsMetadata *>()
- ? I.get<ValueAsMetadata *>()
- : *I.get<ValueAsMetadata **>();
- return VAM->getValue();
- };
- Value *operator*() {
- ValueAsMetadata *VAM = I.is<ValueAsMetadata *>()
- ? I.get<ValueAsMetadata *>()
- : *I.get<ValueAsMetadata **>();
- return VAM->getValue();
- }
- location_op_iterator &operator++() {
- if (I.is<ValueAsMetadata *>())
- I = I.get<ValueAsMetadata *>() + 1;
- else
- I = I.get<ValueAsMetadata **>() + 1;
- return *this;
- }
- location_op_iterator &operator--() {
- if (I.is<ValueAsMetadata *>())
- I = I.get<ValueAsMetadata *>() - 1;
- else
- I = I.get<ValueAsMetadata **>() - 1;
- return *this;
- }
- };
- /// Get the locations corresponding to the variable referenced by the debug
- /// info intrinsic. Depending on the intrinsic, this could be the
- /// variable's value or its address.
- iterator_range<location_op_iterator> location_ops() const;
- Value *getVariableLocationOp(unsigned OpIdx) const;
- void replaceVariableLocationOp(Value *OldValue, Value *NewValue);
- void replaceVariableLocationOp(unsigned OpIdx, Value *NewValue);
- /// Adding a new location operand will always result in this intrinsic using
- /// an ArgList, and must always be accompanied by a new expression that uses
- /// the new operand.
- void addVariableLocationOps(ArrayRef<Value *> NewValues,
- DIExpression *NewExpr);
- void setVariable(DILocalVariable *NewVar) {
- setArgOperand(1, MetadataAsValue::get(NewVar->getContext(), NewVar));
- }
- void setExpression(DIExpression *NewExpr) {
- setArgOperand(2, MetadataAsValue::get(NewExpr->getContext(), NewExpr));
- }
- unsigned getNumVariableLocationOps() const {
- if (hasArgList())
- return cast<DIArgList>(getRawLocation())->getArgs().size();
- return 1;
- }
- bool hasArgList() const { return isa<DIArgList>(getRawLocation()); }
- /// Does this describe the address of a local variable. True for dbg.addr and
- /// dbg.declare, but not dbg.value, which describes its value, or dbg.assign,
- /// which describes a combination of the variable's value and address.
- bool isAddressOfVariable() const {
- return getIntrinsicID() != Intrinsic::dbg_value &&
- getIntrinsicID() != Intrinsic::dbg_assign;
- }
- void setKillLocation() {
- // TODO: When/if we remove duplicate values from DIArgLists, we don't need
- // this set anymore.
- SmallPtrSet<Value *, 4> RemovedValues;
- for (Value *OldValue : location_ops()) {
- if (!RemovedValues.insert(OldValue).second)
- continue;
- Value *Poison = PoisonValue::get(OldValue->getType());
- replaceVariableLocationOp(OldValue, Poison);
- }
- }
- bool isKillLocation() const {
- return (getNumVariableLocationOps() == 0 &&
- !getExpression()->isComplex()) ||
- any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); });
- }
- DILocalVariable *getVariable() const {
- return cast<DILocalVariable>(getRawVariable());
- }
- DIExpression *getExpression() const {
- return cast<DIExpression>(getRawExpression());
- }
- Metadata *getRawLocation() const {
- return cast<MetadataAsValue>(getArgOperand(0))->getMetadata();
- }
- Metadata *getRawVariable() const {
- return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
- }
- Metadata *getRawExpression() const {
- return cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
- }
- /// Use of this should generally be avoided; instead,
- /// replaceVariableLocationOp and addVariableLocationOps should be used where
- /// possible to avoid creating invalid state.
- void setRawLocation(Metadata *Location) {
- return setArgOperand(0, MetadataAsValue::get(getContext(), Location));
- }
- /// Get the size (in bits) of the variable, or fragment of the variable that
- /// is described.
- std::optional<uint64_t> getFragmentSizeInBits() const;
- /// Get the FragmentInfo for the variable.
- std::optional<DIExpression::FragmentInfo> getFragment() const {
- return getExpression()->getFragmentInfo();
- }
- /// \name Casting methods
- /// @{
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::dbg_declare:
- case Intrinsic::dbg_value:
- case Intrinsic::dbg_addr:
- case Intrinsic::dbg_assign:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// @}
- protected:
- void setArgOperand(unsigned i, Value *v) {
- DbgInfoIntrinsic::setArgOperand(i, v);
- }
- void setOperand(unsigned i, Value *v) { DbgInfoIntrinsic::setOperand(i, v); }
- };
- /// This represents the llvm.dbg.declare instruction.
- class DbgDeclareInst : public DbgVariableIntrinsic {
- public:
- Value *getAddress() const {
- assert(getNumVariableLocationOps() == 1 &&
- "dbg.declare must have exactly 1 location operand.");
- return getVariableLocationOp(0);
- }
- /// \name Casting methods
- /// @{
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::dbg_declare;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// @}
- };
- /// This represents the llvm.dbg.addr instruction.
- class DbgAddrIntrinsic : public DbgVariableIntrinsic {
- public:
- Value *getAddress() const {
- assert(getNumVariableLocationOps() == 1 &&
- "dbg.addr must have exactly 1 location operand.");
- return getVariableLocationOp(0);
- }
- /// \name Casting methods
- /// @{
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::dbg_addr;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This represents the llvm.dbg.value instruction.
- class DbgValueInst : public DbgVariableIntrinsic {
- public:
- // The default argument should only be used in ISel, and the default option
- // should be removed once ISel support for multiple location ops is complete.
- Value *getValue(unsigned OpIdx = 0) const {
- return getVariableLocationOp(OpIdx);
- }
- iterator_range<location_op_iterator> getValues() const {
- return location_ops();
- }
- /// \name Casting methods
- /// @{
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::dbg_value ||
- I->getIntrinsicID() == Intrinsic::dbg_assign;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// @}
- };
- /// This represents the llvm.dbg.assign instruction.
- class DbgAssignIntrinsic : public DbgValueInst {
- enum Operands {
- OpValue,
- OpVar,
- OpExpr,
- OpAssignID,
- OpAddress,
- OpAddressExpr,
- };
- public:
- Value *getAddress() const;
- Metadata *getRawAddress() const {
- return cast<MetadataAsValue>(getArgOperand(OpAddress))->getMetadata();
- }
- Metadata *getRawAssignID() const {
- return cast<MetadataAsValue>(getArgOperand(OpAssignID))->getMetadata();
- }
- DIAssignID *getAssignID() const { return cast<DIAssignID>(getRawAssignID()); }
- Metadata *getRawAddressExpression() const {
- return cast<MetadataAsValue>(getArgOperand(OpAddressExpr))->getMetadata();
- }
- DIExpression *getAddressExpression() const {
- return cast<DIExpression>(getRawAddressExpression());
- }
- void setAddressExpression(DIExpression *NewExpr) {
- setArgOperand(OpAddressExpr,
- MetadataAsValue::get(NewExpr->getContext(), NewExpr));
- }
- void setAssignId(DIAssignID *New);
- void setAddress(Value *V);
- /// Kill the address component.
- void setKillAddress();
- /// Check whether this kills the address component. This doesn't take into
- /// account the position of the intrinsic, therefore a returned value of false
- /// does not guarentee the address is a valid location for the variable at the
- /// intrinsic's position in IR.
- bool isKillAddress() const;
- void setValue(Value *V);
- /// \name Casting methods
- /// @{
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::dbg_assign;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// @}
- };
- /// This represents the llvm.dbg.label instruction.
- class DbgLabelInst : public DbgInfoIntrinsic {
- public:
- DILabel *getLabel() const { return cast<DILabel>(getRawLabel()); }
- Metadata *getRawLabel() const {
- return cast<MetadataAsValue>(getArgOperand(0))->getMetadata();
- }
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
- /// @{
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::dbg_label;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// @}
- };
- /// This is the common base class for vector predication intrinsics.
- class VPIntrinsic : public IntrinsicInst {
- public:
- /// \brief Declares a llvm.vp.* intrinsic in \p M that matches the parameters
- /// \p Params. Additionally, the load and gather intrinsics require
- /// \p ReturnType to be specified.
- static Function *getDeclarationForParams(Module *M, Intrinsic::ID,
- Type *ReturnType,
- ArrayRef<Value *> Params);
- static std::optional<unsigned> getMaskParamPos(Intrinsic::ID IntrinsicID);
- static std::optional<unsigned> getVectorLengthParamPos(
- Intrinsic::ID IntrinsicID);
- /// The llvm.vp.* intrinsics for this instruction Opcode
- static Intrinsic::ID getForOpcode(unsigned OC);
- // Whether \p ID is a VP intrinsic ID.
- static bool isVPIntrinsic(Intrinsic::ID);
- /// \return The mask parameter or nullptr.
- Value *getMaskParam() const;
- void setMaskParam(Value *);
- /// \return The vector length parameter or nullptr.
- Value *getVectorLengthParam() const;
- void setVectorLengthParam(Value *);
- /// \return Whether the vector length param can be ignored.
- bool canIgnoreVectorLengthParam() const;
- /// \return The static element count (vector number of elements) the vector
- /// length parameter applies to.
- ElementCount getStaticVectorLength() const;
- /// \return The alignment of the pointer used by this load/store/gather or
- /// scatter.
- MaybeAlign getPointerAlignment() const;
- // MaybeAlign setPointerAlignment(Align NewAlign); // TODO
- /// \return The pointer operand of this load,store, gather or scatter.
- Value *getMemoryPointerParam() const;
- static std::optional<unsigned> getMemoryPointerParamPos(Intrinsic::ID);
- /// \return The data (payload) operand of this store or scatter.
- Value *getMemoryDataParam() const;
- static std::optional<unsigned> getMemoryDataParamPos(Intrinsic::ID);
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I) {
- return isVPIntrinsic(I->getIntrinsicID());
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- // Equivalent non-predicated opcode
- std::optional<unsigned> getFunctionalOpcode() const {
- return getFunctionalOpcodeForVP(getIntrinsicID());
- }
- // Equivalent non-predicated opcode
- static std::optional<unsigned> getFunctionalOpcodeForVP(Intrinsic::ID ID);
- };
- /// This represents vector predication reduction intrinsics.
- class VPReductionIntrinsic : public VPIntrinsic {
- public:
- static bool isVPReduction(Intrinsic::ID ID);
- unsigned getStartParamPos() const;
- unsigned getVectorParamPos() const;
- static std::optional<unsigned> getStartParamPos(Intrinsic::ID ID);
- static std::optional<unsigned> getVectorParamPos(Intrinsic::ID ID);
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
- /// @{
- static bool classof(const IntrinsicInst *I) {
- return VPReductionIntrinsic::isVPReduction(I->getIntrinsicID());
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// @}
- };
- class VPCastIntrinsic : public VPIntrinsic {
- public:
- static bool isVPCast(Intrinsic::ID ID);
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
- /// @{
- static bool classof(const IntrinsicInst *I) {
- return VPCastIntrinsic::isVPCast(I->getIntrinsicID());
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// @}
- };
- class VPCmpIntrinsic : public VPIntrinsic {
- public:
- static bool isVPCmp(Intrinsic::ID ID);
- CmpInst::Predicate getPredicate() const;
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
- /// @{
- static bool classof(const IntrinsicInst *I) {
- return VPCmpIntrinsic::isVPCmp(I->getIntrinsicID());
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// @}
- };
- /// This is the common base class for constrained floating point intrinsics.
- class ConstrainedFPIntrinsic : public IntrinsicInst {
- public:
- bool isUnaryOp() const;
- bool isTernaryOp() const;
- std::optional<RoundingMode> getRoundingMode() const;
- std::optional<fp::ExceptionBehavior> getExceptionBehavior() const;
- bool isDefaultFPEnvironment() const;
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I);
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// Constrained floating point compare intrinsics.
- class ConstrainedFPCmpIntrinsic : public ConstrainedFPIntrinsic {
- public:
- FCmpInst::Predicate getPredicate() const;
- bool isSignaling() const {
- return getIntrinsicID() == Intrinsic::experimental_constrained_fcmps;
- }
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::experimental_constrained_fcmp:
- case Intrinsic::experimental_constrained_fcmps:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This class represents min/max intrinsics.
- class MinMaxIntrinsic : public IntrinsicInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::umin:
- case Intrinsic::umax:
- case Intrinsic::smin:
- case Intrinsic::smax:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- Value *getLHS() const { return const_cast<Value *>(getArgOperand(0)); }
- Value *getRHS() const { return const_cast<Value *>(getArgOperand(1)); }
- /// Returns the comparison predicate underlying the intrinsic.
- static ICmpInst::Predicate getPredicate(Intrinsic::ID ID) {
- switch (ID) {
- case Intrinsic::umin:
- return ICmpInst::Predicate::ICMP_ULT;
- case Intrinsic::umax:
- return ICmpInst::Predicate::ICMP_UGT;
- case Intrinsic::smin:
- return ICmpInst::Predicate::ICMP_SLT;
- case Intrinsic::smax:
- return ICmpInst::Predicate::ICMP_SGT;
- default:
- llvm_unreachable("Invalid intrinsic");
- }
- }
- /// Returns the comparison predicate underlying the intrinsic.
- ICmpInst::Predicate getPredicate() const {
- return getPredicate(getIntrinsicID());
- }
- /// Whether the intrinsic is signed or unsigned.
- static bool isSigned(Intrinsic::ID ID) {
- return ICmpInst::isSigned(getPredicate(ID));
- };
- /// Whether the intrinsic is signed or unsigned.
- bool isSigned() const { return isSigned(getIntrinsicID()); };
- /// Min/max intrinsics are monotonic, they operate on a fixed-bitwidth values,
- /// so there is a certain threshold value, upon reaching which,
- /// their value can no longer change. Return said threshold.
- static APInt getSaturationPoint(Intrinsic::ID ID, unsigned numBits) {
- switch (ID) {
- case Intrinsic::umin:
- return APInt::getMinValue(numBits);
- case Intrinsic::umax:
- return APInt::getMaxValue(numBits);
- case Intrinsic::smin:
- return APInt::getSignedMinValue(numBits);
- case Intrinsic::smax:
- return APInt::getSignedMaxValue(numBits);
- default:
- llvm_unreachable("Invalid intrinsic");
- }
- }
- /// Min/max intrinsics are monotonic, they operate on a fixed-bitwidth values,
- /// so there is a certain threshold value, upon reaching which,
- /// their value can no longer change. Return said threshold.
- APInt getSaturationPoint(unsigned numBits) const {
- return getSaturationPoint(getIntrinsicID(), numBits);
- }
- /// Min/max intrinsics are monotonic, they operate on a fixed-bitwidth values,
- /// so there is a certain threshold value, upon reaching which,
- /// their value can no longer change. Return said threshold.
- static Constant *getSaturationPoint(Intrinsic::ID ID, Type *Ty) {
- return Constant::getIntegerValue(
- Ty, getSaturationPoint(ID, Ty->getScalarSizeInBits()));
- }
- /// Min/max intrinsics are monotonic, they operate on a fixed-bitwidth values,
- /// so there is a certain threshold value, upon reaching which,
- /// their value can no longer change. Return said threshold.
- Constant *getSaturationPoint(Type *Ty) const {
- return getSaturationPoint(getIntrinsicID(), Ty);
- }
- };
- /// This class represents an intrinsic that is based on a binary operation.
- /// This includes op.with.overflow and saturating add/sub intrinsics.
- class BinaryOpIntrinsic : public IntrinsicInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::uadd_with_overflow:
- case Intrinsic::sadd_with_overflow:
- case Intrinsic::usub_with_overflow:
- case Intrinsic::ssub_with_overflow:
- case Intrinsic::umul_with_overflow:
- case Intrinsic::smul_with_overflow:
- case Intrinsic::uadd_sat:
- case Intrinsic::sadd_sat:
- case Intrinsic::usub_sat:
- case Intrinsic::ssub_sat:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- Value *getLHS() const { return const_cast<Value *>(getArgOperand(0)); }
- Value *getRHS() const { return const_cast<Value *>(getArgOperand(1)); }
- /// Returns the binary operation underlying the intrinsic.
- Instruction::BinaryOps getBinaryOp() const;
- /// Whether the intrinsic is signed or unsigned.
- bool isSigned() const;
- /// Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap.
- unsigned getNoWrapKind() const;
- };
- /// Represents an op.with.overflow intrinsic.
- class WithOverflowInst : public BinaryOpIntrinsic {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::uadd_with_overflow:
- case Intrinsic::sadd_with_overflow:
- case Intrinsic::usub_with_overflow:
- case Intrinsic::ssub_with_overflow:
- case Intrinsic::umul_with_overflow:
- case Intrinsic::smul_with_overflow:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// Represents a saturating add/sub intrinsic.
- class SaturatingInst : public BinaryOpIntrinsic {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::uadd_sat:
- case Intrinsic::sadd_sat:
- case Intrinsic::usub_sat:
- case Intrinsic::ssub_sat:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// Common base class for all memory intrinsics. Simply provides
- /// common methods.
- /// Written as CRTP to avoid a common base class amongst the
- /// three atomicity hierarchies.
- template <typename Derived> class MemIntrinsicBase : public IntrinsicInst {
- private:
- enum { ARG_DEST = 0, ARG_LENGTH = 2 };
- public:
- Value *getRawDest() const {
- return const_cast<Value *>(getArgOperand(ARG_DEST));
- }
- const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
- Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
- Value *getLength() const {
- return const_cast<Value *>(getArgOperand(ARG_LENGTH));
- }
- const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
- Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
- /// This is just like getRawDest, but it strips off any cast
- /// instructions (including addrspacecast) that feed it, giving the
- /// original input. The returned value is guaranteed to be a pointer.
- Value *getDest() const { return getRawDest()->stripPointerCasts(); }
- unsigned getDestAddressSpace() const {
- return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
- }
- /// FIXME: Remove this function once transition to Align is over.
- /// Use getDestAlign() instead.
- LLVM_DEPRECATED("Use getDestAlign() instead", "getDestAlign")
- unsigned getDestAlignment() const {
- if (auto MA = getParamAlign(ARG_DEST))
- return MA->value();
- return 0;
- }
- MaybeAlign getDestAlign() const { return getParamAlign(ARG_DEST); }
- /// Set the specified arguments of the instruction.
- void setDest(Value *Ptr) {
- assert(getRawDest()->getType() == Ptr->getType() &&
- "setDest called with pointer of wrong type!");
- setArgOperand(ARG_DEST, Ptr);
- }
- void setDestAlignment(MaybeAlign Alignment) {
- removeParamAttr(ARG_DEST, Attribute::Alignment);
- if (Alignment)
- addParamAttr(ARG_DEST,
- Attribute::getWithAlignment(getContext(), *Alignment));
- }
- void setDestAlignment(Align Alignment) {
- removeParamAttr(ARG_DEST, Attribute::Alignment);
- addParamAttr(ARG_DEST,
- Attribute::getWithAlignment(getContext(), Alignment));
- }
- void setLength(Value *L) {
- assert(getLength()->getType() == L->getType() &&
- "setLength called with value of wrong type!");
- setArgOperand(ARG_LENGTH, L);
- }
- };
- /// Common base class for all memory transfer intrinsics. Simply provides
- /// common methods.
- template <class BaseCL> class MemTransferBase : public BaseCL {
- private:
- enum { ARG_SOURCE = 1 };
- public:
- /// Return the arguments to the instruction.
- Value *getRawSource() const {
- return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE));
- }
- const Use &getRawSourceUse() const {
- return BaseCL::getArgOperandUse(ARG_SOURCE);
- }
- Use &getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE); }
- /// This is just like getRawSource, but it strips off any cast
- /// instructions that feed it, giving the original input. The returned
- /// value is guaranteed to be a pointer.
- Value *getSource() const { return getRawSource()->stripPointerCasts(); }
- unsigned getSourceAddressSpace() const {
- return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
- }
- /// FIXME: Remove this function once transition to Align is over.
- /// Use getSourceAlign() instead.
- LLVM_DEPRECATED("Use getSourceAlign() instead", "getSourceAlign")
- unsigned getSourceAlignment() const {
- if (auto MA = BaseCL::getParamAlign(ARG_SOURCE))
- return MA->value();
- return 0;
- }
- MaybeAlign getSourceAlign() const {
- return BaseCL::getParamAlign(ARG_SOURCE);
- }
- void setSource(Value *Ptr) {
- assert(getRawSource()->getType() == Ptr->getType() &&
- "setSource called with pointer of wrong type!");
- BaseCL::setArgOperand(ARG_SOURCE, Ptr);
- }
- void setSourceAlignment(MaybeAlign Alignment) {
- BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
- if (Alignment)
- BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment(
- BaseCL::getContext(), *Alignment));
- }
- void setSourceAlignment(Align Alignment) {
- BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
- BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment(
- BaseCL::getContext(), Alignment));
- }
- };
- /// Common base class for all memset intrinsics. Simply provides
- /// common methods.
- template <class BaseCL> class MemSetBase : public BaseCL {
- private:
- enum { ARG_VALUE = 1 };
- public:
- Value *getValue() const {
- return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE));
- }
- const Use &getValueUse() const { return BaseCL::getArgOperandUse(ARG_VALUE); }
- Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); }
- void setValue(Value *Val) {
- assert(getValue()->getType() == Val->getType() &&
- "setValue called with value of wrong type!");
- BaseCL::setArgOperand(ARG_VALUE, Val);
- }
- };
- // The common base class for the atomic memset/memmove/memcpy intrinsics
- // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
- class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> {
- private:
- enum { ARG_ELEMENTSIZE = 3 };
- public:
- Value *getRawElementSizeInBytes() const {
- return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
- }
- ConstantInt *getElementSizeInBytesCst() const {
- return cast<ConstantInt>(getRawElementSizeInBytes());
- }
- uint32_t getElementSizeInBytes() const {
- return getElementSizeInBytesCst()->getZExtValue();
- }
- void setElementSizeInBytes(Constant *V) {
- assert(V->getType() == Type::getInt8Ty(getContext()) &&
- "setElementSizeInBytes called with value of wrong type!");
- setArgOperand(ARG_ELEMENTSIZE, V);
- }
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memcpy_element_unordered_atomic:
- case Intrinsic::memmove_element_unordered_atomic:
- case Intrinsic::memset_element_unordered_atomic:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This class represents atomic memset intrinsic
- // i.e. llvm.element.unordered.atomic.memset
- class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- // This class wraps the atomic memcpy/memmove intrinsics
- // i.e. llvm.element.unordered.atomic.memcpy/memmove
- class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memcpy_element_unordered_atomic:
- case Intrinsic::memmove_element_unordered_atomic:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This class represents the atomic memcpy intrinsic
- /// i.e. llvm.element.unordered.atomic.memcpy
- class AtomicMemCpyInst : public AtomicMemTransferInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This class represents the atomic memmove intrinsic
- /// i.e. llvm.element.unordered.atomic.memmove
- class AtomicMemMoveInst : public AtomicMemTransferInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This is the common base class for memset/memcpy/memmove.
- class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> {
- private:
- enum { ARG_VOLATILE = 3 };
- public:
- ConstantInt *getVolatileCst() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(ARG_VOLATILE)));
- }
- bool isVolatile() const { return !getVolatileCst()->isZero(); }
- void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); }
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memcpy:
- case Intrinsic::memmove:
- case Intrinsic::memset:
- case Intrinsic::memset_inline:
- case Intrinsic::memcpy_inline:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This class wraps the llvm.memset and llvm.memset.inline intrinsics.
- class MemSetInst : public MemSetBase<MemIntrinsic> {
- public:
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memset:
- case Intrinsic::memset_inline:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This class wraps the llvm.memset.inline intrinsic.
- class MemSetInlineInst : public MemSetInst {
- public:
- ConstantInt *getLength() const {
- return cast<ConstantInt>(MemSetInst::getLength());
- }
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memset_inline;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This class wraps the llvm.memcpy/memmove intrinsics.
- class MemTransferInst : public MemTransferBase<MemIntrinsic> {
- public:
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memcpy:
- case Intrinsic::memmove:
- case Intrinsic::memcpy_inline:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This class wraps the llvm.memcpy intrinsic.
- class MemCpyInst : public MemTransferInst {
- public:
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memcpy ||
- I->getIntrinsicID() == Intrinsic::memcpy_inline;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This class wraps the llvm.memmove intrinsic.
- class MemMoveInst : public MemTransferInst {
- public:
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memmove;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This class wraps the llvm.memcpy.inline intrinsic.
- class MemCpyInlineInst : public MemCpyInst {
- public:
- ConstantInt *getLength() const {
- return cast<ConstantInt>(MemCpyInst::getLength());
- }
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memcpy_inline;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- // The common base class for any memset/memmove/memcpy intrinsics;
- // whether they be atomic or non-atomic.
- // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
- // and llvm.memset/memcpy/memmove
- class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> {
- public:
- bool isVolatile() const {
- // Only the non-atomic intrinsics can be volatile
- if (auto *MI = dyn_cast<MemIntrinsic>(this))
- return MI->isVolatile();
- return false;
- }
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memcpy:
- case Intrinsic::memcpy_inline:
- case Intrinsic::memmove:
- case Intrinsic::memset:
- case Intrinsic::memset_inline:
- case Intrinsic::memcpy_element_unordered_atomic:
- case Intrinsic::memmove_element_unordered_atomic:
- case Intrinsic::memset_element_unordered_atomic:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This class represents any memset intrinsic
- // i.e. llvm.element.unordered.atomic.memset
- // and llvm.memset
- class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memset:
- case Intrinsic::memset_inline:
- case Intrinsic::memset_element_unordered_atomic:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- // This class wraps any memcpy/memmove intrinsics
- // i.e. llvm.element.unordered.atomic.memcpy/memmove
- // and llvm.memcpy/memmove
- class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memcpy:
- case Intrinsic::memcpy_inline:
- case Intrinsic::memmove:
- case Intrinsic::memcpy_element_unordered_atomic:
- case Intrinsic::memmove_element_unordered_atomic:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This class represents any memcpy intrinsic
- /// i.e. llvm.element.unordered.atomic.memcpy
- /// and llvm.memcpy
- class AnyMemCpyInst : public AnyMemTransferInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memcpy:
- case Intrinsic::memcpy_inline:
- case Intrinsic::memcpy_element_unordered_atomic:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This class represents any memmove intrinsic
- /// i.e. llvm.element.unordered.atomic.memmove
- /// and llvm.memmove
- class AnyMemMoveInst : public AnyMemTransferInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memmove:
- case Intrinsic::memmove_element_unordered_atomic:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This represents the llvm.va_start intrinsic.
- class VAStartInst : public IntrinsicInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::vastart;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); }
- };
- /// This represents the llvm.va_end intrinsic.
- class VAEndInst : public IntrinsicInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::vaend;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); }
- };
- /// This represents the llvm.va_copy intrinsic.
- class VACopyInst : public IntrinsicInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::vacopy;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- Value *getDest() const { return const_cast<Value *>(getArgOperand(0)); }
- Value *getSrc() const { return const_cast<Value *>(getArgOperand(1)); }
- };
- /// A base class for all instrprof intrinsics.
- class InstrProfInstBase : public IntrinsicInst {
- public:
- // The name of the instrumented function.
- GlobalVariable *getName() const {
- return cast<GlobalVariable>(
- const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
- }
- // The hash of the CFG for the instrumented function.
- ConstantInt *getHash() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
- }
- // The number of counters for the instrumented function.
- ConstantInt *getNumCounters() const;
- // The index of the counter that this instruction acts on.
- ConstantInt *getIndex() const;
- };
- /// This represents the llvm.instrprof.cover intrinsic.
- class InstrProfCoverInst : public InstrProfInstBase {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::instrprof_cover;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This represents the llvm.instrprof.increment intrinsic.
- class InstrProfIncrementInst : public InstrProfInstBase {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::instrprof_increment ||
- I->getIntrinsicID() == Intrinsic::instrprof_increment_step;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- Value *getStep() const;
- };
- /// This represents the llvm.instrprof.increment.step intrinsic.
- class InstrProfIncrementInstStep : public InstrProfIncrementInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::instrprof_increment_step;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This represents the llvm.instrprof.value.profile intrinsic.
- class InstrProfValueProfileInst : public InstrProfInstBase {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::instrprof_value_profile;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- Value *getTargetValue() const {
- return cast<Value>(const_cast<Value *>(getArgOperand(2)));
- }
- ConstantInt *getValueKind() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
- }
- // Returns the value site index.
- ConstantInt *getIndex() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4)));
- }
- };
- class PseudoProbeInst : public IntrinsicInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::pseudoprobe;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- ConstantInt *getFuncGuid() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(0)));
- }
- ConstantInt *getIndex() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
- }
- ConstantInt *getAttributes() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
- }
- ConstantInt *getFactor() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
- }
- };
- class NoAliasScopeDeclInst : public IntrinsicInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::experimental_noalias_scope_decl;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- MDNode *getScopeList() const {
- auto *MV =
- cast<MetadataAsValue>(getOperand(Intrinsic::NoAliasScopeDeclScopeArg));
- return cast<MDNode>(MV->getMetadata());
- }
- void setScopeList(MDNode *ScopeList) {
- setOperand(Intrinsic::NoAliasScopeDeclScopeArg,
- MetadataAsValue::get(getContext(), ScopeList));
- }
- };
- /// Common base class for representing values projected from a statepoint.
- /// Currently, the only projections available are gc.result and gc.relocate.
- class GCProjectionInst : public IntrinsicInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate ||
- I->getIntrinsicID() == Intrinsic::experimental_gc_result;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// Return true if this relocate is tied to the invoke statepoint.
- /// This includes relocates which are on the unwinding path.
- bool isTiedToInvoke() const {
- const Value *Token = getArgOperand(0);
- return isa<LandingPadInst>(Token) || isa<InvokeInst>(Token);
- }
- /// The statepoint with which this gc.relocate is associated.
- const Value *getStatepoint() const;
- };
- /// Represents calls to the gc.relocate intrinsic.
- class GCRelocateInst : public GCProjectionInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::experimental_gc_relocate;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// The index into the associate statepoint's argument list
- /// which contains the base pointer of the pointer whose
- /// relocation this gc.relocate describes.
- unsigned getBasePtrIndex() const {
- return cast<ConstantInt>(getArgOperand(1))->getZExtValue();
- }
- /// The index into the associate statepoint's argument list which
- /// contains the pointer whose relocation this gc.relocate describes.
- unsigned getDerivedPtrIndex() const {
- return cast<ConstantInt>(getArgOperand(2))->getZExtValue();
- }
- Value *getBasePtr() const;
- Value *getDerivedPtr() const;
- };
- /// Represents calls to the gc.result intrinsic.
- class GCResultInst : public GCProjectionInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::experimental_gc_result;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This represents intrinsics that guard a condition
- class CondGuardInst : public IntrinsicInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::assume ||
- I->getIntrinsicID() == Intrinsic::experimental_guard;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- /// This represents the llvm.assume intrinsic.
- class AssumeInst : public CondGuardInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::assume;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
- } // end namespace llvm
- #endif // LLVM_IR_INTRINSICINST_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|