109 Views

Download Presentation
##### SSA: Static Single-Assignment Form

**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. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -

**SSA: Static Single-Assignment Form**Compiler Baojian Hua bjhua@ustc.edu.cn**Middle End**translation AST IR1 translation IR2 other IR and translation asm**Optimizations**opt opt translation AST IR1 opt translation IR2 opt opt other IR and translation asm**SSA History**• Optimization is IR-dependent: • We’ve discussed optimizations on the AST, TAC or CFG • Key problem: is there a best IR for optimization? • In late 1980’, researchers at IBM watson research center developed a new IR: SSA • with many fancy properties • great for optimizations • Later, SSA is used in many optimizing compilers: • GCC, MS VC, Jikes, MLton, LLVM, hotspot, … • As a result, SSA becomes a de-factor standard IR for optimizing compilers**Values ≠ Locations**int i, sum1=0, sum2=0; for (i=0; i<10; i++) sum1 += i; for (i=0; i<100; i++) sum2 += i;**Use-Def Chains & Def-Use Chains**int i, sum1=0, sum2=0; for (i=0; i<10; i++) sum1 += i; for (i=0; i<100; i++) sum2 += i;**UD Chains & DU Chains can be very Expensive**int i, j, x, y; switch (i){ case 1: x = 1; break; case 2: x = 2; break; case 3: x = 3; break; case 4: x = 4; break; default: x = 5; break; } switch (j){ case 1: y = x+1; break; case 2: y = x-2; break; case 3: y = x*8; break; default: y = x/3; break; } For M uses and N defs: O(M *N) space and time.**UD Chains & DU Chains can be Expensive**int i, j, x, y, z; switch (i){ case 1: x = 1; break; case 2: x = 2; break; case 3: x = 3; break; case 4: x = 4; break; default: x = 5; break; } z = x; switch (j){ case 1: y = z+1; break; case 2: y = z-2; break; case 3: y = z*8; break; default: y = z/3; break; } A solution to this is to limit each variable to have just one definition site.**SSA**• SSA is an IR in which every variable is assigned at most once (in text) x = 2 x = 1 x = 2 x = 1 y = x**Advantages of SSA**• Make DU and UD chains explicit • each definition knows its use • each use knows its unique definition • Make optimizations: • easier • faster • For most optimizations, also reduce the time/space requirements**Example: Constant propagation on SSA**x = 3 … Each variable has just one definition, so we need not do reaching definition analysis. … a = x Can we replace this “x” with constant “3”?**Example: Copy propagation on SSA**x = y … Each variable has just one definition, so we need not do reaching definition analysis. … a = x Can we replace this “x” with the variable “y”?**Example: Dead code elimination (DCE) on SSA**x = v … Can we eliminate this assignment? … If “x” is not used anywhere, then one can eliminate this. (No liveness analysis!) …**Example: Common Sub-expression Elimination (CSE) on SSA**x = a+b … Both a and b should have been assigned before this definition! SSA: each variable assigned at most once! If x dominates y, then one can do this substitution! (Why?) … y = a+b Can we replace this “a+b” with the variable “x”? No available expression analysis and reaching expression analysis!**Converting to SSA**• Easy for a basic block • rename each definition • and rewrite each use to the recent def. a = x+y b = a+x a = b+2 c = y+1 a = c+a a1 = x+y b1 = a1+x a2 = b1+2 c1 = y+1 a3 = c1+a2**CFG**c = 1 c1 = 1 a = x + y b = a + x a = b + 2 c = y + 1 a1 = x + y b1 = a1 +x a2 = b +2 c2 = y +1 a = c + a a3 = c? + a? So how to rewrite such kind of uses? Use a fiction of Φfunction.**Merging at joins with Φ function**c = 1 c1 = 1 a = x + y b = a + x a = b + 2 c = y + 1 a1 = x + y b1 = a1 +x a2 = b +2 c2 = y +1 a = c + a a3 = Φ(a1, a2) b2 = Φ(b1, ?) c3 = Φ(c1, c2) a4 = c3 + a3 Φfunction indicates which definition to use.**The Φ function**• Φ merges multiple definitions along multiple control paths into a single definition • For a basic block b with p predessors: • x = Φ (x1, x2, …, xp) • How does Φ know which xi to choose? • don’t care for analysis • can eliminate Φ before execution**Eliminating Φ function**c1 = 1 c1 = 1 a1 = x + y b1 = a1 +x a2 = b +2 c2 = y +1 a1 = x + y b1 = a1 +x a3 = a1 c3 = c1 a2 = b +2 c2 = y +1 a3 = a2 c3 = c2 a3 = Φ(a1, a2) c3 = Φ(c1, c2) a4 = c3 + a3 a4 = c3 + a3**Trivial SSA Construction**• At each join point, insert Φ for every live variable x = 1 x1 = 1 y = 2 y = 3 y1 = 2 y2 = 3 z = x + y x2 =Φ(x1, x1) y3 =Φ(y1, y2) z1 = x2 + y3 This Φ function is unnecessary!**Minimal SSA Construction**• At each join point, insert Φ for every variable with different outstanding definitions x = 1 x1 = 1 y = 2 y = 3 y1 = 2 y2 = 3 z = x + y y3 =Φ(y1, y2) z1 = x2 + y3**Where to insert Φ?**1 Suppose there is a definition of “x” in block 4, which node needs a Φ? 2 3 4 Alternatively, which node does not need a Φ? 5 6 8 7 9 11 10 12**Where to insert Φ?**1 1 2 2 3 4 4 3 5 5 6 6 7 12 8 7 8 11 9 11 9 10 12 10**Dominance Frontier (DF)**1 1 2 2 3 4 4 3 5 5 6 6 7 12 8 7 8 11 9 11 9 10 12 10**Example: DF for node 5**1 1 2 2 3 4 4 3 5 5 6 6 7 12 8 7 8 11 9 11 9 10 12 10**Using DF to Place Φ**• If there is a definition in node n, then there should be a Φ in DF(n) • for the definition “x=v”, insert • x=Φ(x, …, x) • where the number of arguments equal with the number of predecessors of n • One can use a worklist algorithm**Placing Φ**place_phi () compute defsites(x) for every variable x; for (each variable x) for (each defsite d in defsites(x)) for (each node n in DF(d)) if we haven’t place Φ, then put one for x of the form x = Φ(x, …, x); if (n not in defsites(x)) defsites(x) \/= {n};**Example**1: {} 2: {2} 3: {2} 4: {} 5: {7} 6: {7} 7: {2} i = 1 j = 1 k = 0 1 1 2 3 4 k < 100? 2 3 4 5 6 7 j < 20? return j 5 6 j = i k = k+1 j = k k = k+2 7**Placing Φ**1: {} 2: {2} 3: {2} 4: {} 5: {7} 6: {7} 7: {2} Var i: w = defsites(i) = {1} i = 1 j = 1 k = 0 1 k < 100? 2 3 4 j < 20? return j 5 6 j = i k = k+1 j = k k = k+2 7**Placing Φ**1: {} 2: {2} 3: {2} 4: {} 5: {7} 6: {7} 7: {2} Var j: w = defsites(j) = {1,5,6} i = 1 j = 1 k = 0 1 n = 1, w={5,6} n = 5, w={6} k < 100? 2 3 4 j < 20? return j 5 6 j = i k = k+1 j = k k = k+2 7 {j}**Placing Φ**i = 1 j = 1 k = 0 1: {} 2: {2} 3: {2} 4: {} 5: {7} 6: {7} 7: {2} Var j: w = defsites(j) = {1,5,6} 1 n = 1, w={5,6} {j} n = 5, w={6} 2 k < 100? n = 5, w={6, 7} n = 6, w={7} 3 j < 20? 4 return j n = 7, w={} 5 j = i k = k+1 j = k k = k+2 6 7 {j} j = Φ(j, j)**Placing Φ**i = 1 j = 1 k = 0 1: {} 2: {2} 3: {2} 4: {} 5: {7} 6: {7} 7: {2} Var j: w = defsites(j) = {1,5,6} 1 n = 1, w={5,6} n = 5, w={6} {j} 2 j = Φ(j, j)k < 100? n = 5, w={6, 7} n = 6, w={7} n = 7, w={} 3 j < 20? 4 return j n = 7, w={2} n = 2, w={} 5 j = i k = k+1 j = k k = k+2 6 {j} 7 j = Φ(j, j)**Placing Φ**i = 1 j = 1 k = 0 1: {} 2: {2} 3: {2} 4: {} 5: {7} 6: {7} 7: {2} Similar for k. Leave it to you. 1 {j, k} 2 j = Φ(j, j)k = Φ(k, k) k < 100? 3 4 j < 20? return j 5 6 j = i k = k+1 j = k k = k+2 {j, k} j = Φ(j, j) k = Φ(k, k) 7**Renaming variables**• Walk the dominator tree, renaming variable as you go • Replace each variable use with most recent renamed definition • easy for a basic block • for branches, use the most recent definition above the dominator tree nodes • that is, a pre-order tree walk**Rename Variables**i = 1 j = 1 k = 0 1 1 1 1 1 2 2 j = Φ(j , j )k = Φ(k , k ) k < 100? 1 3 4 1 3 4 5 6 7 j < 20? return j 5 6 j = i k = k + 1 j = k k = k + 2 1 Walk the dominator tree (in pre-order). 3 2 j = Φ(j , j ) k = Φ(k , k ) 7**Rename Variables**i = 1 j = 1 k = 0 1 1 1 1 1 2 2 j = Φ(j , j )k = Φ(k , k ) k < 100? 2 1 3 4 2 1 2 3 4 5 6 7 j < 20? return j 5 6 j = i k = k + 1 j = k k = k + 2 Walk the dominator tree (in pre-order). j = Φ(j , j ) k = Φ(k , k ) 7**Rename Variables**i = 1 j = 1 k = 0 1 1 1 1 1 2 2 j = Φ(j , j )k = Φ(k , k ) k < 100? 2 1 3 4 2 1 2 3 4 5 6 7 j < 20? return j 2 5 6 j = i k = k + 1 j = k k = k + 2 Walk the dominator tree (in pre-order). j = Φ(j , j ) k = Φ(k , k ) 7**Rename Variables**i = 1 j = 1 k = 0 1 1 1 1 1 2 2 j = Φ(j , j )k = Φ(k , k ) k < 100? 2 1 3 4 2 1 2 3 4 5 6 7 j < 20? return j 2 5 6 j = i k = k + 1 j = k k = k + 2 3 1 Walk the dominator tree (in pre-order). 3 2 j = Φ(j , j ) k = Φ(k , k ) 7 3 3**Rename Variables**i = 1 j = 1 k = 0 1 1 1 1 1 2 2 j = Φ(j , j )k = Φ(k , k ) k < 100? 2 1 3 4 2 1 2 3 4 5 6 7 j < 20? return j 2 5 6 j = i k = k + 1 j = k k = k + 2 3 1 2 Walk the dominator tree (in pre-order). 4 3 2 4 2 j = Φ(j , j ) k = Φ(k , k ) 7 3 4 3 4**Rename Variables**i = 1 j = 1 k = 0 1 1 1 1 1 2 2 j = Φ(j , j )k = Φ(k , k ) k < 100? 2 1 5 3 4 2 1 5 2 3 4 5 6 7 j < 20? return j 2 5 6 j = i k = k + 1 j = k k = k + 2 3 1 2 Walk the dominator tree (in pre-order). 4 3 2 4 2 j = Φ(j , j ) k = Φ(k , k ) 7 5 3 4 5 3 4**Rename Variables**i = 1 j = 1 k = 0 1 1 1 1 1 2 2 j = Φ(j , j )k = Φ(k , k ) k < 100? 2 1 5 3 4 2 1 5 2 3 4 5 6 7 j < 20? return j 2 2 5 6 j = i k = k + 1 j = k k = k + 2 3 1 2 Walk the dominator tree (in pre-order). 4 3 2 4 2 j = Φ(j , j ) k = Φ(k , k ) 7 5 3 4 5 3 4**Summary**• SSA is an intermediate representation • static single definition for every variable • invariant maintained by fake Φ functions • Conversion to SSA can be very fast • linear-time algorithm exists • SSA is very compact • linear size of the original program • Optimizations on SSA is very easy • no need to do data-flow analysis • more on this next time