MIR optimizations are optimizations run on the MIR to produce better MIR before codegen. This is important for two reasons: first, it makes the final generated executable code better, and second, it means that LLVM has less work to do, so compilation is faster. Note that since MIR is generic (not monomorphized yet), these optimizations are particularly effective; we can optimize the generic version, so all of the monomorphizations are cheaper!
MIR optimizations run after borrow checking. We run a series of optimization
passes over the MIR to improve it. Some passes are required to run on all code,
some passes don't actually do optimizations but only check stuff, and some
passes are only turned on in
optimized_mir query is called to produce the optimized MIR
for a given
DefId. This query makes sure that the borrow checker has
run and that some validation has occurred. Then, it steals the MIR,
optimizes it, and returns the improved MIR.
The list of passes run and the order in which they are run is defined by the
run_optimization_passes function. It contains an array of passes to
run. Each pass in the array is a struct that implements the
The array is an array of
&dyn MirPass trait objects. Typically, a pass is
implemented in its own submodule of the
Some examples of passes are:
CleanupNonCodegenStatements: remove some of the info that is only needed for analyses, rather than codegen.
ConstProp: Does constant propagation
You can see the "Implementors" section of the
MirPass rustdocs for more examples.
MIR optimizations can come in various levels of readiness. Experimental
optimizations may cause miscompilations, or slow down compile times.
These passes are still included in nightly builds to gather feedback and make it easier to modify
the pass. To enable working with slow or otherwise experimental optimization passes,
you can specify the
-Z mir-opt-level debug flag. You can find the
definitions of the levels in the compiler MCP. If you are developing a MIR pass and
want to query whether your optimization pass should run, you can check the
current level using