llvm/mlir/test/mlir-tblgen/op-interface.td
River Riddle a60e83fe7c [mlir][Interfaces] Add a extraSharedClassDeclaration field
This field allows for defining a code block that is placed in both the interface
and trait declarations. This is very useful when defining a set of utilities to
expose on both the Interface class and the derived attribute/operation/type.

In non-static methods, `$_attr`/`$_op`/`$_type` (depending on the type of
interface) may be used to refer to an instance of the IR entity. In the interface
declaration, this is an instance of the interface class. In the trait declaration,
this is an instance of the concrete entity class (e.g. `IntegerAttr`, `FuncOp`, etc.).

Differential Revision: https://reviews.llvm.org/D116961
2022-01-12 14:12:08 -08:00

75 lines
2.4 KiB
TableGen

// RUN: mlir-tblgen -gen-op-interface-decls -I %S/../../include %s | FileCheck %s --check-prefix=DECL
// RUN: mlir-tblgen -gen-op-decls -I %S/../../include %s | FileCheck %s --check-prefix=OP_DECL
include "mlir/IR/OpBase.td"
def ExtraShardDeclsInterface : OpInterface<"ExtraShardDeclsInterface"> {
let extraSharedClassDeclaration = [{
bool sharedMethodDeclaration() {
return $_op.someOtherMethod();
}
}];
}
// DECL: class ExtraShardDeclsInterface
// DECL: bool sharedMethodDeclaration() {
// DECL-NEXT: return (*this).someOtherMethod();
// DECL-NEXT: }
// DECL: struct ExtraShardDeclsInterfaceTrait
// DECL: bool sharedMethodDeclaration() {
// DECL-NEXT: return (*static_cast<ConcreteOp *>(this)).someOtherMethod();
// DECL-NEXT: }
def TestOpInterface : OpInterface<"TestOpInterface"> {
let description = [{some op interface description}];
let methods = [
InterfaceMethod<
/*desc=*/[{some function comment}],
/*retTy=*/"int",
/*methodName=*/"foo",
/*args=*/(ins "int":$input)
>,
InterfaceMethod<
/*desc=*/[{some function comment}],
/*retTy=*/"int",
/*methodName=*/"default_foo",
/*args=*/(ins "int":$input),
/*body=*/[{}],
/*defaultBody=*/[{ return 0; }]
>,
];
}
// Define Ops with TestOpInterface and
// DeclareOpInterfaceMethods<TestOpInterface> traits to check that there
// are not duplicated C++ classes generated.
def TestDialect : Dialect {
let name = "test";
}
def OpInterfaceOp : Op<TestDialect, "op_interface_op", [TestOpInterface]>;
def DeclareMethodsOp : Op<TestDialect, "declare_methods_op",
[DeclareOpInterfaceMethods<TestOpInterface>]>;
def DeclareMethodsWithDefaultOp : Op<TestDialect, "declare_methods_op",
[DeclareOpInterfaceMethods<TestOpInterface, ["default_foo"]>]>;
// DECL-LABEL: TestOpInterfaceInterfaceTraits
// DECL: class TestOpInterface : public ::mlir::OpInterface<TestOpInterface, detail::TestOpInterfaceInterfaceTraits>
// DECL: int foo(int input);
// DECL: template<typename ConcreteOp>
// DECL: int detail::TestOpInterfaceInterfaceTraits::Model<ConcreteOp>::foo
// OP_DECL-LABEL: class DeclareMethodsOp : public
// OP_DECL: int foo(int input);
// OP_DECL-NOT: int default_foo(int input);
// OP_DECL-LABEL: class DeclareMethodsWithDefaultOp : public
// OP_DECL: int foo(int input);
// OP_DECL: int default_foo(int input);