1 / 17

Code Optimization Circa 1969

Code Optimization Circa 1969. Flow Graphs Constant Folding Global Common Subexpressions Induction Variables/Reduction in Strength. Jeffrey D. Ullman Stanford University. Dawn of Code Optimization. A never-published Stanford technical report by Fran Allen in 1968 .

ura
Download Presentation

Code Optimization Circa 1969

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Code Optimization Circa 1969 Flow GraphsConstant FoldingGlobal Common SubexpressionsInduction Variables/Reduction in Strength Jeffrey D. Ullman Stanford University

  2. Dawn of Code Optimization • A never-published Stanford technical report by Fran Allen in 1968. • Fran won the Turing award in 2006. • Flow graphs of intermediate code. • Key things worth doing.

  3. Intermediate Code • 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.

  4. Example: Intermediate Code • Here’s typical source code: for (i=0; i<n; i++) A[i] = 1.0; • Intermediate code exposes optimizable constructs we cannot see at source-code level. i = 0 L1: if i>n goto L2 t1 = 8*i A[t1] = 1.0 i = i+1 goto L1 L2: ... Notice hidden offset calculation.

  5. Basic Blocks • 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 = • First statement. • Statements targeted by a branch or goto. • Statements following a branch. • Simplification: make each intermediate-code statement its own basic block. • Saves the trouble of figuring out data flow within blocks.

  6. i = 0 if i>n goto … t1 = 8*i A[t1] = 1.0 i = i+1 Example: Basic Blocks i = 0 L1: if i>n goto L2 t1 = 8*i A[t1] = 1.0 i = i+1 goto L1 L2: ...

  7. Induction Variables • x is an induction variableat 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).

  8. Example: Replace i by t1 • 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 = t1 + 8. • 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.

  9. i = 0 if i>n goto … t1 = 8*i A[t1] = 1.0 i = i+1 Example: Eliminating i Needed to express condition i <= n in terms of t1 t1 = 0 n1 = 8*n if t1>n1 goto … A[t1] = 1.0 t1 = t1+8 Question: is that always good? Initialization block grows, but the loop block shrinks

  10. Loop-Invariant Code Motion • 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. Example: y+z is Loop-Invariant So move computation of t1 here and compute it only once i = 0 i = 0 t1 = y+z if i>n goto … if i>n goto … t1 = y+z x = x+t1 i = i+1 x = x+t1 i = i+1 Neither y nor z changes within the loop

  12. Constant Folding • 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 Example: First Flowgraph, but Fixed n Notice n1 is no longer needed So make the substitution at compile time Only possible assignment to this n1 is n1 = 800 t1 = 0 n1 = 8*100 t1 = 0 if t1>n1 goto … if t1>800 goto … A[t1] = 1.0 t1 = t1+8 A[t1] = 1.0 t1 = t1+8 Not only did we eliminate n1, but comparison of a variable And a constant can’t be worse than comparing two variables.

  14. Global Common Subexpressions • Suppose block B has a computation of x+y. • Suppose we are certain that when we reach this computation, we have: • Computed x+y, and • Not subsequently reassigned x or y. • Then we can hold the value of x+yin a temporary variable and use it in B.

  15. a = x+y t = x+y a = t b = x+y t = x+y b = t c = x+y c = t Example: Common Subexpression Elimination 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

  16. Partial Redundancy Elimination • Not known in 1969. • 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.

  17. t = x+y a = t t = x+y b = t c = t Example: Partial Redundancy Elimination We may already have computed x+y So duplicate the block, depending on how it is reached t = x+y a = t b = t t = x+y b = t c = t Here, t already holds the value we need for b Here it doesn’t; so compute it

More Related