Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 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 | |||
161 | 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 | } |
||
170 | 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) |
||
182 | unsigned getOverloadArgNumber() const { |
||
183 | assert(Kind == VecOfAnyPtrsToElt || Kind == AnyPtrToElt); |
||
184 | return Argument_Info >> 16; |
||
185 | } |
||
186 | unsigned getRefArgNumber() const { |
||
187 | assert(Kind == VecOfAnyPtrsToElt || Kind == AnyPtrToElt); |
||
188 | return Argument_Info & 0xFFFF; |
||
189 | } |
||
190 | |||
191 | static IITDescriptor get(IITDescriptorKind K, unsigned Field) { |
||
192 | IITDescriptor Result = { K, { Field } }; |
||
193 | return Result; |
||
194 | } |
||
195 | |||
196 | 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 | |||
203 | 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 |