[Mlir-commits] [mlir] 5030dea - [mlir][Transforms] Dialect conversion: No rollback during analysis conversion (#106414)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Oct 4 00:34:13 PDT 2024
Author: Matthias Springer
Date: 2024-10-04T09:34:08+02:00
New Revision: 5030deadeffe83b68ff209e27d4ec7f1dbaff01a
URL: https://github.com/llvm/llvm-project/commit/5030deadeffe83b68ff209e27d4ec7f1dbaff01a
DIFF: https://github.com/llvm/llvm-project/commit/5030deadeffe83b68ff209e27d4ec7f1dbaff01a.diff
LOG: [mlir][Transforms] Dialect conversion: No rollback during analysis conversion (#106414)
This commit changes the implementation of analysis conversions, so that
no rollback is needed at the end of the analysis. Instead, the dialect conversion is run on a clone of the IR.
The purpose of this commit is to reduce the number of rollbacks in the
dialect conversion framework. (Long term goal: Remove rollback
functionality entirely.)
Added:
Modified:
mlir/lib/Transforms/Utils/DialectConversion.cpp
Removed:
################################################################################
diff --git a/mlir/lib/Transforms/Utils/DialectConversion.cpp b/mlir/lib/Transforms/Utils/DialectConversion.cpp
index a5872cd3d30696..97dd3ab1f48293 100644
--- a/mlir/lib/Transforms/Utils/DialectConversion.cpp
+++ b/mlir/lib/Transforms/Utils/DialectConversion.cpp
@@ -2466,13 +2466,8 @@ LogicalResult OperationConverter::convertOperations(ArrayRef<Operation *> ops) {
// legalized.
finalize(rewriter);
- // After a successful conversion, apply rewrites if this is not an analysis
- // conversion.
- if (mode == OpConversionMode::Analysis) {
- rewriterImpl.undoRewrites();
- } else {
- rewriterImpl.applyRewrites();
- }
+ // After a successful conversion, apply rewrites.
+ rewriterImpl.applyRewrites();
// Gather all unresolved materializations.
SmallVector<UnrealizedConversionCastOp> allCastOps;
@@ -3215,13 +3210,78 @@ LogicalResult mlir::applyFullConversion(Operation *op,
//===----------------------------------------------------------------------===//
// Analysis Conversion
+/// Find a common IsolatedFromAbove ancestor of the given ops. If at least one
+/// op is a top-level module op (which is expected to be isolated from above),
+/// return that op.
+static Operation *findCommonAncestor(ArrayRef<Operation *> ops) {
+ // Check if there is a top-level operation within `ops`. If so, return that
+ // op.
+ for (Operation *op : ops) {
+ if (!op->getParentOp()) {
+#ifndef NDEBUG
+ assert(op->hasTrait<OpTrait::IsIsolatedFromAbove>() &&
+ "expected top-level op to be isolated from above");
+ for (Operation *other : ops)
+ assert(op->isAncestor(other) &&
+ "expected ops to have a common ancestor");
+#endif // NDEBUG
+ return op;
+ }
+ }
+
+ // No top-level op. Find a common ancestor.
+ Operation *commonAncestor =
+ ops.front()->getParentWithTrait<OpTrait::IsIsolatedFromAbove>();
+ for (Operation *op : ops.drop_front()) {
+ while (!commonAncestor->isProperAncestor(op)) {
+ commonAncestor =
+ commonAncestor->getParentWithTrait<OpTrait::IsIsolatedFromAbove>();
+ assert(commonAncestor &&
+ "expected to find a common isolated from above ancestor");
+ }
+ }
+
+ return commonAncestor;
+}
+
LogicalResult mlir::applyAnalysisConversion(
ArrayRef<Operation *> ops, ConversionTarget &target,
const FrozenRewritePatternSet &patterns, ConversionConfig config) {
+#ifndef NDEBUG
+ if (config.legalizableOps)
+ assert(config.legalizableOps->empty() && "expected empty set");
+#endif // NDEBUG
+
+ // Clone closted common ancestor that is isolated from above.
+ Operation *commonAncestor = findCommonAncestor(ops);
+ IRMapping mapping;
+ Operation *clonedAncestor = commonAncestor->clone(mapping);
+ // Compute inverse IR mapping.
+ DenseMap<Operation *, Operation *> inverseOperationMap;
+ for (auto &it : mapping.getOperationMap())
+ inverseOperationMap[it.second] = it.first;
+
+ // Convert the cloned operations. The original IR will remain unchanged.
+ SmallVector<Operation *> opsToConvert = llvm::map_to_vector(
+ ops, [&](Operation *op) { return mapping.lookup(op); });
OperationConverter opConverter(target, patterns, config,
OpConversionMode::Analysis);
- return opConverter.convertOperations(ops);
+ LogicalResult status = opConverter.convertOperations(opsToConvert);
+
+ // Remap `legalizableOps`, so that they point to the original ops and not the
+ // cloned ops.
+ if (config.legalizableOps) {
+ DenseSet<Operation *> originalLegalizableOps;
+ for (Operation *op : *config.legalizableOps)
+ originalLegalizableOps.insert(inverseOperationMap[op]);
+ *config.legalizableOps = std::move(originalLegalizableOps);
+ }
+
+ // Erase the cloned IR.
+ clonedAncestor->erase();
+ return status;
}
+
LogicalResult
mlir::applyAnalysisConversion(Operation *op, ConversionTarget &target,
const FrozenRewritePatternSet &patterns,
More information about the Mlir-commits
mailing list