Post on 16-Oct-2021
Advanced Compiler Design – Homework 1
SSA Construction & Destruction
Michael Faesmichael.faes@inf.ethz.ch
(slides originally stolen from Luca Della Toffola)
SSA Pipeline
1. Build the control-flow graph of the program
2. Convert the program into SSA form
3. Apply optimizations
4. Convert the program back to non-SSA form
5. Generate code from the control-flow graph
2
Homework 1 Tasks
1. Build the control-flow graph of the program
2. Convert the program into SSA form
3. Apply optimizations
4. Convert the program back to non-SSA form
5. Generate code from the control-flow graph
(Due date: Mar 24, 2016)
3
SSA Construction
1. Compute Dominance Frontier
• Using Dominator Tree
2. Insert ɸ-operations where necessary
• In join nodes with different incoming assignments
• Use dominance frontier
3. Add versions to variables (renaming)
4
SSA Destruction
1. Replace ɸ-operations with copy statements in direct predecessor blocks
5
DOMINANCE RELATIONS REVIEWHomework 1
6
Dominator
A (CFG) node y dominates n if y lies in every path from the entry node to n.
DOM(n) = the set of all dominators of n
Note:• Every node dominates itself• The entry node dominates all nodes
Notation from Cooper et al.
7
n DOM(n)
A {entry, A}
B {entry, B}
C {entry, A, C}
D {entry, D}
E {entry, B, E}
F {entry, A, C, F}
G {entry, D, G}
H {entry, H}
A
D
B
EC
GF
H
entry
8
SDOM(n) = the set of strict dominators of n
Note:• SDOM(n) = DOM(n) \ {n}
Strict Dominator
A node y strictly dominates n
if y dominates n and n ≠ y.
9
A
D
B
EC
GF
H
n SDOM(n)
A {entry}
B {entry}
C {entry, A}
D {entry}
E {entry, B}
F {entry, A, C}
G {entry, D}
H {entry}
entry
10
IDOM(n) = the immediate dominator of n
Note:• Every node (except the entry) has exactly one
immediate dominator
Immediate Dominator
Node y immediately dominates n if y is the closest strict dominator of n on any path from entry to n.
11
A
D
B
EC
GF
H
n IDOM(n)
A {entry}
B {entry}
C {A}
D {entry}
E {B}
F {C}
G {D}
H {entry}
entry
12
Dominator Tree
• Contains all nodes of the CFG with edges that reflect the dominance relation
• Each node n is a child of its IDOM(n)
• Bottom-up traversal results in DOM(n)
13
A
D
B
EC
GF
H
CFG
A DB
EC G
F
H
Dominator Tree
14
DOMINATOR TREE CONSTRUCTIONHomework 1 – SSA Construction
15
Iterative Dominator Algorithm
Idea: Solve the following data-flow problem:
• For n n0, initialize DOM(n) with all nodes• Update DOM(n) according to equations• Walk over the CFG, repeat until no changes.
entry
16
direct!
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
Dominator Algorithm: Example
17
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
Dominator Algorithm: Example
{A}
17
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
Dominator Algorithm: Example
{A}
{A,B,C,D,E}
{A,B,C,D,E}
{A,B,C,D,E}
{A,B,C,D,E}
17
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
while changed:for n in nodes:pre = intersect(DOM(preds(n)))new = union(pre, n)DOM(n) = new
Dominator Algorithm: Example
{A}
{A,B,C,D,E}
{A,B,C,D,E}
{A,B,C,D,E}
{A,B,C,D,E}
17
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
while changed:for n in nodes:pre = intersect(DOM(preds(n)))new = union(pre, n)DOM(n) = new
Dominator Algorithm: Example
{A}
{A,B,C,D,E}
{A,B,C,D,E}
{A,B,C,D,E}
{A,B,C,D,E}
17
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
while changed:for n in nodes:pre = intersect(DOM(preds(n)))new = union(pre, n)DOM(n) = new
Dominator Algorithm: Example
{A}
{A,B,C,D,E}
{A,B,C,D,E}
{A,B,C,D,E}
{A,B,C,D,E}
17
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
while changed:for n in nodes:pre = intersect(DOM(preds(n)))new = union(pre, n)DOM(n) = new
Dominator Algorithm: Example
{A}
{A,B,C,D,E}
{A,B,C,D,E}
{A,B,C,D,E}
{A,B,C,D,E}
17
{A,C}
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
while changed:for n in nodes:pre = intersect(DOM(preds(n)))new = union(pre, n)DOM(n) = new
Dominator Algorithm: Example
{A}
{A,B,C,D,E}
{A,B,C,D,E}
{A,B,C,D,E}
17
{A,C}
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
while changed:for n in nodes:pre = intersect(DOM(preds(n)))new = union(pre, n)DOM(n) = new
Dominator Algorithm: Example
{A}
{A,B,C,D,E}
{A,B,C,D,E}
{A,B,C,D,E}
17
{A,C}
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
while changed:for n in nodes:pre = intersect(DOM(preds(n)))new = union(pre, n)DOM(n) = new
Dominator Algorithm: Example
{A}
{A,B,C,D,E}
{A,B,C,D,E}
{A,B,C,D,E}
17
{A,C,D}
{A,C}
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
while changed:for n in nodes:pre = intersect(DOM(preds(n)))new = union(pre, n)DOM(n) = new
Dominator Algorithm: Example
{A}
{A,B,C,D,E}
{A,B,C,D,E}
17
{A,C,D}
{A,C}
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
while changed:for n in nodes:pre = intersect(DOM(preds(n)))new = union(pre, n)DOM(n) = new
Dominator Algorithm: Example
{A}
{A,B,C,D,E}
{A,B,C,D,E}
17
{A,C,D}
{A,C}
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
while changed:for n in nodes:pre = intersect(DOM(preds(n)))new = union(pre, n)DOM(n) = new
Dominator Algorithm: Example
{A}
{A,B,C,D,E}
{A,B,C,D,E}
17
{A,C,D}
{A,B}
{A,C}
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
while changed:for n in nodes:pre = intersect(DOM(preds(n)))new = union(pre, n)DOM(n) = new
Dominator Algorithm: Example
{A}
{A,B,C,D,E}17
{A,C,D}
{A,B}
{A,C}
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
while changed:for n in nodes:pre = intersect(DOM(preds(n)))new = union(pre, n)DOM(n) = new
Dominator Algorithm: Example
{A}
{A,B,C,D,E}17
{A,C,D}
{A,B}
{A,C}
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
while changed:for n in nodes:pre = intersect(DOM(preds(n)))new = union(pre, n)DOM(n) = new
Dominator Algorithm: Example
{A}
{A,B,C,D,E}17
{A,C,D}
{A,E}
{A,B}
{A,C}
A
C
B
D
E
DOM(n0) = {n0}
for n in nodes \ {n0}:DOM(n) = nodes
while changed:for n in nodes:pre = intersect(DOM(preds(n)))new = union(pre, n)DOM(n) = new
Dominator Algorithm: Example
{A}
17
Computing Dominators
• Shown algorithm
– Simple but not very efficient
– How to get IDOM(n) from DOM(n)?
• Efficient algorithm described in A Simple, Fast Dominance Algorithm by Cooper et al.
– Same idea, still very simple
– Not required for getting full marks
– Also covers shown algorithm
34
DOMINANCE FRONTIER CONSTRUCTION
Homework 1 – SSA Construction
35
Dominance Frontier
DF(n) = all nodes y such that n dominates a direct predecessor of y but does not strictly dominate y.
Intuition:The Dominance Frontier of n is where n’s dominance “ends”.
CFG!
36
Dominance Frontier: Intuition
H
A
B
F
C
D
J
I
G
E
37
Dominance Frontier: Example
A
C E
D
B
n dominates a direct pred. of y and n not strictly dominates y
38
Dominance Frontier: Example
A
C E
D
B
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
Dominance Frontier: Example
A
C E
D
B
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
Dominance Frontier: Example
A
C E
D
B
DF(A) = {}
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
Dominance Frontier: Example
A
C E
D
B
DF(A) = {}
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
Dominance Frontier: Example
A
C E
D
B
DF(A) = {}
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
Dominance Frontier: Example
A
C E
D
B
DF(A) = {}
DF(B) = {D}
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
Dominance Frontier: Example
A
C E
D
B
DF(A) = {}
DF(B) = {D}
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
Dominance Frontier: Example
A
C E
D
B
DF(A) = {}
DF(B) = {D}
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
Dominance Frontier: Example
A
C E
D
B
DF(A) = {}
DF(B) = {D}
DF(C) = {D}
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
Dominance Frontier: Example
A
C E
D
B
DF(A) = {}
DF(B) = {D}
DF(C) = {D}
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
DF(C) = {C, D}
Dominance Frontier: Example
A
C E
D
B
DF(A) = {}
DF(B) = {D}
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
DF(C) = {C, D}
Dominance Frontier: Example
A
C E
D
B
DF(A) = {}
DF(B) = {D}
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
DF(C) = {C, D}
Dominance Frontier: Example
A
C E
D
B
DF(A) = {}
DF(B) = {D}
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
DF(C) = {C, D}
Dominance Frontier: Example
A
C E
D
B
DF(A) = {}
DF(B) = {D} DF(E) = {C}
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
DF(C) = {C, D}
Dominance Frontier: Example
A
C E
D
B
DF(A) = {}
DF(B) = {D} DF(E) = {C}
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
DF(C) = {C, D}
Dominance Frontier: Example
A
C E
D
B
DF(A) = {}
DF(B) = {D}
DF(D) = {}
DF(E) = {C}
n dominates a direct pred. of y and n not strictly dominates y
A
B DC
E
Dominator Tree
38
Computing the DF
• Idea:
– Given node n, do not compute DF(n) directly
– Instead, find nodes y for which n is in DF(y)
• Simple algorithm based on two observations
55
Computing the DF: Observation 1
Direct predecessors of a node n have n in theirDF unless they dominate n.
A
C
D
B
1
3
2
I
II
56
Computing the DF: Observation 2
Dominators of direct predecessors of a node nhave n in their DF unless they dominate n.
A
E
F
C
B D
… …
1
4
3
2
…
57
for n in nodes:for p in preds(n):r = pwhile r != IDOM(n):
DF(r) += nr = IDOM(r)
A
C E
D
B
A
D C
E
B
Dominator TreeCFG
n = DDF(B) = {D}DF(C) = {D}
n = CDF(E) = {C}DF(C) = {C,D}
DF(A) = {}DF(B) = {D}DF(C) = {C,D}DF(E) = {C}DF(D) = {}
Dominance Frontier Algorithm
58
direct!
ɸ-FUNCTION INSERTION & VARIABLE VERSIONING
Homework 1 – SSA Construction
59
ɸ-Function Insertion
• ɸ-functions need to be inserted in all join nodes with different incoming assignments
• ɸ-operations are assignments too!
Assignments require a ɸ-function to be inserted in the DF nodes of the block containing the assignment
BB4
x = ɸ(x,x)write(x);
BB1
x = 0
BB2
x = 1BB3
write(x)
60
DF and ɸ-Functions: Example
H
A
B
F
C
D
J
I
G
E
x = 1
x = 4
write(x)
write(x)
write(x)
61
DF and ɸ-Functions: Example
H
A
B
F
C
D
J
I
G
E
x = 1
x = 4
write(x)
write(x)
write(x)
61
DF and ɸ-Functions: Example
H
A
B
F
C
D
J
I
G
E
x = 1
x = 4
write(x)
write(x)
write(x)
61
DF and ɸ-Functions: Example
H
A
B
F
C
D
J
I
G
E
x = 1
x = 4
write(x)
write(x)
write(x)
61
DF and ɸ-Functions: Example
H
A
B
F
C
D
J
I
G
E
x = 1
x = 4
x = ɸ(x,x) x = ɸ(x,x)write(x)
x = ɸ(x,x,x)write(x)
write(x)
61
Variable Versioning
• Need to add versions to all variables
– S.t. each version is assigned only once (statically)
• Make sure that always the “newest” version of a variable is used
– Traverse the CFG, keep track of current (newest) and highest variable versions
– Replace all uses of unversioned variables
• Also in ɸ-functions!
66
Variable Versioning: Example
BB6
x = ɸ(x ,x )write(x );
BB1
x = 0
BB2
x = 1BB3
write(x )
BB5
x = x + 1BB4
x = ɸ(x ,x )
67
Variable Versioning: Example
BB6
x = ɸ(x ,x )write(x );
BB1
x = 0
BB2
x = 1BB3
write(x )
BB5
x = x + 1BB4
x = ɸ(x ,x )
1
67
Variable Versioning: Example
BB6
x = ɸ(x ,x )write(x );
BB1
x = 0
BB2
x = 1BB3
write(x )
BB5
x = x + 1BB4
x = ɸ(x ,x )
1
2
67
Variable Versioning: Example
BB6
x = ɸ(x ,x )write(x );
BB1
x = 0
BB2
x = 1BB3
write(x )
BB5
x = x + 1BB4
x = ɸ(x ,x )
1
2
2
67
Variable Versioning: Example
BB6
x = ɸ(x ,x )write(x );
BB1
x = 0
BB2
x = 1BB3
write(x )
BB5
x = x + 1BB4
x = ɸ(x ,x )
1
12
2
67
Variable Versioning: Example
BB6
x = ɸ(x ,x )write(x );
BB1
x = 0
BB2
x = 1BB3
write(x )
BB5
x = x + 1BB4
x = ɸ(x ,x )
1
1
1
2
2
67
Variable Versioning: Example
BB6
x = ɸ(x ,x )write(x );
BB1
x = 0
BB2
x = 1BB3
write(x )
BB5
x = x + 1BB4
x = ɸ(x ,x )
1
1
1
2
2
3
67
Variable Versioning: Example
BB6
x = ɸ(x ,x )write(x );
BB1
x = 0
BB2
x = 1BB3
write(x )
BB5
x = x + 1BB4
x = ɸ(x ,x )
1
1
1
2
2
3
3
67
Variable Versioning: Example
BB6
x = ɸ(x ,x )write(x );
BB1
x = 0
BB2
x = 1BB3
write(x )
BB5
x = x + 1BB4
x = ɸ(x ,x )
1
1
1
2
2
3 3
3
67
Variable Versioning: Example
BB6
x = ɸ(x ,x )write(x );
BB1
x = 0
BB2
x = 1BB3
write(x )
BB5
x = x + 1BB4
x = ɸ(x ,x )
1
1
1
2
2
3 34
3
67
Variable Versioning: Example
BB6
x = ɸ(x ,x )write(x );
BB1
x = 0
BB2
x = 1BB3
write(x )
BB5
x = x + 1BB4
x = ɸ(x ,x )
1
1
1
2
2
3 344
3
67
Variable Versioning: Example
BB6
x = ɸ(x ,x )write(x );
BB1
x = 0
BB2
x = 1BB3
write(x )
BB5
x = x + 1BB4
x = ɸ(x ,x )
1
1
1
2
2
3 344
35
67
Variable Versioning: Example
BB6
x = ɸ(x ,x )write(x );
BB1
x = 0
BB2
x = 1BB3
write(x )
BB5
x = x + 1BB4
x = ɸ(x ,x )
1
1
1
2
2
3 344
35
5
67
SSA DESTRUCTIONHomework 1
80
SSA Destruction
• Replace ɸ-operations with copy statements in direct predecessors
81
Removing ɸ-Functions: Example 1
BB1
x1 = 0
BB2
x2 = 1BB3
write(x1)
BB4
x3 = ɸ(x2,x1)write(x3)
82
Removing ɸ-Functions: Example 1
BB1
x1 = 0
BB2
x2 = 1BB3
write(x1)
BB4
x3 = ɸ(x2,x1)write(x3)
82
Removing ɸ-Functions: Example 1
BB1
x1 = 0
BB2
x2 = 1x3 = x2
BB3
write(x1)x3 = x1
BB4
x3 = ɸ(x2,x1)write(x3)
82
Removing ɸ-Functions: Example 2
BB1
x1 = 0
BB2
x2 = 1
BB3
x3 = ɸ(x2,x1)write(x3)
85
Removing ɸ-Functions: Example 2
BB1
x1 = 0
BB2
x2 = 1
BB3
x3 = ɸ(x2,x1)write(x3)
85
Removing ɸ-Functions: Example 2
BB1
x1 = 0x3 = x1
BB2
x2 = 1x3 = x2
BB3
x3 = ɸ(x2,x1)write(x3)
85
Removing ɸ-Functions: Example 2
BB1
x1 = 0x3 = x1
BB2
x2 = 1x3 = x2
BB3
x3 = ɸ(x2,x1)write(x3)
• Process may insert redundantassignments:
x3 = x1...
x3 = x2
• Solution: Insert empty blocks where necessary
85
Removing ɸ-Functions: Example 2
BB1
x1 = 0
BB2
x2 = 1
BB3
x3 = ɸ(x2,x1)write(x3)
• Process may insert redundantassignments:
x3 = x1...
x3 = x2
• Solution: Insert empty blocks where necessary
BB4
89
Removing ɸ-Functions: Example 2
BB1
x1 = 0
BB2
x2 = 1
BB3
x3 = ɸ(x2,x1)write(x3)
• Process may insert redundantassignments:
x3 = x1...
x3 = x2
• Solution: Insert empty blocks where necessary
BB4
89
Removing ɸ-Functions: Example 2
BB1
x1 = 0
BB2
x2 = 1x3 = x2
BB3
x3 = ɸ(x2,x1)write(x3)
• Process may insert redundantassignments:
x3 = x1...
x3 = x2
• Solution: Insert empty blocks where necessary
BB4
x3 = x1
89
Removing ɸ-Functions: Example 2
BB1
x1 = 0
BB2
x2 = 1x3 = x2
BB3
x3 = ɸ(x2,x1)write(x3)
• Process may insert redundantassignments:
x3 = x1...
x3 = x2
• Solution: Insert empty blocks where necessary– Already done in CFG construction
phase in HW1 fragment
BB4
x3 = x1
89
PRACTICAL TIPS(FRAMEWORK)
Homework 1
93
Framework: Dominator Tree
• Computation of IDOM(n) and DF(n) in cd.transform.Dominator class
• Dominator tree edges directly in BasicBlock:
dominatorTreeParent: BB
dominatorTreeChildren: List<BB>
dominanceFrontier: Set<BB>
cd.ir.BasicBlock
IDOM(n)
94
Framework: Variable Versions
• VariableSymbol has new field: version
• New constructor to create a new version:VariableSymbol(VariableSymbol v0sym, int version)
95
Framework: ɸ-Operations
• ɸ-operations represented by class cd.ir.Phi
write(x)
x3 = ɸ(x1,x2)write(x3)
v0sym: VariableSymbol
lhs: VariableSymbol
rhs: List<Expr>
cd.ir.Phi
96
Framework: ɸ-Operations
• BasicBlock contains all attached ɸ-ops
• Map key is original variable (version 0)
• Add the new symbols to the method locals
phis: Map<VS,Phi>
cd.ir.BasicBlock
97
Testing & Debugging
• No comparison of SSA form between your and reference solution available
– Others still work, e.g., .exec vs .exec.ref
• Manually inspect .dom.dot, .ssa.dot, and
.dessa.dot files– Again, using Graphviz et al.
• Need to write test programs nevertheless!
– Or even a few little unit tests?...
98
?Questions
99