Expand description
A jump threading optimization.
This optimization seeks to replace join-then-switch control flow patterns by straight jumps X = 0 X = 0 ————\ /–––– ———— X = 1 X––X SwitchInt(X) => X = 1 ————/ -—–– ————
We proceed by walking the cfg backwards starting from each SwitchInt terminator,
looking for assignments that will turn the SwitchInt into a simple Goto.
The algorithm maintains a set of replacement conditions:
conditions[place]containsCondition { value, polarity: Eq, target }if assigningvaluetoplaceturns theSwitchIntintoGoto { target }.conditions[place]containsCondition { value, polarity: Ne, target }if assigning anything different fromvaluetoplaceturns theSwitchIntintoGoto { target }.
In this file, we denote as place ?= value the existence of a replacement condition
on place with given value, irrespective of the polarity and target of that
replacement condition.
We then walk the CFG backwards transforming the set of conditions.
When we find a fulfilling assignment, we record a ThreadingOpportunity.
All ThreadingOpportunitys are applied to the body, by duplicating blocks if required.
The optimization search can be very heavy, as it performs a DFS on MIR starting from
each SwitchInt terminator. To manage the complexity, we:
- bound the maximum depth by a constant
MAX_BACKTRACK; - we only traverse
Gototerminators.
We try to avoid creating irreducible control-flow by not threading through a loop header.
Likewise, applying the optimisation can create a lot of new MIR, so we bound the instruction
cost by MAX_COST.
Structs§
- Condition 🔒
- Represent the following statement. If we can prove that the current local is equal/not-equal
to
value, jump totarget. - Condition
Set 🔒 - Jump
Threading 🔒 - Opportunity
Set 🔒 - TOFinder 🔒
- Threading
Opportunity 🔒
Enums§
Constants§
- MAX_
BACKTRACK 🔒 - MAX_
COST 🔒 - MAX_
PLACES 🔒