xref: /llvm-project/mlir/test/lib/Dialect/Test/TestAttrDefs.td (revision db273c6c242f51792ed4298a24bd2c344214ce38)
1//===-- TestAttrDefs.td - Test dialect attr 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// TableGen data attribute definitions for Test dialect.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef TEST_ATTRDEFS
14#define TEST_ATTRDEFS
15
16// To get the test dialect definition.
17include "TestDialect.td"
18include "TestEnumDefs.td"
19include "mlir/Dialect/Polynomial/IR/PolynomialAttributes.td"
20include "mlir/Dialect/Utils/StructuredOpsUtils.td"
21include "mlir/IR/AttrTypeBase.td"
22include "mlir/IR/BuiltinAttributeInterfaces.td"
23include "mlir/IR/EnumAttr.td"
24include "mlir/IR/OpAsmInterface.td"
25
26// All of the attributes will extend this class.
27class Test_Attr<string name, list<Trait> traits = []>
28    : AttrDef<Test_Dialect, name, traits>;
29
30class Test_LocAttr<string name> : LocationAttrDef<Test_Dialect, name, []>;
31
32def SimpleAttrA : Test_Attr<"SimpleA"> {
33  let mnemonic = "smpla";
34}
35
36// A more complex parameterized attribute.
37def CompoundAttrA : Test_Attr<"CompoundA"> {
38  let mnemonic = "cmpnd_a";
39
40  // List of type parameters.
41  let parameters = (
42    ins
43    "int":$widthOfSomething,
44    "::mlir::Type":$oneType,
45    // This is special syntax since ArrayRefs require allocation in the
46    // constructor.
47    ArrayRefParameter<
48      "int", // The parameter C++ type.
49      "An example of an array of ints" // Parameter description.
50      >: $arrayOfInts
51  );
52  let hasCustomAssemblyFormat = 1;
53}
54def CompoundAttrNested : Test_Attr<"CompoundAttrNested"> {
55  let mnemonic = "cmpnd_nested";
56  let parameters = (ins CompoundAttrA : $nested );
57  let assemblyFormat = "`<` `nested` `=` $nested `>`";
58}
59
60// An attribute testing AttributeSelfTypeParameter.
61def AttrWithSelfTypeParam
62    : Test_Attr<"AttrWithSelfTypeParam", [TypedAttrInterface]> {
63  let mnemonic = "attr_with_self_type_param";
64  let parameters = (ins AttributeSelfTypeParameter<"">:$type);
65  let assemblyFormat = "";
66}
67
68// An attribute testing AttributeSelfTypeParameter.
69def AttrWithTypeBuilder
70    : Test_Attr<"AttrWithTypeBuilder", [TypedAttrInterface]> {
71  let mnemonic = "attr_with_type_builder";
72  let parameters = (ins
73    "::mlir::IntegerAttr":$attr,
74    AttributeSelfTypeParameter<"", "mlir::Type", "$attr.getType()">:$type
75  );
76  let assemblyFormat = "$attr";
77}
78
79def TestAttrTrait : NativeAttrTrait<"TestAttrTrait">;
80
81// The definition of a singleton attribute that has a trait.
82def AttrWithTrait : Test_Attr<"AttrWithTrait", [TestAttrTrait]> {
83  let mnemonic = "attr_with_trait";
84}
85
86// An attribute of a list of decimal formatted integers in similar format to shapes.
87def TestDecimalShapeAttr : Test_Attr<"TestDecimalShape"> {
88  let mnemonic = "decimal_shape";
89
90  let parameters = (ins ArrayRefParameter<"int64_t">:$shape);
91
92  let hasCustomAssemblyFormat = 1;
93}
94
95// Test support for ElementsAttrInterface.
96def TestI64ElementsAttr : Test_Attr<"TestI64Elements", [ElementsAttrInterface]> {
97  let mnemonic = "i64_elements";
98  let parameters = (ins
99    AttributeSelfTypeParameter<"", "::mlir::ShapedType">:$type,
100    ArrayRefParameter<"uint64_t">:$elements
101  );
102  let extraClassDeclaration = [{
103    /// The set of data types that can be iterated by this attribute.
104    using ContiguousIterableTypesT = std::tuple<uint64_t>;
105    using NonContiguousIterableTypesT = std::tuple<mlir::Attribute, llvm::APInt>;
106
107    /// Provide begin iterators for the various iterable types.
108    // * uint64_t
109    mlir::FailureOr<const uint64_t *>
110    try_value_begin_impl(OverloadToken<uint64_t>) const {
111      return getElements().begin();
112    }
113    // * Attribute
114    auto try_value_begin_impl(OverloadToken<mlir::Attribute>) const {
115      mlir::Type elementType = getType().getElementType();
116      return mlir::success(llvm::map_range(getElements(), [=](uint64_t value) {
117        return mlir::IntegerAttr::get(elementType,
118                                      llvm::APInt(/*numBits=*/64, value));
119      }).begin());
120    }
121    // * APInt
122    auto try_value_begin_impl(OverloadToken<llvm::APInt>) const {
123      return mlir::success(llvm::map_range(getElements(), [=](uint64_t value) {
124        return llvm::APInt(/*numBits=*/64, value);
125      }).begin());
126    }
127  }];
128  let genVerifyDecl = 1;
129  let hasCustomAssemblyFormat = 1;
130}
131
132def TestSubElementsAccessAttr : Test_Attr<"TestSubElementsAccess"> {
133  let mnemonic = "sub_elements_access";
134
135  let parameters = (ins
136    "::mlir::Attribute":$first,
137    "::mlir::Attribute":$second,
138    "::mlir::Attribute":$third
139  );
140  let hasCustomAssemblyFormat = 1;
141}
142
143// A more complex parameterized attribute with multiple level of nesting.
144def CompoundNestedInner : Test_Attr<"CompoundNestedInner"> {
145  let mnemonic = "cmpnd_nested_inner";
146  // List of type parameters.
147  let parameters = (
148    ins
149    "int":$some_int,
150    CompoundAttrA:$cmpdA
151  );
152  let assemblyFormat = "`<` $some_int $cmpdA `>`";
153}
154
155def CompoundNestedOuter : Test_Attr<"CompoundNestedOuter"> {
156  let mnemonic = "cmpnd_nested_outer";
157
158  // List of type parameters.
159  let parameters = (
160    ins
161    CompoundNestedInner:$inner
162  );
163  let assemblyFormat = "`<` `i`  $inner `>`";
164}
165
166def CompoundNestedOuterQual : Test_Attr<"CompoundNestedOuterQual"> {
167  let mnemonic = "cmpnd_nested_outer_qual";
168
169  // List of type parameters.
170  let parameters = (ins CompoundNestedInner:$inner);
171  let assemblyFormat = "`<` `i`  qualified($inner) `>`";
172}
173
174def TestParamOne : AttrParameter<"int64_t", ""> {}
175
176def TestParamTwo : AttrParameter<"std::string", "", "llvm::StringRef"> {
177  let printer = "$_printer << '\"' << $_self << '\"'";
178}
179
180def TestParamFour : ArrayRefParameter<"int", ""> {
181  let cppStorageType = "llvm::SmallVector<int>";
182  let parser = "::parseIntArray($_parser)";
183  let printer = "::printIntArray($_printer, $_self)";
184}
185
186
187def TestParamVector : ArrayRefParameter<"int", ""> {
188  let cppStorageType = "std::vector<int>";
189}
190
191def TestParamUnsigned : AttrParameter<"uint64_t", ""> {}
192
193def TestAttrWithFormat : Test_Attr<"TestAttrWithFormat"> {
194  let parameters = (
195    ins
196    TestParamOne:$one,
197    TestParamTwo:$two,
198    "::mlir::IntegerAttr":$three,
199    TestParamFour:$four,
200    TestParamUnsigned:$five,
201    TestParamVector:$six,
202    // Array of another attribute.
203    ArrayRefParameter<
204      "AttrWithTypeBuilderAttr", // The parameter C++ type.
205      "An example of an array of another Attribute" // Parameter description.
206      >: $arrayOfAttrWithTypeBuilderAttr
207  );
208
209  let mnemonic = "attr_with_format";
210  let assemblyFormat = [{
211    `<` $one `:` struct($two, $four) `:` $three `:` $five `:` `[` $six `]` `,`
212    `[` `` $arrayOfAttrWithTypeBuilderAttr `]` `>`
213  }];
214  let genVerifyDecl = 1;
215}
216
217def TestAttrWithOptionalSigned : Test_Attr<"TestAttrWithOptionalSigned"> {
218  let parameters = (ins OptionalParameter<"std::optional<int64_t>">:$value);
219  let assemblyFormat = "`<` $value `>`";
220  let mnemonic = "attr_with_optional_signed";
221}
222
223def TestAttrWithOptionalUnsigned : Test_Attr<"TestAttrWithOptionalUnsigned"> {
224  let parameters = (ins OptionalParameter<"std::optional<uint64_t>">:$value);
225  let assemblyFormat = "`<` $value `>`";
226  let mnemonic = "attr_with_optional_unsigned";
227}
228
229def TestAttrWithOptionalEnum : Test_Attr<"TestAttrWithOptionalEnum"> {
230  let parameters = (ins OptionalParameter<"std::optional<SimpleEnum>">:$value);
231  let assemblyFormat = "`<` $value `>`";
232  let mnemonic = "attr_with_optional_enum";
233}
234
235def TestAttrUgly : Test_Attr<"TestAttrUgly"> {
236  let parameters = (ins "::mlir::Attribute":$attr);
237
238  let mnemonic = "attr_ugly";
239  let assemblyFormat = "`begin` $attr `end`";
240}
241
242def TestAttrParams: Test_Attr<"TestAttrParams"> {
243  let parameters = (ins "int":$v0, "int":$v1);
244
245  let mnemonic = "attr_params";
246  let assemblyFormat = "`<` params `>`";
247}
248
249// Test types can be parsed/printed.
250def TestAttrWithTypeParam : Test_Attr<"TestAttrWithTypeParam"> {
251  let parameters = (ins "::mlir::IntegerType":$int_type,
252                        "::mlir::Type":$any_type);
253  let mnemonic = "attr_with_type";
254  let assemblyFormat = "`<` $int_type `,` $any_type `>`";
255}
256
257// Test self type parameter with assembly format.
258def TestAttrSelfTypeParameterFormat
259    : Test_Attr<"TestAttrSelfTypeParameterFormat", [TypedAttrInterface]> {
260  let parameters = (ins "int":$a, AttributeSelfTypeParameter<"">:$type);
261
262  let mnemonic = "attr_self_type_format";
263  let assemblyFormat = "`<` $a `>`";
264}
265
266def TestAttrSelfTypeParameterStructFormat
267    : Test_Attr<"TestAttrSelfTypeParameterStructFormat", [TypedAttrInterface]> {
268  let parameters = (ins "int":$a, AttributeSelfTypeParameter<"">:$type);
269
270  let mnemonic = "attr_self_type_struct_format";
271  let assemblyFormat = "`<` struct(params) `>`";
272}
273
274// Test overridding attribute builders with a custom builder.
275def TestOverrideBuilderAttr : Test_Attr<"TestOverrideBuilder"> {
276  let mnemonic = "override_builder";
277  let parameters = (ins "int":$a);
278  let assemblyFormat = "`<` $a `>`";
279
280  let skipDefaultBuilders = 1;
281  let builders = [AttrBuilder<(ins "int":$a), [{
282    return ::mlir::IntegerAttr::get(::mlir::IndexType::get($_ctxt), a);
283  }], "::mlir::Attribute">];
284}
285
286// Test simple extern 1D vector using ElementsAttrInterface.
287def TestExtern1DI64ElementsAttr : Test_Attr<"TestExtern1DI64Elements", [ElementsAttrInterface]> {
288  let mnemonic = "e1di64_elements";
289  let parameters = (ins
290    AttributeSelfTypeParameter<"", "::mlir::ShapedType">:$type,
291    ResourceHandleParameter<"TestDialectResourceBlobHandle">:$handle
292  );
293  let extraClassDeclaration = [{
294    /// Return the elements referenced by this attribute.
295    llvm::ArrayRef<uint64_t> getElements() const;
296
297    /// The set of data types that can be iterated by this attribute.
298    using ContiguousIterableTypesT = std::tuple<uint64_t>;
299
300    /// Provide begin iterators for the various iterable types.
301    // * uint64_t
302    mlir::FailureOr<const uint64_t *>
303    try_value_begin_impl(OverloadToken<uint64_t>) const {
304      return getElements().begin();
305    }
306  }];
307  let assemblyFormat = "`<` $handle `>`";
308}
309
310// An array of nested attributes.
311def TestArrayOfUglyAttrs : ArrayOfAttr<Test_Dialect, "ArrayOfUglyAttrs",
312    "array_of_ugly", "TestAttrUglyAttr"> {
313  let assemblyFormat = "`[` (`]`) : ($value^ ` ` `]`)?";
314}
315
316// An array of integers.
317def TestArrayOfInts : ArrayOfAttr<Test_Dialect, "ArrayOfInts",
318    "array_of_ints", "int32_t">;
319
320// An array of enum attributes.
321def TestSimpleEnumAttr : EnumAttr<Test_Dialect, TestSimpleEnum, "simple_enum"> {
322  let assemblyFormat = "`` $value";
323}
324def TestArrayOfEnums : ArrayOfAttr<Test_Dialect, "ArrayOfEnums",
325    "array_of_enums", "SimpleEnumAttr">;
326
327// Test custom directive as optional group anchor.
328def TestCustomAnchor : Test_Attr<"TestCustomAnchor"> {
329  let parameters = (ins "int":$a, OptionalParameter<"std::optional<int>">:$b);
330  let mnemonic = "custom_anchor";
331  let assemblyFormat = "`<` $a (`>`) : (`,` custom<TrueFalse>($b)^ `>`)?";
332}
333
334def Test_IteratorTypeEnum
335    : EnumAttr<Test_Dialect, IteratorType, "iterator_type"> {
336  let assemblyFormat = "`<` $value `>`";
337}
338
339def Test_IteratorTypeArrayAttr
340    : TypedArrayAttrBase<Test_IteratorTypeEnum,
341  "Iterator type should be an enum.">;
342
343def TestParamCopyCount : AttrParameter<"CopyCount", "", "const CopyCount &"> {}
344
345// Test overridding attribute builders with a custom builder.
346def TestCopyCount : Test_Attr<"TestCopyCount"> {
347  let mnemonic = "copy_count";
348  let parameters = (ins TestParamCopyCount:$copy_count);
349  let assemblyFormat = "`<` $copy_count `>`";
350}
351
352def TestConditionalAliasAttr : Test_Attr<"TestConditionalAlias"> {
353  let mnemonic = "conditional_alias";
354  let parameters = (ins "mlir::StringAttr":$value);
355  let assemblyFormat = [{
356    `<` custom<ConditionalAlias>($value) `>`
357  }];
358}
359
360// Test AsmParser::parseFloat(const fltSemnatics&, APFloat&) API through the
361// custom parser and printer.
362def TestCustomFloatAttr : Test_Attr<"TestCustomFloat"> {
363  let mnemonic = "custom_float";
364  let parameters = (ins "mlir::StringAttr":$type_str, APFloatParameter<"">:$value);
365
366  let assemblyFormat = [{
367    `<` custom<CustomFloatAttr>($type_str, $value) `>`
368  }];
369}
370
371def NestedPolynomialAttr : Test_Attr<"NestedPolynomialAttr"> {
372  let mnemonic = "nested_polynomial";
373  let parameters = (ins Polynomial_IntPolynomialAttr:$poly);
374  let assemblyFormat = [{
375    `<` struct(params) `>`
376  }];
377}
378
379def NestedPolynomialAttr2 : Test_Attr<"NestedPolynomialAttr2"> {
380  let mnemonic = "nested_polynomial2";
381  let parameters = (ins OptionalParameter<"::mlir::polynomial::IntPolynomialAttr">:$poly);
382  let assemblyFormat = [{
383    `<` struct(params) `>`
384  }];
385}
386
387
388// Test custom location handling.
389def TestCustomLocationAttr : Test_LocAttr<"TestCustomLocation"> {
390  let mnemonic = "custom_location";
391  let parameters = (ins "mlir::StringAttr":$file, "unsigned":$line);
392
393  // Choose a silly separator token so we know it's hitting this code path
394  // and not another.
395  let assemblyFormat = "`<` $file `*` $line `>`";
396}
397
398#endif // TEST_ATTRDEFS
399