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
24namespace llvm {
25
26class Type;
27class FunctionType;
28class Function;
29class LLVMContext;
30class Module;
31class 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().
36namespace 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
162 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 }
171 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)
182 unsigned getOverloadArgNumber() const {
183 assert(Kind == VecOfAnyPtrsToElt);
184 return Argument_Info >> 16;
185 }
186 unsigned getRefArgNumber() const {
187 assert(Kind == VecOfAnyPtrsToElt);
188 return Argument_Info & 0xFFFF;
189 }
190
191 static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
192 IITDescriptor Result = { K, { Field } };
193 return Result;
194 }
195
196 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
203 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