[Mlir-commits] [mlir] 8f4859d - Create Optimization Pass Wrapper for MLIR Reduce

Mauricio Sifontes llvmlistbot at llvm.org
Tue Aug 18 09:47:47 PDT 2020


Author: Mauricio Sifontes
Date: 2020-08-18T16:47:10Z
New Revision: 8f4859d35120b007c53ac075375d9d1791ec6c86

URL: https://github.com/llvm/llvm-project/commit/8f4859d35120b007c53ac075375d9d1791ec6c86
DIFF: https://github.com/llvm/llvm-project/commit/8f4859d35120b007c53ac075375d9d1791ec6c86.diff

LOG: Create Optimization Pass Wrapper for MLIR Reduce

Create a reduction pass that accepts an optimization pass as argument
and only replaces the golden module in the pipeline if the output of the
optimization pass is smaller than the input and still exhibits the
interesting behavior.

Add a -test-pass option to test individual passes in the MLIR Reduce
tool.

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D84783

Added: 
    mlir/include/mlir/Reducer/OptReductionPass.h
    mlir/test/mlir-reduce/dce-test.mlir
    mlir/test/mlir-reduce/multiple-function.mlir
    mlir/test/mlir-reduce/simple-test.mlir
    mlir/test/mlir-reduce/single-function.mlir
    mlir/tools/mlir-reduce/OptReductionPass.cpp

Modified: 
    mlir/include/mlir/Reducer/Passes.td
    mlir/include/mlir/Reducer/ReductionTreePass.h
    mlir/tools/mlir-reduce/CMakeLists.txt
    mlir/tools/mlir-reduce/mlir-reduce.cpp

Removed: 
    mlir/test/mlir-reduce/reduction-tree-pass.mlir
    mlir/test/mlir-reduce/test-reducer-pass.mlir
    mlir/test/mlir-reduce/testcase-linux.mlir


################################################################################
diff  --git a/mlir/include/mlir/Reducer/OptReductionPass.h b/mlir/include/mlir/Reducer/OptReductionPass.h
new file mode 100644
index 000000000000..2168ea215950
--- /dev/null
+++ b/mlir/include/mlir/Reducer/OptReductionPass.h
@@ -0,0 +1,52 @@
+//===- OptReductionPass.h - Optimization Reduction Pass Wrapper -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Opt Reduction Pass Wrapper. It creates a pass to run
+// any optimization pass within it and only replaces the output module with the
+// transformed version if it is smaller and interesting.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_REDUCER_OPTREDUCTIONPASS_H
+#define MLIR_REDUCER_OPTREDUCTIONPASS_H
+
+#include "PassDetail.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Pass/PassManager.h"
+#include "mlir/Reducer/ReductionNode.h"
+#include "mlir/Reducer/ReductionTreePass.h"
+#include "mlir/Reducer/Tester.h"
+#include "mlir/Transforms/Passes.h"
+#include "llvm/Support/Debug.h"
+
+namespace mlir {
+
+class OptReductionPass : public OptReductionBase<OptReductionPass> {
+public:
+  OptReductionPass(const Tester *test, MLIRContext *context,
+                   std::unique_ptr<Pass> optPass);
+
+  OptReductionPass(const OptReductionPass &srcPass);
+
+  /// Runs the pass instance in the pass pipeline.
+  void runOnOperation() override;
+
+private:
+  // Points to the context to be used in the pass manager.
+  MLIRContext *context;
+
+  // This is used to test the interesting behavior of the transformed module.
+  const Tester *test;
+
+  // Points to the mlir-opt pass to be called.
+  std::unique_ptr<Pass> optPass;
+};
+
+} // end namespace mlir
+
+#endif

diff  --git a/mlir/include/mlir/Reducer/Passes.td b/mlir/include/mlir/Reducer/Passes.td
index 4703dd746a70..d3a934ef6933 100644
--- a/mlir/include/mlir/Reducer/Passes.td
+++ b/mlir/include/mlir/Reducer/Passes.td
@@ -17,7 +17,10 @@ include "mlir/Pass/PassBase.td"
 
 def ReductionTree : Pass<"reduction-tree", "ModuleOp"> {
   let summary = "A general reduction tree pass for the MLIR Reduce Tool";
-  let constructor = "mlir::createReductionTreePass()";
 }
 
-#endif // MLIR_REDUCE_PASSES
+def OptReduction : Pass<"opt-reduction-pass", "ModuleOp"> {
+  let summary = "A reduction pass wrapper for optimization passes";
+}
+
+#endif // MLIR_REDUCER_PASSES

