Check out the demo plugin for a minimal example. It uses our custom add_mim_plugin CMake command. A plugin generally consists of two halves with the same name: a <plugin>.mim file that declares the public annexes and a shared library that registers the runtime behavior.
Plugin names may only contain letters, digits, and underscores, and are limited to 8 characters.
The MimIR Plugin Registry is the central hub for discovering, sharing, and maintaining third-party MimIR plugins. The registry lists available plugins and provides guidance on how to discover and use them. If you've created a plugin you'd like to share with the community, please consider submitting it to the registry.
Create a new in-tree plugin foobar based on the demo plugin:
The script also supports -h/--help and prints the same usage text when called incorrectly.
By default, the script creates an in-tree plugin and updates src/mim/plug/CMakeLists.txt. The generated files are:
To create a self-contained third-party plugin repository in extra/, use:
This creates extra/<plugin>/ with:
In --extra mode, the script also:
If you clone a plugin repository into extra/, MimIR picks it up automatically during configuration when the repository contains a CMakeLists.txt as a direct child of extra/.
If the plugin repository also contains lit/*.mim tests, they are picked up automatically by the main lit target as well.
To move an existing in-tree plugin into extra/foobar, use:
This moves:
It also:
The extracted plugin is staged with git add but not committed, allowing you to review the changes before committing.
After installing MimIR, a third-party plugin only needs to find the mim package. For example, a plugin called foo can be set up like this:
Configure the project standalone with:
The authoritative reference for add_mim_plugin itself lives in cmake/Mim.cmake.
Backends such as ll sometimes need to emit calls to functionality that is awkward or brittle to express as hand-written LLVM IR — for example libc helpers, or complex argument setup for vendor APIs. Instead of emitting the implementation inline, a backend can offload it to a small C wrapper that is compiled to LLVM IR by clang and pulled into the output. This keeps the backend focused on emitting LLVM and lets clang deal with platform- and version-specific details.
The add_mim_runtime CMake command compiles a plugin's C wrapper sources to textual LLVM IR:
All sources are merged into a single module <libdir>/mim/rt/<plugin>_rt.ll (next to the plugins) and, with INSTALL, installed alongside them — one runtime module per plugin, addressable by a well-known name no matter how many .c files it is split into. This step is optional: it requires clang (discovered as MIM_CLANG; merging multiple sources additionally needs llvm-link) and is skipped when clang is unavailable or MIM_BUILD_LL_RUNTIME is OFF.
The ll backend locates such a runtime module via the driver's search paths and either embeds it into or links it with its emitted module, selected via -X ll:rt=embed (default) or -X ll:rt=extern; see the CLI reference. The in-tree examples are src/mim/plug/ll/rt/mim_rt.c, which provides @mim_jmpbuf_size for %clos.alloc_jmpbuf, and src/mim/plug/ll_nvptx/rt/mim_cuda_rt.c, whose @mim_cu_check performs the ll_nvptx backend's CUDA driver-API error handling. The ll_nvptx backend reuses the very same load_rt_module helper as ll, differing only in the runtime module it names.
The authoritative reference for add_mim_runtime lives in cmake/Mim.cmake.
Normalizers usually obtain the owning World from one of their arguments, often type->world(), and then build the replacement directly in that world. Small normalizers are expected to be direct and side-effect free.
That often leads to tiny functions of the form: