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