Index: mlir/include/mlir/IR/OpBase.td =================================================================== --- mlir/include/mlir/IR/OpBase.td +++ mlir/include/mlir/IR/OpBase.td @@ -243,6 +243,7 @@ // Format: // - `$_storage` is the storage type value. // - `$_writer` is a `DialectBytecodeWriter`. + // - `$_ctxt` is a `MLIRContext *`. code writeToMlirBytecode = [{ writeToMlirBytecode($_writer, $_storage) }]; @@ -252,6 +253,7 @@ // 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 @@ 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; Index: mlir/test/IR/properties-bytecode-roundtrip.mlir =================================================================== --- /dev/null +++ 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}> : () -> () Index: mlir/test/lib/Dialect/Test/TestOps.td =================================================================== --- mlir/test/lib/Dialect/Test/TestOps.td +++ mlir/test/lib/Dialect/Test/TestOps.td @@ -3360,6 +3360,17 @@ 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. Index: mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp =================================================================== --- mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp +++ mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp @@ -1360,7 +1360,8 @@ FmtContext fctx; fctx.addSubst("_reader", "reader") .addSubst("_writer", "writer") - .addSubst("_storage", propertyStorage); + .addSubst("_storage", propertyStorage) + .addSubst("_ctxt", "this->getContext()"); readPropertiesMethod << formatv( R"( {{