Skip to content

Commit 631e291

Browse files
author
Matteo Franciolini
authored
[mlir][bytecode] Fix D155919 and enable backward-compatibility and back-deployment between version 5 and version 6 of the bytecode encoding (#70498)
Before D155919, when a dialect was leveraging properties to store attributes with `usePropertiesForAttributes`, the operand segment sizes attribute was emitted in the property section in sorted order together with all the other attributes of an op. After D155919, version 5 of the bytecode was emitting and parsing operand segment sizes after all the properties of an op, breaking backward compatibility and back deployment. This patch fixes the emission ordering and allows to parse bytecode files emitted before (D155919) with version 5 of MLIR bytecode. The patch also enables to emit correctly version 5 of MLIR bytecode.
1 parent f70e39e commit 631e291

File tree

1 file changed

+81
-24
lines changed

1 file changed

+81
-24
lines changed

mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp

Lines changed: 81 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -156,26 +156,36 @@ static const char *const valueRangeReturnCode = R"(
156156
)";
157157

158158
/// Read operand/result segment_size from bytecode.
159-
static const char *const readBytecodeSegmentSize = R"(
160-
if ($_reader.getBytecodeVersion() < /*kNativePropertiesODSSegmentSize=*/6) {
161-
::mlir::DenseI32ArrayAttr attr;
162-
if (::mlir::failed($_reader.readAttribute(attr))) return ::mlir::failure();
163-
if (attr.size() > static_cast<int64_t>(sizeof($_storage) / sizeof(int32_t))) {
164-
$_reader.emitError("size mismatch for operand/result_segment_size");
165-
return ::mlir::failure();
159+
static const char *const readBytecodeSegmentSizeNative = R"(
160+
if ($_reader.getBytecodeVersion() >= /*kNativePropertiesODSSegmentSize=*/6)
161+
return $_reader.readSparseArray(::llvm::MutableArrayRef($_storage));
162+
)";
163+
164+
static const char *const readBytecodeSegmentSizeLegacy = R"(
165+
if ($_reader.getBytecodeVersion() < /*kNativePropertiesODSSegmentSize=*/6) {
166+
auto &$_storage = prop.$_propName;
167+
::mlir::DenseI32ArrayAttr attr;
168+
if (::mlir::failed($_reader.readAttribute(attr))) return ::mlir::failure();
169+
if (attr.size() > static_cast<int64_t>(sizeof($_storage) / sizeof(int32_t))) {
170+
$_reader.emitError("size mismatch for operand/result_segment_size");
171+
return ::mlir::failure();
172+
}
173+
::llvm::copy(::llvm::ArrayRef<int32_t>(attr), $_storage.begin());
166174
}
167-
::llvm::copy(::llvm::ArrayRef<int32_t>(attr), $_storage.begin());
168-
} else {
169-
return $_reader.readSparseArray(::llvm::MutableArrayRef($_storage));
170-
}
171175
)";
172176

173177
/// Write operand/result segment_size to bytecode.
174-
static const char *const writeBytecodeSegmentSize = R"(
175-
if ($_writer.getBytecodeVersion() < /*kNativePropertiesODSSegmentSize=*/6)
176-
$_writer.writeAttribute(::mlir::DenseI32ArrayAttr::get(getContext(), $_storage));
177-
else
178-
$_writer.writeSparseArray(::llvm::ArrayRef($_storage));
178+
static const char *const writeBytecodeSegmentSizeNative = R"(
179+
if ($_writer.getBytecodeVersion() >= /*kNativePropertiesODSSegmentSize=*/6)
180+
$_writer.writeSparseArray(::llvm::ArrayRef($_storage));
181+
)";
182+
183+
/// Write operand/result segment_size to bytecode.
184+
static const char *const writeBytecodeSegmentSizeLegacy = R"(
185+
if ($_writer.getBytecodeVersion() < /*kNativePropertiesODSSegmentSize=*/6) {
186+
auto &$_storage = prop.$_propName;
187+
$_writer.writeAttribute(::mlir::DenseI32ArrayAttr::get($_ctxt, $_storage));
188+
}
179189
)";
180190

181191
/// A header for indicating code sections.
@@ -389,6 +399,14 @@ class OpOrAdaptorHelper {
389399
return resultSegmentsSize;
390400
}
391401

