xref: /llvm-project/mlir/test/mlir-tblgen/op-interface.td (revision d01f559ce9eedc7ab036b5a9e3d03fc861bc6a5d)
1// RUN: mlir-tblgen -gen-op-interface-decls -I %S/../../include %s | FileCheck %s --check-prefix=DECL
2// RUN: mlir-tblgen -gen-op-interface-defs -I %S/../../include %s | FileCheck %s --check-prefix=DEF
3// RUN: mlir-tblgen -gen-op-decls -I %S/../../include %s | FileCheck %s --check-prefix=OP_DECL
4// RUN: mlir-tblgen -gen-op-interface-docs -I %S/../../include %s | FileCheck %s --check-prefix=DOCS
5
6include "mlir/IR/OpBase.td"
7
8def ExtraClassOfInterface : OpInterface<"ExtraClassOfInterface"> {
9  let extraClassOf = "return $_op->someOtherMethod();";
10}
11
12// DECL: class ExtraClassOfInterface
13// DECL:   static bool classof(::mlir::Operation * base) {
14// DECL-NEXT:     auto* interface = getInterfaceFor(base);
15// DECL-NEXT:     if (!interface)
16// DECL-NEXT:       return false;
17// DECL-NEXT:     ExtraClassOfInterface odsInterfaceInstance(base, interface);
18// DECL-NEXT:     return odsInterfaceInstance->someOtherMethod();
19// DECL-NEXT:   }
20
21def ExtraShardDeclsInterface : OpInterface<"ExtraShardDeclsInterface"> {
22  let extraSharedClassDeclaration = [{
23    bool sharedMethodDeclaration() {
24      return $_op.someOtherMethod();
25    }
26  }];
27}
28
29// DECL: class ExtraShardDeclsInterface
30// DECL:      bool sharedMethodDeclaration() {
31// DECL-NEXT:   return (*this).someOtherMethod();
32// DECL-NEXT: }
33
34// DECL: struct ExtraShardDeclsInterfaceTrait
35// DECL:      bool sharedMethodDeclaration() {
36// DECL-NEXT:   return (*static_cast<ConcreteOp *>(this)).someOtherMethod();
37// DECL-NEXT: }
38
39def TestInheritanceMultiBaseInterface : OpInterface<"TestInheritanceMultiBaseInterface"> {
40  let methods = [
41    InterfaceMethod<
42      /*desc=*/[{some function comment}],
43      /*retTy=*/"int",
44      /*methodName=*/"baz",
45      /*args=*/(ins "int":$input)
46    >
47  ];
48}
49
50def TestInheritanceBaseInterface : OpInterface<"TestInheritanceBaseInterface", [TestInheritanceMultiBaseInterface]> {
51  let methods = [
52    InterfaceMethod<
53      /*desc=*/[{some function comment}],
54      /*retTy=*/"int",
55      /*methodName=*/"foo",
56      /*args=*/(ins "int":$input)
57    >
58  ];
59}
60def TestInheritanceMiddleBaseInterface
61 : OpInterface<"TestInheritanceMiddleBaseInterface", [TestInheritanceBaseInterface]> {
62  let methods = [
63    InterfaceMethod<
64      /*desc=*/[{some function comment}],
65      /*retTy=*/"int",
66      /*methodName=*/"bar",
67      /*args=*/(ins "int":$input)
68    >
69  ];
70}
71def TestInheritanceZDerivedInterface
72  : OpInterface<"TestInheritanceZDerivedInterface", [TestInheritanceMiddleBaseInterface]>;
73
74// DECL: class TestInheritanceZDerivedInterface
75// DECL: struct Concept {
76// DECL:     const TestInheritanceMultiBaseInterface::Concept *implTestInheritanceMultiBaseInterface = nullptr;
77// DECL-NOT: const TestInheritanceMultiBaseInterface::Concept
78// DECL:     const TestInheritanceBaseInterface::Concept *implTestInheritanceBaseInterface = nullptr;
79// DECL:     const TestInheritanceMiddleBaseInterface::Concept *implTestInheritanceMiddleBaseInterface = nullptr;
80
81// DECL:     void initializeInterfaceConcept(::mlir::detail::InterfaceMap &interfaceMap) {
82// DECL:       implTestInheritanceBaseInterface = interfaceMap.lookup<TestInheritanceBaseInterface>();
83// DECL:       assert(implTestInheritanceBaseInterface && "`TestInheritanceZDerivedInterface` expected its base interface `TestInheritanceBaseInterface` to be registered");
84// DECL:       implTestInheritanceMiddleBaseInterface = interfaceMap.lookup<TestInheritanceMiddleBaseInterface>();
85// DECL:       assert(implTestInheritanceMiddleBaseInterface
86// DECL:     }
87
88// DECL:    //===----------------------------------------------------------------===//
89// DECL:    // Inherited from TestInheritanceBaseInterface
90// DECL:    //===----------------------------------------------------------------===//
91// DECL:    operator TestInheritanceBaseInterface () const {
92// DECL:      return TestInheritanceBaseInterface(*this, getImpl()->implTestInheritanceBaseInterface);
93// DECL:    }
94// DECL:    /// some function comment
95// DECL:    int foo(int input);
96
97// DECL:    //===----------------------------------------------------------------===//
98// DECL:    // Inherited from TestInheritanceMiddleBaseInterface
99// DECL:    //===----------------------------------------------------------------===//
100// DECL:    operator TestInheritanceMiddleBaseInterface () const {
101// DECL:      return TestInheritanceMiddleBaseInterface(*this, getImpl()->implTestInheritanceMiddleBaseInterface);
102// DECL:    }
103// DECL:    /// some function comment
104// DECL:    int bar(int input);
105
106// DEF: int TestInheritanceZDerivedInterface::foo(int input) {
107// DEF-NEXT:    getImpl()->implTestInheritanceBaseInterface->foo(getImpl()->implTestInheritanceBaseInterface, getOperation(), input);
108
109// DEF: int TestInheritanceZDerivedInterface::bar(int input) {
110// DEF-NEXT:   return getImpl()->implTestInheritanceMiddleBaseInterface->bar(getImpl()->implTestInheritanceMiddleBaseInterface, getOperation(), input);
111
112def TestOpInterface : OpInterface<"TestOpInterface"> {
113  let description = [{some op interface description}];
114
115  let methods = [
116    InterfaceMethod<
117      /*desc=*/[{some function comment}],
118      /*retTy=*/"int",
119      /*methodName=*/"foo",
120      /*args=*/(ins "int":$input)
121    >,
122    InterfaceMethod<
123      /*desc=*/[{some function comment}],
124      /*retTy=*/"int",
125      /*methodName=*/"body_foo",
126      /*args=*/(ins "int":$input),
127      /*body=*/[{ return 0; }]
128    >,
129    InterfaceMethod<
130      /*desc=*/[{some function comment}],
131      /*retTy=*/"int",
132      /*methodName=*/"default_foo",
133      /*args=*/(ins "int":$input),
134      /*body=*/[{}],
135      /*defaultBody=*/[{ return 0; }]
136    >,
137  ];
138}
139
140def TestOpInterfaceVerify : OpInterface<"TestOpInterfaceVerify"> {
141  let verify = [{
142    return foo();
143  }];
144}
145
146def TestOpInterfaceVerifyRegion : OpInterface<"TestOpInterfaceVerifyRegion"> {
147  let verify = [{
148    return foo();
149  }];
150  let verifyWithRegions = 1;
151}
152
153// Define Ops with TestOpInterface and
154// DeclareOpInterfaceMethods<TestOpInterface> traits to check that there
155// are not duplicated C++ classes generated.
156def TestDialect : Dialect {
157  let name = "test";
158}
159
160def OpInterfaceOp : Op<TestDialect, "op_interface_op", [TestOpInterface]>;
161
162def OpInterfaceInterfacesOp : Op<TestDialect, "op_inherit_interface_op", [TestInheritanceZDerivedInterface]>;
163
164def DeclareMethodsOp : Op<TestDialect, "declare_methods_op",
165                          [DeclareOpInterfaceMethods<TestOpInterface>]>;
166
167def DeclareMethodsWithDefaultOp : Op<TestDialect, "declare_methods_op",
168      [DeclareOpInterfaceMethods<TestOpInterface, ["default_foo"]>]>;
169
170// DECL-LABEL: TestOpInterfaceInterfaceTraits
171// DECL: class TestOpInterface : public ::mlir::OpInterface<TestOpInterface, detail::TestOpInterfaceInterfaceTraits>
172
173// DECL: /// some function comment
174// DECL: int foo(int input);
175
176// DECL-LABEL: struct TestOpInterfaceVerifyTrait
177// DECL: verifyTrait
178
179// DECL-LABEL: struct TestOpInterfaceVerifyRegionTrait
180// DECL: verifyRegionTrait
181
182// Method implementations come last, after all class definitions.
183// DECL: template<typename ConcreteOp>
184// DECL: int detail::TestOpInterfaceInterfaceTraits::Model<ConcreteOp>::foo
185
186// OP_DECL-LABEL: class DeclareMethodsOp : public
187// OP_DECL: int foo(int input);
188// OP_DECL-NOT: int default_foo(int input);
189
190// OP_DECL-LABEL: class DeclareMethodsWithDefaultOp : public
191// OP_DECL: int foo(int input);
192// OP_DECL: int default_foo(int input);
193
194// OP_DECL: class OpInterfaceInterfacesOp :
195// OP_DECL-SAME: TestInheritanceBaseInterface::Trait, TestInheritanceMiddleBaseInterface::Trait, TestInheritanceZDerivedInterface::Trait
196
197// DOCS-LABEL: {{^}}## TestOpInterface (`TestOpInterface`)
198// DOCS: some op interface description
199
200// DOCS: {{^}}### Methods:
201
202// DOCS: {{^}}#### `foo`
203// DOCS: some function comment
204
205// DOCS: {{^}}#### `body_foo`
206// DOCS: some function comment
207
208// DOCS: {{^}}#### `default_foo`
209// DOCS: some function comment
210