Outline Outline • Unreachable-Code Elimination Unreachable Code Elimination Control-Flow and Low-Level • Straightening • If and Loop Simplifications If and Loop Simplifications Optimizations Optimizations • Loop Inversion and Unswitching • Branch Optimizations Branch Optimizations • Tail Merging (Cross Jumping) • Conditional Moves Conditional Moves • Dead-Code Elimination • Branch Prediction Branch Prediction • Peephole Optimization • Machine Idioms & Instruction Combining Machine Idioms & Instruction Combining Unreachable-Code Elimination Unreachable Code Elimination Unreachable Code Elimination Unreachable-Code Elimination entry y entry y Unreachable code is code that cannot be executed Unreachable code is code that cannot be executed, regardless of the input data c = a + b c = a + b – code that is never executable for any input data d th t i t bl f i t d t d = c d = c f = a + c e > c e > c – code that has become unreachable due to a previous g = e compiler transformation il t f ti a = e +c f = c – g f = c – g b c + 1 b = c + 1 b c + 1 b = c + 1 h = e + 1 Unreachable code elimination removes this code d = 4 * a d = 4 * a e = d – 7 e = d – 7 e < a – reduces the code space reduces the code space f = e + 2 f e + 2 f = e + 2 f e + 2 – improves instruction-cache utilization – enables other control-flow transformations enables other control-flow transformations exit it exit it
Straightening Straightening Straightening Example Straightening Example Straightening is applicable to pairs of basic blocks such Straightening is applicable to pairs of basic blocks such Straightening in the presence of fall throughs is tricky Straightening in the presence of fall-throughs is tricky... that the first has no successors other than the second L1: … L1: L1: L1: … and the second has no predecessors other than the first and the second has no predecessors other than the first a = b + c a = b + c goto L2 b = c * 2 a = a + 1 … … L6: … if c < 0 goto L3 a = b + c a = b + c a = b + c goto L4 t L4 goto L5 t L5 b = c * 2 b = c * 2 a = a + 1 L2: b c 2 L2: b = c * 2 L6: L6: … a = a + 1 c < 0 a = a + 1 goto L4 c < 0 if c < 0 goto L3 L5: … L5: … If Simplifications If Simplifications If Simplification Example If Simplification Example a > d a > d If simplifications apply to conditional constructs If simplifications apply to conditional constructs Y Y N N one or both of whose branches are empty: b = a b = a b – if either the then or the else part of an if -construct is c = 4 * b c = 4 * b (a >= d) or bool empty, the corresponding branch can be eliminated Y Y N N – one branch of an if with a constant-valued condition d = b d = c d = b can also be eliminated – we can also simplify if s whose condition, C, occurs e = a + b e = a + b in the scope of a condition that implies C (and none in the scope of a condition that implies C (and none of the condition’s operands has changed value) … …
Loop Simplifications Loop Simplifications Loop Simplification Example Loop Simplification Example • A loop whose body is empty can be eliminated • A loop whose body is empty can be eliminated s = 0 0 i = 0 if the iteration-control code has no side-effects s = 0 i = i + 1 i i + 1 i = 0 (Side-effects might be simple enough that they can be s = s + i i = 4 L1: if i >= 4 goto L2 replaced with non-looping code at compile time) i = i + 1 s 10 s = 10 i i = i + 1 i + 1 s = s + i L2: … s = s + i i = i + 1 goto L1 goto L1 • If number of iterations is small enough loops • If number of iterations is small enough, loops s s = s + i s + i L2: … i = i + 1 can be unrolled into branchless code and the s = s + i s s i loop body can be executed at compile time l b d b d il i L2: … Loop Inversion Loop Inversion Loop Inversion Example 1 Loop Inversion Example 1 Loop inversion transforms a while loop into a Loop inversion transforms a while loop into a for (i = 0; i < 100; i++) { for (i = 0; i < 100; i++) { Loop bounds Loop bounds are known repeat loop (i.e. moves the loop-closing test a[i] = i + 1; } } from before the loop to after it). – Has the advantage that only one branch instruction g y needs to be executed to close the loop. – Requires that we determine that the loop is entered Requires that we determine that the loop is entered i = 0; i = 0; i i = 0; 0 at least once! while (i < 100) { do { a[i] = i + 1; a[i] i + 1; a[i] = i + 1; a[i] = i + 1; i++; i++; } } while (i < 100) } while (i 100)
Loop Inversion Example 2 Loop Inversion Example 2 Unswitching Unswitching Unswitching is a control-flow transformation that Unswitching is a control flow transformation that moves loop-invariant conditional branches out if (k > n) goto L if (k >= n) goto L of loops of loops for (i = k; i < n; i++) { i = k; if (k == 2) { a[i] = i + 1; do { do { for (i = 1; i < 100; i++) { for (i = 1; i < 100; i++) { for (i = 1; i < 100; i++) } a[i] = i + 1; if (k == 2) a[i] = a[i] + 1; i++; ; a[i] a[i] + 1; a[i] = a[i] + 1; } else { } l { } while (i < n) Loop bounds else for (i = 1; i < 100; i++) L: are unknown a[i] = a[i] – 1; a[i] a[i] 1; a[i] = a[i] – 1; a[i] a[i] 1; } } Unswitching Example Unswitching Example Branch Optimizations Branch Optimizations Branches to branches are remarkably common! Branches to branches are remarkably common! – An unconditional branch to an unconditional branch can be if (k == 2) { replaced by a branch to the latter s target replaced by a branch to the latter’s target for (i = 1; i < 100; i++) { for (i = 1; i < 100; i++) { – A conditional branch to an unconditional branch can be if (a[i] > 0) replaced by the corresponding conditional branch to the replaced by the corresponding conditional branch to the if (k if (k == 2 && a[i] > 0) 2 && a[i] > 0) a[i] = a[i] + 1; [i] [i] + 1 latter branch’s target a[i] = a[i] + 1; } – An unconditional branch to a conditional branch can be } } } else { } else { replaced by a copy of the conditional branch i = 100; – A conditional branch to a conditional branch can be replaced } by a conditional branch with the former’s test and the latter’s target as long as the latter condition is true whenever the f former one is i
Branch Optimization Examples Branch Optimization Examples Eliminating Useless Control-Flow Eliminating Useless Control Flow The Problem: The Problem: if a == 0 goto L1 if 0 t L1 if a == 0 goto L2 if 0 t L2 … … – After optimization, the CFG might contain empty blocks L1: if a >= 0 goto L2 L1: if a 0 goto L2 L1: if a L1: if a >= 0 goto L2 0 goto L2 – “Empty” blocks still end with either a branch or jump … … – Produces jump to jump, which wastes time and space L2: … L2: … The Algorithm: ( Clean ) The Algorithm: ( Clean ) g goto L1 L1: … L1: … – Use four distinct transformations – Apply them in a carefully selected order A l h i f ll l d d if a == 0 goto L1 if a != 0 goto L2 goto L2 – Iterate until done L1: … L1: L1: … L1 Eliminating Useless Control-Flow Eliminating Useless Control Flow Eliminating Useless Control Flow Eliminating Useless Control-Flow Transformation 1 Transformation 1 Transformation 2 Transformation 2 Merging an empty block Merging an empty block Both sides of branch target B2 Both sides of branch target B2 – Empty B1 ends with a jump – Neither block must be empty B1 B1 B1 B1 empty empty – Coalesce B1 and B2 Coalesce B1 and B2 – Replace it with a jump to B1 R l it ith j t B1 B1 – Move B1’s incoming edges – Simple rewrite of the last – Eliminates extraneous jump j p operation in B1 operation in B1 B2 B2 – Faster, smaller code B2 B2 B2 Branch, not a jump B h t j How does this happen? How does this happen? Eliminating redundant branches – By rewriting other branches Eliminating empty blocks – By eliminating operations in B1 By eliminating operations in B1 How do we recognize it? How do we recognize it? – Check each branch – Test for empty block Test for empty block
Recommend
More recommend