Global Optimization
Lecture Outline • Global flow analysis • Global constant propagation • Liveness analysis 2 Compiler Design I (2011)
Local Optimization Recall the simple basic-block optimizations – Constant propagation – Dead code elimination x := 42 x := 42 y := z * w y := z * w y := z * w q := y + x q := y + 42 q := y + 42 3 Compiler Design I (2011)
Global Optimization These optimizations can be extended to an entire control-flow graph x := 42 b > 0 y := z * w y := 0 q := y + x 4 Compiler Design I (2011)
Global Optimization These optimizations can be extended to an entire control-flow graph x := 42 b > 0 y := z * w y := 0 q := y + x 5 Compiler Design I (2011)
Global Optimization These optimizations can be extended to an entire control-flow graph x := 42 b > 0 y := z * w y := 0 q := y + 42 6 Compiler Design I (2011)
Correctness • How do we know it is OK to globally propagate constants? • There are situations where it is incorrect: x := 42 b > 0 y := z * w y := 0 x := 54 q := y + x 7 Compiler Design I (2011)
Correctness (Cont.) To replace a use of x by a constant k we must know that the following property ** holds: On every path to the use of x, the last assignment to x is x := k ** 8 Compiler Design I (2011)
Example 1 Revisited x := 42 b > 0 y := z * w y := 0 q := y + x 9 Compiler Design I (2011)
Example 2 Revisited x := 42 b > 0 y := z * w y := 0 x := 54 q := y + x 10 Compiler Design I (2011)
Discussion • The correctness condition is not trivial to check • “All paths” includes paths around loops and through branches of conditionals • Checking the condition requires global analysis – An analysis that determines how data flows over the entire control-flow graph 11 Compiler Design I (2011)
Global Analysis Global optimization tasks share several traits: – The optimization depends on knowing a property P at a particular point in program execution – Proving P at any point requires knowledge of the entire function body – It is OK to be conservative: If the optimization requires P to be true, then want to know either • that P is definitely true, or • that we don’t know whether P is true – It is always safe to say “don’t know” 12 Compiler Design I (2011)
Global Analysis (Cont.) • Global dataflow analysis is a standard technique for solving problems with these characteristics • Global constant propagation is one example of an optimization that requires global dataflow analysis 13 Compiler Design I (2011)
Global Constant Propagation • Global constant propagation can be performed at any point where property ** holds • Consider the case of computing ** for a single variable x at all program points 14 Compiler Design I (2011)
Global Constant Propagation (Cont.) • To make the problem precise, we associate one of the following values with x at every program point value interpretation This statement never executes # c x = constant c * Don’t know whether X is a constant 15 Compiler Design I (2011)
Example x = * x := 42 x = 42 b > 0 x = 42 x = 42 y := z * w y := 0 x = 42 x := 54 x = 42 x = 54 x = * q := y + x x = * 16 Compiler Design I (2011)
Using the Information • Given global constant information, it is easy to perform the optimization – Simply inspect the x = ? associated with a statement using x – If x is constant at that point replace that use of x by the constant • But how do we compute the properties x = ? 17 Compiler Design I (2011)
The Analysis Idea The analysis of a (complicated) program can be expressed as a combination of simple rules relating the change in information between adjacent statements 18 Compiler Design I (2011)
Explanation • The idea is to “push” or “transfer” information from one statement to the next • For each statement s, we compute information about the value of x immediately before and after s C in (x,s) = value of x before s C out (x,s) = value of x after s 19 Compiler Design I (2011)
Transfer Functions • Define a transfer function that transfers information from one statement to another • In the following rules, let statement s have as immediate predecessors statements p 1 ,…,p n 20 Compiler Design I (2011)
Rule 1 x = * x = ? x = ? x = ? x = * s if C out (x, p i ) = * for any i, then C in (x, s) = * 21 Compiler Design I (2011)
Rule 2 x = d x = ? x = c x = ? x = * s If C out (x, p i ) = c and C out (x, p j ) = d and d ≠ c then C in (x, s) = * 22 Compiler Design I (2011)
Rule 3 x = c x = # x = c x = # x = c s if C out (x, p i ) = c or # for all i, then C in (x, s) = c 23 Compiler Design I (2011)
Rule 4 x = # x = # x = # x = # x = # s if C out (x, p i ) = # for all i, then C in (x, s) = # 24 Compiler Design I (2011)
The Other Half • Rules 1-4 relate the out of one statement to the in of the successor statement • We also need rules relating the in of a statement to the out of the same statement 25 Compiler Design I (2011)
Rule 5 x = # s x = # C out (x, s) = # if C in (x, s) = # 26 Compiler Design I (2011)
Rule 6 x = ? x := c x = c C out (x, x := c) = c if c is a constant 27 Compiler Design I (2011)
Rule 7 x = ? x := f(…) x = * C out (x, x := f(…)) = * This rule says that we do not perform inter-procedural analysis (i.e. we do not look at other functions do) 28 Compiler Design I (2011)
Rule 8 x = a y := . . . x = a C out (x, y := …) = C in (x, y := …) if x ≠ y 29 Compiler Design I (2011)
An Algorithm 1. For every entry s to the function, set C in (x, s) = * 2. Set C in (x, s) = C out (x, s) = # everywhere else 3. Repeat until all points satisfy 1-8: Pick s not satisfying 1-8 and update using the appropriate rule 30 Compiler Design I (2011)
The Value # To understand why we need #, look at a loop x = * x := 42 x = 42 b > 0 x = 42 x = 42 y := z * w y := 0 x = 42 q := y + x q < b 31 Compiler Design I (2011)
Discussion • Consider the statement y := 0 • To compute whether x is constant at this point, we need to know whether x is constant at the two predecessors – x := 42 – q := y + x • But information for q := y + x depends on its predecessors, including y := 0! 32 Compiler Design I (2011)
The Value # (Cont.) • Because of cycles, all points must have values at all times • Intuitively, assigning some initial value allows the analysis to break cycles • The initial value # means “So far as we know, control never reaches this point” 33 Compiler Design I (2011)
Example x = * x := 42 x = 42 b > 0 x = 42 x = 42 y := z * w y := 0 x = 42 x = # x = # q := x + y x = # q < b 34 Compiler Design I (2011)
Example x = * x := 42 x = 42 b > 0 x = 42 x = 42 y := z * w y := 0 x = 42 x = # x = 42 q := x + y x = # q < b 35 Compiler Design I (2011)
Example x = * x := 42 x = 42 b > 0 x = 42 x = 42 y := z * w y := 0 x = 42 x = # x = 42 q := x + y x = 42 q < b 36 Compiler Design I (2011)
Example x = * x := 42 x = 42 b > 0 x = 42 x = 42 y := z * w y := 0 x = 42 x = 42 x = 42 q := x + y x = 42 q < b 37 Compiler Design I (2011)
Orderings • We can simplify the presentation of the analysis by ordering the values # < c < * • Drawing a picture with “lower” values drawn lower, we get * -1 0 1 ... ... # 38 Compiler Design I (2011)
Orderings (Cont.) • * is the greatest value, # is the least – All constants are in between and incomparable • Let lub be the least-upper bound in this ordering • Rules 1-4 can be written using lub: C in (x, s) = lub { C out (x, p) | p is a predecessor of s } 39 Compiler Design I (2011)
Termination • Simply saying “repeat until nothing changes” doesn’t guarantee that eventually we reach a point where nothing changes • The use of lub explains why the algorithm terminates – Values start as # and only increase – # can change to a constant, and a constant to * – Thus, C_(x, s) can change at most twice 40 Compiler Design I (2011)
Termination (Cont.) Thus the algorithm is linear in program size Number of steps = Number of C_(….) values computed * 2 = Number of program statements * 4 41 Compiler Design I (2011)
Liveness Analysis Once constants have been globally propagated, we would like to eliminate dead code x := 42 b > 0 y := z * w y := 0 q := y + x After constant propagation, x := 42 is dead (assuming x is not used elsewhere) 42 Compiler Design I (2011)
Live and Dead Variables • The first value of x is x := 42 dead (never used) • The second value of x is x := 54 live (may be used) • Liveness is an important concept for the compiler y := x 43 Compiler Design I (2011)
Liveness A variable x is live at statement s if – There exists a statement s’ that uses x – There is a path from s to s’ – That path has no intervening assignment to x 44 Compiler Design I (2011)
Recommend
More recommend