Next: Forward ICR optimizations, Previous: Goals for ICR optimizations, Up: ICR optimize [Contents]
Things done:
We take care not to merge blocks that are in different functions or have different cleanups. This guarantees that non-local exits are always at block ends and that cleanup code never needs to be inserted within a block.
We eliminate IFs with identical consequent and alternative. This would most likely happen if both the consequent and alternative were optimized away.
[Could also be done if the consequent and alternative were different blocks, but computed the same value. This could be done by a sort of cross-jumping optimization that looked at the predecessors for a block and merged code shared between predecessors. IFs with identical branches would eventually be left with nothing in their branches.]
We eliminate IF-IF constructs:
(IF (IF A B C) D E) ==> (IF A (IF B D E) (IF C D E))
In reality, what we do is replicate blocks containing only an IF node where the predicate continuation is the block start. We make one copy of the IF node for each use, leaving the consequent and alternative the same. If you look at the flow graph representation, you will see that this is really the same thing as the above source to source transformation.