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