Module rustc_mir_transform::simplify
source · Expand description
A number of passes which remove various redundancies in the CFG.
The SimplifyCfg
pass gets rid of unnecessary blocks in the CFG, whereas the SimplifyLocals
gets rid of all the unnecessary local variable declarations.
The SimplifyLocals
pass is kinda expensive and therefore not very suitable to be run often.
Most of the passes should not care or be impacted in meaningful ways due to extra locals
either, so running the pass once, right before codegen, should suffice.
On the other side of the spectrum, the SimplifyCfg
pass is considerably cheap to run, thus
one should run it after every pass which may modify CFG in significant ways. This pass must
also be run before any analysis passes because it removes dead blocks, and some of these can be
ill-typed.
The cause of this typing issue is typeck allowing most blocks whose end is not reachable have an arbitrary return type, rather than having the usual () return type (as a note, typeck’s notion of reachability is in fact slightly weaker than MIR CFG reachability - see #31617). A standard example of the situation is:
fn example() {
let _a: char = { return; };
}
Here the block ({ return; }
) has the return type char
, rather than ()
, but the MIR we
naively generate still contains the _a = ()
write in the unreachable block “after” the
return.
Structs
- Keeps track of used & unused locals.
Enums
Functions
- Construct the mapping while swapping out unused stuff out from the
vec
. - Removes unused definitions. Updates the used locals to reflect the changes made.
- Some MIR transforms can determine at compile time that a sequences of statements will never be executed, so they can be dropped from the MIR. For example, an
if
orelse
block that is guaranteed to never be executed because its condition can be evaluated at compile time, such as by const evaluation:if false { ... }
.