[Mlir-commits] [mlir] [mlir][reducer] Add eraseALlOpsInRegion function to reduction-tree pass (PR #185892)

lonely eagle llvmlistbot at llvm.org
Wed Mar 11 07:44:50 PDT 2026


https://github.com/linuxlonelyeagle created https://github.com/llvm/llvm-project/pull/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.

>From 855dcce75ae03804dac045e8327c3429dd89d1f1 Mon Sep 17 00:00:00 2001
From: linuxlonelyeagle <2020382038 at qq.com>
Date: Wed, 11 Mar 2026 14:40:13 +0000
Subject: [PATCH] add eraseALlOpsInRegion function to tree-reduce pass.

---
 mlir/lib/Reducer/ReductionTreePass.cpp | 46 ++++++++++++++++++++++++--
 mlir/test/mlir-reduce/simple-test.mlir |  8 ++++-
 2 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/mlir/lib/Reducer/ReductionTreePass.cpp b/mlir/lib/Reducer/ReductionTreePass.cpp
index 1e00ed645f71e..6cb1ba5a211c9 100644
--- a/mlir/lib/Reducer/ReductionTreePass.cpp
+++ b/mlir/lib/Reducer/ReductionTreePass.cpp
@@ -145,19 +145,59 @@ static LogicalResult findOptimal(ModuleOp module, Region &region,
   return success();
 }
 
+/// This function attempts to erase all operations within the region currently
+/// being processed.
+static LogicalResult eraseALlOpsInRegion(ModuleOp module, Region &region,
+                                         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}};
+  ReductionNode *root = allocator.Allocate();
+  new (root) ReductionNode(nullptr, ranges, allocator);
+
+  // 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 &region,
                                  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