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 ————/ -—–– ————
This implementation is heavily inspired by the work outlined in libfirm.
The general algorithm proceeds in two phases: (1) walk the CFG backwards to construct a graph of threading conditions, and (2) propagate fulfilled conditions forward by duplicating blocks.
§1. Condition graph construction
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.
Inside a block, we associate with each condition c a set of targets:
Goto(target)if fulfillingcchanges the terminator into aGoto { target };Chain(target, c2)if fulfillingcmeans thatc2is fulfilled insidetarget.
Before walking a block bb, we construct the exit set of condition from its successors.
For each condition c in a successor s, we record that fulfilling c in bb will fulfill
c in s, as a Chain(s, c) condition.
When encountering a switchInt(place) -> [value: bb...] terminator, we also record a
place == value condition for each value, and associate a Goto(target) condition.
Then, we walk the statements backwards, transforming the set of conditions along the way, resulting in a set of conditions at the block entry.
We try to avoid creating irreducible control-flow by not threading through a loop header.
Applying the optimisation can create a lot of new MIR, so we bound the instruction
cost by MAX_COST.
§2. Block duplication
We now have the set of fulfilled conditions inside each block and their targets.
For each block bb in reverse postorder, we apply in turn the target associated with each
fulfilled condition:
- for
Goto(target), change the terminator ofbbinto aGoto { target }; - for
Chain(target, cond), duplicatetargetinto a new block which fulfills the same conditions and also fulfillscond. This is made efficient by maintaining a map of duplicates,duplicate[(target, cond)]to avoid cloning blocks multiple times.
Structs§
- Condition 🔒
- Represent the following statement. If we can prove that the current local is equal/not-equal
to
value, jump totarget. - Condition
Index 🔒 - Condition
Set 🔒 - Jump
Threading 🔒 - Opportunity
Set 🔒 - TOFinder 🔒
Enums§
- Edge
Effect 🔒 - Represent the effect of fulfilling a condition.
- Polarity 🔒
Constants§
- MAX_
COST 🔒 - MAX_
PLACES 🔒
Functions§
- remove_
costly_ 🔒conditions - simplify_
conditions 🔒 - Propagate fulfilled conditions forward in the CFG to reduce the amount of duplication.