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