mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 01:58:44 +08:00
[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.
This commit is contained in:
committed by
GitHub
parent
e214f004cb
commit
3a70335bae
@@ -1006,18 +1006,46 @@ public:
|
||||
: OperationRewrite(Kind::ModifyOperation, rewriterImpl, op),
|
||||
loc(op->getLoc()), attrs(op->getAttrDictionary()),
|
||||
operands(op->operand_begin(), op->operand_end()),
|
||||
successors(op->successor_begin(), op->successor_end()) {}
|
||||
successors(op->successor_begin(), op->successor_end()) {
|
||||
if (OpaqueProperties prop = op->getPropertiesStorage()) {
|
||||
// Make a copy of the properties.
|
||||
propertiesStorage = operator new(op->getPropertiesStorageSize());
|
||||
OpaqueProperties propCopy(propertiesStorage);
|
||||
op->getName().initOpProperties(propCopy, /*init=*/prop);
|
||||
}
|
||||
}
|
||||
|
||||
static bool classof(const IRRewrite *rewrite) {
|
||||
return rewrite->getKind() == Kind::ModifyOperation;
|
||||
}
|
||||
|
||||
~ModifyOperationRewrite() override {
|
||||
assert(!propertiesStorage &&
|
||||
"rewrite was neither committed nor rolled back");
|
||||
}
|
||||
|
||||
void commit() override {
|
||||
if (propertiesStorage) {
|
||||
OpaqueProperties propCopy(propertiesStorage);
|
||||
op->getName().destroyOpProperties(propCopy);
|
||||
operator delete(propertiesStorage);
|
||||
propertiesStorage = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void rollback() override {
|
||||
op->setLoc(loc);
|
||||
op->setAttrs(attrs);
|
||||
op->setOperands(operands);
|
||||
for (const auto &it : llvm::enumerate(successors))
|
||||
op->setSuccessor(it.value(), it.index());
|
||||
if (propertiesStorage) {
|
||||
OpaqueProperties propCopy(propertiesStorage);
|
||||
op->copyProperties(propCopy);
|
||||
op->getName().destroyOpProperties(propCopy);
|
||||
operator delete(propertiesStorage);
|
||||
propertiesStorage = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -1025,6 +1053,7 @@ private:
|
||||
DictionaryAttr attrs;
|
||||
SmallVector<Value, 8> operands;
|
||||
SmallVector<Block *, 2> successors;
|
||||
void *propertiesStorage = nullptr;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -334,3 +334,15 @@ func.func @test_move_op_before_rollback() {
|
||||
}) : () -> ()
|
||||
"test.return"() : () -> ()
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
// CHECK-LABEL: func @test_properties_rollback()
|
||||
func.func @test_properties_rollback() {
|
||||
// CHECK: test.with_properties <{a = 32 : i64,
|
||||
// expected-remark @below{{op 'test.with_properties' is not legalizable}}
|
||||
test.with_properties
|
||||
<{a = 32 : i64, array = array<i64: 1, 2, 3, 4>, b = "foo"}>
|
||||
{modify_inplace}
|
||||
"test.return"() : () -> ()
|
||||
}
|
||||
|
||||
@@ -807,6 +807,21 @@ struct TestUndoBlockErase : public ConversionPattern {
|
||||
}
|
||||
};
|
||||
|
||||
/// A pattern that modifies a property in-place, but keeps the op illegal.
|
||||
struct TestUndoPropertiesModification : public ConversionPattern {
|
||||
TestUndoPropertiesModification(MLIRContext *ctx)
|
||||
: ConversionPattern("test.with_properties", /*benefit=*/1, ctx) {}
|
||||
LogicalResult
|
||||
matchAndRewrite(Operation *op, ArrayRef<Value> operands,
|
||||
ConversionPatternRewriter &rewriter) const final {
|
||||
if (!op->hasAttr("modify_inplace"))
|
||||
return failure();
|
||||
rewriter.modifyOpInPlace(
|
||||
op, [&]() { cast<TestOpWithProperties>(op).getProperties().setA(42); });
|
||||
return success();
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Type-Conversion Rewrite Testing
|
||||
|
||||
@@ -1086,7 +1101,8 @@ struct TestLegalizePatternDriver
|
||||
TestChangeProducerTypeF32ToInvalid, TestUpdateConsumerType,
|
||||
TestNonRootReplacement, TestBoundedRecursiveRewrite,
|
||||
TestNestedOpCreationUndoRewrite, TestReplaceEraseOp,
|
||||
TestCreateUnregisteredOp, TestUndoMoveOpBefore>(&getContext());
|
||||
TestCreateUnregisteredOp, TestUndoMoveOpBefore,
|
||||
TestUndoPropertiesModification>(&getContext());
|
||||
patterns.add<TestDropOpSignatureConversion>(&getContext(), converter);
|
||||
mlir::populateAnyFunctionOpInterfaceTypeConversionPattern(patterns,
|
||||
converter);
|
||||
|
||||
Reference in New Issue
Block a user