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   // Intrinsic ID type. This is an opaque typedef to facilitate splitting up
38   // the enum into target-specific enums.
39   typedef unsigned ID;
40 
41   enum IndependentIntrinsics : unsigned {
42     not_intrinsic = 0, // Must be zero
43 
44   // Get the intrinsic enums generated from Intrinsics.td
45 #define GET_INTRINSIC_ENUM_VALUES
46 #include "llvm/IR/IntrinsicEnums.inc"
47 #undef GET_INTRINSIC_ENUM_VALUES
48   };
49 
50   /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
51   /// Note, this version is for intrinsics with no overloads.  Use the other
52   /// version of getName if overloads are required.
53   StringRef getName(ID id);
54 
55   /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
56   /// Note, this version of getName supports overloads, but is less efficient
57   /// than the StringRef version of this function.  If no overloads are
58   /// requried, it is safe to use this version, but better to use the StringRef
59   /// version.
60   std::string getName(ID id, ArrayRef<Type*> Tys);
61 
62   /// Return the function type for an intrinsic.
63   FunctionType *getType(LLVMContext &Context, ID id,
64                         ArrayRef<Type*> Tys = None);
65 
66   /// Returns true if the intrinsic can be overloaded.
67   bool isOverloaded(ID id);
68 
69   /// Returns true if the intrinsic is a leaf, i.e. it does not make any calls
70   /// itself.  Most intrinsics are leafs, the exceptions being the patchpoint
71   /// and statepoint intrinsics. These call (or invoke) their "target" argument.
72   bool isLeaf(ID id);
73 
74   /// Return the attributes for an intrinsic.
75   AttributeList getAttributes(LLVMContext &C, ID id);
76 
77   /// Create or insert an LLVM Function declaration for an intrinsic, and return
78   /// it.
79   ///
80   /// The Tys parameter is for intrinsics with overloaded types (e.g., those
81   /// using iAny, fAny, vAny, or iPTRAny).  For a declaration of an overloaded
82   /// intrinsic, Tys must provide exactly one type for each overloaded type in
83   /// the intrinsic.
84   Function *getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys = None);
85 
86   /// Looks up Name in NameTable via binary search. NameTable must be sorted
87   /// and all entries must start with "llvm.".  If NameTable contains an exact
88   /// match for Name or a prefix of Name followed by a dot, its index in
89   /// NameTable is returned. Otherwise, -1 is returned.
90   int lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
91                                 StringRef Name);
92 
93   /// Map a GCC builtin name to an intrinsic ID.
94   ID getIntrinsicForGCCBuiltin(const char *Prefix, StringRef BuiltinName);
95 
96   /// Map a MS builtin name to an intrinsic ID.
97   ID getIntrinsicForMSBuiltin(const char *Prefix, StringRef BuiltinName);
98 
99   /// This is a type descriptor which explains the type requirements of an
100   /// intrinsic. This is returned by getIntrinsicInfoTableEntries.
101   struct IITDescriptor {
102     enum IITDescriptorKind {
103       Void,
104       VarArg,
105       MMX,
106       Token,
107       Metadata,
108       Half,
109       BFloat,
110       Float,
111       Double,
112       Quad,
113       Integer,
114       Vector,
115       Pointer,
116       Struct,
117       Argument,
118       ExtendArgument,
119       TruncArgument,
120       HalfVecArgument,
121       SameVecWidthArgument,
122       PtrToArgument,
123       PtrToElt,
124       VecOfAnyPtrsToElt,
125       VecElementArgument,
126       Subdivide2Argument,
127       Subdivide4Argument,
128       VecOfBitcastsToInt
129     } Kind;
130 
131     union {
132       unsigned Integer_Width;
133       unsigned Float_Width;
134       unsigned Pointer_AddressSpace;
135       unsigned Struct_NumElements;
136       unsigned Argument_Info;
137       ElementCount Vector_Width;
138     };
139 
140     enum ArgKind {
141       AK_Any,
142       AK_AnyInteger,
143       AK_AnyFloat,
144       AK_AnyVector,
145       AK_AnyPointer,
146       AK_MatchType = 7
147     };
148 
getArgumentNumberIITDescriptor149     unsigned getArgumentNumber() const {
150       assert(Kind == Argument || Kind == ExtendArgument ||
151              Kind == TruncArgument || Kind == HalfVecArgument ||
152              Kind == SameVecWidthArgument || Kind == PtrToArgument ||
153              Kind == PtrToElt || Kind == VecElementArgument ||
154              Kind == Subdivide2Argument || Kind == Subdivide4Argument ||
155              Kind == VecOfBitcastsToInt);
156       return Argument_Info >> 3;
157     }
getArgumentKindIITDescriptor158     ArgKind getArgumentKind() const {
159       assert(Kind == Argument || Kind == ExtendArgument ||
160              Kind == TruncArgument || Kind == HalfVecArgument ||
161              Kind == SameVecWidthArgument || Kind == PtrToArgument ||
162              Kind == VecElementArgument || Kind == Subdivide2Argument ||
163              Kind == Subdivide4Argument || Kind == VecOfBitcastsToInt);
164       return (ArgKind)(Argument_Info & 7);
165     }
166 
167     // VecOfAnyPtrsToElt uses both an overloaded argument (for address space)
168     // and a reference argument (for matching vector width and element types)
getOverloadArgNumberIITDescriptor169     unsigned getOverloadArgNumber() const {
170       assert(Kind == VecOfAnyPtrsToElt);
171       return Argument_Info >> 16;
172     }
getRefArgNumberIITDescriptor173     unsigned getRefArgNumber() const {
174       assert(Kind == VecOfAnyPtrsToElt);
175       return Argument_Info & 0xFFFF;
176     }
177 
getIITDescriptor178     static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
179       IITDescriptor Result = { K, { Field } };
180       return Result;
181     }
182 
getIITDescriptor183     static IITDescriptor get(IITDescriptorKind K, unsigned short Hi,
184                              unsigned short Lo) {
185       unsigned Field = Hi << 16 | Lo;
186       IITDescriptor Result = {K, {Field}};
187       return Result;
188     }
189 
getVectorIITDescriptor190     static IITDescriptor getVector(unsigned Width, bool IsScalable) {
191       IITDescriptor Result;
192       Result.Kind = Vector;
193       Result.Vector_Width.Min = Width;
194       Result.Vector_Width.Scalable = IsScalable;
195       return Result;
196     }
197   };
198 
199   /// Return the IIT table descriptor for the specified intrinsic into an array
200   /// of IITDescriptors.
201   void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T);
202 
203   enum MatchIntrinsicTypesResult {
204     MatchIntrinsicTypes_Match = 0,
205     MatchIntrinsicTypes_NoMatchRet = 1,
206     MatchIntrinsicTypes_NoMatchArg = 2,
207   };
208 
209   /// Match the specified function type with the type constraints specified by
210   /// the .td file. If the given type is an overloaded type it is pushed to the
211   /// ArgTys vector.
212   ///
213   /// Returns false if the given type matches with the constraints, true
214   /// otherwise.
215   MatchIntrinsicTypesResult
216   matchIntrinsicSignature(FunctionType *FTy, ArrayRef<IITDescriptor> &Infos,
217                           SmallVectorImpl<Type *> &ArgTys);
218 
219   /// Verify if the intrinsic has variable arguments. This method is intended to
220   /// be called after all the fixed arguments have been matched first.
221   ///
222   /// This method returns true on error.
223   bool matchIntrinsicVarArg(bool isVarArg, ArrayRef<IITDescriptor> &Infos);
224 
225   /// Gets the type arguments of an intrinsic call by matching type contraints
226   /// specified by the .td file. The overloaded types are pushed into the
227   /// AgTys vector.
228   ///
229   /// Returns false if the given function is not a valid intrinsic call.
230   bool getIntrinsicSignature(Function *F, SmallVectorImpl<Type *> &ArgTys);
231 
232   // Checks if the intrinsic name matches with its signature and if not
233   // returns the declaration with the same signature and remangled name.
234   llvm::Optional<Function*> remangleIntrinsicFunction(Function *F);
235 
236 } // End Intrinsic namespace
237 
238 } // End llvm namespace
239 
240 #endif
241