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 /// This is a type descriptor which explains the type requirements of an
109 /// intrinsic. This is returned by getIntrinsicInfoTableEntries.
110 struct IITDescriptor {
111 enum IITDescriptorKind {
112 Void,
113 VarArg,
114 MMX,
115 Token,
116 Metadata,
117 Half,
118 BFloat,
119 Float,
120 Double,
121 Quad,
122 Integer,
123 Vector,
124 Pointer,
125 Struct,
126 Argument,
127 ExtendArgument,
128 TruncArgument,
129 HalfVecArgument,
130 SameVecWidthArgument,
131 VecOfAnyPtrsToElt,
132 VecElementArgument,
133 Subdivide2Argument,
134 Subdivide4Argument,
135 VecOfBitcastsToInt,
136 AMX,
137 PPCQuad,
138 AArch64Svcount,
139 } Kind;
140
141 union {
142 unsigned Integer_Width;
143 unsigned Float_Width;
144 unsigned Pointer_AddressSpace;
145 unsigned Struct_NumElements;
146 unsigned Argument_Info;
147 ElementCount Vector_Width;
148 };
149
150 // AK_% : Defined in Intrinsics.td
151 enum ArgKind {
152#define GET_INTRINSIC_ARGKIND
153#include "llvm/IR/IntrinsicEnums.inc"
154#undef GET_INTRINSIC_ARGKIND
155 };
156
157 unsigned getArgumentNumber() const {
158 assert(Kind == Argument || Kind == ExtendArgument ||
159 Kind == TruncArgument || Kind == HalfVecArgument ||
160 Kind == SameVecWidthArgument || Kind == VecElementArgument ||
161 Kind == Subdivide2Argument || Kind == Subdivide4Argument ||
162 Kind == VecOfBitcastsToInt);
163 return Argument_Info >> 3;
164 }
165 ArgKind getArgumentKind() const {
166 assert(Kind == Argument || Kind == ExtendArgument ||
167 Kind == TruncArgument || Kind == HalfVecArgument ||
168 Kind == SameVecWidthArgument ||
169 Kind == VecElementArgument || Kind == Subdivide2Argument ||
170 Kind == Subdivide4Argument || Kind == VecOfBitcastsToInt);
171 return (ArgKind)(Argument_Info & 7);
172 }
173
174 // VecOfAnyPtrsToElt uses both an overloaded argument (for address space)
175 // and a reference argument (for matching vector width and element types)
176 unsigned getOverloadArgNumber() const {
177 assert(Kind == VecOfAnyPtrsToElt);
178 return Argument_Info >> 16;
179 }
180 unsigned getRefArgNumber() const {
181 assert(Kind == VecOfAnyPtrsToElt);
182 return Argument_Info & 0xFFFF;
183 }
184
185 static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
186 IITDescriptor Result = { .Kind: K, { .Integer_Width: Field } };
187 return Result;
188 }
189
190 static IITDescriptor get(IITDescriptorKind K, unsigned short Hi,
191 unsigned short Lo) {
192 unsigned Field = Hi << 16 | Lo;
193 IITDescriptor Result = {.Kind: K, {.Integer_Width: Field}};
194 return Result;
195 }
196
197 static IITDescriptor getVector(unsigned Width, bool IsScalable) {
198 IITDescriptor Result = {.Kind: Vector, {.Integer_Width: 0}};
199 Result.Vector_Width = ElementCount::get(MinVal: Width, Scalable: IsScalable);
200 return Result;
201 }
202 };
203
204 /// Return the IIT table descriptor for the specified intrinsic into an array
205 /// of IITDescriptors.
206 void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T);
207
208 enum MatchIntrinsicTypesResult {
209 MatchIntrinsicTypes_Match = 0,
210 MatchIntrinsicTypes_NoMatchRet = 1,
211 MatchIntrinsicTypes_NoMatchArg = 2,
212 };
213
214 /// Match the specified function type with the type constraints specified by
215 /// the .td file. If the given type is an overloaded type it is pushed to the
216 /// ArgTys vector.
217 ///
218 /// Returns false if the given type matches with the constraints, true
219 /// otherwise.
220 MatchIntrinsicTypesResult
221 matchIntrinsicSignature(FunctionType *FTy, ArrayRef<IITDescriptor> &Infos,
222 SmallVectorImpl<Type *> &ArgTys);
223
224 /// Verify if the intrinsic has variable arguments. This method is intended to
225 /// be called after all the fixed arguments have been matched first.
226 ///
227 /// This method returns true on error.
228 bool matchIntrinsicVarArg(bool isVarArg, ArrayRef<IITDescriptor> &Infos);
229
230 /// Gets the type arguments of an intrinsic call by matching type contraints
231 /// specified by the .td file. The overloaded types are pushed into the
232 /// AgTys vector.
233 ///
234 /// Returns false if the given function is not a valid intrinsic call.
235 bool getIntrinsicSignature(Function *F, SmallVectorImpl<Type *> &ArgTys);
236
237 // Checks if the intrinsic name matches with its signature and if not
238 // returns the declaration with the same signature and remangled name.
239 // An existing GlobalValue with the wanted name but with a wrong prototype
240 // or of the wrong kind will be renamed by adding ".renamed" to the name.
241 std::optional<Function *> remangleIntrinsicFunction(Function *F);
242
243} // End Intrinsic namespace
244
245} // End llvm namespace
246
247#endif
248

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