Static Single Assignment (SSA) Form

Download Report

Transcript Static Single Assignment (SSA) Form

Static Single Assignment
(SSA) Form
Jaeho Shin <[email protected]>
2005-03-11 16:00
ROPAS Weekly Show & Tell
Outline
1.
2.
3.
4.
Preliminaries
Concept and definition of SSA form
Algorithm for computing SSA form
Relation with
–
–
functional programming
continuation passing style
5. Flow sensitivity of analyses with SSA
2/32
Preliminaries
• Control flow graph
– predecessor, successor
• Dominators, strict dominators
• Immediate dominator
• Dominator tree
– parent, children
• Continuation passing style
3/32
Definition of SSA form
• Static Single Assignment Form is a
transformed program
– Whose variables are renamed
• e.g. x --> xi
– Having only one definition for each variable
– Without changing the semantics of the
original program
• i.e. every renamed variable xi of x must have the
same value for every possible control flow path
4/32
Why SSA form?
• More compact def-use chain
• Control flow becomes explicit on
variable names
• Improves performance of many dataflow analyses
5/32
Example 1
a=x+y
b=a-1
a=y+b
b=x*4
a=a+b
a1 = x + y
b1 = a1 - 1
a2 = y + b1
b2 = x * 4
a3 = a2 + b2
It’s so easy! Isn’t it?
Well… not in general!
6/32
Example 2
o=0
e=0
i=0
while (i<100)
if (i % 2 == 0)
e=e+i
else
o=o+i
i=i+1
print i, o, e
7/32
Example 2
as a CFG
o=0
e=0
i=0
if i < 100
if i % 2 == 0
e=e+i
o=o+i
i=i+1
print i, o, e
8/32
Example 2
What’s the matter?
o1 = 0
e1 = 0
i1 = 0
e1, o1, i1
e3, o3, i3
o2 = ?
e2 = ?
i2 = ?
if i2 < 100
if i2 % 2 == 0
e3 = e2 + i2
o3 = o2 + i2
i3 = i2 + 1
print i2, o2, e2
9/32
We need f-function
• f-function:
– a function that is defined to magically
choose the correct variable from incoming
control flow edges
• But, where should we place f’s?
10/32
Example 2
How about this?
o1 = 0
e1 = 0
i1 = 0
o2 = f(o1,o7)
e2 = f(e1,e7)
i2 = f(i1,i7)
if i2 < 100
o8 = f(o2)
e8 = f(e2)
i8 = f(i2)
print i8, o8, e8
o3 = f(o2)
e3 = f(e2)
i3 = f(i2)
if i3 % 2 == 0
o4 = f(o3)
e4 = f(e3)
i4 = f(i3)
e6 = e4 + i4
o5 = f(o3)
e5 = f(e3)
i5 = f(i3)
o6 = o5 + i5
o7 = f(o4,o6)
e7 = f(e6,e5)
i6 = f(i4,i5)
i7 = i6 + 1
11/32
Dominance Frontiers
• Dominance frontier of a CFG node X:
– The set of all CFG nodes Y such that
X dominates a predecessor of Y
but does not strictly dominate Y
12/32
Dominance Frontiers (cont’d)
• Dominance frontiers
of node X form the
boundary between
following nodes of X
that X dominates
and does not
nodes
dominated by X
X
Y
W
Z
dominance
frontiers of X
13/32
Placing f’s at DF
• Definitions other
than those in X may
flow into Y, Z or W
• We need to place
f’s for each variable
defined in X
at the dominance
frontiers of X
x=1
a=x+1
X
x=2
Y
W
Z
y=x*2
14/32
Example 2
in minimal SSA form
o1 = 0
e1 = 0
i1 = 0
o2 = f(o1,o4)
e2 = f(e1,e4)
i2 = f(i1,i3)
if i2 < 100
if i2 % 2 == 0
e3 = e2 + i2
o3 = o2 + i2
o4 = f(o2,o3)
e4 = f(e2,e3)
i3 = i2 + 1
print i2, o2, e2
15/32
SSA form algorithm
• R. Cytron, et al. [1] presented an efficient algorithm
computing SSA form using dominance frontiers
– For each variable v
• Place f-function for v at each nodes in DF+ of nodes defining v
where DF+(S) = least fix point (lT.DF(T) U S) {}
– Traversing the dominator tree in pre-order,
for each node X using the parent’s last map(*)
• For each assignments in X
– Rename used variables v --> vmap(v)
– Rename defined variables u --> ucount(u)
– replace map(u) = count(u) and count(u) = count(u) + 1
• For each successor Y of X, and for each f-function for v in Y
– Replace vmap(v) for corresponding argument
16/32
SSA is FP
• A. Appel [2] has shown converting to
SSA is actually functional programming
• We can rewrite example 2 in a
functional programming language
19/32
SSA is FP
numbering BBs in example 2
o1 = 0
e1 = 0
i1 = 0 1
o2 = f(o1,o7)
e2 = f(e1,e7)
i2 = f(i1,i7)
if i2 < 100
2
o8 = f(o2)
e8 = f(e2)
i8 = f(i2)
print i8, o8, e8 7
o3 = f(o2)
e3 = f(e2)
i3 = f(i2)
if i3 % 2 == 0 3
o4 = f(o3)
e4 = f(e3)
i4 = f(i3)
e6 = e4 + i4 4
o5 = f(o3)
e5 = f(e3)
i5 = f(i3)
o6 = o5 + i5 5
o7 = f(o4,o6)
e7 = f(e6,e5)
i6 = f(i4,i5)
i7 = i6 + 1
6
20/32
SSA is FP
translating BBs into ftns
fun f1() =
let val o1 = 0 and e1 = 0 and i1 = 0
in f2(o1, e1, i1)
fun f4(o4, e4, i4) =
let val e6 = e4 + i4
in f6(o4, e6, i4)
fun f2(o2, e2, i2) =
if i2 < 100 then f3(o2, e2, i2)
else f7(o2, e2, i2)
fun f5(o5, e5, i5) =
let val o6 = o5 + i5
in f6(o6, e5, i5)
fun f3(o3, e3, i3) =
if i3 % 2 == 0 then f4(o3, e3, i3)
else f5(o3, e3, i3)
fun f6(o7, e7, i6) =
let val i7 = i6 + 1
in f2(o7, e7, i7)
fun f7(o8, e8, i8) = print(i8, o8, e8)
Still ugly, right?
21/32
SSA is FP
making use of nested scopes
let val o1 = 0 and e1 = 0 and i1 = 0
fun f2(o2, e2, i2) =
if i2 < 100
then let fun f6(o4, e4) =
let val i3 = i2 + 1
in f2(o4, e4, i3)
in if i2 % 2 == 0
then let val e3 = e2 + i2
in f6(o2, e3)
else let val o3 = o2 + i2
in f6(o3, e2)
else print(i2, o2, e2)
in f2(o1, e1, i1)
• This is the SSA form
of example 2!
• The algorithm for
converting programs
to SSA form can be
used for nesting
functions to eliminate
unnecessary argument
passing
22/32
Relation with
continuation passing style
• R. Kelsey [3] claims that CPS can be
written into SSA and vice versa
• SSA --> CPS is possible since SSA is FP
• But, is CPS --> SSA generally possible?
• What’s the intuition?
23/32
Improving accuracy of
flow-insensitive analyses
• Flow-insensitive analyses
– Analysis which can’t distinguish control flow
• SSA makes control flow soak into names
of variables (however, with some limitations)
24/32
Example 3
Set-based string analysis for C
char *s = “”;
strcat(s, “begin ”);
for (i=0; i<10; i++) {
sprintf(tmp, “%d ”, i);
strcat(s, tmp);
}
strcat(s, “end”);
What string does s have here?
printf(s);
25/32
Example 3
Using intermediate language
s = “”;
s = s @ “begin ”;
for (i=0; i<10; i=i+1) {
tmp = i @ “ ”;
s = s @ tmp;
}
s = s @ “end”;
What string does s have here?
printf(s);
26/32
Example 3
Derived set-constraints
{
}
Vs ⊇ “”,
Vs ⊇ Vs @ “begin ”,
Vi ⊇ 0, Vi ⊇ Vi + 1,
Vtmp ⊇ Vi @ “ ”,
Vs ⊇ Vs @ Vtmp,
Vs ⊇ Vs @ “end”,
X ⊇ Vprintf(Vs)
• Vs ⊇ { “”, “begin ”,
“begin 0”, “begin 0 1
2 3 4 5 6 7 8 9 end”,
…, “end0 ”, “begin
100”, “endbegin ”, … }
• Vs which represents
the set of strings
that variable s may
contain is too large
• Too inaccurate!
27/32
Example 3
into SSA form
s1 = “”;
s2 = s1 @ “begin ”;
s3 = s2;
for (i1=0, i2=i1; i2<10; i3=i2+1, i2 = i3) {
tmp1 = i2 @ “ ”;
s4 = s3 @ tmp1;
s3 = s4;
}
s5 = s3 @ “end”;
printf(s5);
What string does s5 have?
28/32
Example 3
Constraints from SSA form
{
Vs1 ⊇ “”,
Vs2 ⊇ Vs1 @ “begin ”,
Vs3 ⊇ Vs2,
Vi1 ⊇ 0, Vi2 ⊇ Vi1,
Vi3 ⊇ Vi2 + 1, Vi2 ⊇ Vi3,
Vtmp1 ⊇ Vi2 @ “ ”,
Vs4 ⊇ Vs3 @ Vtmp1,
Vs3 ⊇ Vs4
Vs5 ⊇ Vs3 @ “end”,
X ⊇ Vprintf(Vs5)
}
Vtmp1 ⊇ { “0 ”,“1 ”,“2 ”, … }
Vs3 ⊇ { “begin ” }
 Vs3 @ Vtmp1
Vs5 ⊇ Vs3 @ “end”
• Vs5 ⊇ { “begin end”,
“begin 0 end”, “begin 0 1
2 3 4 5 6 7 8 9 end”,
“begin 9 8 2 1 end”,
“begin 100 10 37 end”,
…}
• Better than before :-)
29/32
Problems for SSA form
• How should we handle
– Global variables?
– Arrays and pointers?
• We sometimes need to turn SSA form
back to programs without f-functions
– Handling critical edges
– Reducing redundant assignments
30/32
Conclusions
• SSA form is a transformed program
where every variable has one definition
• Minimal SSA form can be computed with
dominance frontiers
• With SSA form we can improve the
accuracy of flow-insensitive analyses
without modifying the analysis itself
• Converting to SSA form is similar to
nesting functions in functional programs
31/32
References
[1] R. Cytron, et al., “An efficient method of
computing static single assignment form”,
POPL, 1989.
[2] A. Appel, “SSA is functional programming”,
ACM SIGPLAN Notices, 1998.
[3] R. Kelsey, “A correspondence between
continuation passing style and static single
assignment form”, ACM SIGPLAN Notices,
1993.
32/32