Presentation is loading. Please wait.

Presentation is loading. Please wait.

CMPUT680 Topic G: Static Single- Assignment Form José Nelson Amaral CMPUT 680 - Compiler Design and Optimization 1.

Similar presentations


Presentation on theme: "CMPUT680 Topic G: Static Single- Assignment Form José Nelson Amaral CMPUT 680 - Compiler Design and Optimization 1."— Presentation transcript:

1 CMPUT680 Topic G: Static Single- Assignment Form José Nelson Amaral CMPUT Compiler Design and Optimization 1

2 Reading Material CMPUT Compiler Design and Optimization 2 Chapter 19 of the “Tiger book” (with a grain of salt!!). Bilardi, G., Pingali, K., “The Static Single Assignment Form and its Computation,” unpublished? (citeseer). Cytron, R., Ferrante, J., Rosen, B. K., Wegman, M. N., Zadeck, F. K., “An Efficient Method of Computing Static Single Assignment Form,” ACM Symposium on Principles of Programming Languages (PoPL), pp , Austin, TX, Jan., Cytron, R., Ferrante, J., Rosen, B. K., Wegman, M. N., “Efficiently Computing Static Single Assignment Form and the Control Dependence Graph,” ACM Transactions on Programming Languages and Systems (TOPLAS), Vol. 13, No. 4, October, 1991, pp Sreedhar, V. C., Gao, G. R., “A Linear Time Algorithm for Placing  -Nodes,” ACM Symposium on Principles of Programming Languages (PoPL), pp , 1995.

3 Static Single-Assignment Form CMPUT Compiler Design and Optimization 3 Each variable has only one definition in the program text. This single static definition can be in a loop and may be executed many times. Thus even in a program expressed in SSA, a variable can be dynamically defined many times.

4 Advantages of SSA Simpler dataflow analysis No need to use use-def/def-use chains, which requires N ∗ M space for N uses and M definitions SSA form relates in a useful way with dominance structures. SSA simplifies algorithms that construct interference graphs. CMPUT Compiler Design and Optimization 4

5 Main Goal of SSA To create a sparse representation of the flow of values in a computer program. – Prevents propagation of a value through regions of the program that do not use it. – Factorize value propagation – If p definitions must be propagated to q uses, a dense flow representation requires p×q edges. An SSA representation requires only p+q edges. CMPUT Compiler Design and Optimization 5

6 SSA Form in Control-Flow Path Merges CMPUT Compiler Design and Optimization 6 b ← M[x] a ← 0 if b<4 a ← b c ← a + b B1 B2 B3 B4 Is this code in SSA form? No, two definitions of a appear in the code (in B1 and B3) How can we transform this code into a code in SSA form? We can create two versions of a, one for B1 and another for B3.

7 SSA Form in Control-Flow Path Merges CMPUT Compiler Design and Optimization 7 b ← M[x] a1 ← 0 if b<4 a2 ← b c ← a? + b B1 B2 B3 B4 But which version should we use in B4 now? We define a fictional function that “knows” which control path was taken to reach the basic block B4:

8 SSA Form in Control-Flow Path Merges CMPUT Compiler Design and Optimization 8 b ← M[x] a1 ← 0 if b<4 a2 ← b a3 ← ψ(a2,a1) c ← a3 + b B1 B2 B3 B4 But which version should we use in B4 now? We define a fictional function that “knows” which control path was taken to reach the basic block B4:

9 SSA Form in Control-Flow Path Merges CMPUT Compiler Design and Optimization 9 b ← M[x] a1 ← 0 if b<4 a2 ← b a3 ← ϕ (a2,a1) c ← a3 + b B1 B2 B3 B4 In some compilers the actual representation of this Φ function is: Φ(a1,a2,B2,B3)

10 A Loop Example CMPUT Compiler Design and Optimization 10 a ← 0 b ← a+1 c ← c+b a ← b*2 if a < N return a0 ← undef b0 ← undef c0 ← undef a1 ← 0 b1 ← a?+1 c1 ← c?+b1 a2 ← b1*2 if a2 < N return

11 A Loop Example CMPUT Compiler Design and Optimization 11 a ← 0 b ← a+1 c ← c+b a ← b*2 if a < N return a0 ← undef b0 ← undef c0 ← undef a1 ← 0 a3 ← Φ(a1,a2) b1 ← a3+1 c1 ← c?+b1 a2 ← b1*2 if a2 < N return

12 A Loop Example CMPUT Compiler Design and Optimization 12 a0 ← undef b0 ← undef c0 ← undef a1 ← 0 a3 ← Φ(a1,a2) c2 ← Φ(c0,c1) b1 ← a3+1 c1 ← c2+b1 a2 ← b1*2 if a2 < N return a ← 0 b ← a+1 c ← c+b a ← b*2 if a < N return

13 A Loop Example CMPUT Compiler Design and Optimization 13 a0 ← undef b0 ← undef c0 ← undef a1 ← 0 a3 ← ϕ (a1,a2) c2 ← ϕ (c0,c1) b2 ← ϕ (b0,b1) b1 ← a3+1 c1 ← c2+b1 a2 ← b1*2 if a2 < N return Φ(b0,b1) is not necessary because b2 is never used. But the phase that generates Φ functions does not know it. Unnecessary Φ functions are later eliminated by dead code elimination. a ← 0 b ← a+1 c ← c+b a ← b*2 if a < N return

14 The Φ Function CMPUT Compiler Design and Optimization 14 How can we implement a Φ function that “knows” which control path was taken? Answer 1: We don’t!! The Φ function is used only to connect use to definitions during optimization, but is never implemented. Answer 2: If we must execute the Φ function, we can implement it by inserting MOVE instructions in all control paths.

15 Criteria for Inserting Φ Functions CMPUT Compiler Design and Optimization 15 We could insert one Φ function for each variable at every join point (a point in the CFG with more than one predecessor). But that would be wasteful. What criteria should we use to insert a Φ function for a variable a at node z of the CFG? Intuitively, we should add a function Φ if there are two definitions of a that can reach the point z through distinct paths.

16 Path Convergence Criterion (Cytron-Ferrante/89) CMPUT Compiler Design and Optimization 16 Insert a Φ function for a variable a at a node z if all the following conditions are true: 1. There is a block x that defines a 2. There is a block y ≠ x that defines a 3. There are paths x → z and y → z 4. Paths x → z and y → z don’t have any nodes in common other than z 5. The node z does not appear in both x → z and y → z prior to the end, but it may appear in one or the other. Note: The start node contains an implicit definition of every variable.

17 Examples CMPUT Compiler Design and Optimization 17 a ← ⋅⋅⋅ x y z x y z x y z x y z

18 Φ-Candidates are Join Nodes CMPUT Compiler Design and Optimization 18 Notice that according to the path convergence criterion, the node z that will receive the Φ function must be a join node. z is the first node that joins the paths P xz and P yz.

19 Iterated Path-Convergence Criterion CMPUT Compiler Design and Optimization 19 The Φ function itself is a definition of a. Therefore the path-convergence criterion is a set of equations that must be satisfied. while there are nodes x, y, z satisfying conditions 1-5 and z does not contain a Φ function for a do insert a ← Φ(a 0, a 1, …, a n ) at node z This algorithm is extremely costly, because it requires the examination of every triple of nodes x, y, z and every path from x to z and from y to z. Can we do better?

20 The SSA Conversion Problem CMPUT Compiler Design and Optimization 20 For each variable x defined in a CFG G=(V,E), given the set of nodes S ⊆ V such that each S contains a definition for x, find the minimal set J(S) of nodes that requires a Φ(x i,x j ) function. By definition, the START node defines all the variables, therefore ∀ S ⊆ V, START ∈ S. If we need to compute Φ nodes for several variables, it may be efficient to precompute data structures based on the CFG.

21 Processing Time for SSA Conversion CMPUT Compiler Design and Optimization 21 The performance of an SSA conversion algorithm should be measured by the processing time Tp, the preprocessing space Sp, and the query time Tq. (Shapiro and Saint 1970): outline an algorithm (Reif and Tarjan 1981): extend the Lengauer-Tarjan dominator algorithm to compute Φ-nodes. (Cytron et al. 1991): show that SSA conversion can use the idea of dominance frontiers, resulting on an O(|V| 2 ) algorithm. (Sreedhar and Gao, 1995): An O(|E|) algorithm, but in private commun. with Pingali in 1996 admits that it is in practice 5 times slower than Cytron et al.

