Refactor the pass manager to support operations other than FuncOp/ModuleOp.
authorRiver Riddle <riverriddle@google.com>
Tue, 3 Sep 2019 02:24:47 +0000 (19:24 -0700)
committerA. Unique TensorFlower <gardener@tensorflow.org>
Tue, 3 Sep 2019 02:25:26 +0000 (19:25 -0700)
commit5c036e682d7cd5b7898242670ebfad7bb270ee35
tree93099fc27d88a066adab41467b0275fa9c972aa1
parent6563b1c4463472d5bdc83a3a62a1da1a3052ce18
Refactor the pass manager to support operations other than FuncOp/ModuleOp.

This change generalizes the structure of the pass manager to allow arbitrary nesting pass managers for other operations, at any level. The only user visible change to existing code is the fact that a PassManager must now provide an MLIRContext on construction. A new class `OpPassManager` has been added that represents a pass manager on a specific operation type. `PassManager` will remain the top-level entry point into the pipeline, with OpPassManagers being nested underneath. OpPassManagers will still be implicitly nested if the operation type on the pass differs from the pass manager. To explicitly build a pipeline, the 'nest' methods on OpPassManager may be used:

// Pass manager for the top-level module.
PassManager pm(ctx);

// Nest a pipeline operating on FuncOp.
OpPassManager &fpm = pm.nest<FuncOp>();
fpm.addPass(...);

// Nest a pipeline under the FuncOp pipeline that operates on spirv::ModuleOp
OpPassManager &spvModulePM = pm.nest<spirv::ModuleOp>();

// Nest a pipeline on FuncOps inside of the spirv::ModuleOp.
OpPassManager &spvFuncPM = spvModulePM.nest<FuncOp>();

To help accomplish this a new general OperationPass is added that operates on opaque Operations. This pass can be inserted in a pass manager of any type to operate on any operation opaquely. An example of this opaque OperationPass is a VerifierPass, that simply runs the verifier opaquely on the current operation.

/// Pass to verify an operation and signal failure if necessary.
class VerifierPass : public OperationPass<VerifierPass> {
  void runOnOperation() override {
    Operation *op = getOperation();
    if (failed(verify(op)))
      signalPassFailure();
    markAllAnalysesPreserved();
  }
};

PiperOrigin-RevId: 266840344
17 files changed:
mlir/bindings/python/pybind.cpp
mlir/examples/Linalg/Linalg1/include/linalg1/Common.h
mlir/examples/Linalg/Linalg3/Example.cpp
mlir/examples/Linalg/Linalg4/Example.cpp
mlir/examples/toy/Ch4/toyc.cpp
mlir/examples/toy/Ch5/toyc.cpp
mlir/g3doc/Tutorials/Toy/Ch-4.md
mlir/include/mlir/Pass/Pass.h
mlir/include/mlir/Pass/PassManager.h
mlir/lib/Pass/IRPrinting.cpp
mlir/lib/Pass/Pass.cpp
mlir/lib/Pass/PassDetail.h
mlir/lib/Pass/PassTiming.cpp
mlir/lib/Support/JitRunner.cpp
mlir/lib/Support/MlirOptMain.cpp
mlir/test/Pass/pass-timing.mlir
mlir/tools/mlir-cuda-runner/mlir-cuda-runner.cpp