| //===-- TestInterfaces.td - Test dialect interfaces --------*- tablegen -*-===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #ifndef MLIR_TEST_DIALECT_TEST_INTERFACES | |
| #define MLIR_TEST_DIALECT_TEST_INTERFACES | |
| include "mlir/IR/OpBase.td" | |
| include "mlir/Interfaces/SideEffectInterfaceBase.td" | |
| // A set of type interfaces used to test interface inheritance. | |
| def TestBaseTypeInterfacePrintTypeA : TypeInterface<"TestBaseTypeInterfacePrintTypeA"> { | |
| let cppNamespace = "::test"; | |
| let methods = [ | |
| InterfaceMethod<"Prints the type name.", | |
| "void", "printTypeA", (ins "::mlir::Location":$loc), [{ | |
| emitRemark(loc) << $_type << " - TestA"; | |
| }] | |
| > | |
| ]; | |
| } | |
| def TestBaseTypeInterfacePrintTypeB | |
| : TypeInterface<"TestBaseTypeInterfacePrintTypeB", [TestBaseTypeInterfacePrintTypeA]> { | |
| let cppNamespace = "::test"; | |
| let methods = [ | |
| InterfaceMethod<"Prints the type name.", | |
| "void", "printTypeB", (ins "::mlir::Location":$loc), | |
| [{}], /*defaultImplementation=*/[{ | |
| emitRemark(loc) << $_type << " - TestB"; | |
| }] | |
| > | |
| ]; | |
| } | |
| // A type interface used to test the ODS generation of type interfaces. | |
| def TestTypeInterface | |
| : TypeInterface<"TestTypeInterface", [TestBaseTypeInterfacePrintTypeB]> { | |
| let cppNamespace = "::test"; | |
| let methods = [ | |
| InterfaceMethod<"Prints the type name.", | |
| "void", "printTypeC", (ins "::mlir::Location":$loc) | |
| >, | |
| // Check that we can have multiple method with the same name. | |
| InterfaceMethod<"Prints the type name, with a value prefixed.", | |
| "void", "printTypeC", (ins "::mlir::Location":$loc, "int":$value) | |
| >, | |
| InterfaceMethod<"Prints the type name, with a value prefixed.", | |
| "void", "printTypeC", (ins "::mlir::Location":$loc, "float":$value), | |
| [{}], /*defaultImplementation=*/[{ | |
| emitRemark(loc) << $_type << " - " << value << " - Float TestC"; | |
| }] | |
| >, | |
| // It should be possible to use the interface type name as result type | |
| // as well as in the implementation. | |
| InterfaceMethod<"Prints the type name and returns the type as interface.", | |
| "TestTypeInterface", "printTypeRet", (ins "::mlir::Location":$loc), | |
| [{}], /*defaultImplementation=*/[{ | |
| emitRemark(loc) << $_type << " - TestRet"; | |
| return $_type; | |
| }] | |
| >, | |
| ]; | |
| let extraClassDeclaration = [{ | |
| /// Prints the type name. | |
| void printTypeD(::mlir::Location loc) const { | |
| emitRemark(loc) << *this << " - TestD"; | |
| } | |
| }]; | |
| let extraTraitClassDeclaration = [{ | |
| /// Prints the type name. | |
| void printTypeE(::mlir::Location loc) const { | |
| emitRemark(loc) << $_type << " - TestE"; | |
| } | |
| }]; | |
| } | |
| def TestExternalTypeInterface : TypeInterface<"TestExternalTypeInterface"> { | |
| let cppNamespace = "::mlir"; | |
| let methods = [ | |
| InterfaceMethod<"Returns the bitwidth of the type plus 'arg'.", | |
| "unsigned", "getBitwidthPlusArg", (ins "unsigned":$arg)>, | |
| StaticInterfaceMethod<"Returns some value plus 'arg'.", | |
| "unsigned", "staticGetSomeValuePlusArg", (ins "unsigned":$arg)>, | |
| InterfaceMethod<"Returns the argument doubled.", | |
| "unsigned", "getBitwidthPlusDoubleArgument", (ins "unsigned":$arg), "", | |
| "return $_type.getIntOrFloatBitWidth() + 2 * arg;">, | |
| StaticInterfaceMethod<"Returns the argument.", | |
| "unsigned", "staticGetArgument", (ins "unsigned":$arg), "", | |
| "return arg;">, | |
| // Overloaded method (same name, different arity) used to check that an | |
| // external model can override an overloaded interface method by its source | |
| // name. Both overloads have a default so other models stay unaffected. | |
| InterfaceMethod<"Overloaded method, single argument.", | |
| "unsigned", "getOverloadedValue", (ins "unsigned":$arg), "", | |
| "return 1000 + arg;">, | |
| InterfaceMethod<"Overloaded method, two arguments.", | |
| "unsigned", "getOverloadedValue", (ins "unsigned":$arg, "unsigned":$arg2), | |
| "", "return 2000 + arg + arg2;">, | |
| InterfaceMethod<"Overloaded method, three arguments.", | |
| "unsigned", "getOverloadedValue", (ins "unsigned":$arg, "unsigned":$arg2, "unsigned":$arg3), | |
| "", "return 3000 + arg + arg2 + arg3;">, | |
| ]; | |
| } | |
| def TestExternalFallbackTypeInterface | |
| : TypeInterface<"TestExternalFallbackTypeInterface"> { | |
| let cppNamespace = "::mlir"; | |
| let methods = [ | |
| InterfaceMethod<"Returns the bitwidth of the given integer type.", | |
| "unsigned", "getBitwidth", (ins), "", "return $_type.getWidth();">, | |
| ]; | |
| } | |
| def TestExternalAttrInterface : AttrInterface<"TestExternalAttrInterface"> { | |
| let cppNamespace = "::mlir"; | |
| let methods = [ | |
| InterfaceMethod<"Gets the dialect pointer.", "const ::mlir::Dialect *", | |
| "getDialectPtr">, | |
| StaticInterfaceMethod<"Returns some number.", "int", "getSomeNumber">, | |
| ]; | |
| } | |
| def TestExternalOpInterface : OpInterface<"TestExternalOpInterface"> { | |
| let cppNamespace = "::mlir"; | |
| let methods = [ | |
| InterfaceMethod<"Returns the length of the operation name plus arg.", | |
| "unsigned", "getNameLengthPlusArg", (ins "unsigned":$arg)>, | |
| StaticInterfaceMethod< | |
| "Returns the length of the operation name plus arg twice.", "unsigned", | |
| "getNameLengthPlusArgTwice", (ins "unsigned":$arg)>, | |
| InterfaceMethod< | |
| "Returns the length of the product of the operation name and arg.", | |
| "unsigned", "getNameLengthTimesArg", (ins "unsigned":$arg), "", | |
| "return arg * $_op->getName().getStringRef().size();">, | |
| StaticInterfaceMethod<"Returns the length of the operation name minus arg.", | |
| "unsigned", "getNameLengthMinusArg", (ins "unsigned":$arg), "", | |
| "return ConcreteOp::getOperationName().size() - arg;">, | |
| ]; | |
| } | |
| def TestEffectOpInterface | |
| : EffectOpInterfaceBase<"TestEffectOpInterface", | |
| "::mlir::TestEffects::Effect"> { | |
| let cppNamespace = "::mlir"; | |
| } | |
| class TestEffect<string effectName> | |
| : SideEffect<TestEffectOpInterface, effectName, DefaultResource, 0, | |
| PartialEffect>; | |
| class TestEffects<list<TestEffect> effects = []> | |
| : SideEffectsTraitBase<TestEffectOpInterface, effects>; | |
| def TestConcreteEffect : TestEffect<"TestEffects::Concrete">; | |
| def TestOptionallyImplementedOpInterface | |
| : OpInterface<"TestOptionallyImplementedOpInterface"> { | |
| let cppNamespace = "::mlir"; | |
| let methods = [ | |
| InterfaceMethod<"", "bool", "getImplementsInterface", (ins)>, | |
| ]; | |
| let extraClassOf = [{ | |
| return $_op.getImplementsInterface(); | |
| }]; | |
| } | |
| def TestOptionallyImplementedAttrInterface | |
| : AttrInterface<"TestOptionallyImplementedAttrInterface"> { | |
| let cppNamespace = "::mlir"; | |
| let methods = [ | |
| InterfaceMethod<"", "bool", "getImplementsInterface", (ins)>, | |
| ]; | |
| let extraClassOf = [{ | |
| return $_attr.getImplementsInterface(); | |
| }]; | |
| } | |
| def TestOptionallyImplementedTypeInterface | |
| : TypeInterface<"TestOptionallyImplementedTypeInterface"> { | |
| let cppNamespace = "::mlir"; | |
| let methods = [ | |
| InterfaceMethod<"", "bool", "getImplementsInterface", (ins)>, | |
| ]; | |
| let extraClassOf = [{ | |
| return $_type.getImplementsInterface(); | |
| }]; | |
| } | |
| // Dummy type interface "A" that requires type interface "B" to be complete. | |
| def TestCyclicTypeInterfaceA : TypeInterface<"TestCyclicTypeInterfaceA"> { | |
| let cppNamespace = "::mlir"; | |
| let methods = [ | |
| InterfaceMethod<"", | |
| "::mlir::FailureOr<::mlir::TestCyclicTypeInterfaceB>", | |
| /*methodName=*/"returnB", | |
| (ins), | |
| /*methodBody=*/"", | |
| /*defaultImpl=*/"return mlir::failure();" | |
| >, | |
| ]; | |
| } | |
| // Dummy type interface "B" that requires type interface "A" to be complete. | |
| def TestCyclicTypeInterfaceB : TypeInterface<"TestCyclicTypeInterfaceB"> { | |
| let cppNamespace = "::mlir"; | |
| let methods = [ | |
| InterfaceMethod<"", | |
| "::mlir::FailureOr<::mlir::TestCyclicTypeInterfaceA>", | |
| /*methodName=*/"returnA", | |
| (ins), | |
| /*methodBody=*/"", | |
| /*defaultImpl=*/"return mlir::failure();" | |
| >, | |
| ]; | |
| } | |
| #endif // MLIR_TEST_DIALECT_TEST_INTERFACES |