Presentation on theme: "Jeffrey D. Ullman Stanford University. 2 A never-published Stanford technical report by Fran Allen in 1968. Fran won the Turing award in 2006. Flow."— Presentation transcript:
Jeffrey D. Ullman Stanford University
2 A never-published Stanford technical report by Fran Allen in Fran won the Turing award in Flow graphs of intermediate code. Key things worth doing.
Steps with < 3 addresses (2 operands + result). Assignments with < 1 arithmetic operator. Examples: x = 0; x = y; x = y+z but not x = w+y*z. Indirection and pointer access. Examples: x = *p; p = &x; x = a[i]; x[i] = y. Branches with one comparison operator, gotos. Examples: if x == 0 goto s1; goto s2 but not if x == 0 || y == 1 goto s3. Call, return. Arguments copied like assignments w/o operator. 3
4 Here’s typical source code: for (i=0; in goto L2 t1 = 8*i A[t1] = 1.0 i = i+1 goto L1 L2:... Notice hidden offset calculation.
Make flow explicit by breaking into basic blocks = sequences of steps with entry at beginning, exit at end, no branches in interior. Break intermediate code at leaders = 1.First statement. 2.Statements targeted by a branch or goto. 3.Statements following a branch. Simplification: make each intermediate-code statement its own basic block. Saves the trouble of figuring out data flow within blocks. 5
6 i = 0 if i>n goto … t1 = 8*i A[t1] = 1.0 i = i+1 i = 0 L1: if i>n goto L2 t1 = 8*i A[t1] = 1.0 i = i+1 goto L1 L2:...
7 x is an induction variable at a point within a loop if it takes on a linear sequence of values each time through that point. One induction variable can do the job of another. Common case: loop index like i and computed array offset like t1. We really don’t need i. Replace multiplication by addition (reduction in strength).
In the basic block t1 = 8*i; A[t1] = 1.0; i = i+1, t1 = 8i at the point where t1 is used, at A[t1] = 1.0. Replace i = i+1 by t1 = t Initialize t1 = 0. Now, t1 always has value 8i where it is used, even though its calculation does not depend on i. We can drop i = 0 and t1 = 8*i altogether if we replace the test i <= n. 8
9 i = 0 if i>n goto … t1 = 8*i A[t1] = 1.0 i = i+1 t1 = 0 n1 = 8*n if t1>n1 goto … A[t1] = 1.0 t1 = t1+8 Needed to express condition i <= n in terms of t1 Initialization block grows, but the loop block shrinks Question: is that always good?
10 Sometimes, a computation is done each time around a loop. Move it before the loop to save n-1 computations. Be careful: could n=0? I.e., the loop is typically executed 0 times.
11 i = 0 if i>n goto … t1 = y+z x = x+t1 i = i+1 i = 0 t1 = y+z if i>n goto … x = x+t1 i = i+1 Neither y nor z changes within the loop So move computation of t1 here and compute it only once
12 Sometimes a variable has a known constant value at a point. If so, replacing the variable by the constant simplifies and speeds-up the code. Easy within a basic block; harder across blocks.
13 i = 0 n = 100 if i>n goto … t1 = 8*i A[t1] = 1.0 i = i+1 t1 = 0 n1 = 8*100 if t1>n1 goto … A[t1] = 1.0 t1 = t1+8 Only possible assignment to this n1 is n1 = 800 t1 = 0 if t1>800 goto … A[t1] = 1.0 t1 = t1+8 So make the substitution at compile time Notice n1 is no longer needed Not only did we eliminate n1, but comparison of a variable And a constant can’t be worse than comparing two variables.
14 Suppose block B has a computation of x+y. Suppose we are certain that when we reach this computation, we have: 1.Computed x+y, and 2.Not subsequently reassigned x or y. Then we can hold the value of x+y in a temporary variable and use it in B.
15 a = x+y b = x+y c = x+y t = x+y a = t t = x+y b = t c = t t holds value of x+y Every place x+y might be computed prior to c = x+y We know t has the right value here
Not known in Sometimes, an expression has been computed along some paths to a block B, but not along others. Replicate the block so the expression is computed exactly when it is needed. 16
17 t = x+y a = t b = t c = t t = x+y a = t t = x+y b = t c = t t = x+y b = t We may already have computed x+y So duplicate the block, depending on how it is reached Here, t already holds the value we need for b Here it doesn’t; so compute it