Liveness Analysis Mooly Sagiv Schrierber 317 03-640-7606 Wed 10:00-12:00...
-
date post
20-Dec-2015 -
Category
Documents
-
view
216 -
download
1
Transcript of Liveness Analysis Mooly Sagiv Schrierber 317 03-640-7606 Wed 10:00-12:00...
Liveness Analysis
Mooly Sagiv
Schrierber 31703-640-7606
Wed 10:00-12:00
html://www.math.tau.ac.il/~msagiv/courses/wcc02.html
Basic Compiler PhasesSource program (string)
Fin. Assembly
lexical analysis
syntax analysis
semantic analysis
Translate
Instruction selection
Register Allocation
Tokens
Abstract syntax tree
Intermediate representation
Assembly
Frame
Register Allocation• Input:
– Sequence of machine code instructions(assembly)
• Unbounded number of temporary registers
• Output– Sequence of machine code instructions
(assembly)– Machine registers – Some MOVE instructions removed– Missing prologue and epilogue
LABEL(l3)
CJUMP(EQ, TEMP t128, CONST 0, l0, l1)
LABEL( l1)
MOVE(TEMP t131, TEMP t128)
MOVE(TEMP t130, CALL(nfactor, BINOP(MINUS, TEMP t128, CONST 1)))
MOVE(TEMP t129, BINOP(TIMES, TEMP t131, TEMP t130))
LABEL(l2)
MOVE(TEMP t103, TEMP t129)
JUMP(NAME lend)
LABEL(l0)
MOVE(TEMP t129, CONST 1)
JUMP(NAME l2)
Missing updates for static link
l3: beq t128, $0, l0
l1: or t131, $0, t128
addi t132, t128, -1
or $4, $0, t132
jal nfactor
or t130, $0, $2
or t133, $0, t131
mult t133, t130
mflo t133
or t129, $0, t133
l2: or t103, $0, t129
b lend
l0: addi t129, $0, 1
b l2
l3: beq $25, $0, l0
l1: or $30, $0, $25
addi $4, $25, -1
/* or $4, $0, $4 */
jal nfactor
/* or $2, $0, $2 */
/* or $30, $0, $30 */
mult $30, $2
mflo $30
/* or $30, $0, $30 */
l2: or $2, $0, $30
b lend
l0: addi $30, $0, 1
b l2
t128 $25
t129 $30
t130 $2
t131 $30
t132 $4
t133 $30
t103 $2
.global nfactor
.ent nfactor
factor_framesize=40
.frame $sp,nfactor_framesize,$31
nfactor: addiu $sp,$sp,-nfactor_framesize
sw $2,0+nfactor_framesize($sp)
or $25, $0, $4
sw $31,-4+nfactor_framesize($sp)
sw $30,-8+nfactor_framesize($sp)
lend: lw $30,-8+nfactor_framesize($sp)
lw $31,-4+nfactor_framesize($sp)
addiu $sp,$sp,nfactor_framesize
j $31
.end nfactor
l3: beq $25, $0, l0
l1: or $30, $0, $25
addi $4, $25, -1
jal nfactor
mult $30, $2
mflo $30
l2: or $2, $0, $30
b lend
l0: addi $30, $0, 1
b l2
The need for “spilling”• The number of registers may not be enough
– Spill the content of some registers into memory– Load when needed
• Increase the number of instructions
• Increase CPU time
Outline• Liveness Analysis
– Motivation– Static Liveness– Dataflow Equations– Solutions– An Iterative Algorithm– Liveness in Tiger (Targil)
• Actual Allocation– Next week
Liveness Analysis• The same register may be assigned (at
compile-time) to two temporaries if their “life-times” do not overlap
• A variable is live a givenprogram point– its current is used after this point prior to a
definition (assignment)
• v is live at a given program point• There exists an execution sequence from this point
to a use of v that does not assign to v
• Two variables interfere at a given point– they are simultaneously live at this point
A Simple Example/* c */
L0: a := 0
/* ac */
L1: b := a + 1
/* bc */
c := c + b
/* bc */
a := b * 2
/* ac */
if c < N goto L1
/* c */
return c
a b
c
Liveness Interference Graph• For every compiled function
• Nodes– Pre-colored machine registers – Temporaries
• Undirected-Edges– Temporaries that are simultaneously alive– Different machine registers
• Undirected MOVE edges– “Correlated” temporaries and registers
A Simple Example/* c */
L0: a := 0
/* ac */
L1: b := a + 1
/* bc */
c := c + b
/* bc */
a := b * 2
/* ac */
if c < N goto L1
/* c */
return c
a b
c
l3: beq t128, $0, l0 /* $0, t128 */
l1: or t131, $0, t128 /* $0, t128, t131 */
addi t132, t128, -1 /* $0, t131, t132 */
or $4, $0, t132 /* $0, $4, t131 */
jal nfactor /* $0, $2, t131 */
or t130, $0, $2 /* $0, t130, t131 */
or t133, $0, t131 /* $0, t130, t133 */
mult t133, t130 /* $0, t133 */
mflo t133 /* $0, t133 */
or t129, $0, t133 /* $0, t129 */
l2: or t103, $0, t129 /* $0, t103 */
b lend /* $0, t103 */
l0: addi t129, $0, 1 /* $0, t129 */
b l2 /* $0, t129 */
t133
$2
$0
$4
t128
t129
t130
t131
t132
t103
Undecidabily
• A variable is live at a givenpoint in the program– if its current value is used after this point prior
to a definition in some execution path
• It is undecidable if a variable is live at a given program location
Conservative
• The compiler need not generate the optimal code
• Can use more registers (“spill code”) than necessary
• Find an upper approximation of the live variables
• A superset of edges in the interference graph
• Not too many superfluous live variables
Control Flow Graph
• Nodes– Assembly instructions
• Directed-Edges– If an instruction x can be immediately followed
by an instruction y• A directed edge xy
Static Liveness
• A variable v is statically live at control flow node n– there exists a directed path p from n to a use of v
such that• p does not include an assignment to v
• Every live variable is statically live
• Some statically live variables are not live– since some control flow paths are non-
executable
Example
a := b * b ;
c := a + b ;
if (c >= b)
then return c;
else return a;
a := b * b ;
c := a + b ;
c >= b
return c; return a;
/* c */
L0: a := 0
/* ac */
L1: b := a + 1
/* bc */
c := c + b
/* bc */
a := b * 2
/* ac */
if c < N goto L1
/* c */
return c
a := 0 ;
b := a +1 ;
c := c +b ;
a := b*2 ;
c <N goto L1
return c ;
Computing Static Liveness
• Generate a system of equations for every function– define the set of live variables recursively
• Iteratively compute a minimal solution
The System of Equations
• For every instruction n– def[n]
• The temporary and physical register(s) assigned by n
– use[n]• The temporary and physical register used in n
• System of equations– LiveOut[ex] = – LiveOut[n] = (n, m) Edges Live[m]
– Live[n] = (LiveOut[n] – def[n]) use[n]
a := 0 ;
b := a +1 ;
c := c +b ;
a := b*2 ;
c <N goto L1
return c ;
1
2
3
4
5
6
ins def[n] use[n]
1 {a}
2 {b} {a}
3 {c} {c, b}
4 {a} {b}
5 {c}
6 {c}
LiveOut[6] = Live[6] = (LiveOut[6] – ) {c}
LiveOut[5] = Live[6] Live[2]
Live[5] = (LiveOut[5] – ) {c}
LiveOut[4] = Live[5] Live[4] = (LiveOut[4] – {a}) {b}
LiveOut[3] = Live[4] Live[3] = (LiveOut[3] – {c}) {c, b}
LiveOut[2] = Live[3] Live[2] = (LiveOut[2] – {b}) {a}
LiveOut[1] = Live[2] Live[1] = (LiveOut[1] – {a})
a := 0 ;
b := a +1 ;
c := c +b ;
a := b*2 ;
c <N goto L1
return c ;
1
2
3
4
5
6
ins def[n] use[n]
1 {a}
2 {b} {a}
3 {c} {c, b}
4 {a} {b}
5 {c}
6 {c}
LiveOut[6] = Live[6] = LiveOut[6] {c}
LiveOut[5] = Live[6] Live[2]
Live[5] = LiveOut[5] {c}
LiveOut[4] = Live[5] Live[4] = (LiveOut[4] – {a}) {b}
LiveOut[3] = Live[4] Live[3] = (LiveOut[3] – {c}) {c, b}
LiveOut[2] = Live[3] Live[2] = (LiveOut[2] – {b}) {a}
LiveOut[1] = Live[2] Live[1] = (LiveOut[1] – {a})
Fixed Points• A fixed point is a vector solution Live and LiveOut
– for every instruction n• LiveOut[ex] = • LiveOut[n] = (n, m) Edges Live[m]• Live[n] = (LiveOut[n] – def[n]) use[n]
• There more than one fixed point• Every fixed point contains at least the statically live
variables• The least fixed point (in terms of set inclusion)
uniquely exists– it contains exactly the statically live variables
a := 0 ;
b := a +1 ;
c := c +b ;
a := b*2 ;
c <N goto L1
return c ;
1
2
3
4
5
6
LiveOut[6] = Live[6] = LiveOut[6] {c}
LiveOut[5] = Live[6] Live[2]
Live[5] = LiveOut[5] {c}
LiveOut[4] = Live[5] Live[4] = (LiveOut[4] – {a}) {b}
LiveOut[3] = Live[4] Live[3] = (LiveOut[3] – {c}) {c, b}
LiveOut[2] = Live[3] Live[2] = (LiveOut[2] – {b}) {a}
LiveOut[1] = Live[2] Live[1] = (LiveOut[1] – {a})
ins LiveOut Live
1 {c, a} {c}
2 {c, b} {c, a}
3 {c, b} {c, b}
4 {c, a} {c, b}
5 {c,a} {c, a}
6 {c}
a := 0 ;
b := a +1 ;
c := c +b ;
a := b*2 ;
c <N goto L1
return c ;
1
2
3
4
5
6
LiveOut[6] = Live[6] = LiveOut[6] {c}
LiveOut[5] = Live[6] Live[2]
Live[5] = LiveOut[5] {c}
LiveOut[4] = Live[5] Live[4] = (LiveOut[4] – {a}) {b}
LiveOut[3] = Live[4] Live[3] = (LiveOut[3] – {c}) {c, b}
LiveOut[2] = Live[3] Live[2] = (LiveOut[2] – {b}) {a}
LiveOut[1] = Live[2] Live[1] = (LiveOut[1] – {a})
ins LiveOut Live
1 {c, a, d} {c, d}
2 {c, b, d} {c, a, d}
3 {c, b, d} {c, b, d}
4 {c, a, d} {c, b, d}
5 {c,a, d} {c, a, d}
6 {c}
a := 0 ;
b := a +1 ;
c := c +b ;
a := b*2 ;
c <N goto L1
return c ;
1
2
3
4
5
6
LiveOut[6] = Live[6] = LiveOut[6] {c}
LiveOut[5] = Live[6] Live[2]
Live[5] = LiveOut[5] {c}
LiveOut[4] = Live[5] Live[4] = (LiveOut[4] – {a}) {b}
LiveOut[3] = Live[4] Live[3] = (LiveOut[3] – {c}) {c, b}
LiveOut[2] = Live[3] Live[2] = (LiveOut[2] – {b}) {a}
LiveOut[1] = Live[2] Live[1] = (LiveOut[1] – {a})
ins LiveOut Live
1 {c, a, b} {c, b}
2 {c, b} {c, a}
3 {c, b} {c, b}
4 {c, a} {c, b}
5 {c, a} {c, a}
6 {c}
a := 0 ;
b := a +1 ;
c := c +b ;
a := b*2 ;
c <N goto L1
return c ;
1
2
3
4
5
6
LiveOut[6] = Live[6] = LiveOut[6] {c}
LiveOut[5] = Live[6] Live[2]
Live[5] = LiveOut[5] {c}
LiveOut[4] = Live[5] Live[4] = (LiveOut[4] – {a}) {b}
LiveOut[3] = Live[4] Live[3] = (LiveOut[3] – {c}) {c, b}
LiveOut[2] = Live[3] Live[2] = (LiveOut[2] – {b}) {a}
LiveOut[1] = Live[2] Live[1] = (LiveOut[1] – {a})
ins LiveOut Live
1 {c, a} {c}
2 {c, b} {c, a}
3 {c, b} {c, b}
4 {c} {c, b}
5 {c} {c}
6 {c}
Computing Least Fixed Points
• Start with an empty set of Live and LiveOut for every instruction
• Repeatedly add new variables according to the equations
• The sets of LiveOut and Live variables must monotonically increase
• The process must terminate
• Unique least solution
WL := ;
for each instruction n
LiveOut[n] :=
Live[n] :=
WL := WL {n}
while WL !=
select and remove n from WL
new := (LiveOut[n] –def[n]) use[n]
if new != Live[n] then
Live[n] := new
for all predecessors m of n do
LiveOut[m] := LiveOut[m] Live[n]
WL := WL {m}
An Iterative Algorithm
a := 0 ;
b := a +1 ;
c := c +b ;
a := b*2 ;
c <N goto L1
return c ;
1
2
3
4
5
6
n Live[n] LiveOut WL
{6, 5, 4, 3, 2, 1}
6 {c} LiveOut[5]={c} {5, 4, 3, 2, 1}
5 {c} LiveOut[4]={c} {4, 5, 2, 1}
4 {c, b} LiveOut[3]={c,b} {3, 2, 1}
3 {c, b} LiveOut[2]={c,b} {2, 1}
2 {c, a} LiveOut[1]={c,a}
LiveOut[5]={c,a}
{5, 1}
5 {c, a} LiveOut[4]={c,a} {4, 1}
4 {c, b} {1}
1 {c}
Representation of Sets
• Bit-Vectors– Var bits for every n– Live[n][v] = 1
• the variable v is live before n
– Cost of set operation is • O(Vars/word-size)
• Ordered Elements– Linear time for set operations
Time Complexity• Parameters
– N number of nodes (instructions)– Assume that pred[n] is constant– V Number of variables– d Number of loop nesting level
• DFS back edges
• Initialization NV• Inner-Most Iteration V• For-Loop N• Repeat
– Worst-Case NV– Worst-Case-DFS d + 1
• Total-Worst-Case (NV)2
• Total-DFS NVd• Single-variable N
for every instruction n
for every variable a def[n]
for every variable b LiveOut[n]
Create an interference edge
An Interference Graph
b a
May introduce too many edges for move instructions
for every non move instruction n
for every variable a def[n]
for every variable b LiveOut[n]
Create an interference edge
An Interference Graph
b a
for every move instruction n a:= c
for every variable b LiveOut[n] – {c} Create an interference edge
b a
A Simple Example/* c */
L0: a := 0
/* ac */
L1: b := a + 1
/* bc */
c := c + b
/* bc */
a := b * 2
/* ac */
if c < N goto L1
/* c */
return c
a b
c
l3: beq t128, $0, l0 /* $0, t128 */
l1: or t131, $0, t128 /* $0, t128, t131 */
addi t132, t128, -1 /* $0, t131, t132 */
or $4, $0, t132 /* $0, $4, t131 */
jal nfactor /* $0, $2, t131 */
or t130, $0, $2 /* $0, t130, t131 */
or t133, $0, t131 /* $0, t130, t133 */
mult t133, t130 /* $0, t133 */
mflo t133 /* $0, t133 */
or t129, $0, t133 /* $0, t129 */
l2: or t103, $0, t129 /* $0, t103 */
b lend /* $0, t103 */
l0: addi t129, $0, 1 /* $0, t129 */
b l2 /* $0, t129 */
t133
$2
$0
$4
t128
t129
t130
t131
t132
t103