In a ModuleOp pass how can I replace the top level ModuleOp?

I have an OperationPass<ModuleOp>.
I want to have something like

void runOnOperation() override {
  ModuleOp moduleOp = getOperation();
  ModuleOp newModuleOp = ...;
  std::swap(*moduleOp.getOperation(), *newModuleOp.getOperation());

You cannot do that. You can transform anything inside of the ModuleOp. If you have an OperationPass on funcOp, then you can transform anything in the funcOp.

Why do you want to replace the module?

I want to convert the whole MLIR into another representation, transform it and then convert it back.

Either start from scratch or have nested modules.

Technically, I want to swap or move the contents of the operation. I don’t want to edit its parent container.

You can transform the content of moduleOp, but not moduleOp itself.

Start from scratch?

It’s not possible to replace the top level op in a pass. You can just do it out of the pass management though

I ended up moving the stuff inside the module.

void move(ModuleOp src, ModuleOp dst) {
  src->setAttrs(SmallVector<NamedAttribute, 1>());

The single region and attributes should be all that is in a module.

Pass Infrastructure - MLIR states that

I don’t see why changing the attributes of a module should not be allowed.

Here is an example where they attach an interface to a module and set attributes. It is however probably outside and before the pass pipeline.

It not about module or otherwise, it’s about having siblings actually. We could reframe the rule with an exception for the “top-most operation” in the IR I think.