734dd459ca0b3437e9c9ceeff68233a726e5cd46
[lldb.git] / mlir / include / mlir / Dialect / LLVMIR / LLVMOpBase.td
1 //===-- LLVMOpBase.td - LLVM IR dialect shared definitions -*- tablegen -*-===//
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 contains shared definitions for the LLVM IR dialect and its
10 // subdialects.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVMIR_OP_BASE
15 #define LLVMIR_OP_BASE
16
17 include "mlir/IR/OpBase.td"
18 include "mlir/Interfaces/SideEffectInterfaces.td"
19
20 //===----------------------------------------------------------------------===//
21 // LLVM Dialect.
22 //===----------------------------------------------------------------------===//
23
24 def LLVM_Dialect : Dialect {
25   let name = "llvm";
26   let cppNamespace = "::mlir::LLVM";
27
28   let hasRegionArgAttrVerify = 1;
29   let hasOperationAttrVerify = 1;
30   let extraClassDeclaration = [{
31     /// Name of the data layout attributes.
32     static StringRef getDataLayoutAttrName() { return "llvm.data_layout"; }
33     static StringRef getAlignAttrName() { return "llvm.align"; }
34     static StringRef getNoAliasAttrName() { return "llvm.noalias"; }
35
36     /// Verifies if the given string is a well-formed data layout descriptor.
37     /// Uses `reportError` to report errors.
38     static LogicalResult verifyDataLayoutString(
39         StringRef descr, llvm::function_ref<void (const Twine &)> reportError);
40
41     /// Name of the target triple attribute.
42     static StringRef getTargetTripleAttrName() { return "llvm.target_triple"; }
43   }];
44 }
45
46 //===----------------------------------------------------------------------===//
47 // LLVM dialect type constraints.
48 //===----------------------------------------------------------------------===//
49
50 // LLVM dialect type.
51 def LLVM_Type : DialectType<LLVM_Dialect,
52                             CPred<"$_self.isa<::mlir::LLVM::LLVMType>()">,
53                             "LLVM dialect type">;
54
55 // Type constraint accepting LLVM integer types.
56 def LLVM_AnyInteger : Type<
57   CPred<"$_self.isa<::mlir::LLVM::LLVMIntegerType>()">,
58   "LLVM integer type">;
59
60 // Type constraints accepting LLVM integer type of a specific width.
61 class LLVM_IntBase<int width> :
62     Type<And<[
63         LLVM_AnyInteger.predicate,
64         CPred<"$_self.cast<::mlir::LLVM::LLVMIntegerType>().getBitWidth() == "
65               # width>]>,
66         "LLVM " # width # "-bit integer type">,
67     BuildableType<
68         "::mlir::LLVM::LLVMIntegerType::get($_builder.getContext(), "
69         # width # ")">;
70
71 def LLVM_i1 : LLVM_IntBase<1>;
72 def LLVM_i8 : LLVM_IntBase<8>;
73 def LLVM_i32 : LLVM_IntBase<32>;
74
75 // Type constraint accepting LLVM primitive types, i.e. all types except void
76 // and function.
77 def LLVM_PrimitiveType : Type<
78   And<[LLVM_Type.predicate,
79        CPred<"!$_self.isa<::mlir::LLVM::LLVMVoidType, "
80                          "::mlir::LLVM::LLVMFunctionType>()">]>,
81   "primitive LLVM type">;
82
83 // Type constraint accepting any LLVM floating point type.
84 def LLVM_AnyFloat : Type<
85   CPred<"$_self.isa<::mlir::LLVM::LLVMBFloatType, "
86                    "::mlir::LLVM::LLVMHalfType, "
87                    "::mlir::LLVM::LLVMFloatType, "
88                    "::mlir::LLVM::LLVMDoubleType, "
89                    "::mlir::LLVM::LLVMFP128Type, "
90                    "::mlir::LLVM::LLVMX86FP80Type>()">,
91   "floating point LLVM type">;
92
93 // Type constraint accepting any LLVM pointer type.
94 def LLVM_AnyPointer : Type<CPred<"$_self.isa<::mlir::LLVM::LLVMPointerType>()">,
95                           "LLVM pointer type">;
96
97 // Type constraint accepting LLVM pointer type with an additional constraint
98 // on the element type.
99 class LLVM_PointerTo<Type pointee> : Type<
100   And<[LLVM_AnyPointer.predicate,
101        SubstLeaves<
102          "$_self",
103          "$_self.cast<::mlir::LLVM::LLVMPointerType>().getElementType()",
104          pointee.predicate>]>,
105   "LLVM pointer to " # pointee.description>;
106
107 // Type constraint accepting any LLVM structure type.
108 def LLVM_AnyStruct : Type<CPred<"$_self.isa<::mlir::LLVM::LLVMStructType>()">,
109                          "LLVM structure type">;
110
111 // Type constraint accepting opaque LLVM structure type.
112 def LLVM_OpaqueStruct : Type<
113   And<[LLVM_AnyStruct.predicate,
114        CPred<"$_self.cast<::mlir::LLVM::LLVMStructType>().isOpaque()">]>>;
115
116 // Type constraint accepting any LLVM type that can be loaded or stored, i.e. a
117 // type that has size (not void, function or opaque struct type).
118 def LLVM_LoadableType : Type<
119   And<[LLVM_PrimitiveType.predicate, Neg<LLVM_OpaqueStruct.predicate>]>,
120   "LLVM type with size">;
121
122 // Type constraint accepting any LLVM aggregate type, i.e. structure or array.
123 def LLVM_AnyAggregate : Type<
124   CPred<"$_self.isa<::mlir::LLVM::LLVMStructType, "
125                    "::mlir::LLVM::LLVMArrayType>()">,
126   "LLVM aggregate type">;
127
128 // Type constraint accepting any LLVM non-aggregate type, i.e. not structure or
129 // array.
130 def LLVM_AnyNonAggregate : Type<Neg<LLVM_AnyAggregate.predicate>,
131                                "LLVM non-aggregate type">;
132
133 // Type constraint accepting any LLVM vector type.
134 def LLVM_AnyVector : Type<CPred<"$_self.isa<::mlir::LLVM::LLVMVectorType>()">,
135                          "LLVM vector type">;
136
137 // Type constraint accepting an LLVM vector type with an additional constraint
138 // on the vector element type.
139 class LLVM_VectorOf<Type element> : Type<
140   And<[LLVM_AnyVector.predicate,
141        SubstLeaves<
142          "$_self",
143          "$_self.cast<::mlir::LLVM::LLVMVectorType>().getElementType()",
144          element.predicate>]>,
145   "LLVM vector of " # element.description>;
146
147 // Type constraint accepting a constrained type, or a vector of such types.
148 class LLVM_ScalarOrVectorOf<Type element> :
149     AnyTypeOf<[element, LLVM_VectorOf<element>]>;
150
151 // Base class for LLVM operations. Defines the interface to the llvm::IRBuilder
152 // used to translate to LLVM IR proper.
153 class LLVM_OpBase<Dialect dialect, string mnemonic, list<OpTrait> traits = []> :
154     Op<dialect, mnemonic, traits> {
155   // A pattern for constructing the LLVM IR Instruction (or other Value) that
156   // corresponds to this op.  This pattern can use `builder` to refer to an
157   // `llvm::IRBuilder<>` instance, $-names of arguments and results and the
158   // following special variable names:
159   //   - $_resultType - substituted with the LLVM IR type of the result;
160   //   - $_numOperands - substituted with the number of operands (including
161   //                     the variadic ones);
162   //   - $_hasResult - substituted with a check that a variadic-result op does
163   //                   have a result (LLVM ops can have 0 or 1 result);
164   //   - $_location - mlir::Location object of the instruction.
165   // Additionally, `$$` can be used to produce the dollar character.
166   string llvmBuilder = "";
167 }
168
169 //===----------------------------------------------------------------------===//
170 // Base classes for LLVM dialect operations.
171 //===----------------------------------------------------------------------===//
172
173 // Base class for LLVM operations. All operations get an "llvm." prefix in
174 // their name automatically. LLVM operations have either zero or one result,
175 // this class is specialized below for both cases and should not be used
176 // directly.
177 class LLVM_Op<string mnemonic, list<OpTrait> traits = []> :
178     LLVM_OpBase<LLVM_Dialect, mnemonic, traits>;
179
180 // Case of the LLVM enum attribute backed by I64Attr with customized string
181 // representation that corresponds to what is visible in the textual IR form.
182 // The parameters are as follows:
183 //   - `cppSym`: name of the C++ enumerant for this case in MLIR API;
184 //   - `irSym`: keyword used in the custom form of MLIR operation;
185 //   - `llvmSym`: name of the C++ enumerant for this case in LLVM API.
186 // For example, `LLVM_EnumAttrCase<"Weak", "weak", "WeakAnyLinkage">` is usable
187 // as `<MlirEnumName>::Weak` in MLIR API, `WeakAnyLinkage` in LLVM API and
188 // is printed/parsed as `weak` in MLIR custom textual format.
189 class LLVM_EnumAttrCase<string cppSym, string irSym, string llvmSym, int val> :
190     I64EnumAttrCase<cppSym, val, irSym> {
191
192   // The name of the equivalent enumerant in LLVM.
193   string llvmEnumerant = llvmSym;
194 }
195
196 // LLVM enum attribute backed by I64Attr with string representation
197 // corresponding to what is visible in the textual IR form.
198 // The parameters are as follows:
199 //   - `name`: name of the C++ enum class in MLIR API;
200 //   - `llvmName`: name of the C++ enum in LLVM API;
201 //   - `description`: textual description for documentation purposes;
202 //   - `cases`: list of enum cases.
203 // For example, `LLVM_EnumAttr<Linkage, "::llvm::GlobalValue::LinkageTypes`
204 // produces `mlir::LLVM::Linkage` enum class in MLIR API that corresponds to (a
205 // subset of) values in the `llvm::GlobalValue::LinkageTypes` in LLVM API.
206 class LLVM_EnumAttr<string name, string llvmName, string description,
207                     list<LLVM_EnumAttrCase> cases> :
208     I64EnumAttr<name, description, cases> {
209
210   // The equivalent enum class name in LLVM.
211   string llvmClassName = llvmName;
212 }
213
214 // For every value in the list, substitutes the value in the place of "$0" in
215 // "pattern" and stores the list of strings as "lst".
216 class ListIntSubst<string pattern, list<int> values> {
217   list<string> lst = !foreach(x, values,
218                               !subst("$0", !cast<string>(x), pattern));
219 }
220
221 // Patterns with code obtaining the LLVM IR type of the given operand or result
222 // of operation. "$0" is expected to be replaced by the position of the operand
223 // or result in the operation.
224 def LLVM_IntrPatterns {
225   string operand =
226     [{convertType(opInst.getOperand($0).getType().cast<LLVM::LLVMType>())}];
227   string result =
228     [{convertType(opInst.getResult($0).getType().cast<LLVM::LLVMType>())}];
229 }
230
231
232 // Base class for LLVM intrinsics operation. It is similar to LLVM_Op, but
233 // provides the "llvmBuilder" field for constructing the intrinsic. The builder
234 // relies on the contents on "overloadedResults" and "overloadedOperands" lists
235 // that contain the positions of intrinsic results and operands that are
236 // overloadable in the LLVM sense, that is their types must be passed in during
237 // the construction of the intrinsic declaration to differentiate between
238 // differently-typed versions of the intrinsic. "opName" contains the name of
239 // the operation to be associated with the intrinsic and "enumName" contains the
240 // name of the intrinsic as appears in `llvm::Intrinsic` enum; one usually wants
241 // these to be related.
242 class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName,
243                       list<int> overloadedResults, list<int> overloadedOperands,
244                       list<OpTrait> traits, bit hasResult>
245     : LLVM_OpBase<dialect, opName, traits>,
246       Results<!if(hasResult, (outs LLVM_Type:$res), (outs))> {
247   let llvmBuilder = [{
248     llvm::Module *module = builder.GetInsertBlock()->getModule();
249     llvm::Function *fn = llvm::Intrinsic::getDeclaration(
250         module,
251         llvm::Intrinsic::}] # enumName # [{,
252         { }] # StrJoin<!listconcat(
253             ListIntSubst<LLVM_IntrPatterns.result, overloadedResults>.lst,
254             ListIntSubst<LLVM_IntrPatterns.operand,
255                          overloadedOperands>.lst)>.result # [{
256         });
257     auto operands = lookupValues(opInst.getOperands());
258     }] # !if(hasResult, "$res = ", "") # [{builder.CreateCall(fn, operands);
259   }];
260 }
261
262 // Base class for LLVM intrinsic operations, should not be used directly. Places
263 // the intrinsic into the LLVM dialect and prefixes its name with "intr.".
264 class LLVM_IntrOp<string mnem, list<int> overloadedResults,
265                   list<int> overloadedOperands, list<OpTrait> traits,
266                   bit hasResult>
267     : LLVM_IntrOpBase<LLVM_Dialect, "intr." # mnem, !subst(".", "_", mnem),
268                       overloadedResults, overloadedOperands, traits, hasResult>;
269
270 // Base class for LLVM intrinsic operations returning no results. Places the
271 // intrinsic into the LLVM dialect and prefixes its name with "intr.".
272 //
273 // Sample use: derive an entry from this class and populate the fields.
274 //
275 //    def LLVM_Name : LLVM_ZeroResultIntrOp<"name", [0], [NoSideEffect]>,
276 //                    Arguments<(ins LLVM_Type, LLVM_Type)>;
277 //
278 // The mnemonic will be prefixed with "llvm.intr.", where the "llvm." part comes
279 // from the LLVM dialect. The overloadedOperands list contains the indices of
280 // the operands the type of which will be passed in the LLVM IR intrinsic
281 // builder. In the example above, the Op has two arguments, but only the first
282 // one (as indicated by `[0]`) is necessary to resolve the overloaded intrinsic.
283 // The Op has no results.
284 class LLVM_ZeroResultIntrOp<string mnem, list<int> overloadedOperands = [],
285                             list<OpTrait> traits = []>
286     : LLVM_IntrOp<mnem, [], overloadedOperands, traits, 0>;
287
288 // Base class for LLVM intrinsic operations returning one result. Places the
289 // intrinsic into the LLVM dialect and prefixes its name with "intr.". This is
290 // similar to LLVM_ZeroResultIntrOp but allows one to define Ops returning one
291 // result, called "res". Additionally, the overloadedResults list should contain
292 // "0" if the result must be used to resolve overloaded intrinsics, or remain
293 // empty otherwise.
294 class LLVM_OneResultIntrOp<string mnem, list<int> overloadedResults = [],
295                            list<int> overloadedOperands = [],
296                            list<OpTrait> traits = []>
297     : LLVM_IntrOp<mnem, overloadedResults, overloadedOperands, traits, 1>;
298
299 // LLVM vector reduction over a single vector.
300 class LLVM_VectorReduction<string mnem>
301     : LLVM_OneResultIntrOp<"vector.reduce." # mnem,
302                            [], [0], [NoSideEffect]>,
303       Arguments<(ins LLVM_Type)>;
304
305 // LLVM vector reduction over a single vector, with an initial value,
306 // and with permission to reassociate the reduction operations.
307 class LLVM_VectorReductionAcc<string mnem>
308     : LLVM_OpBase<LLVM_Dialect, "intr.vector.reduce." # mnem,
309                   [NoSideEffect]>,
310       Results<(outs LLVM_Type:$res)>,
311       Arguments<(ins LLVM_Type, LLVM_Type,
312                  DefaultValuedAttr<BoolAttr, "false">:$reassoc)> {
313   let llvmBuilder = [{
314     llvm::Module *module = builder.GetInsertBlock()->getModule();
315     llvm::Function *fn = llvm::Intrinsic::getDeclaration(
316         module,
317         llvm::Intrinsic::vector_reduce_}] # mnem # [{,
318         { }] # StrJoin<ListIntSubst<LLVM_IntrPatterns.operand, [1]>.lst>.result # [{
319         });
320     auto operands = lookupValues(opInst.getOperands());
321     llvm::FastMathFlags origFM = builder.getFastMathFlags();
322     llvm::FastMathFlags tempFM = origFM;
323     tempFM.setAllowReassoc($reassoc);
324     builder.setFastMathFlags(tempFM);  // set fastmath flag
325     $res = builder.CreateCall(fn, operands);
326     builder.setFastMathFlags(origFM);  // restore fastmath flag
327   }];
328 }
329
330 #endif  // LLVMIR_OP_BASE