Content
- Overview- Local: Backward Copy Propagation
- Local: Common Subexpression Elimination
- Global: Induction Variable Elimination
- Global: Common Subexpression Elimination
- Global: Data Flow Analysis- Reachability Analysis
- Availability Analysis
 
 
Overview
- Local- Constant folding
- Constant combining
- Strength reduction
- Constant propagation
- Common subexpression elimination
- Backward copy propagation
 
- Global- Deadcode elimination
- Constant propagation
- Forward copy propagation
- Common subexpression elimination
- Code motion
- Loop strength reduction
- Induction variable elimination
 
Local: Backward Copy Propagation

- Rules- Xand- Yin same block
- Yis a move to register
- dest(X)is not live out of the block
- Yuses- dest(X)
- dest(Y)not used between- Xand- Y
- dest(X)not used after the first redef of- dest(Y)
- Replace src(Y)withdest(Y)on pathXtoY
 
Local: Common Subexpression Elimination

- Rules- Xand- Yhave same opcode;- Yfollows- X
- src(X) = src(Y)for all srcs
- No def of src between XandYfor all srcs
- No def of dest(X)betweenXandY
- Replace Ywithdest(Y) = dest(X)
 
Global: Induction Variable Elimination

Global: Common Subexpression Elimination

- Rules- Xand- Yhave same opcode;- Xdominates- Y
- src(X) = src(Y)for all srcs
- No def of src between XandYfor all srcs
- Insert rx = dest(X)afterX
- Replace Ywithdest(Y) = rx
 
Dominance
ndominatesmif all paths tomgoes throughn
Global: Data Flow Analysis
Liveliness and reachability are important knowledge derived from data flow analysis. Used for applications e.g. CSE, copy propagation, etc.
Reachability Analysis
Whether a definition reaches a statement.
in[B]     - variables live on entry of B
out[B]    - variables live on exit of B
gen[B]    - definitions generated by B
kill[B]   - subsequent definitions killing those in B | killed by B
gen[n: v = f(...)] = {n}
kill[n] = defs[v] - {n} if n defines v
in[n] = ∪_pred_P_of_n(out[P])
out[n] = gen[n] ∪ (in[n] - kill[n])

Availability Analysis
For CSE, reachability is not safe.
in[n] = ∩_pred_P_of_n(out[P]) if n not entry
out[n] = gen[n] ∪ (in[n] - kill[n])
If (<x op y> reaches s ≡ b = x op y) && (s is in B):
    For all s' s.t. (s' ≡ z = x op y) && (s' reaches s):
        Replace s' by (t1 = x op y; z = t1;) where t1 is the same for all s'
    Replace s by (b = t1;)
 

If the subexpression is expensive, better reuse the result even it comes from only 1 branch.
Glossary
- Define: an expression having its value computed at point p
- Kill: one of the arguments of an expression is redefined at point p
- Available: every path leading to point p contains a prior definition of an expression that is not killed between its definition and p
