[Mlir-commits] [mlir] 671ccfe - [mlir][reducer] Add eraseAllOpsInRegion function to reduction-tree pass (#185892)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Mar 18 03:51:58 PDT 2026
Author: lonely eagle
Date: 2026-03-18T18:51:52+08:00
New Revision: 671ccfea2767feda3d992970f11279f828e2fda3
URL: https://github.com/llvm/llvm-project/commit/671ccfea2767feda3d992970f11279f828e2fda3
DIFF: https://github.com/llvm/llvm-project/commit/671ccfea2767feda3d992970f11279f828e2fda3.diff
LOG: [mlir][reducer] Add eraseAllOpsInRegion function to reduction-tree pass (#185892)
Added logic to erase all operations within a region. This addresses
scenarios where the test script always returns 1 (interesting), in which
case the simplest output from mlir-reduce should be an empty ModuleOp.
Added:
Modified:
mlir/lib/Reducer/ReductionTreePass.cpp
mlir/test/mlir-reduce/simple-test.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Reducer/ReductionTreePass.cpp b/mlir/lib/Reducer/ReductionTreePass.cpp
index 1e00ed645f71e..83497143d9669 100644
--- a/mlir/lib/Reducer/ReductionTreePass.cpp
+++ b/mlir/lib/Reducer/ReductionTreePass.cpp
@@ -145,19 +145,63 @@ static LogicalResult findOptimal(ModuleOp module, Region ®ion,
return success();
}
+/// This function attempts to erase all operations within the region currently
+/// being processed.
+static LogicalResult eraseAllOpsInRegion(ModuleOp module, Region ®ion,
+ const Tester &test) {
+ std::pair<Tester::Interestingness, size_t> initStatus =
+ test.isInteresting(module);
+
+ // While exploring the reduction tree, we always branch from an interesting
+ // node. Thus the root node must be interesting.
+ if (initStatus.first != Tester::Interestingness::True)
+ return module.emitWarning() << "uninterested module will not be reduced";
+ llvm::SpecificBumpPtrAllocator<ReductionNode> allocator;
+
+ // Setting the ranges to {{0, 0}} will result in the deletion of all ops
+ // within the region.
+ std::vector<ReductionNode::Range> ranges{{0, 0}};
+
+ // We allocate memory on the stack, and the 'allocator' is only used to
+ // construct the 'root node'. Since we won't be constructing any child nodes
+ // for emptyRegionNode, it is only used within the current scope.
+ ReductionNode emptyRegionNode(nullptr, ranges, allocator);
+ ReductionNode *root = &emptyRegionNode;
+
+ // Create a copy of the current IR.
+ if (failed(root->initialize(module, region)))
+ llvm_unreachable("unexpected initialization failure");
+
+ // Erase all operations within the corresponding region of the clone.
+ applyPatterns(root->getRegion(), {}, root->getRanges(), true);
+ root->update(test.isInteresting(root->getModule()));
+ if (root->isInteresting() == Tester::Interestingness::True) {
+ // If we can successfully remove all ops in the region, we apply the same
+ // transformation to the original IR and return success.
+ applyPatterns(region, {}, root->getRanges(), true);
+ return success();
+ }
+ return failure();
+}
+
template <typename IteratorType>
static LogicalResult findOptimal(ModuleOp module, Region ®ion,
const FrozenRewritePatternSet &patterns,
const Tester &test) {
- // We separate the reduction process into 2 steps, the first one is to erase
+ // We separate the reduction process into 3 steps, the first one is to erase
// redundant operations and the second one is to apply the reducer patterns.
- // In the first phase, we don't apply any patterns so that we only select the
+ // In the first phase, we attempt to erase all operations within the entire
+ // region.
+ if (succeeded(eraseAllOpsInRegion(module, region, test)))
+ return success();
+
+ // In the second phase, we don't apply any patterns so that we only select the
// range of operations to keep to the module stay interesting.
if (failed(findOptimal<IteratorType>(module, region, /*patterns=*/{}, test,
/*eraseOpNotInRange=*/true)))
return failure();
- // In the second phase, we suppose that no operation is redundant, so we try
+ // In the third phase, we suppose that no operation is redundant, so we try
// to rewrite the operation into simpler form.
return findOptimal<IteratorType>(module, region, patterns, test,
/*eraseOpNotInRange=*/false);
diff --git a/mlir/test/mlir-reduce/simple-test.mlir b/mlir/test/mlir-reduce/simple-test.mlir
index 1cc414946a592..b50c39590bb92 100644
--- a/mlir/test/mlir-reduce/simple-test.mlir
+++ b/mlir/test/mlir-reduce/simple-test.mlir
@@ -1,5 +1,8 @@
// UNSUPPORTED: system-windows
-// RUN: mlir-reduce %s -reduction-tree='traversal-mode=0 test=%S/test.sh'
+// RUN: mlir-reduce %s -reduction-tree='traversal-mode=0 test=%S/test.sh' | FileCheck %s
+
+// Since the test.sh always returns 1 (interesting),
+// all operations within the ModuleOp should be erased.
func.func @simple1(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
cf.cond_br %arg0, ^bb1, ^bb2
@@ -11,3 +14,6 @@ func.func @simple1(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
^bb3(%1: memref<2xf32>):
return
}
+
+// CHECK: module {
+// CHECK: }
More information about the Mlir-commits
mailing list