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