Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:03

0001 //===- Intrinsics.h - LLVM Intrinsic Function Handling ----------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines a set of enums which allow processing of intrinsic
0010 // functions. Values of these enum types are returned by
0011 // Function::getIntrinsicID.
0012 //
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_IR_INTRINSICS_H
0016 #define LLVM_IR_INTRINSICS_H
0017 
0018 #include "llvm/ADT/ArrayRef.h"
0019 #include "llvm/Support/TypeSize.h"
0020 #include <optional>
0021 #include <string>
0022 
0023 namespace llvm {
0024 
0025 class Type;
0026 class FunctionType;
0027 class Function;
0028 class LLVMContext;
0029 class Module;
0030 class AttributeList;
0031 
0032 /// This namespace contains an enum with a value for every intrinsic/builtin
0033 /// function known by LLVM. The enum values are returned by
0034 /// Function::getIntrinsicID().
0035 namespace Intrinsic {
0036   // Abstraction for the arguments of the noalias intrinsics
0037   static const int NoAliasScopeDeclScopeArg = 0;
0038 
0039   // Intrinsic ID type. This is an opaque typedef to facilitate splitting up
0040   // the enum into target-specific enums.
0041   typedef unsigned ID;
0042 
0043   enum IndependentIntrinsics : unsigned {
0044     not_intrinsic = 0, // Must be zero
0045 
0046   // Get the intrinsic enums generated from Intrinsics.td
0047 #define GET_INTRINSIC_ENUM_VALUES
0048 #include "llvm/IR/IntrinsicEnums.inc"
0049 #undef GET_INTRINSIC_ENUM_VALUES
0050   };
0051 
0052   /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
0053   /// Note, this version is for intrinsics with no overloads.  Use the other
0054   /// version of getName if overloads are required.
0055   StringRef getName(ID id);
0056 
0057   /// Return the LLVM name for an intrinsic, without encoded types for
0058   /// overloading, such as "llvm.ssa.copy".
0059   StringRef getBaseName(ID id);
0060 
0061   /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx" or
0062   /// "llvm.ssa.copy.p0s_s.1". Note, this version of getName supports overloads.
0063   /// This is less efficient than the StringRef version of this function.  If no
0064   /// overloads are required, it is safe to use this version, but better to use
0065   /// the StringRef version. If one of the types is based on an unnamed type, a
0066   /// function type will be computed. Providing FT will avoid this computation.
0067   std::string getName(ID Id, ArrayRef<Type *> Tys, Module *M,
0068                       FunctionType *FT = nullptr);
0069 
0070   /// Return the LLVM name for an intrinsic. This is a special version only to
0071   /// be used by LLVMIntrinsicCopyOverloadedName. It only supports overloads
0072   /// based on named types.
0073   std::string getNameNoUnnamedTypes(ID Id, ArrayRef<Type *> Tys);
0074 
0075   /// Return the function type for an intrinsic.
0076   FunctionType *getType(LLVMContext &Context, ID id, ArrayRef<Type *> Tys = {});
0077 
0078   /// Returns true if the intrinsic can be overloaded.
0079   bool isOverloaded(ID id);
0080 
0081   /// isTargetIntrinsic - Returns true if IID is an intrinsic specific to a
0082   /// certain target. If it is a generic intrinsic false is returned.
0083   bool isTargetIntrinsic(ID IID);
0084 
0085   ID lookupIntrinsicID(StringRef Name);
0086 
0087   /// Return the attributes for an intrinsic.
0088   AttributeList getAttributes(LLVMContext &C, ID id);
0089 
0090   /// Look up the Function declaration of the intrinsic \p id in the Module
0091   /// \p M. If it does not exist, add a declaration and return it. Otherwise,
0092   /// return the existing declaration.
0093   ///
0094   /// The \p Tys parameter is for intrinsics with overloaded types (e.g., those
0095   /// using iAny, fAny, vAny, or pAny).  For a declaration of an overloaded
0096   /// intrinsic, Tys must provide exactly one type for each overloaded type in
0097   /// the intrinsic.
0098   Function *getOrInsertDeclaration(Module *M, ID id, ArrayRef<Type *> Tys = {});
0099 
0100   LLVM_DEPRECATED("Use getOrInsertDeclaration instead",
0101                   "getOrInsertDeclaration")
0102   inline Function *getDeclaration(Module *M, ID id, ArrayRef<Type *> Tys = {}) {
0103     return getOrInsertDeclaration(M, id, Tys);
0104   }
0105 
0106   /// Look up the Function declaration of the intrinsic \p id in the Module
0107   /// \p M and return it if it exists. Otherwise, return nullptr. This version
0108   /// supports non-overloaded intrinsics.
0109   Function *getDeclarationIfExists(const Module *M, ID id);
0110 
0111   /// This version supports overloaded intrinsics.
0112   Function *getDeclarationIfExists(Module *M, ID id, ArrayRef<Type *> Tys,
0113                                    FunctionType *FT = nullptr);
0114 
0115   /// Map a Clang builtin name to an intrinsic ID.
0116   ID getIntrinsicForClangBuiltin(StringRef TargetPrefix, StringRef BuiltinName);
0117 
0118   /// Map a MS builtin name to an intrinsic ID.
0119   ID getIntrinsicForMSBuiltin(StringRef TargetPrefix, StringRef BuiltinName);
0120 
0121   /// Returns true if the intrinsic ID is for one of the "Constrained
0122   /// Floating-Point Intrinsics".
0123   bool isConstrainedFPIntrinsic(ID QID);
0124 
0125   /// Returns true if the intrinsic ID is for one of the "Constrained
0126   /// Floating-Point Intrinsics" that take rounding mode metadata.
0127   bool hasConstrainedFPRoundingModeOperand(ID QID);
0128 
0129   /// This is a type descriptor which explains the type requirements of an
0130   /// intrinsic. This is returned by getIntrinsicInfoTableEntries.
0131   struct IITDescriptor {
0132     enum IITDescriptorKind {
0133       Void,
0134       VarArg,
0135       MMX,
0136       Token,
0137       Metadata,
0138       Half,
0139       BFloat,
0140       Float,
0141       Double,
0142       Quad,
0143       Integer,
0144       Vector,
0145       Pointer,
0146       Struct,
0147       Argument,
0148       ExtendArgument,
0149       TruncArgument,
0150       HalfVecArgument,
0151       SameVecWidthArgument,
0152       VecOfAnyPtrsToElt,
0153       VecElementArgument,
0154       Subdivide2Argument,
0155       Subdivide4Argument,
0156       VecOfBitcastsToInt,
0157       AMX,
0158       PPCQuad,
0159       AArch64Svcount,
0160     } Kind;
0161 
0162     union {
0163       unsigned Integer_Width;
0164       unsigned Float_Width;
0165       unsigned Pointer_AddressSpace;
0166       unsigned Struct_NumElements;
0167       unsigned Argument_Info;
0168       ElementCount Vector_Width;
0169     };
0170 
0171     // AK_% : Defined in Intrinsics.td
0172     enum ArgKind {
0173 #define GET_INTRINSIC_ARGKIND
0174 #include "llvm/IR/IntrinsicEnums.inc"
0175 #undef GET_INTRINSIC_ARGKIND
0176     };
0177 
0178     unsigned getArgumentNumber() const {
0179       assert(Kind == Argument || Kind == ExtendArgument ||
0180              Kind == TruncArgument || Kind == HalfVecArgument ||
0181              Kind == SameVecWidthArgument || Kind == VecElementArgument ||
0182              Kind == Subdivide2Argument || Kind == Subdivide4Argument ||
0183              Kind == VecOfBitcastsToInt);
0184       return Argument_Info >> 3;
0185     }
0186     ArgKind getArgumentKind() const {
0187       assert(Kind == Argument || Kind == ExtendArgument ||
0188              Kind == TruncArgument || Kind == HalfVecArgument ||
0189              Kind == SameVecWidthArgument ||
0190              Kind == VecElementArgument || Kind == Subdivide2Argument ||
0191              Kind == Subdivide4Argument || Kind == VecOfBitcastsToInt);
0192       return (ArgKind)(Argument_Info & 7);
0193     }
0194 
0195     // VecOfAnyPtrsToElt uses both an overloaded argument (for address space)
0196     // and a reference argument (for matching vector width and element types)
0197     unsigned getOverloadArgNumber() const {
0198       assert(Kind == VecOfAnyPtrsToElt);
0199       return Argument_Info >> 16;
0200     }
0201     unsigned getRefArgNumber() const {
0202       assert(Kind == VecOfAnyPtrsToElt);
0203       return Argument_Info & 0xFFFF;
0204     }
0205 
0206     static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
0207       IITDescriptor Result = { K, { Field } };
0208       return Result;
0209     }
0210 
0211     static IITDescriptor get(IITDescriptorKind K, unsigned short Hi,
0212                              unsigned short Lo) {
0213       unsigned Field = Hi << 16 | Lo;
0214       IITDescriptor Result = {K, {Field}};
0215       return Result;
0216     }
0217 
0218     static IITDescriptor getVector(unsigned Width, bool IsScalable) {
0219       IITDescriptor Result = {Vector, {0}};
0220       Result.Vector_Width = ElementCount::get(Width, IsScalable);
0221       return Result;
0222     }
0223   };
0224 
0225   /// Return the IIT table descriptor for the specified intrinsic into an array
0226   /// of IITDescriptors.
0227   void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T);
0228 
0229   enum MatchIntrinsicTypesResult {
0230     MatchIntrinsicTypes_Match = 0,
0231     MatchIntrinsicTypes_NoMatchRet = 1,
0232     MatchIntrinsicTypes_NoMatchArg = 2,
0233   };
0234 
0235   /// Match the specified function type with the type constraints specified by
0236   /// the .td file. If the given type is an overloaded type it is pushed to the
0237   /// ArgTys vector.
0238   ///
0239   /// Returns false if the given type matches with the constraints, true
0240   /// otherwise.
0241   MatchIntrinsicTypesResult
0242   matchIntrinsicSignature(FunctionType *FTy, ArrayRef<IITDescriptor> &Infos,
0243                           SmallVectorImpl<Type *> &ArgTys);
0244 
0245   /// Verify if the intrinsic has variable arguments. This method is intended to
0246   /// be called after all the fixed arguments have been matched first.
0247   ///
0248   /// This method returns true on error.
0249   bool matchIntrinsicVarArg(bool isVarArg, ArrayRef<IITDescriptor> &Infos);
0250 
0251   /// Gets the type arguments of an intrinsic call by matching type contraints
0252   /// specified by the .td file. The overloaded types are pushed into the
0253   /// AgTys vector.
0254   ///
0255   /// Returns false if the given ID and function type combination is not a
0256   /// valid intrinsic call.
0257   bool getIntrinsicSignature(Intrinsic::ID, FunctionType *FT,
0258                              SmallVectorImpl<Type *> &ArgTys);
0259 
0260   /// Same as previous, but accepts a Function instead of ID and FunctionType.
0261   bool getIntrinsicSignature(Function *F, SmallVectorImpl<Type *> &ArgTys);
0262 
0263   // Checks if the intrinsic name matches with its signature and if not
0264   // returns the declaration with the same signature and remangled name.
0265   // An existing GlobalValue with the wanted name but with a wrong prototype
0266   // or of the wrong kind will be renamed by adding ".renamed" to the name.
0267   std::optional<Function *> remangleIntrinsicFunction(Function *F);
0268 
0269 } // End Intrinsic namespace
0270 
0271 } // End llvm namespace
0272 
0273 #endif