advanced compilers use-def analysis and ssa (static single...
TRANSCRIPT
1
Advanced Compilers Use-Def Analysis and SSA (Static
Single Assignment) Fall. 2016
Chungnam National Univ.
Eun-Sun Cho
Use-Definition Analysis
mostly from “Intra-procedural Data Flow Analysis,”
© Nielson&Nielson
http://cs.sookmyung.ac.kr/~chang/lecture/popa05/forward.pdf
http://www.rw.cdl.uni-saarland.de/private/joba/PA/Slides/backward_4.pdf
2
Use-Definition and Definition-Use Chains
Use-Definition chains (ud chains)
Each use of a variable is linked to all
assignments that reach it
3 ud chains du chains
1: x = 0
2: x = 3
4: z = 0 5: z =x
6: y =x
7: x =y+z
3: z = x ?
1: x = 0
2: x = 3
4: z = 0 5: z =x
6: y =x
7: x =y+z
3: z = x ?
Definition-Use chains (du chains)
Each assignment to a variable is
linked to all uses of it
4
l: x = n ..: x = …
…: …x… l‘ : …x …
du-chain
ud-chain
…
…
Example
1: x = 0
2: x = 3
4: z = 0 5: z =x
6: y =x
7: x =y+z
3: z = x ?
l RD-in (l) (== RDo(l))
1 {x?, y?, z?}
2 {x1, y?, z?}
3 {x2, y?, z?}
4 {x2, y?, z?}
5 {x2, y?, z?}
6 {x2, y?, z4, z5}
7 {x2, y6, z4, z5}
ud(x,l) x y z
1
2
3 {2} {?}
4
5 {2}
6 {2}
7 {6} {4,5}
du(x,l) x y z
1
2 {3,5,6}
3
4 {7}
5 {7}
6 {7}
7
? {3}
Note: Notations for Various Data Flow Analyses
• Different dataflow analyses may be composed and mixed together into
another, more usable analysis
• We need new notations of dataflow analyses (instead of simple ‘IN’ and
‘OUT’) to differentiate one from another.
• eg.
– RD(l) : IN of block l
– RD(l) : OUT of block l
RD(l) = genRD(l) ∪ (RD(l) – killRD(l))
RD(l) = {RD(l’) | (l’, l) flow} if l ≠ init
{(x, ?)| x FV} if l = init
killRD([l: x = a]) = {(x, ?)} ∪ {(x, l’) | block l’ is an assignment to x}
genRD([l: x = a]) = {(x, l ) }
killRD(l) = genRD(l) = , otherwise
6
UD-Chains
UD(x, l) = {l’ | (x, l’) RD(l) } if x used (l)
otherwise
where used([l: x = a]) = FV(a), used([l: b]) = FV(b) and used([l:
skip]) =
7
SSA (Static Single Assignment) Form
8
SSA (Static Single Assignment) Form
• SSA
– each assignment to a variable is given a unique
name
• All of the uses reached by that assignment are renamed
– Easy for straight-line code
– What about control flow? ===> -nodes
9
v := 4
w := v+5
v := 6
w := v+7
v0 := 4
w0 := v0+5
v1 := 6
w1 := v1+7
Examples
10
if (…)
x5 x3
yx
B1
B0
B2
B3
if (…)
x05 x13
x2 (x0, x1)
yx2
B1
B0
B2
B3
i 1
i i+1
B1
B2
i0 1
i1 (i0, i2)
i2 i1+1
B1
B2
gcc Example
int main(){
int x;
int y;
if (x == y)
x = 1;
else
x = 2;
y = x;
}
11
main ()
{
int y;
int x;
<bb 2>:
if (x_2(D) == y_3(D))
goto <bb 3>;
else
goto <bb 4>;
<bb 3>:
x_4 = 1;
goto <bb 5>;
<bb 4>:
x_5 = 2;
<bb 5>:
# x_1 = PHI <x_4(3), x_5(4)>
y_6 = x_1;
return;
gcc -fdump-tree-all t.c
(v4.6.3)
t.c
t.c.017t.ssa
Advantages of SSA
• Definitions are explicit merging of values
• More compact representation
• Over use-def chains
– Each USE has only one definition
12
Eg. Constant Propagation with SSA
13
UNDEF
(T)
c1 NAC
()
UNDEF
(T) UNDEF c1 NAC
c1 c1 c1 NAC
c2
c1
c2 NAC NAC
NAC
() NAC NAC NAC
• Use only ‘SSA edges’ • “connections between the unique
definition to a variable to each of its
uses”
• Same result, fewer meet operation
(perform meet operations only at
-nodes)
14
a1 < b1
c1 4 c2 5
c3 (c1,c2)
B4
B3
B5
B6
entry
a1 2
b1 3
exit
B1
B2 SSA edges
Where To Put -nodes ?
• Condition
– If two non-null paths X+Z and Y + Z converge at node Z, and
nodes X and Y contain assignments to V, then a -node for V must be
inserted at Z
• Minimal
– As few as possible subject to condition
– Briggs-minimal
• As few as possible subject to condition, and V must be live across
some basic block
– pruned
• As few as possible subject to condition, and without dead -nodes
15
Definitions Dominance Frontiers
• Dominance Frontiers
DF(X) = {Y | P pred(Y),
X is dom(P) and X is not dom!(Y)}
where, X= dom!(Y) means X= dom(Y) and XY
– The dominance frontier of X is the set of nodes Y s.t X dominates a
predecessor of Y, but X does not strictly dominate Y.
16
What is dominating or dom()/dom!()?
Dominator
• Dominator
– “If node x is necessarily executed in every path from Entry to node y in
the CFG, we call x a dominator of y”
• “x dominates y” means
“x is always executed before y is executed.” …. x dom(y)
• Properties
– Every node dominates itself
– if x dominates y, and y dominates z, then x dominates z
– if both x and y dominates z, x dominates y or y dominates x
• Strictly dominating : x is a strictly dominator of y, when x dominates y but x is not y ….. x dom(y) but x y
Dominator Examples
BB1
BB2
BB4
BB3
BB5 BB6
BB7
Entry
Exit
BB2
BB3
BB4
BB5
Entry
Exit
BB6
BB1
Dominator Analysis • dom(BBi) = set of BBs that dominate BBi
• Initialization
– dom(ENTRY) = ENTRY
– dom(everything else) = all nodes
– change = true
• Iterative computation – while change, do
• change = false
• for each BB (except ENTRY)
– tmp(BB) = BB + {Intersection of dominators of all predecessors}
– if (tmp(BB) != dom(BB))
» dom(BB) = tmp(BB)
» change = true
BB1
BB2
BB4
BB3
BB5 BB6
BB7
Entry
Exit
Usage of Dominators
• Dominators are used for most global
optimization
eg.
Loop detection ! (see loop detection chapter)
Redundant computation : If there is an
expression that is computed at the dominator of
the program point, and there is no in-between
operations which kill the expressions’ free
variables, the evaluation of the expression can
be eliminated
BB1
BB2
BB4
BB3
BB5 BB6
BB7
Entry
Exit
Dominator Tree
• Graph representing
inclusion relationships
between dominators
21
BB2
BB3
BB4
BB5
Entry
Exit
BB6
BB1 dom(1) = E,1
dom(2) = E,1,2
dom(4) = E,1,2,3,4
dom(3) = E,1,2,3
dom(5) = E,1,2,3,5
dom(6) = E,1,2,6
BB1
BB2
BB3
BB4 BB5
BB6
<Dominator Tree> <Control Flow Graph>
22
So, Dominance Frontiers
• Dominance Frontiers
DF(X) = {Y | P pred(Y),
X is dom(P) and X is not dom!(Y)}
where, X= dom!(Y) means X= dom(Y) and XY
– The dominance frontier of X is the set of nodes Y s.t X dominates a
predecessor of Y, but X does not strictly dominate Y.
23
Dominance Frontier Example
• DF(8)= {10}
– 8 dom(8) , succ(8) = 10, 8
dom! (10)
• DF(9) = {10}
– 9 dom(9) , succ(9) = 10, 9
dom! (10)
• DF(10)= {6}
• 10 dom(10) , succ(10) = 6,
10 dom! (6)
24
A= 2
1
7
A= A= 9 3 8 4
5 10
6
• DF(2) = {6}
• 2 dom(2), 2 dom(3), 2 dom(4), 2 dom(5),
• succ({2,3,4,5}) = {3,4,5,6},
• 2 dom!(6),
• 2 dom!(3), 2 dom!(4), 2 dom!(5),
3,4,or 5 is not in DF(2)
Iterated Dominance Frontier
• Building SSA Form
– Insert -node
– Rename values
• DF(L) for a set of nodes L
– DF(L) = ∪XL DF(X)
• DF+(L)
– the limit of the sequence DF1 = DF(L), DFi+1=DF(L ∪ DFi)
• Theorem 1 The set of nodes that need -node for any variable
V is the iterated dominance frontier DF+ (L), where L is the set
of nodes with assignments to V
25
cf. Dominator Tree
26
1
entry
2
3 4
5 6 exit
k false
i 1
j 2
j j *2
k true
i i+1
k 3
print j i i+1 5
exit
6
entry
i < n
1
2
4
represents
dominating relationships
More SSA Example
Dominance Frontier
27
k false
i 1
j 2
j j *2
k true
i i+1
k 3
print j i i+1 5
exit
6
entry
i < n
1
2
4
• DF(entry)
entry dom(entry), entry dom(1),
…, entry dom(exit)
succ({entry,1,2,…exit}) = {1,2,3,..,exit}
entry dom!(1) ? NO
entry dom!(2) ? NO ...
entry dom!(exit) ? NO
DF(entry) = {}
• DF(1)
1 dom(1), 1dom(2), … 1dom(exit)
succ({1,2,3,…exit}) = {2,3,4,…,exit}
1 dom!(2) ? NO 1 dom!(3) ? NO,
... 1 dom!(exit) ? NO
DF(1) = {}
• DF(3)
3 dom(3), succ(3) = {2}
3 dom!(2) ? YES
DF(3) = {2}
• DF(6)
6 dom(6), succ(6) = {exit}
6 dom!(exit) ? YES
DF(6) = {exit}
Position To Insert Node
28
for k, j: DF+({entry, 1, 3})
DF({entry, 1, 3})
= DF(entry) ∪ DF(1) ∪ DF(3)= {} ∪ {} ∪ {2}
= {2}
DF(DF({e,1,3}) ∪ {e,1,3} )= DF({2, e, 1, 3})
= DF(2) ∪ DF({e,1,3}) = {} ∪ {2} = {2}
…
DF+(e,1,3) = {2}
for i: DF+({entry, 1, 3, 6})
DF({entry, 1, 3, 6})
= DF(entry) ∪ DF(1) ∪ DF(3) ∪ DF(6) = {2,exit}
DF(DF({e,1,3,6}) ∪ {e,1,3,6} ) = DF ({2, exit, e,1,3,6})
= DF({2, exit}) ∪ DF({e,1,3,6}) = {} ∪ {2, exit}
= {2,exit}
…..
DF+(e,1,3,6) = {2, exit}
29
k1 false
i1 1
j1 2
j2 j3*2
k2 true
i2 i3+1
k3 3
print j3 i4 i3+1 5
i5 (i3,i4)
exit
6
entry
k3 (k1,k2)
i3 (i1,i2)
j3 (j1,j2)
i3< n
1
2
4
Result