22 Processing Time for SSA Conversion CMPUT Compiler Design and Optimization 22 Bilardi, Pingali, 1999: present a generalized framework and a parameterized Augmented Dominator Tree (ADT) algorithm that allows for a space-time tradeoff. They show that Cytron et al. and Gao-Shreedhar are special cases of the ADT algorithm. Bilardi and Pingali describe three strategies to compute Φ-placement: Two-Phase Algorithms Lock-Step Algorithms Lazy Algorithms

23 Two-Phase Algorithms CMPUT Compiler Design and Optimization 23 First build the entire Dominance Frontier Graph, then find the nodes reachable from S Simple DF Graph may be quite large DF Computation Reachability DF Graph J(S) S CFG

24 Lock-Step Algorithms CMPUT Compiler Design and Optimization 24 Performs the reachability computation incrementally while the DF relation is computed. DF Computation Reachability J(S) Avoid storing the DF Graph. Perform computations at all nodes of the graph, even though most are irrelevant Inneficient when computing the Φ-nodes for many variables. CFG S

25 Lazy Algorithms CMPUT Compiler Design and Optimization 25 Lazily compute only the portion fo the DF Graph that is needed. Carefully select a portion of the DF Graph to compute eagerly (before it is needed). A Two-Phase Algorithm is an extreme case of a lazy algorithm. DF Computation Reachability DF Graph SubGraph J(S) S CFG

