Passing options to passes assembled in a PassManager

Is there any way to quickly set an option for a pass when simply adding passes to a PassManager and then executing them?

The documentation mentions pass options in the section Instance Specific Pass Options, but this only seems to apply to custom pass pipelines.

I’m looking for a solution to specify an option for a pass in a setting similar to this one:

mlir::PassManager pm(&context);
pm.addPass(std::move(createXXXPass()));
pm.addPass(std::move(createYYYPass()));
pm.addPass(std::move(createZZZPass()));
pm.run(module);

Neither the pass constructors, nor PassManager seem to provide anything that would allow for options to be passed.

Thanks!

The constructor is the API: it may or may not expose all of the pass options defined by the pass.
Right now it is a manual process to update the constructor to allow defining some options, but there is a GitHub issue to automate this.

I am +1 for this.

Recently, I noticed that you can declare options for a pass on tablegen like this:

def MyFirstOptions {
  list<Option> options = [
    Option<"dmaAddress", "dma-address", "unsigned", /*default=*/"0",
           "DMA address">,
    Option<"dmaInputAddress", "dma-input-address", "unsigned", /*default=*/"0",
           "DMA input buffer address">,
    Option<"dmaInputBufferSize", "dma-input-buffer-size", "unsigned", /*default=*/"0",
           "DMA input buffer address">,
    Option<"dmaOutputAddress", "dma-output-address", "unsigned", /*default=*/"0",
           "DMA output buffer address">,
    Option<"dmaOutputBufferSize", "dma-output-buffer-size", "unsigned", /*default=*/"0",
           "DMA output buffer address">,
  ];
}

def MySecondOptions {
  list<Option> options = [
    Option<"flowCpuAcc", "flow-cpu-accumulation", "bool", /*default=*/"false",
           "Decide if code to accumulate on the CPU must be generated">,
  ];
}

def DoSomething: Pass<"test-do-something", "ModuleOp"> {
  let summary = "summary...";
  let constructor = "mlir::createDoSomethingPass()";
  let dependentDialects = [
    "AffineDialect",
    "memref::MemRefDialect",
    "scf::SCFDialect",
    "LLVM::LLVMDialect",
  ];
  let options = [
    Option<"tileSize", "tile-size", "unsigned", /*default=*/"4",
           "Use this tile size for all loops">,
  ] # MyFirstOptions.options # MySecondOptions.options;
}

Last lines are the interesting bit.

However, in the generated Passas.h.inc file, there is no mention to MyFirstOptions, MySecondOptions, as the lists get flattened. I.e.: You will see dmaAddress, dmaInputAddress, etc, as protected members of the Pass, accessible with this->dmaAddress, this->dmaInputAddress, etc.

I wonder if as a first step we could have tablegen generate the xxxOptions data-structure from something like def MyFirstOptions : PassOptions {} line, respecting the initial values when present. With the developer in charge of implementing the constructor and initialization of the relevant protected members.


I think this is the issue Mehdi mentioned: