[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 &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}};
+
+  // 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 &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