Usage
MimIR is my Intermediate Representation.
Arguments
| Argument | Description |
| <file> | Input file. |
Options
| Option | Description |
| -h, --help | Display this help and exit. |
| --help-md | Displays this help as Markdown and exits. |
| -v, --version | Displays version info and exits. |
| -l, --list-search-paths | Lists the search paths in order and exits. |
| -p, --plugin <plugin> | Dynamically loads a plugin. |
| -P, --plugin-path <path> | Path to search for plugins; also searched for imports. |
| -I, --import-path <path> | Path to search for imports. |
| -R, --prefix-path <path> | Install prefix/root to derive plugin, import, and runtime directories from. |
| -X, --plugin-arg <plugin:arg> | Passes an argument to a plugin/phase, e.g. -X ll:o=output.ll. Repeatable. |
| --force-load | Loads plugins even on version mismatch. |
| --bootstrap | Bootstrap mode: only read Mim AST, don't compile to MimIR. |
| -V, --verbose | Raises the log level from error to warn, info, verbose, debug, trace; repeatable. |
Output
| Option | Description |
| -a, --ascii | Uses ASCII alternatives in output instead of UTF-8. |
| --output-ast <file> | Emits the AST of the input. |
| --output-dot <file> | Emits the Mim program as a MimIR graph using Graphviz' DOT language. |
| --output-h <file> | Emits a header file to be used to interface with a plugin in C++. |
| --output-md <file> | Emits the input formatted as Markdown. |
| -o, --output-mim <file> | Emits the Mim program again. |
| --dump-recursive | Dumps the Mim program with a simple recursive algorithm; the result is not readable again but works for broken programs. |
| --output-nest <file> | Emits the program's nesting tree using Graphviz' DOT language. |
| --output-py <file> | Emits a Python enum to be used to interface with a plugin in Python. |
| --output-sexpr <file> | Emits the program as symbolic expression. |
| --output-sexpr-slotted <file> | Emits the program as symbolic expression that follows the format required by slotted-egraphs. |
| --sexpr-include-types | Wraps each term of a symbolic expression in a type annotation; types themselves stay unwrapped. |
DOT Output
| Option | Description |
| --dot-all-annexes | Emits all annexes in DOT output - even unused ones. |
| --dot-default-filter | Always shows a lambda's filter in DOT output - even if it is the default one (ff for continuations, tt for direct-style functions). |
| --dot-follow-types | Follows type dependencies in DOT output. |
| --dot-inline-consts | Wires up literals, axioms, etc. with normal edges in DOT output instead of detaching them into a separate row; useful for small graphs. |
| --dot-show-hidden | Renders otherwise-transparent detached edges in DOT output - back-edges from a Var to its binder, shared literals/axioms, and type edges - in a subtle gray. |
Diagnostics
| Option | Description |
| --gutter <width> | Width of a diagnostic's line-number column. [default: 5] |
| --loc-style <style> | How a diagnostic spells out a source location: full (path:row:col-row:col), rowcol (path:row:col), row (path:row), or msvc (path(row,col)). |
| --max-errors <num> | Maximum number of errors to report before dropping the rest; 0 reports all of them. [default: 0] |
| --max-rows <num> | Maximum number of rows a diagnostic's snippet renders before eliding its middle; 0 elides nothing. [default: 8] |
| --no-snippet | Does not render the offending source line and caret underneath a diagnostic. |
| --werror | Treats warnings as errors. |
Profiling
| Option | Description |
| --output-profile <file> | Where to write the profiling information; defaults to stdout and implies --profile trace, if no <mode> is given. |
| --profile <mode> | Measures how long each phase takes; <mode> is summary, tree, or trace (chrome://tracing compatible). |
Optimization
| Option | Description |
| --aggr-lam-spec | Overrides LamSpec behavior to follow recursive calls. |
| --max-fp-iters <num> | Maximum number of fixed-point iterations before a phase errors out; guards against non-monotone analyses. [default: 1024] |
| --scalarize-threshold <threshold> | MimIR will not scalarize tuples/packs/sigmas/arrays with a number of elements greater than or equal this threshold. [default: 32] |
Developer Options
| Option | Description |
| -b, --break <gid> | Triggers a breakpoint when a node with this global id is created. |
| --break-on-alpha | Triggers a breakpoint as soon as two expressions turn out not to be alpha-equivalent. |
| --break-on-error | Triggers a breakpoint on an error log. |
| --break-on-warn | Triggers a breakpoint on a warning log. |
| --reeval-breakpoints | Triggers a breakpoint even upon unifying a node that has already been built. |
| --trace-gids | Outputs gids during World::unify/insert. |
| -w, --watch <gid> | Triggers a breakpoint when a node with this global id is set. |
Environment Variables
| Variable | Description |
| MIM_PLUGIN_PATH | Colon-separated list of plugin search paths, searched after those given via -P. |
| MIM_IMPORT_PATH | Colon-separated list of import search paths, searched after those given via -I. |
| MIM_PREFIX_PATH | Colon-separated list of install prefixes, searched after those given via --prefix-path. |
| NO_COLOR | Disables colored output if set to a non-empty value; wins over the two below. |
| CLICOLOR_FORCE | Forces colored output if set to a non-empty value other than 0. |
| CLICOLOR | Disables colored output if set to 0. |
Plugin Arguments
compile
| Argument | Description |
| aggr | Forces compile.aggr to tt, switching fixed-point iteration of the opt pipeline's optimize stage on (off by default). |
| no-aggr | Forces compile.aggr to ff, switching that fixed-point iteration off. |
ll
| Argument | Description |
| o=<file>, output=<file> | Writes the LLVM IR to <file> instead of the default <world>.ll/a.ll; <file> may be - for stdout. |
| rt=embed, rt=extern | How the C runtime wrappers reach the output: embed (default) splices their LLVM IR into the module; extern only declares them and leaves linking to you. |
ll_nvptx
| Argument | Description |
| o=<file>, output=<file> | Writes the host LLVM IR to <file> instead of the default <world>.ll/a.ll; <file> may be - for stdout. |
| o-dev=<file>, output-dev=<file> | Writes the device LLVM IR to <file> instead of the default <world>_dev.ll/a_dev.ll; <file> may be - for stdout. |
| rt=embed, rt=extern | Like ll's rt, but for the host module's C runtime wrappers such as @mim_cu_check. |
| embed, no-embed | Embeds the compiled device binary into the host LLVM IR, or doesn't; the default is embed on Linux and no-embed elsewhere. |
| no-ptx-embed | When embedding: omits the PTX image from the fat binary (default: both PTX and CUBIN). |
| no-cubin-embed | When embedding: omits the CUBIN image from the fat binary (default: both PTX and CUBIN). |
| sm=<SM> | When embedding: compiles the device binary for compute capability sm_<SM>. |
| libdevice=<path> | When embedding and linking libdevice: uses the NVVM library at <path> instead of locating it via the CUDA paths. |
| Xlink_llvm=<args> | When embedding and linking libdevice: passes <args> to link_llvm (default: none). |
| Xopt=<args> | When embedding and linking libdevice: passes <args> to opt (default: -passes="default<O2>,nvvm-reflect"). |
| Xllc=<args> | When embedding: passes <args> to llc (default: none). |
| Xptxas=<args> | When embedding: passes <args> to ptxas (default: none); also passed to fatbinary via --cmdline when the PTX image is embedded. |
| Xfatbinary=<args> | When embedding: passes <args> to fatbinary (default: none). |
tensor
| Argument | Description |
| reassoc-max=<n> | Longest matrix chain whose Catalan(n − 1) bracketings tensor.reassoc enumerates and, failing one that provably wins for every extent, dispatches over at run time (default 4; below 3 switches the dispatch off). |
| reassoc-vec=<n> | Vector lanes tensor.reassoc pads a product's vector loop to, so that a bracketing whose intermediates are too narrow to fill a vector is charged for the lanes it leaves idle (1 … 1024, default 8; 1 counts plain scalar multiplications). |
Plugin Environment Variables
ll_nvptx
| Variable | Description |
| CUDA_HOME | Root of the CUDA installation to locate libdevice in, if the CUDA paths do not yield one. |
Every output option accepts "-" to write to stdout.
- Note
- The Developer Options only exist if MimIR was built with MIM_ENABLE_CHECKS; see the CMake switches.
Diagnostics
Errors and warnings are reported as <file>:<row>:<col>: error: <message>, followed by the offending source line with a caret underneath and any notes indented below it. Pass --no-snippet to omit the source line and caret, e.g. when the output is consumed by a script. Use --loc-style to pick how much of a location that header spells out:
| <style> | Renders as |
| full | path:row:col-row:col (default) |
| rowcol | path:row:col |
| row | path:row |
| msvc | path(row,col) |
Plugins
Search Paths
Mim keeps three separate lookups, because the artifacts they find are different in kind: a plugin library is host-native code, a .mim is portable source, and a backend runtime belongs to the target.
Two kinds of entry feed them. A plain directory is probed as-is and is what -P / -I and their environment variables add. A prefix root stands for an install tree and derives <root>/lib/mim, <root>/share/mim, and <root>/lib/mim/rt from itself; --prefix-path / MIM_PREFIX_PATH add one, as do the install prefix and the tree libmim was loaded from.
| Looking for | Order |
| libmim_<name> | cwd, -P, MIM_PLUGIN_PATH, then each root's lib/mim |
| <name>.mim | cwd, -I, MIM_IMPORT_PATH, -P, MIM_PLUGIN_PATH, then each root's share/mim and lib/mim |
| runtime modules | cwd rt, -P and MIM_PLUGIN_PATH each with rt, then each root's lib/mim/rt |
Plugin directories are searched for imports too, since a plugin ships both of its halves together. mim -l prints all three lists fully resolved.
A plugin <name>; directive is special: its <name>.mim is taken from the directory libmim_<name> was actually loaded from, so the two halves of a plugin can never be paired up across different directories. A bare import <name>; has no such anchor and resolves by the table above, so spell an import of your own file as import "<name>.mim" if the name could collide with an installed plugin.
Arguments
Plugins - and in particular backends - often need to be configured from the command line. For example, a backend that invokes an external tool may want to forward optimization levels, a target triple for cross-compilation, or library paths. Use -X / --plugin-arg for this:
mim foo.mim -p ll -X ll:o=out.ll -X compile:aggr
The syntax is -X <plugin>:<arg>:
- The option is repeatable; each occurrence contributes one argument.
- Only the first : separates <plugin> from <arg>, so <arg> may itself contain : or = (e.g. Windows paths or key=value pairs).
- Arguments are keyed by plugin name and collected on the mim::Driver. A mim::Phase reads the arguments addressed to its own plugin via mim::Phase::args; the interpretation of each <arg> is up to the plugin.
Each plugin declares the arguments it understands right next to the code that reads them, so the -X <plugin>:<arg> tables under Usage are generated from those declarations.
Environment Variables
A plugin may also read environment variables - typically to locate an external toolchain it shells out to. It declares them as mim::PluginEnvs next to the code that reads them, so the Plugin Environment Variables tables under Usage are generated from those declarations, just like the -X tables above. Since a plugin only announces them once it is loaded, mim -p <plugin> --help lists the ones belonging to <plugin>.