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

source code of llvm/include/llvm/IR/Intrinsics.h