402+
uint32_t getOperandSegmentSizesLegacyIndex() {
403+
return operandSegmentSizesLegacyIndex;
404+
}
405+
406+
uint32_t getResultSegmentSizesLegacyIndex() {
407+
return resultSegmentSizesLegacyIndex;
408+
}
409+
392410
private:
393411
// Compute the attribute metadata.
394412
void computeAttrMetadata();
@@ -407,6 +425,12 @@ class OpOrAdaptorHelper {
407425
std::optional<NamedProperty> resultSegmentsSize;
408426
std::string resultSegmentsSizeStorage;
409427

428+
// Indices to store the position in the emission order of the operand/result
429+
// segment sizes attribute if emitted as part of the properties for legacy
430+
// bytecode encodings, i.e. versions less than 6.
431+
uint32_t operandSegmentSizesLegacyIndex = 0;
432+
uint32_t resultSegmentSizesLegacyIndex = 0;
433+
410434
// The number of required attributes.
411435
unsigned numRequired;
412436
};
@@ -435,8 +459,8 @@ void OpOrAdaptorHelper::computeAttrMetadata() {
435459
"::mlir::DenseI32ArrayAttr::get($_ctxt, $_storage)",
436460
/*convertFromAttributeCall=*/
437461
"return convertFromAttribute($_storage, $_attr, $_diag);",
438-
/*readFromMlirBytecodeCall=*/readBytecodeSegmentSize,
439-
/*writeToMlirBytecodeCall=*/writeBytecodeSegmentSize,
462+
/*readFromMlirBytecodeCall=*/readBytecodeSegmentSizeNative,
463+
/*writeToMlirBytecodeCall=*/writeBytecodeSegmentSizeNative,
440464
/*hashPropertyCall=*/
441465
"::llvm::hash_combine_range(std::begin($_storage), "
442466
"std::end($_storage));",
@@ -478,6 +502,21 @@ void OpOrAdaptorHelper::computeAttrMetadata() {
478502
return lhs.attrName < rhs.attrName;
479503
});
480504

505+
// Store the position of the legacy operand_segment_sizes /
506+
// result_segment_sizes so we can emit a backward compatible property readers
507+
// and writers.
508+
StringRef legacyOperandSegmentSizeName =
509+
StringLiteral("operand_segment_sizes");
510+
StringRef legacyResultSegmentSizeName = StringLiteral("result_segment_sizes");
511+
operandSegmentSizesLegacyIndex = 0;
512+
resultSegmentSizesLegacyIndex = 0;
513+
for (auto item : sortedAttrMetadata) {
514+
if (item.attrName < legacyOperandSegmentSizeName)
515+
++operandSegmentSizesLegacyIndex;
516+
if (item.attrName < legacyResultSegmentSizeName)
517+
++resultSegmentSizesLegacyIndex;
518+
}
519+
481520
// Compute the subrange bounds for each attribute.
482521
numRequired = 0;
483522
for (AttributeMetadata &attr : sortedAttrMetadata) {
@@ -1580,15 +1619,33 @@ void OpEmitter::genPropertiesSupportForBytecode(
15801619
readPropertiesMethod
15811620
<< " auto &prop = state.getOrAddProperties<Properties>(); (void)prop;";
15821621
writePropertiesMethod << " auto &prop = getProperties(); (void)prop;\n";
1583-
for (const auto &attrOrProp : attrOrProperties) {
1622+
for (const auto &item : llvm::enumerate(attrOrProperties)) {
1623+
auto &attrOrProp = item.value();
1624+
FmtContext fctx;
1625+
fctx.addSubst("_reader", "reader")
1626+
.addSubst("_writer", "writer")
1627+
.addSubst("_storage", propertyStorage)
1628+
.addSubst("_ctxt", "this->getContext()");
1629+
// If the op emits operand/result segment sizes as a property, emit the
1630+
// legacy reader/writer in the appropriate order to allow backward
1631+
// compatibility and back deployment.
1632+
if (emitHelper.getOperandSegmentsSize().has_value() &&
1633+
item.index() == emitHelper.getOperandSegmentSizesLegacyIndex()) {
1634+
FmtContext fmtCtxt(fctx);
1635+
fmtCtxt.addSubst("_propName", operandSegmentAttrName);
1636+
readPropertiesMethod << tgfmt(readBytecodeSegmentSizeLegacy, &fmtCtxt);
1637+
writePropertiesMethod << tgfmt(writeBytecodeSegmentSizeLegacy, &fmtCtxt);
1638+
}
1639+
if (emitHelper.getResultSegmentsSize().has_value() &&
1640+
item.index() == emitHelper.getResultSegmentSizesLegacyIndex()) {
1641+
FmtContext fmtCtxt(fctx);
1642+
fmtCtxt.addSubst("_propName", resultSegmentAttrName);
1643+
readPropertiesMethod << tgfmt(readBytecodeSegmentSizeLegacy, &fmtCtxt);
1644+
writePropertiesMethod << tgfmt(writeBytecodeSegmentSizeLegacy, &fmtCtxt);
1645+
}
15841646
if (const auto *namedProperty =
15851647
attrOrProp.dyn_cast<const NamedProperty *>()) {
15861648
StringRef name = namedProperty->name;
1587-
FmtContext fctx;
1588-
fctx.addSubst("_reader", "reader")
1589-
.addSubst("_writer", "writer")
1590-
.addSubst("_storage", propertyStorage)
1591-
.addSubst("_ctxt", "this->getContext()");
15921649
readPropertiesMethod << formatv(
15931650
R"(
15941651
{{

0 commit comments

Comments
 (0)