Specify a default pass pipeline with MlirOptMain

I want to use MlirOptMain to create a new driver for a project. Looking through the function arguments, the passes or pass pipeline has to be specified via command-line arguments. There doesn’t seem to be a way to specify a default pass pipeline. Is my understanding correct? Would it be useful to look into creating a patch for this?

MlirOptMain is intended to support mlir-opt-like tools, which are testing vehicles for passes, not frontends. I’m not sure you also need all of the functionality that it exposes (timing, parallelization control, output verification) at a seemingly user-facing tool with the default pass pipeline. The entire file llvm-project/MlirOptMain.cpp at main · llvm/llvm-project · GitHub is less than 300 LoC counting includes, comments and CLI flag declarations, have you considered just writing what you need instead of trying to adapt it?

Thanks for your reply! Yes, that’s what I have currently done. I asked wondering if this is something that MlirOptMain is supposed to support.

As Alex mentioned it is a testing & development tool, it makes it easy to experiment and test but isn’t intended to be a production tool but to test/experiment with the components of such a tool. MlirOptMain just makes it easy to make such tools. Another element is that the UI is for developers, passes may change, options may change, so users won’t be as happy than with a dedicated tool where there is more stability or higher order functions exposed (and none of the experimental for test only passes).

Thank you! That makes sense.

We could refactor it so that one of the lower-level entry point takes a PassManager instead of a PassPipelineCLParser and exposing this entry point publicly in addition of the existing one. I think that’d be a cheap refactoring which would provide what you want here.

1 Like

Thanks @mehdi_amini . To create a PassManager, we need an MLIRContext. Because we are using split-input-file, and processing the buffers separately, we create separate contexts for each buffer. To pass in a PassManager to a new public entry point for MlirOptMain(), we’ll have to create the MLIRContext at a higher-level, thereby wouldn’t be able to have separate contexts for the split buffers. We would have to disable the splitting of input files when we want to pass in a PassManager. Does this make sense?

A solution I would like to suggest is to pass in a DefaultPassPipelineFn only if needed, which can be used something like this as an example, ⚙ D113121 Add a default pass pipeline fn

Callback would work for me, but to keep the API simple I rather not add to it but replace the PassPipelineCLParser with the callback (existing caller would just use a lambda invoking their PassPipelineCLParser).
The callback should be able to fail though: using DefaultPassPipelineFn = llvm::function_ref<LogicalResult(PassManager &pm)>;

What did you mean by

I meant that removing const PassPipelineCLParser &passPipeline from the MlirOptMain signature in favor of the callback model, we’d have to update callees to pass instead [&] (PassManager &pm) { return passPipeline.addToPipeline(pm, errorHandler))); } as call site.

Thank you @mehdi_amini. I have put up a patch for review, ⚙ D113144 [mlir] Add callback to provide a pass pipeline to MlirOptMain . Please take a look.

I haven’t committed before to the MLIR project. Do I need to add reviewers?

Usually, yes, but several folks in MLIR are monitoring all patches and may assign reviewers for you. In some cases, the system will add reviewers automatically based on the rules they configured (e.g., if you touch anything in the lib/IR directory, River will be added).