xref: /llvm-project/mlir/include/mlir/IR/AttrTypeBase.td (revision d35098bfa8e1e213f85a6b5035a5a7102f5da315)
1//===-- AttrTypeBase.td - Base Attr/Type definition file ---*- 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 the base set of constructs for defining Attribute and
10// Type classes.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef ATTRTYPEBASE_TD
15#define ATTRTYPEBASE_TD
16
17include "mlir/IR/CommonAttrConstraints.td"
18include "mlir/IR/CommonTypeConstraints.td"
19include "mlir/IR/Constraints.td"
20include "mlir/IR/DialectBase.td"
21include "mlir/IR/Traits.td"
22
23//-------------------------------------------------------------------------===//
24// AttrTrait definitions
25//===----------------------------------------------------------------------===//
26
27// These classes are used to define attribute specific traits.
28
29// Specify attribute specific declarations and definitions in `extraAttrDeclaration`
30// and `extraAttrDefinition` template arguments.
31class NativeAttrTrait<string name,
32                      code extraAttrDeclaration = [{}],
33                      code extraAttrDefinition = [{}]>
34    : NativeTrait<name, "Attribute", extraAttrDeclaration, extraAttrDefinition>;
35
36class ParamNativeAttrTrait<string prop, string params>
37    : ParamNativeTrait<prop, params, "Attribute">;
38class GenInternalAttrTrait<string prop> : GenInternalTrait<prop, "Attribute">;
39class PredAttrTrait<string descr, Pred pred> : PredTrait<descr, pred>;
40
41//===----------------------------------------------------------------------===//
42// TypeTrait definitions
43//===----------------------------------------------------------------------===//
44
45// These classes are used to define type specific traits.
46
47// Specify type specific declarations and definitions in `extraTypeDeclaration`
48// and `extraTypeDefinition` template arguments.
49class NativeTypeTrait<string name,
50                      code extraTypeDeclaration = [{}],
51                      code extraTypeDefinition = [{}]>
52    : NativeTrait<name, "Type", extraTypeDeclaration, extraTypeDefinition>;
53
54class ParamNativeTypeTrait<string prop, string params>
55    : ParamNativeTrait<prop, params, "Type">;
56class GenInternalTypeTrait<string prop> : GenInternalTrait<prop, "Type">;
57class PredTypeTrait<string descr, Pred pred> : PredTrait<descr, pred>;
58
59// Trait required to be added to any type which is mutable.
60def MutableType : NativeTypeTrait<"IsMutable">;
61
62//===----------------------------------------------------------------------===//
63// Builders
64//===----------------------------------------------------------------------===//
65
66// Class for defining a custom getter.
67//
68// TableGen generates several generic getter methods for each attribute and type
69// by default, corresponding to the specified dag parameters. If the default
70// generated ones cannot cover some use case, custom getters can be defined
71// using instances of this class.
72//
73// The signature of the `get` is always either:
74//
75// ```c++
76// static <ClassName> get(MLIRContext *context, <other-parameters>...) {
77//   <body>...
78// }
79// ```
80//
81// or:
82//
83// ```c++
84// static <ClassName> get(MLIRContext *context, <parameters>...);
85// ```
86//
87// To define a custom getter, the parameter list and body should be passed
88// in as separate template arguments to this class. The parameter list is a
89// TableGen DAG with `ins` operation with named arguments, which has either:
90//   - string initializers ("Type":$name) to represent a typed parameter, or
91//   - CArg-typed initializers (CArg<"Type", "default">:$name) to represent a
92//     typed parameter that may have a default value.
93// The type string is used verbatim to produce code and, therefore, must be a
94// valid C++ type. It is used inside the C++ namespace of the parent Type's
95// dialect; explicit namespace qualification like `::mlir` may be necessary if
96// Types are not placed inside the `mlir` namespace. The default value string is
97// used verbatim to produce code and must be a valid C++ initializer the given
98// type. For example, the following signature specification
99//
100// ```
101// AttrOrTypeBuilder<(ins "int":$integerArg, CArg<"float", "3.0f">:$floatArg)>
102// ```
103//
104// has an integer parameter and a float parameter with a default value.
105//
106// If an empty string is passed in for `body`, then *only* the builder
107// declaration will be generated; this provides a way to define complicated
108// builders entirely in C++. If a `body` string is provided, the `Base::get`
109// method should be invoked using `$_get`, e.g.:
110//
111// ```
112// AttrOrTypeBuilder<(ins "int":$integerArg, CArg<"float", "3.0f">:$floatArg), [{
113//   return $_get($_ctxt, integerArg, floatArg);
114// }]>
115// ```
116//
117// This is necessary because the `body` is also used to generate `getChecked`
118// methods, which have a different underlying `Base::get*` call.
119//
120class AttrOrTypeBuilder<dag parameters, code bodyCode = "",
121                        string returnTypeStr = ""> {
122  dag dagParams = parameters;
123  code body = bodyCode;
124
125  // Change the return type of the builder. By default, it is the type of the
126  // attribute or type.
127  string returnType = returnTypeStr;
128
129  // The context parameter can be inferred from one of the other parameters and
130  // is not implicitly added to the parameter list.
131  bit hasInferredContextParam = 0;
132}
133class AttrBuilder<dag parameters, code bodyCode = "", string returnType = "">
134  : AttrOrTypeBuilder<parameters, bodyCode, returnType>;
135class TypeBuilder<dag parameters, code bodyCode = "", string returnType = "">
136  : AttrOrTypeBuilder<parameters, bodyCode, returnType>;
137
138// A class of AttrOrTypeBuilder that is able to infer the MLIRContext parameter
139// from one of the other builder parameters. Instances of this builder do not
140// have `MLIRContext *` implicitly added to the parameter list.
141class AttrOrTypeBuilderWithInferredContext<dag parameters, code bodyCode = "",
142                                           string returnType = "">
143  : TypeBuilder<parameters, bodyCode, returnType> {
144  let hasInferredContextParam = 1;
145}
146class AttrBuilderWithInferredContext<dag parameters, code bodyCode = "",
147                                     string returnType = "">
148  : AttrOrTypeBuilderWithInferredContext<parameters, bodyCode, returnType>;
149class TypeBuilderWithInferredContext<dag parameters, code bodyCode = "",
150                                     string returnType = "">
151  : AttrOrTypeBuilderWithInferredContext<parameters, bodyCode, returnType>;
152
153//===----------------------------------------------------------------------===//
154// Definitions
155//===----------------------------------------------------------------------===//
156
157// Define a new attribute or type, named `name`, that inherits from the given
158// C++ base class.
159class AttrOrTypeDef<string valueType, string name, list<Trait> defTraits,
160                    string baseCppClass> {
161  // The name of the C++ base class to use for this def.
162  string cppBaseClassName = baseCppClass;
163
164  // Additional, longer human-readable description of what the def does.
165  string description = "";
166
167  // Name of storage class to generate or use.
168  string storageClass = name # valueType # "Storage";
169
170  // Namespace (withing dialect c++ namespace) in which the storage class
171  // resides.
172  string storageNamespace = "detail";
173
174  // Specify if the storage class is to be generated.
175  bit genStorageClass = 1;
176
177  // Specify that the generated storage class has a constructor which is written
178  // in C++.
179  bit hasStorageCustomConstructor = 0;
180
181  // The list of parameters for this type. Parameters will become both
182  // parameters to the get() method and storage class member variables.
183  //
184  // The format of this dag is:
185  //    (ins
186  //        "<c++ type>":$param1Name,
187  //        "<c++ type>":$param2Name,
188  //        AttrOrTypeParameter<"c++ type", "param description">:$param3Name)
189  // AttrOrTypeParameters (or more likely one of their subclasses) are required
190  // to add more information about the parameter, specifically:
191  //  - Documentation
192  //  - Code to allocate the parameter (if allocation is needed in the storage
193  //    class constructor)
194  //
195  // For example:
196  //    (ins "int":$width,
197  //         ArrayRefParameter<"bool", "list of bools">:$yesNoArray)
198  //
199  // (ArrayRefParameter is a subclass of AttrOrTypeParameter which has
200  // allocation code for re-allocating ArrayRefs. It is defined below.)
201  dag parameters = (ins);
202
203  // Custom builder methods.
204  // In addition to the custom builders provided here, and unless
205  // skipDefaultBuilders is set, a default builder is generated with the
206  // following signature:
207  //
208  // ```c++
209  // static <ClassName> get(MLIRContext *, <parameters>);
210  // ```
211  //
212  // Note that builders should only be provided when a def has parameters.
213  list<AttrOrTypeBuilder> builders = ?;
214
215  // The list of traits attached to this def.
216  list<Trait> traits = defTraits;
217
218  // Use the lowercased name as the keyword for parsing/printing. Specify only
219  // if you want tblgen to generate declarations and/or definitions of
220  // the printer/parser. If specified and the Attribute or Type contains
221  // parameters, `assemblyFormat` or `hasCustomAssemblyFormat` must also be
222  // specified.
223  string mnemonic = ?;
224
225  // Custom assembly format. Requires 'mnemonic' to be specified. Cannot be
226  // specified at the same time as 'hasCustomAssemblyFormat'. The generated
227  // printer requires 'genAccessors' to be true.
228  string assemblyFormat = ?;
229  /// This field indicates that the attribute or type has a custom assembly format
230  /// implemented in C++. When set to `1` a `parse` and `print` method are generated
231  /// on the generated class. The attribute or type should implement these methods to
232  /// support the custom format.
233  bit hasCustomAssemblyFormat = 0;
234
235  // If set, generate accessors for each parameter.
236  bit genAccessors = 1;
237
238  // Avoid generating default get/getChecked functions. Custom get methods must
239  // be provided.
240  bit skipDefaultBuilders = 0;
241
242  // Generate the verify and getChecked methods.
243  bit genVerifyDecl = 0;
244
245  // Extra code to include in the class declaration.
246  code extraClassDeclaration = [{}];
247
248  // Additional code that will be added to the generated source file. The
249  // generated code is placed inside the class's C++ namespace. `$cppClass` is
250  // replaced by the class name.
251  code extraClassDefinition = [{}];
252}
253
254// Define a new attribute, named `name`, belonging to `dialect` that inherits
255// from the given C++ base class.
256class AttrDef<Dialect dialect, string name, list<Trait> traits = [],
257              string baseCppClass = "::mlir::Attribute">
258    : DialectAttr<dialect, CPred<"">, /*descr*/"">,
259      AttrOrTypeDef<"Attr", name, traits, baseCppClass> {
260  // The name of the C++ Attribute class.
261  string cppClassName = name # "Attr";
262  let storageType = dialect.cppNamespace # "::" # cppClassName;
263
264  // The underlying C++ value type
265  let returnType = dialect.cppNamespace # "::" # cppClassName;
266
267  // Make it possible to use such attributes as parameters for other attributes.
268  string cppType = dialect.cppNamespace # "::" # cppClassName;
269
270  // The unique attribute name.
271  string attrName = dialect.name # "." # mnemonic;
272
273  // The call expression to convert from the storage type to the return
274  // type. For example, an enum can be stored as an int but returned as an
275  // enum class.
276  //
277  // Format: $_self will be expanded to the attribute.
278  //
279  // For example, `$_self.getValue().getSExtValue()` for `IntegerAttr val` will
280  // expand to `getAttrOfType<IntegerAttr>("val").getValue().getSExtValue()`.
281  let convertFromStorage = "::llvm::cast<" # cppType # ">($_self)";
282
283  // The predicate for when this def is used as a constraint.
284  let predicate = CPred<"::llvm::isa<" # cppType # ">($_self)">;
285}
286
287// Provide a LocationAttrDef for dialects to provide their own locations
288// that subclass LocationAttr.
289class LocationAttrDef<Dialect dialect, string name, list<Trait> traits = []>
290    : AttrDef<dialect, name, traits # [NativeAttrTrait<"IsLocation">],
291              "::mlir::LocationAttr">;
292
293// Define a new type, named `name`, belonging to `dialect` that inherits from
294// the given C++ base class.
295class TypeDef<Dialect dialect, string name, list<Trait> traits = [],
296              string baseCppClass = "::mlir::Type">
297    : DialectType<dialect, CPred<"">, /*descr*/"", name # "Type">,
298      AttrOrTypeDef<"Type", name, traits, baseCppClass> {
299  // The name of the C++ Type class.
300  string cppClassName = name # "Type";
301
302  // Make it possible to use such type as parameters for other types.
303  string cppType = dialect.cppNamespace # "::" # cppClassName;
304
305  // The unique type name.
306  string typeName = dialect.name # "." # mnemonic;
307
308  // A constant builder provided when the type has no parameters.
309  let builderCall = !if(!empty(parameters),
310                           "$_builder.getType<" # cppType # ">()",
311                           "");
312
313  // The predicate for when this def is used as a constraint.
314  let predicate = CPred<"::llvm::isa<" # cppType # ">($_self)">;
315}
316
317//===----------------------------------------------------------------------===//
318// Parameters
319//===----------------------------------------------------------------------===//
320
321// 'Parameters' should be subclasses of this or simple strings (which is a
322// shorthand for AttrOrTypeParameter<"C++Type">).
323class AttrOrTypeParameter<string type, string desc, string accessorType = ""> {
324  // Custom memory allocation code for storage constructor.
325  code allocator = ?;
326  // Comparator used to compare two instances for equality. By default, it uses
327  // the C++ equality operator.
328  code comparator = ?;
329  // The C++ type of this parameter.
330  string cppType = type;
331  // The C++ type of the accessor for this parameter.
332  string cppAccessorType = !if(!empty(accessorType), type, accessorType);
333  // The C++ storage type of this parameter if it is a reference, e.g.
334  // `std::string` for `StringRef` or `SmallVector` for `ArrayRef`.
335  string cppStorageType = cppType;
336  // The C++ code to convert from the storage type to the parameter type.
337  string convertFromStorage = "$_self";
338  // One-line human-readable description of the argument.
339  string summary = desc;
340  // The format string for the asm syntax (documentation only).
341  string syntax = ?;
342  // The default parameter parser is `::mlir::FieldParser<T>::parse($_parser)`,
343  // which returns `FailureOr<T>`. Specialize `FieldParser` to support parsing
344  // for your type. Or you can provide a customer printer. For attributes,
345  // "$_type" will be replaced with the required attribute type.
346  string parser = ?;
347  // The default parameter printer is `$_printer << $_self`. Overload the stream
348  // operator of `AsmPrinter` as necessary to print your type. Or you can
349  // provide a custom printer.
350  string printer = ?;
351  // Provide a default value for the parameter. Parameters with default values
352  // are considered optional. If a value was not parsed for the parameter, it
353  // will be set to the default value. Parameters equal to their default values
354  // are elided when printing. Equality is checked using the `comparator` field,
355  // which by default is the C++ equality operator. The current MLIR context is
356  // made available through `$_ctxt`, e.g., for constructing default values for
357  // attributes and types.
358  string defaultValue = "";
359}
360class AttrParameter<string type, string desc, string accessorType = "">
361 : AttrOrTypeParameter<type, desc, accessorType>;
362class TypeParameter<string type, string desc, string accessorType = "">
363 : AttrOrTypeParameter<type, desc, accessorType>;
364
365// An optional parameter.
366class OptionalParameter<string type, string desc = ""> :
367    AttrOrTypeParameter<type, desc> {
368  let defaultValue = cppStorageType # "()";
369}
370
371// A parameter with a default value.
372class DefaultValuedParameter<string type, string value, string desc = ""> :
373    AttrOrTypeParameter<type, desc> {
374  let defaultValue = value;
375}
376
377// For StringRefs, which require allocation.
378class StringRefParameter<string desc = "", string value = ""> :
379    AttrOrTypeParameter<"::llvm::StringRef", desc> {
380  let allocator = [{$_dst = $_allocator.copyInto($_self);}];
381  let printer = [{$_printer.printString($_self);}];
382  let cppStorageType = "std::string";
383  let defaultValue = value;
384}
385
386// For APFloats, which require comparison.
387class APFloatParameter<string desc> :
388    AttrOrTypeParameter<"::llvm::APFloat", desc> {
389  let comparator = "$_lhs.bitwiseIsEqual($_rhs)";
390}
391
392// For standard ArrayRefs, which require allocation.
393class ArrayRefParameter<string arrayOf, string desc = ""> :
394    AttrOrTypeParameter<"::llvm::ArrayRef<" # arrayOf # ">", desc> {
395  let allocator = [{$_dst = $_allocator.copyInto($_self);}];
396  let cppStorageType = "::llvm::SmallVector<" # arrayOf # ">";
397}
398
399// Regular array parameters cannot be parsed when empty. This optional array
400// parameter can be used with optional groups to be parsed when empty.
401class OptionalArrayRefParameter<string arrayOf, string desc = ""> :
402    OptionalParameter<"::llvm::ArrayRef<" # arrayOf # ">", desc> {
403  let allocator = [{$_dst = $_allocator.copyInto($_self);}];
404  let cppStorageType = "::llvm::SmallVector<" # arrayOf # ">";
405  let comparator = cppType # "($_lhs) == " # cppType # "($_rhs)";
406}
407
408// For classes which require allocation and have their own allocateInto method.
409class SelfAllocationParameter<string type, string desc> :
410    AttrOrTypeParameter<type, desc> {
411  let allocator = [{$_dst = $_self.allocateInto($_allocator);}];
412}
413
414// For ArrayRefs which contain things which allocate themselves.
415class ArrayRefOfSelfAllocationParameter<string arrayOf, string desc> :
416    AttrOrTypeParameter<"::llvm::ArrayRef<" # arrayOf # ">", desc> {
417  let allocator = [{
418    llvm::SmallVector<}] # arrayOf # [{, 4> tmpFields;
419    for (size_t i = 0, e = $_self.size(); i < e; ++i)
420      tmpFields.push_back($_self[i].allocateInto($_allocator));
421    $_dst = $_allocator.copyInto(ArrayRef<}] # arrayOf # [{>(tmpFields));
422  }];
423}
424
425// This is a special attribute parameter that represents the "self" type of the
426// attribute. It is specially handled by the assembly format generator to derive
427// its value from the optional trailing type after each attribute.
428//
429// By default, the self type parameter is optional and has a default value of
430// `none`. If a derived type other than `::mlir::Type` is specified, the
431// parameter loses its default value unless another one is specified by
432// `typeBuilder`.
433class AttributeSelfTypeParameter<string desc,
434                                 string derivedType = "::mlir::Type",
435                                 string typeBuilder = ""> :
436    AttrOrTypeParameter<derivedType, desc> {
437  let defaultValue = !if(!and(!empty(typeBuilder),
438                              !eq(derivedType, "::mlir::Type")),
439                         "::mlir::NoneType::get($_ctxt)", typeBuilder);
440}
441
442//===----------------------------------------------------------------------===//
443// ArrayOfAttr
444//===----------------------------------------------------------------------===//
445
446/// This class defines an attribute that contains an array of elements. The
447/// elements can be any type, but if they are attributes, the nested elements
448/// are parsed and printed using the custom attribute syntax.
449class ArrayOfAttr<Dialect dialect, string name, string attrMnemonic,
450                  string eltName, list<Trait> traits = []>
451    : AttrDef<dialect, name, traits> {
452  let parameters = (ins OptionalArrayRefParameter<eltName>:$value);
453  let mnemonic = attrMnemonic;
454  let assemblyFormat = "`[` (`]`) : ($value^ `]`)?";
455
456  let returnType = "::llvm::ArrayRef<" # eltName # ">";
457  let constBuilderCall = "$_builder.getAttr<" # name # "Attr>($0)";
458  let convertFromStorage = "$_self.getValue()";
459
460  let extraClassDeclaration = [{
461    auto begin() const { return getValue().begin(); }
462    auto end() const { return getValue().end(); }
463    bool empty() const { return getValue().empty(); }
464    size_t size() const { return getValue().size(); }
465    auto &front() const { return getValue().front(); }
466    auto &back() const { return getValue().back(); }
467    auto &operator[](size_t index) { return getValue()[index]; }
468    operator }] # returnType # [{() const { return getValue(); }
469  }];
470}
471
472#endif // ATTRTYPEBASE_TD
473