Skip to content

Commit 3a70335

Browse files
[mlir][Transforms] Support rolling back properties in dialect conversion (#82474)
The dialect conversion rolls back in-place op modifications upon failure. Rolling back modifications of attributes is already supported, but there was no support for properties until now.
1 parent e214f00 commit 3a70335

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

mlir/lib/Transforms/Utils/DialectConversion.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1006,25 +1006,54 @@ class ModifyOperationRewrite : public OperationRewrite {
10061006
: OperationRewrite(Kind::ModifyOperation, rewriterImpl, op),
10071007
loc(op->getLoc()), attrs(op->getAttrDictionary()),
10081008
operands(op->operand_begin(), op->operand_end()),
1009-
successors(op->successor_begin(), op->successor_end()) {}
1009+
successors(op->successor_begin(), op->successor_end()) {
1010+
if (OpaqueProperties prop = op->getPropertiesStorage()) {
1011+
// Make a copy of the properties.
1012+
propertiesStorage = operator new(op->getPropertiesStorageSize());
1013+
OpaqueProperties propCopy(propertiesStorage);
1014+
op->getName().initOpProperties(propCopy, /*init=*/prop);
1015+
}
1016+
}
10101017

10111018
static bool classof(const IRRewrite *rewrite) {
10121019
return rewrite->getKind() == Kind::ModifyOperation;
10131020
}
10141021

1022+
~ModifyOperationRewrite() override {
1023+
assert(!propertiesStorage &&
1024+
"rewrite was neither committed nor rolled back");
1025+
}
1026+
1027+
void commit() override {
1028+
if (propertiesStorage) {
1029+
OpaqueProperties propCopy(propertiesStorage);
1030+
op->getName().destroyOpProperties(propCopy);
1031+
operator delete(propertiesStorage);
1032+
propertiesStorage = nullptr;
1033+
}
1034+
}
1035+
10151036
void rollback() override {
10161037
op->setLoc(loc);
10171038
op->setAttrs(attrs);
10181039
op->setOperands(operands);
10191040
for (const auto &it : llvm::enumerate(successors))
10201041
op->setSuccessor(it.value(), it.index());
1042+
if (propertiesStorage) {
1043+
OpaqueProperties propCopy(propertiesStorage);
1044+
op->copyProperties(propCopy);
1045+
op->getName().destroyOpProperties(propCopy);
1046+
operator delete(propertiesStorage);
1047+
propertiesStorage = nullptr;
1048+
}
10211049
}
10221050

10231051
private:
10241052
LocationAttr loc;
10251053
DictionaryAttr attrs;
10261054
SmallVector<Value, 8> operands;
10271055
SmallVector<Block *, 2> successors;
1056+
void *propertiesStorage = nullptr;
10281057
};
10291058
} // namespace
10301059

mlir/test/Transforms/test-legalizer.mlir

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,3 +334,15 @@ func.func @test_move_op_before_rollback() {
334334
}) : () -> ()
335335
"test.return"() : () -> ()
336336
}
337+
338+
// -----
339+
340+
// CHECK-LABEL: func @test_properties_rollback()
341+
func.func @test_properties_rollback() {
342+
// CHECK: test.with_properties <{a = 32 : i64,
343+
// expected-remark @below{{op 'test.with_properties' is not legalizable}}
344+
test.with_properties
345+
<{a = 32 : i64, array = array<i64: 1, 2, 3, 4>, b = "foo"}>
346+
{modify_inplace}
347+
"test.return"() : () -> ()
348+
}

mlir/test/lib/Dialect/Test/TestPatterns.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,21 @@ struct TestUndoBlockErase : public ConversionPattern {
807807
}
808808
};
809809

810+
/// A pattern that modifies a property in-place, but keeps the op illegal.
811+
struct TestUndoPropertiesModification : public ConversionPattern {
812+
TestUndoPropertiesModification(MLIRContext *ctx)
813+
: ConversionPattern("test.with_properties", /*benefit=*/1, ctx) {}
814+
LogicalResult
815+
matchAndRewrite(Operation *op, ArrayRef<Value> operands,
816+
ConversionPatternRewriter &rewriter) const final {
817+
if (!op->hasAttr("modify_inplace"))
818+
return failure();
819+
rewriter.modifyOpInPlace(
820+
op, [&]() { cast<TestOpWithProperties>(op).getProperties().setA(42); });
821+
return success();
822+
}
823+
};
824+
810825
//===----------------------------------------------------------------------===//
811826
// Type-Conversion Rewrite Testing
812827

@@ -1086,7 +1101,8 @@ struct TestLegalizePatternDriver
10861101
TestChangeProducerTypeF32ToInvalid, TestUpdateConsumerType,
10871102
TestNonRootReplacement, TestBoundedRecursiveRewrite,
10881103
TestNestedOpCreationUndoRewrite, TestReplaceEraseOp,
1089-
TestCreateUnregisteredOp, TestUndoMoveOpBefore>(&getContext());
1104+
TestCreateUnregisteredOp, TestUndoMoveOpBefore,
1105+
TestUndoPropertiesModification>(&getContext());
10901106
patterns.add<TestDropOpSignatureConversion>(&getContext(), converter);
10911107
mlir::populateAnyFunctionOpInterfaceTypeConversionPattern(patterns,
10921108
converter);

0 commit comments

Comments
 (0)