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