diff  --git a/mlir/include/mlir/Reducer/ReductionTreePass.h b/mlir/include/mlir/Reducer/ReductionTreePass.h
index 01104aa0429b..d07a475e4f99 100644
--- a/mlir/include/mlir/Reducer/ReductionTreePass.h
+++ b/mlir/include/mlir/Reducer/ReductionTreePass.h
@@ -34,7 +34,7 @@ enum TraversalMode { SinglePath, MultiPath, Concurrent, Backtrack };
 // class.
 class ReductionTreeUtils {
 public:
-  void updateGoldenModule(ModuleOp &golden, ModuleOp reduced);
+  static void updateGoldenModule(ModuleOp &golden, ModuleOp reduced);
 };
 
 /// This class defines the Reduction Tree Pass. It provides a framework to

diff  --git a/mlir/test/mlir-reduce/dce-test.mlir b/mlir/test/mlir-reduce/dce-test.mlir
new file mode 100644
index 000000000000..e368343e056a
--- /dev/null
+++ b/mlir/test/mlir-reduce/dce-test.mlir
@@ -0,0 +1,17 @@
+// UNSUPPORTED: -windows-
+// RUN: mlir-reduce %s -test %S/failure-test.sh -pass-test DCE | FileCheck %s
+// This input should be reduced by the pass pipeline so that only
+// the @simple1 function remains as the other fucntions should be
+// removed by the dead code elimination pass.
+// CHECK-LABEL: func @simple1(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+
+// CHECK-NOT: func @dead_nested_function
+func @dead_private_function() attributes { sym_visibility = "private" }
+
+// CHECK-NOT: func @dead_nested_function
+func @dead_nested_function() attributes { sym_visibility = "nested" }
+
+func @simple1(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+  "test.crashOp" () : () -> ()
+  return
+}

diff  --git a/mlir/test/mlir-reduce/reduction-tree-pass.mlir b/mlir/test/mlir-reduce/multiple-function.mlir
similarity index 90%
rename from mlir/test/mlir-reduce/reduction-tree-pass.mlir
rename to mlir/test/mlir-reduce/multiple-function.mlir
index dc04a626d191..d225df8b8676 100644
--- a/mlir/test/mlir-reduce/reduction-tree-pass.mlir
+++ b/mlir/test/mlir-reduce/multiple-function.mlir
@@ -1,5 +1,5 @@
 // UNSUPPORTED: -windows-
-// RUN: mlir-reduce %s -test %S/failure-test.sh | FileCheck %s
+// RUN: mlir-reduce %s -test %S/failure-test.sh -pass-test function-reducer | FileCheck %s
 // This input should be reduced by the pass pipeline so that only 
 // the @simple5 function remains as this is the shortest function 
 // containing the interesting behavior.

diff  --git a/mlir/test/mlir-reduce/testcase-linux.mlir b/mlir/test/mlir-reduce/simple-test.mlir
similarity index 81%
rename from mlir/test/mlir-reduce/testcase-linux.mlir
rename to mlir/test/mlir-reduce/simple-test.mlir
index f2bb161bb5a6..5329e9552f5b 100644
--- a/mlir/test/mlir-reduce/testcase-linux.mlir
+++ b/mlir/test/mlir-reduce/simple-test.mlir
@@ -1,5 +1,5 @@
 // UNSUPPORTED: -windows-
-// RUN: mlir-reduce %s -test %S/test.sh
+// RUN: mlir-reduce %s -test %S/test.sh -pass-test function
 
 func @simple1(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
   cond_br %arg0, ^bb1, ^bb2
@@ -10,4 +10,4 @@ func @simple1(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
   br ^bb3(%0 : memref<2xf32>)
 ^bb3(%1: memref<2xf32>):
   return
-}
\ No newline at end of file
+}

diff  --git a/mlir/test/mlir-reduce/test-reducer-pass.mlir b/mlir/test/mlir-reduce/single-function.mlir
similarity index 52%
rename from mlir/test/mlir-reduce/test-reducer-pass.mlir
rename to mlir/test/mlir-reduce/single-function.mlir
index da5b0c963355..732963553e90 100644
--- a/mlir/test/mlir-reduce/test-reducer-pass.mlir
+++ b/mlir/test/mlir-reduce/single-function.mlir
@@ -1,5 +1,5 @@
 // RUN: mlir-opt %s
