SSA-based Optimizations Compiler Baojian Hua bjhua@ustc.edu.cn
SSA-based Optimizations translation AST IR1 opt translation SSA opt opt other IR and translation asm
SSA-based Optimization SSA is an IR which makes optimizations: faster and easier This time, we will re-study the previous dataflow-based optimizations, and to see how SSA be of a help constant propagation, copy propagation, dead-code elimination, constant folding, conditional constant propagation, ...
Constant propagation x = 3 … Each variable has just one unique definition, so we can substitute every use of x with 3. … a = x Can we replace this “x” with constant “3”?
Constant Propagation Example j = 1 k = 0 Constant propagation candidates. 1 1 1 The definitions becomes dead code. Why? 1 1 2 j = Φ(j , j ) k = Φ(k , k ) k < 100? 2 1 5 Copy propagation, dead-code elimination can be performed in a similar way. Leave to you. 2 1 5 2 3 4 j < 20? return j Does block 6 ever execute? 2 2 5 1 6 j = i k = k + 1 j = k k = k + 2 3 1 2 4 3 2 4 2 1 j = Φ(j , j ) k = Φ(k , k ) 7 5 3 4 5 3 4
Constant Propagation Example j = 1 k = 0 We found an invariant: j2==1. Assume blocks don’t execute until proven otherwise. Assume values are constants until proven otherwise. 1 1 1 1 j2==1; k2==0 1 To find this, we need conditional constant propagation. 2 j = Φ(j , j ) k = Φ(k , k ) k < 100? 2 1 5 j2==1; k2==1 2 1 5 j2==1; k2==2 2 3 4 j < 20? return j Does block 6 ever execute? 2 2 5 1 6 j = i k = k + 1 j = k k = k + 2 3 1 2 4 j2==1; k3==1 3 2 4 2 j2==1; k3==2 1 j = Φ(j , j ) k = Φ(k , k ) 7 5 3 4 j5==1; k5==1 5 3 4 j5==1; k5==2
Lattice block will executes T no evidence block will execute Information flows down upwards! variable may be of different constant T … -2 -1 1 2 … evidence is seen that variable is constant n no evidence variable is a constant
Lattice Example block 6 is dead! 1 2 3 4 5 6 7 T j2==1 j3==1 j5==1 T j = Φ(1 , j ) k = Φ(0 , k ) k < 100? 2 5 2 5 2 3 4 j2 k2 j3 k3 j4 k4 j5 k5 1 j < 20? return j 2 2 5 6 j = 1 k = k + 1 j = k k = k + 2 3 2 4 1 1 1 1 1 3 2 4 2 1 T T T j = Φ(j , j ) k = Φ(k , k ) 7 5 3 4 5 3 4
Lattice Example i = 1 j = 1 k = 0 1 1 2 k = Φ(0 , k ) k < 100? 2 j = Φ(j , j ) k = Φ(k , k ) k < 100? 2 3 2 1 5 2 1 5 2 2 4 3 4 return 1 j < 20? return j 2 2 5 5 6 k = k + 1 j = i k = k + 1 j = k k = k + 2 3 1 2 4 3 2 3 2 4 2 j = Φ(j , j ) k = Φ(k , k ) 7 5 3 4 5 3 4
Aggressive Dead Code Elimination Do you notice the “useless” code on the left? 1 A statement is live, iff: 1. has side effect (I/O, call, store, …), and 2. defines a var which is used in live stm. 2 k = Φ(0 , k ) k < 100? 2 3 2 Lattice algorithm again: init live stm mark all other dead until proven to be live. 4 return 1 5 k = k + 1 return 1 3 2 This function can be further inlined and eliminated!
Aggressive Dead Code Elimination: pitfalls A statement is live, iff: 1. has side effect (I/O, call, store, …), and 2. defines a var which is used in live stm. 1 The 2nd property is call data-dependency! 2 k = Φ(0 , k ) k < 100? live 2 3 Should this be deleted? 2 4 return k live 2 5 k = k + 1 We need a notion of control-dependency! live 3 2
Fixing this problem If a statement S is live, then if T S is control-dependent on T, T should also be live x = 3 x<10? … live …
Control Dependency A block Y is control-dependent on X iff there exists an edge X->v, which v->exit goes through Y there exists a path X->exit which does not go through y X X u v u v Y Y exit exit
Aggressive Dead Code Elimination Example CFG reverse CFG 1 1 1 2 k = Φ(0 , k ) k < 100? 2 2 2 3 2 5 4 5 4 exit exit 4 return k 2 5 5 1 r k = k + 1 3 2 2 n 1 2 4 5 r DF {r} {2, r} {2} {} 4 exit
Aggressive Dead Code Elimination Example CDG 1 1 2 k = Φ(0 , k ) k < 100? live 2 2 3 live 2 5 4 4 return k live 2 5 k = k + 1 n 1 2 4 5 r DF {r} {2, r} {2} {} live 3 2
Aggressive Dead Code Elimination Example CDG 1 1 2 k = Φ(0 , k ) k < 100? 2 2 3 2 5 4 4 return 1 live return 1 5 k = k + 1 n 1 2 4 5 r DF {r} {2, r} {2} {} 3 2