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 /// This is a type descriptor which explains the type requirements of an 109 /// intrinsic. This is returned by getIntrinsicInfoTableEntries. 110 struct IITDescriptor { 111 enum IITDescriptorKind { 112 Void, 113 VarArg, 114 MMX, 115 Token, 116 Metadata, 117 Half, 118 BFloat, 119 Float, 120 Double, 121 Quad, 122 Integer, 123 Vector, 124 Pointer, 125 Struct, 126 Argument, 127 ExtendArgument, 128 TruncArgument, 129 HalfVecArgument, 130 SameVecWidthArgument, 131 PtrToArgument, 132 PtrToElt, 133 VecOfAnyPtrsToElt, 134 VecElementArgument, 135 Subdivide2Argument, 136 Subdivide4Argument, 137 VecOfBitcastsToInt, 138 AMX, 139 PPCQuad, 140 AnyPtrToElt, 141 } Kind; 142 143 union { 144 unsigned Integer_Width; 145 unsigned Float_Width; 146 unsigned Pointer_AddressSpace; 147 unsigned Struct_NumElements; 148 unsigned Argument_Info; 149 ElementCount Vector_Width; 150 }; 151 152 enum ArgKind { 153 AK_Any, 154 AK_AnyInteger, 155 AK_AnyFloat, 156 AK_AnyVector, 157 AK_AnyPointer, 158 AK_MatchType = 7 159 }; 160 getArgumentNumberIITDescriptor161 unsigned getArgumentNumber() const { 162 assert(Kind == Argument || Kind == ExtendArgument || 163 Kind == TruncArgument || Kind == HalfVecArgument || 164 Kind == SameVecWidthArgument || Kind == PtrToArgument || 165 Kind == PtrToElt || Kind == VecElementArgument || 166 Kind == Subdivide2Argument || Kind == Subdivide4Argument || 167 Kind == VecOfBitcastsToInt); 168 return Argument_Info >> 3; 169 } getArgumentKindIITDescriptor170 ArgKind getArgumentKind() const { 171 assert(Kind == Argument || Kind == ExtendArgument || 172 Kind == TruncArgument || Kind == HalfVecArgument || 173 Kind == SameVecWidthArgument || Kind == PtrToArgument || 174 Kind == VecElementArgument || Kind == Subdivide2Argument || 175 Kind == Subdivide4Argument || Kind == VecOfBitcastsToInt); 176 return (ArgKind)(Argument_Info & 7); 177 } 178 179 // VecOfAnyPtrsToElt and AnyPtrToElt uses both an overloaded argument (for 180 // address space) and a reference argument (for matching vector width and 181 // element types) getOverloadArgNumberIITDescriptor182 unsigned getOverloadArgNumber() const { 183 assert(Kind == VecOfAnyPtrsToElt || Kind == AnyPtrToElt); 184 return Argument_Info >> 16; 185 } getRefArgNumberIITDescriptor186 unsigned getRefArgNumber() const { 187 assert(Kind == VecOfAnyPtrsToElt || Kind == AnyPtrToElt); 188 return Argument_Info & 0xFFFF; 189 } 190 getIITDescriptor191 static IITDescriptor get(IITDescriptorKind K, unsigned Field) { 192 IITDescriptor Result = { K, { Field } }; 193 return Result; 194 } 195 getIITDescriptor196 static IITDescriptor get(IITDescriptorKind K, unsigned short Hi, 197 unsigned short Lo) { 198 unsigned Field = Hi << 16 | Lo; 199 IITDescriptor Result = {K, {Field}}; 200 return Result; 201 } 202 getVectorIITDescriptor203 static IITDescriptor getVector(unsigned Width, bool IsScalable) { 204 IITDescriptor Result = {Vector, {0}}; 205 Result.Vector_Width = ElementCount::get(Width, IsScalable); 206 return Result; 207 } 208 }; 209 210 /// Return the IIT table descriptor for the specified intrinsic into an array 211 /// of IITDescriptors. 212 void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T); 213 214 enum MatchIntrinsicTypesResult { 215 MatchIntrinsicTypes_Match = 0, 216 MatchIntrinsicTypes_NoMatchRet = 1, 217 MatchIntrinsicTypes_NoMatchArg = 2, 218 }; 219 220 /// Match the specified function type with the type constraints specified by 221 /// the .td file. If the given type is an overloaded type it is pushed to the 222 /// ArgTys vector. 223 /// 224 /// Returns false if the given type matches with the constraints, true 225 /// otherwise. 226 MatchIntrinsicTypesResult 227 matchIntrinsicSignature(FunctionType *FTy, ArrayRef<IITDescriptor> &Infos, 228 SmallVectorImpl<Type *> &ArgTys); 229 230 /// Verify if the intrinsic has variable arguments. This method is intended to 231 /// be called after all the fixed arguments have been matched first. 232 /// 233 /// This method returns true on error. 234 bool matchIntrinsicVarArg(bool isVarArg, ArrayRef<IITDescriptor> &Infos); 235 236 /// Gets the type arguments of an intrinsic call by matching type contraints 237 /// specified by the .td file. The overloaded types are pushed into the 238 /// AgTys vector. 239 /// 240 /// Returns false if the given function is not a valid intrinsic call. 241 bool getIntrinsicSignature(Function *F, SmallVectorImpl<Type *> &ArgTys); 242 243 // Checks if the intrinsic name matches with its signature and if not 244 // returns the declaration with the same signature and remangled name. 245 // An existing GlobalValue with the wanted name but with a wrong prototype 246 // or of the wrong kind will be renamed by adding ".renamed" to the name. 247 std::optional<Function *> remangleIntrinsicFunction(Function *F); 248 249 } // End Intrinsic namespace 250 251 } // End llvm namespace 252 253 #endif 254