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