From f117bbca041c9b0c59002835d939e1bc9e76cf39 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Markus=20B=C3=B6ck?= Date: Fri, 21 Jul 2023 07:40:10 +0200 Subject: [PATCH] [mlir] Add opt-in default property bytecode read and write implementation Using properties currently requires at the very least implementing four methods/code snippets: * `convertToAttribute` * `convertFromAttribute` * `writeToMlirBytecode` * `readFromMlirBytecode` This makes replacing attributes with properties harder than it has to be: Attributes by default do not require immediately defining custom bytecode encoding. This patch therefore adds opt-in implementations of `writeToMlirBytecode` and `readFromMlirBytecode` that work with the default implementations of `convertToAttribute` and `convertFromAttribute`. They are provided by `defvar`s in `OpBase.td` and can be used by adding: ``` let writeToMlirBytecode = writeMlirBytecodeWithConvertToAttribute; let readFromMlirBytecode = readMlirBytecodeUsingConvertFromAttribute; ``` to ones TableGen definition. While this bytecode encoding is almost certainly not ideal for a given property, it allows more incremental use of properties and getting something sane working before optimizing the bytecode format. Differential Revision: https://reviews.llvm.org/D155286 --- mlir/include/mlir/IR/OpBase.td | 34 +++++++++++++++++++++++++ mlir/test/IR/properties-bytecode-roundtrip.mlir | 5 ++++ mlir/test/lib/Dialect/Test/TestOps.td | 11 ++++++++ mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp | 3 ++- 4 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 mlir/test/IR/properties-bytecode-roundtrip.mlir diff --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td index 28a1716..940588b 100644 --- a/mlir/include/mlir/IR/OpBase.td +++ b/mlir/include/mlir/IR/OpBase.td @@ -243,6 +243,7 @@ class Property { // Format: // - `$_storage` is the storage type value. // - `$_writer` is a `DialectBytecodeWriter`. + // - `$_ctxt` is a `MLIRContext *`. code writeToMlirBytecode = [{ writeToMlirBytecode($_writer, $_storage) }]; @@ -252,6 +253,7 @@ class Property { // Format: // - `$_storage` is the storage type value. // - `$_reader` is a `DialectBytecodeReader`. + // - `$_ctxt` is a `MLIRContext *`. code readFromMlirBytecode = [{ if (::mlir::failed(readFromMlirBytecode($_reader, $_storage))) return ::mlir::failure(); @@ -261,6 +263,38 @@ class Property { string defaultValue = ?; } +/// Implementation of the Property class's `readFromMlirBytecode` field using +/// the default `convertFromAttribute` implementation. +/// Users not wanting to implement their own `readFromMlirBytecode` and +/// `writeToMlirBytecode` implementations can opt into using this implementation +/// by writing: +/// +/// let writeToMlirBytecode = writeMlirBytecodeWithConvertToAttribute; +/// let readFromMlirBytecode = readMlirBytecodeUsingConvertFromAttribute; +/// +/// in their property definition. +/// Serialization and deserialization is performed using the attributes +/// returned by `convertFromAttribute` and `convertToAttribute`. +/// +/// WARNING: This implementation creates a less than optimal encoding. +/// Users caring about optimal encoding should not use this implementation and +/// implement `readFromMlirBytecode` and `writeToMlirBytecode` themselves. +defvar readMlirBytecodeUsingConvertFromAttribute = [{ + ::mlir::Attribute attr; + if (::mlir::failed($_reader.readAttribute(attr))) + return ::mlir::failure(); + if (::mlir::failed(convertFromAttribute($_storage, attr, nullptr))) + return ::mlir::failure(); +}]; + +/// Implementation of the Property class's `writeToMlirBytecode` field using +/// the default `convertToAttribute` implementation. +/// See description of `readMlirBytecodeUsingConvertFromAttribute` above for +/// details. +defvar writeMlirBytecodeWithConvertToAttribute = [{ + $_writer.writeAttribute(convertToAttribute($_ctxt, $_storage)) +}]; + // Subclass for constraints on an attribute. class AttrConstraint : Constraint; diff --git a/mlir/test/IR/properties-bytecode-roundtrip.mlir b/mlir/test/IR/properties-bytecode-roundtrip.mlir new file mode 100644 index 0000000..b4c3643 --- /dev/null +++ b/mlir/test/IR/properties-bytecode-roundtrip.mlir @@ -0,0 +1,5 @@ +// RUN: mlir-opt -emit-bytecode %s | mlir-opt | FileCheck %s + +// CHECK-LABEL: "test.using_int_property_with_worse_bytecode" +// CHECK-SAME: value = 3 +"test.using_int_property_with_worse_bytecode"() <{value = 3}> : () -> () diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td index 389fac6..6cb4745 100644 --- a/mlir/test/lib/Dialect/Test/TestOps.td +++ b/mlir/test/lib/Dialect/Test/TestOps.td @@ -3367,6 +3367,17 @@ def TestOpUsingPropertyRefInCustom : TEST_Op<"using_property_ref_in_custom"> { let arguments = (ins IntProperty<"int64_t">:$first, IntProperty<"int64_t">:$second); } +def IntPropertyWithWorseBytecode : Property<"int64_t"> { + let writeToMlirBytecode = writeMlirBytecodeWithConvertToAttribute; + + let readFromMlirBytecode = readMlirBytecodeUsingConvertFromAttribute; +} + +def TestOpUsingIntPropertyWithWorseBytecode + : TEST_Op<"using_int_property_with_worse_bytecode"> { + let arguments = (ins IntPropertyWithWorseBytecode:$value); +} + // Op with a properties struct defined out-of-line. The struct has custom // printer/parser. diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp index a935e21..c069e7c 100644 --- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp +++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp @@ -1360,7 +1360,8 @@ void OpEmitter::genPropertiesSupport() { FmtContext fctx; fctx.addSubst("_reader", "reader") .addSubst("_writer", "writer") - .addSubst("_storage", propertyStorage); + .addSubst("_storage", propertyStorage) + .addSubst("_ctxt", "this->getContext()"); readPropertiesMethod << formatv( R"( {{ -- 2.7.4