1 //===- Intrinsics.h - LLVM Intrinsic Function Handling ----------*- C++ -*-===// 2 // 3 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines a set of enums which allow processing of intrinsic 10 // functions. Values of these enum types are returned by 11 // Function::getIntrinsicID. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_IR_INTRINSICS_H 16 #define LLVM_IR_INTRINSICS_H 17 18 #include "llvm/ADT/ArrayRef.h" 19 #include "llvm/Support/Compiler.h" 20 #include "llvm/Support/TypeSize.h" 21 #include <optional> 22 #include <string> 23 24 namespace llvm { 25 26 class Type; 27 class FunctionType; 28 class Function; 29 class LLVMContext; 30 class Module; 31 class AttributeList; 32 class AttributeSet; 33 34 /// This namespace contains an enum with a value for every intrinsic/builtin 35 /// function known by LLVM. The enum values are returned by 36 /// Function::getIntrinsicID(). 37 namespace Intrinsic { 38 // Abstraction for the arguments of the noalias intrinsics 39 static const int NoAliasScopeDeclScopeArg = 0; 40 41 // Intrinsic ID type. This is an opaque typedef to facilitate splitting up 42 // the enum into target-specific enums. 43 typedef unsigned ID; 44 45 enum IndependentIntrinsics : unsigned { 46 not_intrinsic = 0, // Must be zero 47 48 // Get the intrinsic enums generated from Intrinsics.td 49 #define GET_INTRINSIC_ENUM_VALUES 50 #include "llvm/IR/IntrinsicEnums.inc" 51 #undef GET_INTRINSIC_ENUM_VALUES 52 }; 53 54 /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx". 55 /// Note, this version is for intrinsics with no overloads. Use the other 56 /// version of getName if overloads are required. 57 LLVM_ABI StringRef getName(ID id); 58 59 /// Return the LLVM name for an intrinsic, without encoded types for 60 /// overloading, such as "llvm.ssa.copy". 61 LLVM_ABI StringRef getBaseName(ID id); 62 63 /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx" or 64 /// "llvm.ssa.copy.p0s_s.1". Note, this version of getName supports overloads. 65 /// This is less efficient than the StringRef version of this function. If no 66 /// overloads are required, it is safe to use this version, but better to use 67 /// the StringRef version. If one of the types is based on an unnamed type, a 68 /// function type will be computed. Providing FT will avoid this computation. 69 LLVM_ABI std::string getName(ID Id, ArrayRef<Type *> Tys, Module *M, 70 FunctionType *FT = nullptr); 71 72 /// Return the LLVM name for an intrinsic. This is a special version only to 73 /// be used by LLVMIntrinsicCopyOverloadedName. It only supports overloads 74 /// based on named types. 75 LLVM_ABI std::string getNameNoUnnamedTypes(ID Id, ArrayRef<Type *> Tys); 76 77 /// Return the function type for an intrinsic. 78 LLVM_ABI FunctionType *getType(LLVMContext &Context, ID id, 79 ArrayRef<Type *> Tys = {}); 80 81 /// Returns true if the intrinsic can be overloaded. 82 LLVM_ABI bool isOverloaded(ID id); 83 84 /// isTargetIntrinsic - Returns true if IID is an intrinsic specific to a 85 /// certain target. If it is a generic intrinsic false is returned. 86 LLVM_ABI bool isTargetIntrinsic(ID IID); 87 88 LLVM_ABI ID lookupIntrinsicID(StringRef Name); 89 90 /// Return the attributes for an intrinsic. 91 LLVM_ABI AttributeList getAttributes(LLVMContext &C, ID id, FunctionType *FT); 92 93 /// Return the function attributes for an intrinsic. 94 LLVM_ABI AttributeSet getFnAttributes(LLVMContext &C, ID id); 95 96 /// Look up the Function declaration of the intrinsic \p id in the Module 97 /// \p M. If it does not exist, add a declaration and return it. Otherwise, 98 /// return the existing declaration. 99 /// 100 /// The \p Tys parameter is for intrinsics with overloaded types (e.g., those 101 /// using iAny, fAny, vAny, or pAny). For a declaration of an overloaded 102 /// intrinsic, Tys must provide exactly one type for each overloaded type in 103 /// the intrinsic. 104 LLVM_ABI Function *getOrInsertDeclaration(Module *M, ID id, 105 ArrayRef<Type *> Tys = {}); 106 107 LLVM_DEPRECATED("Use getOrInsertDeclaration instead", 108 "getOrInsertDeclaration") 109 inline Function *getDeclaration(Module *M, ID id, ArrayRef<Type *> Tys = {}) { 110 return getOrInsertDeclaration(M, id, Tys); 111 } 112 113 /// Look up the Function declaration of the intrinsic \p id in the Module 114 /// \p M and return it if it exists. Otherwise, return nullptr. This version 115 /// supports non-overloaded intrinsics. 116 LLVM_ABI Function *getDeclarationIfExists(const Module *M, ID id); 117 118 /// This version supports overloaded intrinsics. 119 LLVM_ABI Function *getDeclarationIfExists(Module *M, ID id, 120 ArrayRef<Type *> Tys, 121 FunctionType *FT = nullptr); 122 123 /// Map a Clang builtin name to an intrinsic ID. 124 LLVM_ABI ID getIntrinsicForClangBuiltin(StringRef TargetPrefix, 125 StringRef BuiltinName); 126 127 /// Map a MS builtin name to an intrinsic ID. 128 LLVM_ABI ID getIntrinsicForMSBuiltin(StringRef TargetPrefix, 129 StringRef BuiltinName); 130 131 /// Returns true if the intrinsic ID is for one of the "Constrained 132 /// Floating-Point Intrinsics". 133 LLVM_ABI bool isConstrainedFPIntrinsic(ID QID); 134 135 /// Returns true if the intrinsic ID is for one of the "Constrained 136 /// Floating-Point Intrinsics" that take rounding mode metadata. 137 LLVM_ABI bool hasConstrainedFPRoundingModeOperand(ID QID); 138 139 /// This is a type descriptor which explains the type requirements of an 140 /// intrinsic. This is returned by getIntrinsicInfoTableEntries. 141 struct IITDescriptor { 142 enum IITDescriptorKind { 143 Void, 144 VarArg, 145 MMX, 146 Token, 147 Metadata, 148 Half, 149 BFloat, 150 Float, 151 Double, 152 Quad, 153 Integer, 154 Vector, 155 Pointer, 156 Struct, 157 Argument, 158 ExtendArgument, 159 TruncArgument, 160 OneNthEltsVecArgument, 161 SameVecWidthArgument, 162 VecOfAnyPtrsToElt, 163 VecElementArgument, 164 Subdivide2Argument, 165 Subdivide4Argument, 166 VecOfBitcastsToInt, 167 AMX, 168 PPCQuad, 169 AArch64Svcount, 170 } Kind; 171 172 union { 173 unsigned Integer_Width; 174 unsigned Float_Width; 175 unsigned Pointer_AddressSpace; 176 unsigned Struct_NumElements; 177 unsigned Argument_Info; 178 ElementCount Vector_Width; 179 }; 180 181 // AK_% : Defined in Intrinsics.td 182 enum ArgKind { 183 #define GET_INTRINSIC_ARGKIND 184 #include "llvm/IR/IntrinsicEnums.inc" 185 #undef GET_INTRINSIC_ARGKIND 186 }; 187 getArgumentNumberIITDescriptor188 unsigned getArgumentNumber() const { 189 assert(Kind == Argument || Kind == ExtendArgument || 190 Kind == TruncArgument || Kind == SameVecWidthArgument || 191 Kind == VecElementArgument || Kind == Subdivide2Argument || 192 Kind == Subdivide4Argument || Kind == VecOfBitcastsToInt); 193 return Argument_Info >> 3; 194 } getArgumentKindIITDescriptor195 ArgKind getArgumentKind() const { 196 assert(Kind == Argument || Kind == ExtendArgument || 197 Kind == TruncArgument || Kind == SameVecWidthArgument || 198 Kind == VecElementArgument || Kind == Subdivide2Argument || 199 Kind == Subdivide4Argument || Kind == VecOfBitcastsToInt); 200 return (ArgKind)(Argument_Info & 7); 201 } 202 203 // VecOfAnyPtrsToElt uses both an overloaded argument (for address space) 204 // and a reference argument (for matching vector width and element types) getOverloadArgNumberIITDescriptor205 unsigned getOverloadArgNumber() const { 206 assert(Kind == VecOfAnyPtrsToElt); 207 return Argument_Info >> 16; 208 } 209 // OneNthEltsVecArguments uses both a divisor N and a reference argument for 210 // the full-width vector to match getVectorDivisorIITDescriptor211 unsigned getVectorDivisor() const { 212 assert(Kind == OneNthEltsVecArgument); 213 return Argument_Info >> 16; 214 } getRefArgNumberIITDescriptor215 unsigned getRefArgNumber() const { 216 assert(Kind == VecOfAnyPtrsToElt || Kind == OneNthEltsVecArgument); 217 return Argument_Info & 0xFFFF; 218 } 219 getIITDescriptor220 static IITDescriptor get(IITDescriptorKind K, unsigned Field) { 221 IITDescriptor Result = { K, { Field } }; 222 return Result; 223 } 224 getIITDescriptor225 static IITDescriptor get(IITDescriptorKind K, unsigned short Hi, 226 unsigned short Lo) { 227 unsigned Field = Hi << 16 | Lo; 228 IITDescriptor Result = {K, {Field}}; 229 return Result; 230 } 231 getVectorIITDescriptor232 static IITDescriptor getVector(unsigned Width, bool IsScalable) { 233 IITDescriptor Result = {Vector, {0}}; 234 Result.Vector_Width = ElementCount::get(Width, IsScalable); 235 return Result; 236 } 237 }; 238 239 /// Return the IIT table descriptor for the specified intrinsic into an array 240 /// of IITDescriptors. 241 LLVM_ABI void getIntrinsicInfoTableEntries(ID id, 242 SmallVectorImpl<IITDescriptor> &T); 243 244 enum MatchIntrinsicTypesResult { 245 MatchIntrinsicTypes_Match = 0, 246 MatchIntrinsicTypes_NoMatchRet = 1, 247 MatchIntrinsicTypes_NoMatchArg = 2, 248 }; 249 250 /// Match the specified function type with the type constraints specified by 251 /// the .td file. If the given type is an overloaded type it is pushed to the 252 /// ArgTys vector. 253 /// 254 /// Returns false if the given type matches with the constraints, true 255 /// otherwise. 256 LLVM_ABI MatchIntrinsicTypesResult 257 matchIntrinsicSignature(FunctionType *FTy, ArrayRef<IITDescriptor> &Infos, 258 SmallVectorImpl<Type *> &ArgTys); 259 260 /// Verify if the intrinsic has variable arguments. This method is intended to 261 /// be called after all the fixed arguments have been matched first. 262 /// 263 /// This method returns true on error. 264 LLVM_ABI bool matchIntrinsicVarArg(bool isVarArg, 265 ArrayRef<IITDescriptor> &Infos); 266 267 /// Gets the type arguments of an intrinsic call by matching type contraints 268 /// specified by the .td file. The overloaded types are pushed into the 269 /// AgTys vector. 270 /// 271 /// Returns false if the given ID and function type combination is not a 272 /// valid intrinsic call. 273 LLVM_ABI bool getIntrinsicSignature(Intrinsic::ID, FunctionType *FT, 274 SmallVectorImpl<Type *> &ArgTys); 275 276 /// Same as previous, but accepts a Function instead of ID and FunctionType. 277 LLVM_ABI bool getIntrinsicSignature(Function *F, 278 SmallVectorImpl<Type *> &ArgTys); 279 280 // Checks if the intrinsic name matches with its signature and if not 281 // returns the declaration with the same signature and remangled name. 282 // An existing GlobalValue with the wanted name but with a wrong prototype 283 // or of the wrong kind will be renamed by adding ".renamed" to the name. 284 LLVM_ABI std::optional<Function *> remangleIntrinsicFunction(Function *F); 285 286 } // End Intrinsic namespace 287 288 } // End llvm namespace 289 290 #endif 291