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