-// RUN: not mlir-opt %s -test-mlir-reducer
+// RUN: not mlir-opt %s -test-mlir-reducer -pass-test function-reducer
 
 func @test() {
   "test.crashOp"() : () -> ()

diff  --git a/mlir/tools/mlir-reduce/CMakeLists.txt b/mlir/tools/mlir-reduce/CMakeLists.txt
index b3a7c36a0309..f581eee21fab 100644
--- a/mlir/tools/mlir-reduce/CMakeLists.txt
+++ b/mlir/tools/mlir-reduce/CMakeLists.txt
@@ -32,6 +32,7 @@ set(LIBS
   )
 
 add_llvm_tool(mlir-reduce
+  OptReductionPass.cpp
   Passes/FunctionReducer.cpp
   ReductionNode.cpp
   ReductionTreePass.cpp

diff  --git a/mlir/tools/mlir-reduce/OptReductionPass.cpp b/mlir/tools/mlir-reduce/OptReductionPass.cpp
new file mode 100644
index 000000000000..dbb3d97046d4
--- /dev/null
+++ b/mlir/tools/mlir-reduce/OptReductionPass.cpp
@@ -0,0 +1,55 @@
+//===- OptReductionPass.cpp - Optimization Reduction Pass Wrapper ---------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Opt Reduction Pass class. It creates a pass to run
+// any optimization pass within it and only replaces the output module with the
+// transformed version if it is smaller and interesting.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Reducer/OptReductionPass.h"
+
+#define DEBUG_TYPE "mlir-reduce"
+
+using namespace mlir;
+
+OptReductionPass::OptReductionPass(const Tester *test, MLIRContext *context,
+                                   std::unique_ptr<Pass> optPass)
+    : context(context), test(test), optPass(std::move(optPass)) {}
+
+OptReductionPass::OptReductionPass(const OptReductionPass &srcPass)
+    : test(srcPass.test), optPass(srcPass.optPass.get()) {}
+
+/// Runs the pass instance in the pass pipeline.
+void OptReductionPass::runOnOperation() {
+  LLVM_DEBUG(llvm::dbgs() << "\nOptimization Reduction pass: ");
+  LLVM_DEBUG(llvm::dbgs() << optPass.get()->getName() << "\nTesting:\n");
+
+  ModuleOp module = this->getOperation();
+  ModuleOp moduleVariant = module.clone();
+  PassManager pmTransform(context);
+  pmTransform.addPass(std::move(optPass));
+
+  if (failed(pmTransform.run(moduleVariant)))
+    return;
+
+  ReductionNode original(module, nullptr);
+  original.measureAndTest(test);
+
+  ReductionNode reduced(moduleVariant, nullptr);
+  reduced.measureAndTest(test);
+
+  if (reduced.isInteresting() && reduced.getSize() < original.getSize()) {
+    ReductionTreeUtils::updateGoldenModule(module, reduced.getModule().clone());
+    LLVM_DEBUG(llvm::dbgs() << "\nSuccessful Transformed version\n\n");
+  } else {
+    LLVM_DEBUG(llvm::dbgs() << "\nUnsuccessful Transformed version\n\n");
+  }
+
+  LLVM_DEBUG(llvm::dbgs() << "Pass Complete\n\n");
+}

diff  --git a/mlir/tools/mlir-reduce/mlir-reduce.cpp b/mlir/tools/mlir-reduce/mlir-reduce.cpp
index 93de0703d892..4c69aa0ad217 100644
--- a/mlir/tools/mlir-reduce/mlir-reduce.cpp
+++ b/mlir/tools/mlir-reduce/mlir-reduce.cpp
@@ -19,6 +19,7 @@
 #include "mlir/Parser.h"
 #include "mlir/Pass/Pass.h"
 #include "mlir/Pass/PassManager.h"
+#include "mlir/Reducer/OptReductionPass.h"
 #include "mlir/Reducer/ReductionNode.h"
 #include "mlir/Reducer/ReductionTreePass.h"
 #include "mlir/Reducer/Tester.h"
@@ -46,6 +47,11 @@ static llvm::cl::opt<std::string>
                    llvm::cl::desc("Output filename for the reduced test case"),
                    llvm::cl::init("-"));
 
+// TODO: Use PassPipelineCLParser to define pass pieplines in the command line.
+static llvm::cl::opt<std::string>
+    passTestSpecifier("pass-test",
+                      llvm::cl::desc("Indicate a specific pass to be tested"));
+
 // Parse and verify the input MLIR file.
 static LogicalResult loadModule(MLIRContext &context, OwningModuleRef &module,
                                 StringRef inputFilename) {
@@ -94,10 +100,19 @@ int main(int argc, char **argv) {
   // Reduction pass pipeline.
   PassManager pm(&context);
 
-  // Reduction tree pass with OpReducer variant generation and single path
-  // traversal.
-  pm.addPass(
-      std::make_unique<ReductionTreePass<FunctionReducer, SinglePath>>(&test));
+  if (passTestSpecifier == "DCE") {
+
+    // Opt Reduction Pass with SymbolDCEPass as opt pass.
+    pm.addPass(std::make_unique<OptReductionPass>(&test, &context,
+                                                  createSymbolDCEPass()));
+
+  } else if (passTestSpecifier == "function-reducer") {
+
+    // Reduction tree pass with OpReducer variant generation and single path
+    // traversal.
+    pm.addPass(std::make_unique<ReductionTreePass<FunctionReducer, SinglePath>>(
+        &test));
+  }
 
   ModuleOp m = moduleRef.get().clone();
 


        


More information about the Mlir-commits mailing list