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/ADT/None.h"
20 #include "llvm/ADT/Optional.h"
21 #include "llvm/Support/TypeSize.h"
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 
33 /// This namespace contains an enum with a value for every intrinsic/builtin
34 /// function known by LLVM. The enum values are returned by
35 /// Function::getIntrinsicID().
36 namespace Intrinsic {
37   // Abstraction for the arguments of the noalias intrinsics
38   static const int NoAliasScopeDeclScopeArg = 0;
39 
40   // Intrinsic ID type. This is an opaque typedef to facilitate splitting up
41   // the enum into target-specific enums.
42   typedef unsigned ID;
43 
44   enum IndependentIntrinsics : unsigned {
45     not_intrinsic = 0, // Must be zero
46 
47   // Get the intrinsic enums generated from Intrinsics.td
48 #define GET_INTRINSIC_ENUM_VALUES
49 #include "llvm/IR/IntrinsicEnums.inc"
50 #undef GET_INTRINSIC_ENUM_VALUES
51   };
52 
53   /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
54   /// Note, this version is for intrinsics with no overloads.  Use the other
55   /// version of getName if overloads are required.
56   StringRef getName(ID id);
57 
58   /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
59   /// Note, this version of getName supports overloads, but not unnamed types.
60   /// It is less efficient than the StringRef version of this function. If no
61   /// overloads are required, it is safe to use this version, but better to use
62   /// the StringRef version.
63   std::string getName(ID Id, ArrayRef<Type *> Tys);
64 
65   /// Return the LLVM name for an intrinsic, such as "llvm.ssa.copy.p0s_s.1".
66   /// Note, this version of getName supports overloads and unnamed types, but is
67   /// less efficient than the StringRef version of this function.  If no
68   /// overloads are required, it is safe to use this version, but better to use
69   /// the StringRef version. A function type FT can be provided to avoid
70   /// computing it. It is used (or computed) if one of the types is based on an
71   /// unnamed type.
72   std::string getName(ID Id, ArrayRef<Type *> Tys, Module *M, FunctionType *FT);
73 
74   /// Return the function type for an intrinsic.
75   FunctionType *getType(LLVMContext &Context, ID id,
76                         ArrayRef<Type*> Tys = None);
77 
78   /// Returns true if the intrinsic can be overloaded.
79   bool isOverloaded(ID id);
80 
81   /// Returns true if the intrinsic is a leaf, i.e. it does not make any calls
82   /// itself.  Most intrinsics are leafs, the exceptions being the patchpoint
83   /// and statepoint intrinsics. These call (or invoke) their "target" argument.
84   bool isLeaf(ID id);
85 
86   /// Return the attributes for an intrinsic.
87   AttributeList getAttributes(LLVMContext &C, ID id);
88 
89   /// Create or insert an LLVM Function declaration for an intrinsic, and return
90   /// it.
91   ///
92   /// The Tys parameter is for intrinsics with overloaded types (e.g., those
93   /// using iAny, fAny, vAny, or iPTRAny).  For a declaration of an overloaded
94   /// intrinsic, Tys must provide exactly one type for each overloaded type in
95   /// the intrinsic.
96   Function *getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys = None);
97 
98   /// Looks up Name in NameTable via binary search. NameTable must be sorted
99   /// and all entries must start with "llvm.".  If NameTable contains an exact
100   /// match for Name or a prefix of Name followed by a dot, its index in
101   /// NameTable is returned. Otherwise, -1 is returned.
102   int lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
103                                 StringRef Name);
104 
105   /// Map a GCC builtin name to an intrinsic ID.
106   ID getIntrinsicForGCCBuiltin(const char *Prefix, StringRef BuiltinName);
107 
108   /// Map a MS builtin name to an intrinsic ID.
109   ID getIntrinsicForMSBuiltin(const char *Prefix, StringRef BuiltinName);
110 
111   /// This is a type descriptor which explains the type requirements of an
112   /// intrinsic. This is returned by getIntrinsicInfoTableEntries.
113   struct IITDescriptor {
114     enum IITDescriptorKind {
115       Void,
116       VarArg,
117       MMX,
118       Token,
119       Metadata,
120       Half,
121       BFloat,
122       Float,
123       Double,
124       Quad,
125       Integer,
126       Vector,
127       Pointer,
128       Struct,
129       Argument,
130       ExtendArgument,
131       TruncArgument,
132       HalfVecArgument,
133       SameVecWidthArgument,
134       PtrToArgument,
135       PtrToElt,
136       VecOfAnyPtrsToElt,
137       VecElementArgument,
138       Subdivide2Argument,
139       Subdivide4Argument,
140       VecOfBitcastsToInt,
141       AMX
142     } Kind;
143 
144     union {
145       unsigned Integer_Width;
146       unsigned Float_Width;
147       unsigned Pointer_AddressSpace;
148       unsigned Struct_NumElements;
149       unsigned Argument_Info;
150       ElementCount Vector_Width;
151     };
152 
153     enum ArgKind {
154       AK_Any,
155       AK_AnyInteger,
156       AK_AnyFloat,
157       AK_AnyVector,
158       AK_AnyPointer,
159       AK_MatchType = 7
160     };
161 
getArgumentNumberIITDescriptor162     unsigned getArgumentNumber() const {
163       assert(Kind == Argument || Kind == ExtendArgument ||
164              Kind == TruncArgument || Kind == HalfVecArgument ||
165              Kind == SameVecWidthArgument || Kind == PtrToArgument ||
166              Kind == PtrToElt || Kind == VecElementArgument ||
167              Kind == Subdivide2Argument || Kind == Subdivide4Argument ||
168              Kind == VecOfBitcastsToInt);
169       return Argument_Info >> 3;
170     }
getArgumentKindIITDescriptor171     ArgKind getArgumentKind() const {
172       assert(Kind == Argument || Kind == ExtendArgument ||
173              Kind == TruncArgument || Kind == HalfVecArgument ||
174              Kind == SameVecWidthArgument || Kind == PtrToArgument ||
175              Kind == VecElementArgument || Kind == Subdivide2Argument ||
176              Kind == Subdivide4Argument || Kind == VecOfBitcastsToInt);
177       return (ArgKind)(Argument_Info & 7);
178     }
179 
180     // VecOfAnyPtrsToElt uses both an overloaded argument (for address space)
181     // and a reference argument (for matching vector width and element types)
getOverloadArgNumberIITDescriptor182     unsigned getOverloadArgNumber() const {
183       assert(Kind == VecOfAnyPtrsToElt);
184       return Argument_Info >> 16;
185     }
getRefArgNumberIITDescriptor186     unsigned getRefArgNumber() const {
187       assert(Kind == VecOfAnyPtrsToElt);
188       return Argument_Info & 0xFFFF;
189     }
190 
getIITDescriptor191     static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
192       IITDescriptor Result = { K, { Field } };
193       return Result;
194     }
195 
getIITDescriptor196     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 
getVectorIITDescriptor203     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   llvm::Optional<Function*> remangleIntrinsicFunction(Function *F);
246 
247 } // End Intrinsic namespace
248 
249 } // End llvm namespace
250 
251 #endif
252