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, 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 PPCQuad,
145 } Kind;
146
147 union {
148 unsigned Integer_Width;
149 unsigned Float_Width;
150 unsigned Pointer_AddressSpace;
151 unsigned Struct_NumElements;
152 unsigned Argument_Info;
153 ElementCount Vector_Width;
154 };
155
156 enum ArgKind {
157 AK_Any,
158 AK_AnyInteger,
159 AK_AnyFloat,
160 AK_AnyVector,
161 AK_AnyPointer,
162 AK_MatchType = 7
163 };
164
165 unsigned getArgumentNumber() const {
166 assert(Kind == Argument || Kind == ExtendArgument ||
167 Kind == TruncArgument || Kind == HalfVecArgument ||
168 Kind == SameVecWidthArgument || Kind == PtrToArgument ||
169 Kind == PtrToElt || Kind == VecElementArgument ||
170 Kind == Subdivide2Argument || Kind == Subdivide4Argument ||
171 Kind == VecOfBitcastsToInt);
172 return Argument_Info >> 3;
173 }
174 ArgKind getArgumentKind() const {
175 assert(Kind == Argument || Kind == ExtendArgument ||
176 Kind == TruncArgument || Kind == HalfVecArgument ||
177 Kind == SameVecWidthArgument || Kind == PtrToArgument ||
178 Kind == VecElementArgument || Kind == Subdivide2Argument ||
179 Kind == Subdivide4Argument || Kind == VecOfBitcastsToInt);
180 return (ArgKind)(Argument_Info & 7);
181 }
182
183 // VecOfAnyPtrsToElt uses both an overloaded argument (for address space)
184 // and a reference argument (for matching vector width and element types)
185 unsigned getOverloadArgNumber() const {
186 assert(Kind == VecOfAnyPtrsToElt);
187 return Argument_Info >> 16;
188 }
189 unsigned getRefArgNumber() const {
190 assert(Kind == VecOfAnyPtrsToElt);
191 return Argument_Info & 0xFFFF;
192 }
193
194 static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
195 IITDescriptor Result = { K, { Field } };
196 return Result;
197 }
198
199 static IITDescriptor get(IITDescriptorKind K, unsigned short Hi,
200 unsigned short Lo) {
201 unsigned Field = Hi << 16 | Lo;
202 IITDescriptor Result = {K, {Field}};
203 return Result;
204 }
205
206 static IITDescriptor getVector(unsigned Width, bool IsScalable) {
207 IITDescriptor Result = {Vector, {0}};
208 Result.Vector_Width = ElementCount::get(Width, IsScalable);
209 return Result;
210 }
211 };
212
213 /// Return the IIT table descriptor for the specified intrinsic into an array
214 /// of IITDescriptors.
215 void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T);
216
217 enum MatchIntrinsicTypesResult {
218 MatchIntrinsicTypes_Match = 0,
219 MatchIntrinsicTypes_NoMatchRet = 1,
220 MatchIntrinsicTypes_NoMatchArg = 2,
221 };
222
223 /// Match the specified function type with the type constraints specified by
224 /// the .td file. If the given type is an overloaded type it is pushed to the
225 /// ArgTys vector.
226 ///
227 /// Returns false if the given type matches with the constraints, true
228 /// otherwise.
229 MatchIntrinsicTypesResult
230 matchIntrinsicSignature(FunctionType *FTy, ArrayRef<IITDescriptor> &Infos,
231 SmallVectorImpl<Type *> &ArgTys);
232
233 /// Verify if the intrinsic has variable arguments. This method is intended to
234 /// be called after all the fixed arguments have been matched first.
235 ///
236 /// This method returns true on error.
237 bool matchIntrinsicVarArg(bool isVarArg, ArrayRef<IITDescriptor> &Infos);
238
239 /// Gets the type arguments of an intrinsic call by matching type contraints
240 /// specified by the .td file. The overloaded types are pushed into the
241 /// AgTys vector.
242 ///
243 /// Returns false if the given function is not a valid intrinsic call.
244 bool getIntrinsicSignature(Function *F, SmallVectorImpl<Type *> &ArgTys);
245
246 // Checks if the intrinsic name matches with its signature and if not
247 // returns the declaration with the same signature and remangled name.
248 // An existing GlobalValue with the wanted name but with a wrong prototype
249 // or of the wrong kind will be renamed by adding ".renamed" to the name.
250 llvm::Optional<Function*> remangleIntrinsicFunction(Function *F);
251
252} // End Intrinsic namespace
253
254} // End llvm namespace
255
256#endif
257