`InstanceLike` and `ModuleLike` interfaces

(I’ve prototyped this but posting here for more visibility.)

I propose we create InstanceLike and ModuleLike interfaces for the purposes of optimization and export (e.g. ExportVerilog). ModuleLike being roughly analogous to FunctionLike.

Rationale: frontend language dialects and other dialects will likely want/need to create their own instance and module ops. I expect these to largely be supersets of hw.module and hw.instance. (The HW dialect already has three ModuleLike ops hw.module, hw.module.extern, and hw.module.generated. This would obviate the need for most of the helper functions in HWOps.h.) While they could be lowered to the supported hw ops, there are a few reasons authors may not want to:

  • Loss of structured information. Alternate instance and module ops will contain additional information (if only the operation name). In order to export to verilog, one currently has to run a module through multiple passes and run ExportVerilog, which requires lowing to hw.module/hw.instance. One may want/need to persist the additional information across those passes (I’m assuming ExportVerilog is read-only w/ respect to the IR). E.g. placement data and other “metadata”.
  • Using existing optimizations. Just like FunctionLike allows for inlining of arbitrary function-like ops, alternative instance and module ops will likely be amenable to some of the same optimizations/analyses which hw.module and hw.instance are. Premature lowering, however, may prevent further op-specific optimizations and exports.

What do y’all think?

Alternatively, could we just use FunctionLike and add an InstanceLike (since there doesn’t seem to be a CallLike in MLIR)? I don’t think that would be wise, but could be convinced otherwise.

There is the CallOpInterface: Interfaces - MLIR.

We’ve been using FunctionLike, and it’s been alright for the most part IMHO. However, there is sometimes a little bit of impedance mismatch with the software world, and having a ModuleLike that does what we actually want might be better. Regarding InstanceLike, copying what I said on the PR:

Offhand, I know HW, FIRRTL, LLHD, Handshake, Calyx, and the FSM proposal all have a notion of “instance”. Upstream, MLIR has the CallOpInterface, but having a hardware-specific interface for this kind of thing sounds like a great opportunity.

I was both looking for the term CallLike (the natural name for a dual to FunctionLike) and not reading your comment in that PR. Oops.