26 Computing a Dominator Tree CMPUT Compiler Design and Optimization 26 (Lowry and Medlock, 1969): Introduce the problem and give an O(n 4 ) algorithm. (Lengauer and Tarjan, 1979): Give a complicated O(mα(m.n)) algorithm [α(m.n) is the inverse Ackermann’s function]. (Harel, 1985): Give a linear time algorithm. (Alstrup, Harel and Thorup, 1997): Give a simpler version of Harel’s algorithm. (n: # of nodes; m: # of edges)

27 Dominance Property of the SSA Form CMPUT Compiler Design and Optimization 27 In SSA form definitions dominate uses, i.e.: 1. If x is used in a Φ function in block n, then the definition of x dominates every predecessor of n. 2. If x is used in a non-Φ statement in block n, then the definition of x dominates n.

28 The Dominance Frontier CMPUT Compiler Design and Optimization 28 A node x dominates a node w if every path from the start node to w must go through x. A node x strictly dominates a node w if x dominates w and x ≠ w. The dominance frontier of a node x is the set of all nodes w such that x dominates a predecessor of w, but x does not strictly dominates w.

29 Example CMPUT Compiler Design and Optimization What is the dominance frontier of node 5?

30 Example CMPUT Compiler Design and Optimization First we must find all nodes that node 5 dominates.

31 Example CMPUT Compiler Design and Optimization 31 A node w is in the dominance frontier of node 5 if 5 dominates a predecessor of w, but 5 does not strictly dominates w itself. What is the dominance frontier of 5?

32 Example CMPUT Compiler Design and Optimization A node w is in the dominance frontier of node 5 if 5 dominates a predecessor of w, but 5 does not strictly dominates w itself. What is the dominance frontier of 5?

33 Example CMPUT Compiler Design and Optimization DF(5) = {4, 5, 12, 13} A node w is in the dominance frontier of node 5 if 5 dominates a predecessor of w, but 5 does not strictly dominates w itself. What is the dominance frontier of 5?

34 Dominance Frontier Criterion CMPUT Compiler Design and Optimization 34 Dominance Frontier Criterion: If a node x contains a definition of variable a, then any node z in the dominance frontier of x needs a Φ function for a. Can you think of an intuitive explanation for why a node in the dominance frontier of another node must be a join node?

35 Example CMPUT Compiler Design and Optimization If a node (12) is in the dominance frontier of another node (5), than there must be at least two paths converging to (12). These paths must be non-intersecting, and one of them (5,7,12) must contain a node strictly dominated by (5).

36 Dominator Tree CMPUT Compiler Design and Optimization 36 To compute the dominance frontiers, we first compute the dominator tree of the CFG. There is an edge from node x to node y in the dominator tree if node x immediately dominates node y. I.e., x dominates y≠x, and x does not dominate any other dominator of y. Dominator trees can be computed using the Lengauer-Tarjan algorithm(1979). See sec of Appel.

37 Example: Dominator Tree CMPUT Compiler Design and Optimization Control Flow Graph Dominator Tree

38 Local Dominance Frontier CMPUT Compiler Design and Optimization 38 Cytron-Ferrante define the local dominance frontier of a node n as: DF local [n] = successors of n in the CFG that are not strictly dominated by n

39 Example: Local Dominance Frontier CMPUT Compiler Design and Optimization Control Flow Graph In the example, what are the local dominance frontiers of nodes 5, 6 and 7? DF local [5] =  DF local [6] = {4,8} DF local [7] = {8,12}

40 Dominance Frontier Inherited From Its Children CMPUT Compiler Design and Optimization 40 The dominance frontier of a node n is formed by its local dominance frontier plus nodes that are passed up by the children of n in the dominator tree. The contribution of a node c to its parent’s dominance frontier is defined as [Cytron-Ferrante, 1991]: DF up [c] = nodes in the dominance frontier of c that are not strictly dominated by the immediate dominator of c

41 Example: Local Dominance Frontier CMPUT Compiler Design and Optimization Control Flow Graph In the example, what are the contributions of nodes 6, 7, and 8 to its parent dominance frontier? First we compute the DF and the immediate dominator of each node: DF[6] = {4,8}, idom(6)= 5 DF[7] = {8,12}, idom(7)= 5 DF[8] = {5,13}, idom(8)= 5

42 Example: Local Dominance Frontier CMPUT Compiler Design and Optimization Control Flow Graph First we compute the DF and the immediate dominator of each node: DF[6] = {4,8}, idom(6)= 5 DF[7] = {8,12}, idom(7)= 5 DF[8] = {5,13}, idom(8)= 5 Now we check for the DF up condition: DF up [6] = {4} DF up [7] = {12} DF up [8] = {5,13} DF up [c] = nodes in the dominance frontier of c that are not strictly dominated by the immediate dominator of c

43 A note on implementation CMPUT Compiler Design and Optimization 43 We want to represent these sets efficiently: DF[6] = {4,8} DF[7] = {8,12} DF[8] = {5,13} If we use bitvectors to represent these sets: DF[6] = DF[7] = DF[8] =

44 Strictly Dominated Sets CMPUT Compiler Design and Optimization Dominator Tree We can also represent the strictly dominated sets as vectors: SD[1] = SD[2] = SD[5] = SD[9] =

45 A note on implementation CMPUT Compiler Design and Optimization 45 DF up [c] = nodes in the dominance frontier of c that are not strictly dominated by the immediate dominator of c If we use bitvectors to represent these sets: DF[6] = DF[7] = DF[8] = SD[5] = DF up [c] = DF[6] ^ ~SD[5]

46 Dominance Frontier Inherited From Its Children CMPUT Compiler Design and Optimization 46 The dominance frontier of a node n is formed by its local dominance frontier plus nodes that are passed up by the children of n in the dominator tree. Thus the dominance frontier of a node n is defined as [Cytron-Ferrante, 1991]:

47 Example: Local Dominance Frontier CMPUT Compiler Design and Optimization Control Flow Graph What is DF[5]? Remember that: DF local [5] =  DF up [6] = {4} DF up [7] = {12} DF up [8] = {5,13} DTchildren[5] = {6,7,8}

48 Example: Local Dominance Frontier CMPUT Compiler Design and Optimization Control Flow Graph What is DF[5]? Remember that: DF local [5] = ∅ DF up [6] = {4} DF up [7] = {12} DF up [8] = {5,13} DTchildren[5] = {6,7,8} Thus, DF[5] = {4, 5, 12, 13}

49 Join Sets CMPUT Compiler Design and Optimization 49 In order to insert Φ-nodes for a variable x that is defined in a set of nodes S={n 1, n 2, …, n k } we need to compute the iterated set of join nodes of S. Given a set of nodes S of a control flow graph G, the set of join nodes of S, J(S), is defined as follows: J(S) ={z ∈ G| ∃ two paths P xz and P yz in G that have z as its first common node, x ∈ S and y ∈ S}

50 Iterated Join Sets CMPUT Compiler Design and Optimization 50 Because a Φ-node is itself a definition of a variable, once we insert Φ-nodes in the join set of S, we need to find out the join set of S ∪ J(S). Thus, Cytron-Ferrante define the iterated join set of a set of nodes S, J + (S), as the limit of the sequence:

51 Iterated Dominance Frontier CMPUT Compiler Design and Optimization 51 We can extend the concept of dominance frontier to define the dominance frontier of a set of nodes as: Now we can define the iterated dominance frontier, DF + (S), of a set of nodes S as the limit of the sequence: Exercise: Find an example in which the IDF of a set S is different from the DF of the set! Exercise: Find an example in which the IDF of a set S is different from the DF of the set!

52 Location of Φ-Nodes CMPUT Compiler Design and Optimization 52 Given a variable x that is defined in a set of nodes S={n 1, n 2, …, n k } the set of nodes that must receive Φ-nodes for x is J + (S). An important result proved by Cytron-Ferrante is that: Thus we are mostly interested in computing the iterated dominance frontier of a set of nodes.

53 Algorithms to Compute Dominance Frontier CMPUT Compiler Design and Optimization 53 The algorithm to insert Φ-nodes, due to Cytron and Ferrante (1991), computes the dominance frontier of each node in the set S before computing the iterated dominance frontier of the set. In 1994, Shreedar and Gao proposed a simple, linear algorithm for the insertion of Φ-nodes. In the worst case, the combination of the dominance frontier of the sets can be quadratic in the number of nodes in the CFG. Thus, Cytron-Ferrante’s algorithm has a complexity O(N 2 ).

54 Sreedhar and Gao’s DJ Graph CMPUT Compiler Design and Optimization Control Flow Graph Dominator Tree

55 Sreedhar and Gao’s DJ Graph CMPUT Compiler Design and Optimization Control Flow Graph Dominator Tree D nodes

56 Sreedhar and Gao’s DJ Graph CMPUT Compiler Design and Optimization Control Flow Graph Dominator Tree D nodes J nodes

57 Shreedar-Gao’s Dominance Frontier Algorithm CMPUT Compiler Design and Optimization 57 DominanceFrontier(x) 0: DF[x] = ∅ 1: foreach y ∈ SubTree(x) do 2: if((y → z == J-edge) and 3: (z.level ≤ x.level)) 4: then DF[x] = DF[x] ∪ z What is the DF[5]?

58 Shreedar-Gao’s Dominance Frontier Algorithm CMPUT Compiler Design and Optimization SubTree(5) = {5, 6, 7, 8} Initialization: DF[5] = ∅ DominanceFrontier(x) 0: DF[x] = ∅ 1: foreach y ∈ SubTree(x) do 2: if((y → z == J-edge) and 3: (z.level ≤ x.level)) 4: then DF[x] = DF[x] ∪ z

59 Shreedar-Gao’s Dominance Frontier Algorithm CMPUT Compiler Design and Optimization SubTree(5) = {5, 6, 7, 8} There are three edges originating in 5: {5→6, 5→7, 5→8} but they are all D-edges Initialization: DF[5] = ∅ DominanceFrontier(x) 0: DF[x] = ∅ 1: foreach y ∈ SubTree(x) do 2: if((y → z == J-edge) and 3: (z.level ≤ x.level)) 4: then DF[x] = DF[x] ∪ z

60 Shreedar-Gao’s Dominance Frontier Algorithm CMPUT Compiler Design and Optimization SubTree(5) = {5, 6, 7, 8} There are two edges originating in 6: {6→4, 6→8} but 8.level > 5.level Initialization: DF[5] = ∅ After visiting 6: DF = {4} DominanceFrontier(x) 0: DF[x] = ∅ 1: foreach y ∈ SubTree(x) do 2: if((y → z == J-edge) and 3: (z.level ≤ x.level)) 4: then DF[x] = DF[x] ∪ z

61 Shreedar-Gao’s Dominance Frontier Algorithm CMPUT Compiler Design and Optimization SubTree(5) = {5, 6, 7, 8} There are two edges originating in 7: {7→8, 7→12} again 8.level > 5.level Initialization: DF[5] = ∅ After visiting 6: DF = {4} After visiting 7: DF = {4,12} DominanceFrontier(x) 0: DF[x] = ∅ 1: foreach y ∈ SubTree(x) do 2: if((y → z == J-edge) and 3: (z.level ≤ x.level)) 4: then DF[x] = DF[x] ∪ z

62 Shreedar-Gao’s Dominance Frontier Algorithm CMPUT Compiler Design and Optimization SubTree(5) = {5, 6, 7, 8} There are two edges originating in 8: {8→5, 8→13} both satisfy cond. in steps 2-3 Initialization: DF[5] = ∅ After visiting 6: DF = {4} After visiting 7: DF = {4,12} After visiting 8: DF = {4, 12, 5, 13} DominanceFrontier(x) 0: DF[x] = ∅ 1: foreach y ∈ SubTree(x) do 2: if((y → z == J-edge) and 3: (z.level ≤ x.level)) 4: then DF[x] = DF[x] ∪ z

63 Shreedhar-Gao’s Φ-Node Insertion Algorithm CMPUT Compiler Design and Optimization 63 Using the D-J graph, Shreedhar and Gao propose a linear time algorithm to compute the iterated dominance frontier of a set of nodes. An important intuition in Shreedhar-Gao’s algorithm is: If two nodes x and y are in S, and y is an ancestor of x in the dominator tree, then if we compute DF[x] first, we do not need to recompute DF[x] when computing DF[y].

64 Shreedhar-Gao’s Φ-Node Insertion Algorithm CMPUT Compiler Design and Optimization 64 Shreedhar-Gao’s algorithm also use a work list of nodes hashed by their level in the dominator tree and a visited flag to avoid visiting the same node more than once. The basic operation of the algorithm is similar to their dominance-frontier algorithm, but it requires a careful implementation to deliver the linear-time complexity.

65 Dead-Code Elimination in SSA Form CMPUT Compiler Design and Optimization 65 Because there is only one definition for each variable, if the list of uses of the variable is empty, the definition is dead. When a statement v ← x ⊕ y is eliminated because v is dead, this statement must be removed from the list of uses of x and y. Which might cause those definitions to become dead. Thus we need to iterate the dead code elimination algorithm.

66 Simple Constant Propagation in SSA CMPUT Compiler Design and Optimization 66 If there is a statement v ← c, where c is a constant, then all uses of v can be replaced for c. A Φ function of the form v ← Φ(c 1, c 2, …, c n ) where all c i are identical can be replaced for v ← c. Using a work-list algorithm in a program in SSA form, we can perform constant propagation in linear time In the next slide we assume that x, y, z are variables and a, b, c are constants.

67 Linear Time Optimizations in SSA form CMPUT Compiler Design and Optimization 67 Copy propagation: The statement x ← Φ(y) or the statement x ← y can be deleted and y can substitute every use of x. Constant folding: If we have the statement x ← a ⊕ b, we can evaluate c ← a ⊕ b at compile time and replace the statement for x ← c Constant conditions: The conditional if a < b goto L1 else L2 can be replaced for goto L1 or goto L2, according to the compile time evaluation of a < b, and the CFG, use lists, adjust accordingly Unreachable Code: eliminate unreachable blocks.

68 Single Assignment Form CMPUT Compiler Design and Optimization 68 i=1; j=1; k=0; while(k<100) { if(j<20) { j=i; k=k+1; } else { j=k; k=k+2; } return j; } i ← 1 j ← 1 k← 0 j ← i k ← k+1 j ← k k ← k+2 return j if j<20 if k<100 B1 B2 B3 B5 B6 B4 B7

69 Single Assignment Form CMPUT Compiler Design and Optimization 69 i=1; j=1; k=0; while(k<100) { if(j<20) { j=i; k=k+1; } else { j=k; k=k+2; } return j; } i ← 1 j ← 1 k1← 0 j ← i k3 ← k+1 j ← k k5 ← k+2 return j if j<20 if k<100 B1 B2 B3 B5 B6 B4 B7

70 Single Assignment Form CMPUT Compiler Design and Optimization 70 i=1; j=1; k=0; while(k<100) { if(j<20) { j=i; k=k+1; } else { j=k; k=k+2; } return j; } i ← 1 j ← 1 k1← 0 j ← i k3 ← k+1 j ← k k5 ← k+2 return j if j<20 if k<100 k4 ← Φ(k3,k5) B1 B2 B3 B5 B6 B4 B7

71 Single Assignment Form CMPUT Compiler Design and Optimization 71 i=1; j=1; k=0; while(k<100) { if(j<20) { j=i; k=k+1; } else { j=k; k=k+2; } return j; } i ← 1 j ← 1 k1← 0 j ← i k3 ← k+1 j ← k k5 ← k+2 return j if j<20 k2 ← Φ(k4,k1) if k<100 k4 ← Φ(k3,k5) B1 B2 B3 B5 B6 B4 B7

72 Single Assignment Form CMPUT Compiler Design and Optimization 72 i=1; j=1; k=0; while(k<100) { if(j<20) { j=i; k=k+1; } else { j=k; k=k+2; } return j; } i ← 1 j ← 1 k1← 0 j ← i k3 ← k2+1 j ← k k5 ← k2+2 return j if j<20 k2 ← Φ(k4,k1) if k2<100 k4 ← Φ(k3,k5) B1 B2 B3 B5 B6 B4 B7

73 Single Assignment Form CMPUT Compiler Design and Optimization 73 i=1; j=1; k=0; while(k<100) { if(j<20) { j=i; k=k+1; } else { j=k; k=k+2; } return j; } i1 ← 1 j1 ← 1 k1← 0 j3 ← i1 k3 ← k2+1 j5 ← k2 k5 ← k2+2 return j2 if j2<20 j2 ← Φ(j4,j1) k2 ← Φ(k4,k1) if k2<100 j4 ← Φ(j3,j5) k4 ← Φ(k3,k5) B1 B2 B3 B5 B6 B4 B7

74 Example: Constant Propagation CMPUT Compiler Design and Optimization 74 i1 ← 1 j1 ← 1 k1← 0 j3 ← i1 k3 ← k2+1 j5 ← k2 k5 ← k2+2 return j2 if j2<20 j2 ← Φ(j4,j1) k2 ← Φ(k4,k1) if k2<100 j4 ← Φ(j3,j5) k4 ← Φ(k3,k5) B1 B2 B3 B5 B6 B4 B7 i1 ← 1 j1 ← 1 k1← 0 j3 ← 1 k3 ← k2+1 j5 ← k2 k5 ← k2+2 return j2 if j2<20 j2 ← Φ(j4,1) k2 ← Φ(k4,0) if k2<100 j4 ← Φ(j3,j5) k4 ← Φ(k3,k5) B1 B2 B3 B5 B6 B4 B7

75 Example: Dead-code Elimination CMPUT Compiler Design and Optimization 75 i1 ← 1 j1 ← 1 k1← 0 j3 ← 1 k3 ← k2+1 j5 ← k2 k5 ← k2+2 return j2 if j2<20 j2 ← Φ(j4,1) k2 ← Φ(k4,0) if k2<100 j4 ← Φ(j3,j5) k4 ← Φ(k3,k5) B1 B2 B3 B5 B6 B4 B7 j3 ← 1 k3 ← k2+1 j5 ← k2 k5 ← k2+2 return j2 if j2<20 j2 ← Φ(j4,1) k2 ← Φ(k4,0) if k2<100 j4 ← Φ(j3,j5) k4 ← Φ(k3,k5) B2 B3 B5 B6 B4 B7

76 Constant Propagation and Dead Code Elimination CMPUT Compiler Design and Optimization 76 j3 ← 1 k3 ← k2+1 j5 ← k2 k5 ← k2+2 return j2 if j2<20 j2 ← Φ(j4,1) k2 ← Φ(k4,0) if k2<100 j4 ← Φ(1,j5) k4 ← Φ(k3,k5) B2 B3 B5 B6 B4 B7 j3 ← 1 k3 ← k2+1 j5 ← k2 k5 ← k2+2 return j2 if j2<20 j2 ← Φ(j4,1) k2 ← Φ(k4,0) if k2<100 j4 ← Φ(j3,j5) k4 ← Φ(k3,k5) B2 B3 B5 B6 B4 B7

77 Example: Is this the end? CMPUT Compiler Design and Optimization 77 But block 6 is never executed! How can we find this out, and simplify the program? SSA conditional constant propagation finds the least fixed point for the program and allows further elimination of dead code. See algorithm on pg of Appel. k3 ← k2+1j5 ← k2 k5 ← k2+2 return j2 if j2<20 j2 ← Φ(j4,1) k2 ← Φ(k4,0) if k2<100 j4 ← Φ(1,j5) k4 ← Φ(k3,k5) B2 B3 B5 B6 B4 B7

78 Example: Dead code elimination CMPUT Compiler Design and Optimization 78 k3 ← k2+1j5 ← k2 k5 ← k2+2 return j2 if j2<20 j2 ← Φ(j4,1) k2 ← Φ(k4,0) if k2<100 j4 ← Φ(1,j5) k4 ← Φ(k3,k5) B2 B3 B5 B6 B4 B7 B4 k3 ← k2+1 return j2 j2 ← Φ(j4,1) k2 ← Φ(k4,0) if k2<100 j4 ← Φ(1) k4 ← Φ(k3) B2 B5 B7

79 Example: Single Argument Φ- Function Elimination CMPUT Compiler Design and Optimization 79 k3 ← k2+1 return j2 j2 ← Φ(j4,1) k2 ← Φ(k4,0) if k2<100 j4 ← Φ(1) k4 ← Φ(k3) B2 B5 B7 B4 k3 ← k2+1 return j2 j2 ← Φ(j4,1) k2 ← Φ(k4,0) if k2<100 j4 ← 1 k4 ← k3 B2 B5 B7 B4

80 Example: Constant and Copy Propagation CMPUT Compiler Design and Optimization 80 k3 ← k2+1 return j2 j2 ← Φ(j4,1) k2 ← Φ(k4,0) if k2<100 j4 ← 1 k4 ← k3 B2 B5 B7 k3 ← k2+1 return j2 j2 ← Φ(1,1) k2 ← Φ(k3,0) if k2<100 j4 ← 1 k4 ← k3 B2 B5 B7 B4

81 Example: Dead Code Elimination CMPUT Compiler Design and Optimization 81 k3 ← k2+1 return j2 j2 ← Φ(1,1) k2 ← Φ(k3,0) if k2<100 j4 ← 1 k4 ← k3 B2 B5 B7 B4 k3 ← k2+1 return j2 j2 ← Φ(1,1) k2 ← Φ(k3,0) if k2<100 B2 B5 B4

82 Example: Φ-Function Simplification CMPUT Compiler Design and Optimization 82 k3 ← k2+1 return j2 j2 ← Φ(1,1) k2 ← Φ(k3,0) if k2<100 B2 B5 B4 k3 ← k2+1 return j2 j2 ← 1 k2 ← Φ(k3,0) if k2<100 B2 B5 B4

83 Example: Constant Propagation CMPUT Compiler Design and Optimization 83 k3 ← k2+1 return j2 j2 ← 1 k2 ← Φ(k3,0) if k2<100 B2 B5 B4 k3 ← k2+1 return 1 j2 ← 1 k2 ← Φ(k3,0) if k2<100 B2 B5 B4

84 Example: Dead Code Elimination CMPUT Compiler Design and Optimization 84 k3 ← k2+1 return 1 j2 ← 1 k2 ← Φ(k3,0) if k2<100 B2 B5 B4 return 1 B4


Download ppt "CMPUT680 Topic G: Static Single- Assignment Form José Nelson Amaral CMPUT 680 - Compiler Design and Optimization 1."

Similar presentations


Ads by Google