blob: 08f64be87b1476f03efca693690d843019918b9f [file] [log] [blame]
Andrew Walbran16937d02019-10-22 13:54:20 +01001//===- Intrinsics.h - LLVM Intrinsic Function Handling ----------*- C++ -*-===//
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01002//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
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"
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020021#include "llvm/Support/TypeSize.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010022#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 {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020037 // Intrinsic ID type. This is an opaque typedef to facilitate splitting up
38 // the enum into target-specific enums.
39 typedef unsigned ID;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010040
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020041 enum IndependentIntrinsics : unsigned {
42 not_intrinsic = 0, // Must be zero
43
44 // Get the intrinsic enums generated from Intrinsics.td
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010045#define GET_INTRINSIC_ENUM_VALUES
Andrew Scullcdfcccc2018-10-05 20:58:37 +010046#include "llvm/IR/IntrinsicEnums.inc"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010047#undef GET_INTRINSIC_ENUM_VALUES
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010048 };
49
50 /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
51 /// Note, this version is for intrinsics with no overloads. Use the other
52 /// version of getName if overloads are required.
53 StringRef getName(ID id);
54
55 /// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
56 /// Note, this version of getName supports overloads, but is less efficient
57 /// than the StringRef version of this function. If no overloads are
58 /// requried, it is safe to use this version, but better to use the StringRef
59 /// version.
60 std::string getName(ID id, ArrayRef<Type*> Tys);
61
62 /// Return the function type for an intrinsic.
63 FunctionType *getType(LLVMContext &Context, ID id,
64 ArrayRef<Type*> Tys = None);
65
66 /// Returns true if the intrinsic can be overloaded.
67 bool isOverloaded(ID id);
68
69 /// Returns true if the intrinsic is a leaf, i.e. it does not make any calls
70 /// itself. Most intrinsics are leafs, the exceptions being the patchpoint
71 /// and statepoint intrinsics. These call (or invoke) their "target" argument.
72 bool isLeaf(ID id);
73
74 /// Return the attributes for an intrinsic.
75 AttributeList getAttributes(LLVMContext &C, ID id);
76
77 /// Create or insert an LLVM Function declaration for an intrinsic, and return
78 /// it.
79 ///
80 /// The Tys parameter is for intrinsics with overloaded types (e.g., those
81 /// using iAny, fAny, vAny, or iPTRAny). For a declaration of an overloaded
82 /// intrinsic, Tys must provide exactly one type for each overloaded type in
83 /// the intrinsic.
84 Function *getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys = None);
85
86 /// Looks up Name in NameTable via binary search. NameTable must be sorted
87 /// and all entries must start with "llvm.". If NameTable contains an exact
88 /// match for Name or a prefix of Name followed by a dot, its index in
89 /// NameTable is returned. Otherwise, -1 is returned.
90 int lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
91 StringRef Name);
92
93 /// Map a GCC builtin name to an intrinsic ID.
94 ID getIntrinsicForGCCBuiltin(const char *Prefix, StringRef BuiltinName);
95
96 /// Map a MS builtin name to an intrinsic ID.
97 ID getIntrinsicForMSBuiltin(const char *Prefix, StringRef BuiltinName);
98
99 /// This is a type descriptor which explains the type requirements of an
100 /// intrinsic. This is returned by getIntrinsicInfoTableEntries.
101 struct IITDescriptor {
102 enum IITDescriptorKind {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200103 Void,
104 VarArg,
105 MMX,
106 Token,
107 Metadata,
108 Half,
109 BFloat,
110 Float,
111 Double,
112 Quad,
113 Integer,
114 Vector,
115 Pointer,
116 Struct,
117 Argument,
118 ExtendArgument,
119 TruncArgument,
120 HalfVecArgument,
121 SameVecWidthArgument,
122 PtrToArgument,
123 PtrToElt,
124 VecOfAnyPtrsToElt,
125 VecElementArgument,
126 Subdivide2Argument,
127 Subdivide4Argument,
128 VecOfBitcastsToInt,
129 AMX
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100130 } Kind;
131
132 union {
133 unsigned Integer_Width;
134 unsigned Float_Width;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100135 unsigned Pointer_AddressSpace;
136 unsigned Struct_NumElements;
137 unsigned Argument_Info;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200138 ElementCount Vector_Width;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100139 };
140
141 enum ArgKind {
142 AK_Any,
143 AK_AnyInteger,
144 AK_AnyFloat,
145 AK_AnyVector,
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100146 AK_AnyPointer,
147 AK_MatchType = 7
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100148 };
149
150 unsigned getArgumentNumber() const {
151 assert(Kind == Argument || Kind == ExtendArgument ||
152 Kind == TruncArgument || Kind == HalfVecArgument ||
153 Kind == SameVecWidthArgument || Kind == PtrToArgument ||
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200154 Kind == PtrToElt || Kind == VecElementArgument ||
155 Kind == Subdivide2Argument || Kind == Subdivide4Argument ||
156 Kind == VecOfBitcastsToInt);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100157 return Argument_Info >> 3;
158 }
159 ArgKind getArgumentKind() const {
160 assert(Kind == Argument || Kind == ExtendArgument ||
161 Kind == TruncArgument || Kind == HalfVecArgument ||
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100162 Kind == SameVecWidthArgument || Kind == PtrToArgument ||
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200163 Kind == VecElementArgument || Kind == Subdivide2Argument ||
164 Kind == Subdivide4Argument || Kind == VecOfBitcastsToInt);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100165 return (ArgKind)(Argument_Info & 7);
166 }
167
168 // VecOfAnyPtrsToElt uses both an overloaded argument (for address space)
169 // and a reference argument (for matching vector width and element types)
170 unsigned getOverloadArgNumber() const {
171 assert(Kind == VecOfAnyPtrsToElt);
172 return Argument_Info >> 16;
173 }
174 unsigned getRefArgNumber() const {
175 assert(Kind == VecOfAnyPtrsToElt);
176 return Argument_Info & 0xFFFF;
177 }
178
179 static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
180 IITDescriptor Result = { K, { Field } };
181 return Result;
182 }
183
184 static IITDescriptor get(IITDescriptorKind K, unsigned short Hi,
185 unsigned short Lo) {
186 unsigned Field = Hi << 16 | Lo;
187 IITDescriptor Result = {K, {Field}};
188 return Result;
189 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200190
191 static IITDescriptor getVector(unsigned Width, bool IsScalable) {
192 IITDescriptor Result = {Vector, {0}};
193 Result.Vector_Width = ElementCount::get(Width, IsScalable);
194 return Result;
195 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100196 };
197
198 /// Return the IIT table descriptor for the specified intrinsic into an array
199 /// of IITDescriptors.
200 void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T);
201
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100202 enum MatchIntrinsicTypesResult {
203 MatchIntrinsicTypes_Match = 0,
204 MatchIntrinsicTypes_NoMatchRet = 1,
205 MatchIntrinsicTypes_NoMatchArg = 2,
206 };
207
208 /// Match the specified function type with the type constraints specified by
209 /// the .td file. If the given type is an overloaded type it is pushed to the
210 /// ArgTys vector.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100211 ///
212 /// Returns false if the given type matches with the constraints, true
213 /// otherwise.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100214 MatchIntrinsicTypesResult
215 matchIntrinsicSignature(FunctionType *FTy, ArrayRef<IITDescriptor> &Infos,
216 SmallVectorImpl<Type *> &ArgTys);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100217
218 /// Verify if the intrinsic has variable arguments. This method is intended to
219 /// be called after all the fixed arguments have been matched first.
220 ///
221 /// This method returns true on error.
222 bool matchIntrinsicVarArg(bool isVarArg, ArrayRef<IITDescriptor> &Infos);
223
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200224 /// Gets the type arguments of an intrinsic call by matching type contraints
225 /// specified by the .td file. The overloaded types are pushed into the
226 /// AgTys vector.
227 ///
228 /// Returns false if the given function is not a valid intrinsic call.
229 bool getIntrinsicSignature(Function *F, SmallVectorImpl<Type *> &ArgTys);
230
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100231 // Checks if the intrinsic name matches with its signature and if not
232 // returns the declaration with the same signature and remangled name.
233 llvm::Optional<Function*> remangleIntrinsicFunction(Function *F);
234
235} // End Intrinsic namespace
236
237} // End llvm namespace
238
239#endif