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