diff --git a/mlir/lib/Bindings/Python/Pass.cpp b/mlir/lib/Bindings/Python/Pass.cpp --- a/mlir/lib/Bindings/Python/Pass.cpp +++ b/mlir/lib/Bindings/Python/Pass.cpp @@ -60,6 +60,17 @@ "Parse a textual pass-pipeline and return a top-level PassManager " "that can be applied on a Module. Throw a ValueError if the pipeline " "can't be parsed") + .def( + "run", + [](PyPassManager &passManager, PyModule &module) { + MlirLogicalResult status = + mlirPassManagerRun(passManager.get(), module.get()); + if (mlirLogicalResultIsFailure(status)) + throw SetPyError(PyExc_RuntimeError, + "Failure while executing pass pipeline."); + }, + "Run the pass manager on the provided module, throw a RuntimeError " + "on failure.") .def( "__str__", [](PyPassManager &self) { diff --git a/mlir/test/Bindings/Python/pass_manager.py b/mlir/test/Bindings/Python/pass_manager.py --- a/mlir/test/Bindings/Python/pass_manager.py +++ b/mlir/test/Bindings/Python/pass_manager.py @@ -5,8 +5,7 @@ from mlir.passmanager import * # Log everything to stderr and flush so that we have a unified stream to match -# errors emitted by MLIR to stderr. TODO: this shouldn't be needed when -# everything is plumbed. +# errors/info emitted by MLIR to stderr. def log(*args): print(*args, file=sys.stderr) sys.stderr.flush() @@ -52,3 +51,18 @@ else: log("Exception not produced") run(testParseFail) + + +# Verify that a pass manager can execute on IR +# CHECK-LABEL: TEST: testRun +def testRunPipeline(): + with Context(): + pm = PassManager.parse("print-op-stats") + module = Module.parse(r"""func @successfulParse() { return }""") + pm.run(module) +# CHECK: Operations encountered: +# CHECK: func , 1 +# CHECK: module , 1 +# CHECK: module_terminator , 1 +# CHECK: std.return , 1 +run(testRunPipeline)