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, 77 ArrayRef<Type *> Tys = std::nullopt); 78 79 /// Returns true if the intrinsic can be overloaded. 80 bool isOverloaded(ID id); 81 82 /// Return the attributes for an intrinsic. 83 AttributeList getAttributes(LLVMContext &C, ID id); 84 85 /// Create or insert an LLVM Function declaration for an intrinsic, and return 86 /// it. 87 /// 88 /// The Tys parameter is for intrinsics with overloaded types (e.g., those 89 /// using iAny, fAny, vAny, or iPTRAny). For a declaration of an overloaded 90 /// intrinsic, Tys must provide exactly one type for each overloaded type in 91 /// the intrinsic. 92 Function *getDeclaration(Module *M, ID id, 93 ArrayRef<Type *> Tys = std::nullopt); 94 95 /// Looks up Name in NameTable via binary search. NameTable must be sorted 96 /// and all entries must start with "llvm.". If NameTable contains an exact 97 /// match for Name or a prefix of Name followed by a dot, its index in 98 /// NameTable is returned. Otherwise, -1 is returned. 99 int lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable, 100 StringRef Name); 101 102 /// Map a Clang builtin name to an intrinsic ID. 103 ID getIntrinsicForClangBuiltin(const char *Prefix, StringRef BuiltinName); 104 105 /// Map a MS builtin name to an intrinsic ID. 106 ID getIntrinsicForMSBuiltin(const char *Prefix, StringRef BuiltinName); 107 108 /// Returns true if the intrinsic ID is for one of the "Constrained 109 /// Floating-Point Intrinsics". 110 bool isConstrainedFPIntrinsic(ID QID); 111 112 /// Returns true if the intrinsic ID is for one of the "Constrained 113 /// Floating-Point Intrinsics" that take rounding mode metadata. 114 bool hasConstrainedFPRoundingModeOperand(ID QID); 115 116 /// This is a type descriptor which explains the type requirements of an 117 /// intrinsic. This is returned by getIntrinsicInfoTableEntries. 118 struct IITDescriptor { 119 enum IITDescriptorKind { 120 Void, 121 VarArg, 122 MMX, 123 Token, 124 Metadata, 125 Half, 126 BFloat, 127 Float, 128 Double, 129 Quad, 130 Integer, 131 Vector, 132 Pointer, 133 Struct, 134 Argument, 135 ExtendArgument, 136 TruncArgument, 137 HalfVecArgument, 138 SameVecWidthArgument, 139 VecOfAnyPtrsToElt, 140 VecElementArgument, 141 Subdivide2Argument, 142 Subdivide4Argument, 143 VecOfBitcastsToInt, 144 AMX, 145 PPCQuad, 146 AArch64Svcount, 147 } Kind; 148 149 union { 150 unsigned Integer_Width; 151 unsigned Float_Width; 152 unsigned Pointer_AddressSpace; 153 unsigned Struct_NumElements; 154 unsigned Argument_Info; 155 ElementCount Vector_Width; 156 }; 157 158 // AK_% : Defined in Intrinsics.td 159 enum ArgKind { 160 #define GET_INTRINSIC_ARGKIND 161 #include "llvm/IR/IntrinsicEnums.inc" 162 #undef GET_INTRINSIC_ARGKIND 163 }; 164 getArgumentNumberIITDescriptor165 unsigned getArgumentNumber() const { 166 assert(Kind == Argument || Kind == ExtendArgument || 167 Kind == TruncArgument || Kind == HalfVecArgument || 168 Kind == SameVecWidthArgument || Kind == VecElementArgument || 169 Kind == Subdivide2Argument || Kind == Subdivide4Argument || 170 Kind == VecOfBitcastsToInt); 171 return Argument_Info >> 3; 172 } getArgumentKindIITDescriptor173 ArgKind getArgumentKind() const { 174 assert(Kind == Argument || Kind == ExtendArgument || 175 Kind == TruncArgument || Kind == HalfVecArgument || 176 Kind == SameVecWidthArgument || 177 Kind == VecElementArgument || Kind == Subdivide2Argument || 178 Kind == Subdivide4Argument || Kind == VecOfBitcastsToInt); 179 return (ArgKind)(Argument_Info & 7); 180 } 181 182 // VecOfAnyPtrsToElt uses both an overloaded argument (for address space) 183 // and a reference argument (for matching vector width and element types) getOverloadArgNumberIITDescriptor184 unsigned getOverloadArgNumber() const { 185 assert(Kind == VecOfAnyPtrsToElt); 186 return Argument_Info >> 16; 187 } getRefArgNumberIITDescriptor188 unsigned getRefArgNumber() const { 189 assert(Kind == VecOfAnyPtrsToElt); 190 return Argument_Info & 0xFFFF; 191 } 192 getIITDescriptor193 static IITDescriptor get(IITDescriptorKind K, unsigned Field) { 194 IITDescriptor Result = { K, { Field } }; 195 return Result; 196 } 197 getIITDescriptor198 static IITDescriptor get(IITDescriptorKind K, unsigned short Hi, 199 unsigned short Lo) { 200 unsigned Field = Hi << 16 | Lo; 201 IITDescriptor Result = {K, {Field}}; 202 return Result; 203 } 204 getVectorIITDescriptor205 static IITDescriptor getVector(unsigned Width, bool IsScalable) { 206 IITDescriptor Result = {Vector, {0}}; 207 Result.Vector_Width = ElementCount::get(Width, IsScalable); 208 return Result; 209 } 210 }; 211 212 /// Return the IIT table descriptor for the specified intrinsic into an array 213 /// of IITDescriptors. 214 void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T); 215 216 enum MatchIntrinsicTypesResult { 217 MatchIntrinsicTypes_Match = 0, 218 MatchIntrinsicTypes_NoMatchRet = 1, 219 MatchIntrinsicTypes_NoMatchArg = 2, 220 }; 221 222 /// Match the specified function type with the type constraints specified by 223 /// the .td file. If the given type is an overloaded type it is pushed to the 224 /// ArgTys vector. 225 /// 226 /// Returns false if the given type matches with the constraints, true 227 /// otherwise. 228 MatchIntrinsicTypesResult 229 matchIntrinsicSignature(FunctionType *FTy, ArrayRef<IITDescriptor> &Infos, 230 SmallVectorImpl<Type *> &ArgTys); 231 232 /// Verify if the intrinsic has variable arguments. This method is intended to 233 /// be called after all the fixed arguments have been matched first. 234 /// 235 /// This method returns true on error. 236 bool matchIntrinsicVarArg(bool isVarArg, ArrayRef<IITDescriptor> &Infos); 237 238 /// Gets the type arguments of an intrinsic call by matching type contraints 239 /// specified by the .td file. The overloaded types are pushed into the 240 /// AgTys vector. 241 /// 242 /// Returns false if the given ID and function type combination is not a 243 /// valid intrinsic call. 244 bool getIntrinsicSignature(Intrinsic::ID, FunctionType *FT, 245 SmallVectorImpl<Type *> &ArgTys); 246 247 /// Same as previous, but accepts a Function instead of ID and FunctionType. 248 bool getIntrinsicSignature(Function *F, SmallVectorImpl<Type *> &ArgTys); 249 250 // Checks if the intrinsic name matches with its signature and if not 251 // returns the declaration with the same signature and remangled name. 252 // An existing GlobalValue with the wanted name but with a wrong prototype 253 // or of the wrong kind will be renamed by adding ".renamed" to the name. 254 std::optional<Function *> remangleIntrinsicFunction(Function *F); 255 256 } // End Intrinsic namespace 257 258 } // End llvm namespace 259 260 #endif 261