Dynamic Pass support in mlir-opt

I’ve been working on adding support for dynamic passes written in other languages (specifically Swift) using the c-api and I’ve run into a few points of friction when trying to reuse the mlir-opt infrastructure.

One is that the PassRegistryEntry appears to assume the argument and description strings of a Pass outlive the Pass instance (essentially that they are statically allocated), based on the initialization logic using a temporary Pass here. On the Swift side, it’s convenient to dynamically generate the argument string based on the type name, so ensuring the string’s lifetime outlives the pass instance requires extra bookkeeping. I believe changing these StringRef members to std::string should address this.

Another thing is that it would be nice for this version of MlirOptMain that sets up all of the command line arguments to also take an optional set-up function like here. That would give the Swift side a chance to set up some MlirContext-tied type-bridging infrastructure before any passes are run.

If the changes I mentioned above sound reasonable I can submit a revision.

Seems reasonable to me.

I rather keep the API limited here (not passing the entire context to an arbitrary callback). What do you need to setup on the Context exactly?

The current way that dialect types are bridged to Swift representations is that we set up a mapping on the Swift side from MlirTypeID to various Swift type initializers. A special dialect is used to store this mapping so that the mapping’s lifetime can be tied to the lifetime of the Context that uses it. Since mlir-opt instantiates Contexts on its own, a callback would give the Swift side an opportunity to set up the mapping.
We don’t necessarily need to do it this way though. One alternative is setting up the mapping on demand when a pass is run, though that requires the use of locks since Contexts can be multithreaded. Another alternative is just having a single global mapping instead of one per Context. Any thoughts on these approaches @GeorgeL?