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, without encoded types for
59   /// overloading, such as "llvm.ssa.copy".
60   StringRef getBaseName(ID id);
61 
62   /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx" or
63   /// "llvm.ssa.copy.p0s_s.1". Note, this version of getName supports overloads.
64   /// This is less efficient than the StringRef version of this function.  If no
65   /// overloads are required, it is safe to use this version, but better to use
66   /// the StringRef version. If one of the types is based on an unnamed type, a
67   /// function type will be computed. Providing FT will avoid this computation.
68   std::string getName(ID Id, ArrayRef<Type *> Tys, Module *M,
69                       FunctionType *FT = nullptr);
70 
71   /// Return the LLVM name for an intrinsic. This is a special version only to
72   /// be used by LLVMIntrinsicCopyOverloadedName. It only supports overloads
73   /// based on named types.
74   std::string getNameNoUnnamedTypes(ID Id, ArrayRef<Type *> Tys);
75 
76   /// Return the function type for an intrinsic.
77   FunctionType *getType(LLVMContext &Context, ID id,
78                         ArrayRef<Type*> Tys = None);
79 
80   /// Returns true if the intrinsic can be overloaded.
81   bool isOverloaded(ID id);
82 
83   /// Returns true if the intrinsic is a leaf, i.e. it does not make any calls
84   /// itself.  Most intrinsics are leafs, the exceptions being the patchpoint
85   /// and statepoint intrinsics. These call (or invoke) their "target" argument.
86   bool isLeaf(ID id);
87 
88   /// Return the attributes for an intrinsic.
89   AttributeList getAttributes(LLVMContext &C, ID id);
90 
91   /// Create or insert an LLVM Function declaration for an intrinsic, and return
92   /// it.
93   ///
94   /// The Tys parameter is for intrinsics with overloaded types (e.g., those
95   /// using iAny, fAny, vAny, or iPTRAny).  For a declaration of an overloaded
96   /// intrinsic, Tys must provide exactly one type for each overloaded type in
97   /// the intrinsic.
98   Function *getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys = None);
99 
100   /// Looks up Name in NameTable via binary search. NameTable must be sorted
101   /// and all entries must start with "llvm.".  If NameTable contains an exact
102   /// match for Name or a prefix of Name followed by a dot, its index in
103   /// NameTable is returned. Otherwise, -1 is returned.
104   int lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
105                                 StringRef Name);
106 
107   /// Map a GCC builtin name to an intrinsic ID.
108   ID getIntrinsicForGCCBuiltin(const char *Prefix, StringRef BuiltinName);
109 
110   /// Map a MS builtin name to an intrinsic ID.
111   ID getIntrinsicForMSBuiltin(const char *Prefix, StringRef BuiltinName);
112 
113   /// This is a type descriptor which explains the type requirements of an
114   /// intrinsic. This is returned by getIntrinsicInfoTableEntries.
115   struct IITDescriptor {
116     enum IITDescriptorKind {
117       Void,
118       VarArg,
119       MMX,
120       Token,
121       Metadata,
122       Half,
123       BFloat,
124       Float,
125       Double,
126       Quad,
127       Integer,
128       Vector,
129       Pointer,
130       Struct,
131       Argument,
132       ExtendArgument,
133       TruncArgument,
134       HalfVecArgument,
135       SameVecWidthArgument,
136       PtrToArgument,
137       PtrToElt,
138       VecOfAnyPtrsToElt,
139       VecElementArgument,
140       Subdivide2Argument,
141       Subdivide4Argument,
142       VecOfBitcastsToInt,
143       AMX
144     } Kind;
145 
146     union {
147       unsigned Integer_Width;
148       unsigned Float_Width;
149       unsigned Pointer_AddressSpace;
150       unsigned Struct_NumElements;
151       unsigned Argument_Info;
152       ElementCount Vector_Width;
153     };
154 
155     enum ArgKind {
156       AK_Any,
157       AK_AnyInteger,
158       AK_AnyFloat,
159       AK_AnyVector,
160       AK_AnyPointer,
161       AK_MatchType = 7
162     };
163 
getArgumentNumberIITDescriptor164     unsigned getArgumentNumber() const {
165       assert(Kind == Argument || Kind == ExtendArgument ||
166              Kind == TruncArgument || Kind == HalfVecArgument ||
167              Kind == SameVecWidthArgument || Kind == PtrToArgument ||
168              Kind == PtrToElt || 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 || Kind == PtrToArgument ||
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 function is not a valid intrinsic call.
243   bool getIntrinsicSignature(Function *F, SmallVectorImpl<Type *> &ArgTys);
244 
245   // Checks if the intrinsic name matches with its signature and if not
246   // returns the declaration with the same signature and remangled name.
247   // An existing GlobalValue with the wanted name but with a wrong prototype
248   // or of the wrong kind will be renamed by adding ".renamed" to the name.
249   llvm::Optional<Function*> remangleIntrinsicFunction(Function *F);
250 
251 } // End Intrinsic namespace
252 
253 } // End llvm namespace
254 
255 #endif
256