Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
DATAFLOW ANALYSIS
Motivazione.
necessario conoscere le definizioni (def o gen) e luso (use) delle informazioni nei blocchi basici per:
constant folding dead-code elimination redundant computation elimination code motion induction variable elimination build data dependence graph (DDG) etc.
DataFlow Analysis
3
Definizione e uso
4
S:
V1 = V2
S una definizione di V1
S un uso di V2
B1
d1: i := m-1 d2: j := n d3: a := u1
Un point in un blocco basico si trova: - fra istruzioni - prima della prima istruzione del blocco - dopo lultima istruzione
B2
d4: i := i+1
B3
d5: j := j+1
Nellesempio?
B4
B5
d6: a := u2
B6
Points e Paths
7
B1
d1: i := m-1 d2: j := n d3: a := u1
B2
d4: i := i+1
B3
d5: j := j+1
un path una sequenza di punti p1, p2, , pn tali che: (i) se p i immediatamente precede S, allora p i+1 immediatamente segue S. (ii) o p i la fine di un blocco basico e pi+1 linizio del blocco successivo
Nellesempio c un cammino dallinizio del blocco B5 allinizio del blocco B6?
B6
B4
B5
d6: a := u2
Reach e Kill
8
Kill
d1: x :=
una definizione d1 di una variablie v uccisa (killed) fra p1 e p2 se in ogni cammino da p1 a p2 c una definizione di v.
d2 : x :=
Reach un definizione d raggiunge (reaches) un punto p se un cammino d p, e d non ucciso (killed) allinterno del path
Esempio di Reach
9
B1
PROGRAM READ(L) N =0 K= 0 M =1
K= K + M C =K > L IF C THEN GOTO S11
B2
B3
N =N + 1 M =M + 2 GOTO S5
WRITE(N) END
B4 Linsieme def raggiunge luso di N in S8: {S2, S8} (S2, S3, S4, S5, S6, S7, S11)
10
Statement id := Expression | Statement ; Statement | if Expression then Statement else Statement | do Statement while Expression Expression id + id | id
Programmi strutturati
11
S1 S2
If E goto S1 S1 S2
S1
If E goto S1
S1 S2
if E then S1 else S2
do S1 while E
Data-Flow Values
12
2. Un Data-flow value rappresenta I possibili stati osservabile allinterno del programma 3. I data-flow value dipendono dallobiettivo dellanalisi.
Data una istruzione S, in(S) e out(S) rappresentano rispettivamente I data-flow values prima o dopo lesecuzione di S.
13
14
Per risolvere questi problemi dobbiamo prendere in considerazione il data-flow e il control-flow del programma Un metodo comune per risolvere tali problemi quello di creare un insieme di equazioni dataflow.
15
Definire un insieme di relazioni dataflow per ogni blocco basico Stabilire un insieme di equazioni dataflow fra i blocchi basici Stabilire una soluzione iniziale Iterativamente risolvere le equazioni fino al raggiungimento del punto fisso (fixed point )
In generale, una definizion d appartiene a gen(S) se d raggiunge la fine di S independentemente dal fatto che essa raggiunga linizio di S. Se S un blocco basico, gen(S) contiene tuttie le definizioni allinterno del blocco che sono immediatamente visibili dopo il blocco
a := a := a: a :=
...
17
Linsieme kill del blocco basico lunione di tutte le definizioni uccise dalle singole istruzioni.
Reaching Definitions
18
19
in [B] =
P predecessori di B
out [P]
Algoritmo 1) out(ENTRY) = ; 2) for (each basic block B other than ENTRY) out(B) = ; Necessit di un flag per verificare se un out 3) while ( ci sono modifiche) cambiato! Il valore 4) for ( each B other than ENTRY) iniziale del flag true. { in[B] = out[P]; P predecessore di B
out[B] =gen[B]
(in[B] kill[B]);
10
gen[S] = {d}
S d : a := b + c
S1 S2
gen [S] = gen [S2] (gen [S1] - kill [S2]) kill [S] = kill [S2] (kill [S1] - gen [S2])
S1
Dataflow Equations
22
d : a := b + c
S1 S2
S1
S2
S1
11
loop L d2 :
. . i= i + 1
out
in (L) = {d 1 } out(L) gen (L) = {d 2 } kill (L) = {d 1 } out [L] = gen [L] {in [L] - kill[L]}
Inizializzazione
24
Soluzione
d1 :
i= 0 in loop L
out(L) = gen (L) (in (L) - kill (L)) = {d2} ({d1} - {d 1}) = {d2}
Seconda iterazione out(L) = gen (L) (in (L) - kill (L)) Ma ora: in (L) = {d 1} out (L) = {d 1} {d2} = {d 1, d2}
d2 :
. . i= i + 1 out
comunque:
in (L) = {d1 } out(L) gen (L) = {d2 } kill (L) = {d1 } out [L] = gen [L] {in [L] - kill[L]}
12
ENTRY
B1 d1: i := m-1
d2: j := n d3: a := u1
gen[B1] = {d 1, d 2, d 3}
B2 d4: i := i+1
d5: j :=j - 1
B3
d6: a := u2
kill [B2] = {d1, d2, d7} gen[B3] = {d6} kill [B3] = {d3}
gen[B4] = {d7} kill [B4] = {d1, d4}
B4 d7: i := u3
EXIT
26
ENTRY
Inizializzazione:
out[B1] =
out[B2] = out[B3] = out[B4] =
B2 d4: i := i+1
d5: j :=j - 1
B3
d6: a := u2
B4 d7: i := u3
EXIT
13
27
ENTRY
Per semplificare la rappresentazone di in[B] e out[B] gli insiemi sono rappresentabili come sequenza di bit. Assumendo la rappresentazione d1d2d3 d4d5d6d7 si ottieme:
Initializzazione:
out[B1] = Block B1 B2 B3 B4 in[B]
B3
d6: a := u2
out[B2] =
out[B3] = out[B4] =
B4 d7: i := u3
EXIT
Initial out[B] 000 0000 000 0000 000 0000 000 0000
gen[B1] = {d1, d2, d3} kill[B1] = {d4, d5, d6, d7} gen[B2] = {d4, d5} kill [B2] = {d1, d2, d7} gen[B3] = {d6} kill [B3] = {d3} 28 gen[B4] = {d7} kill [B4] = {d1, d4}
ENTRY
dove P un predecessore di B out[B] = gen[B] (in[B]-kill[B]) in[B] = out[P]
B1 d1: i := m-1
d2: j := n d3: a := u1
B2 d4: i := i+1
d5: j :=j - 1
Block B1 B2 B3 B4 Block B1 B2 B3 B4
in[B]
B3
d6: a := u2
Initial out[B] 000 0000 000 0000 000 0000 000 0000
B4 d7: i := u3
EXIT Notation: d 1d2d3 d 4d5d6d7
First Iteration in[B] out[B] 000 0000 111 0000 000 0000 000 1100 000 0000 000 0010 000 0000 000 0001
out(B) = gen(B)
14
gen[B1] = {d1, d2, d3} kill[B1] = {d4, d5, d6, d7} gen[B2] = {d4, d5} kill [B2] = {d1, d2, d7} gen[B3] = {d6} kill [B3] = {d3} 29 gen[B4] = {d7} ENTRY kill [B4] = {d1, d4}
in[B] = out[P]
Block
B3
d6: a := u2
B1 B2 B3 B4
Block B1 B2 B3 B4
First Iteration in[B] out[B] 000 0000 111 0000 000 0000 000 1100 000 0000 000 0010 000 0000 000 0001
B4 d7: i := u3
EXIT Notation: d 1d2d3 d 4d5d6d7
Second Iteration in[B] out[B] 000 0000 111 0000 111 0010 001 1110 000 1100 000 11 10 000 1100 001 0111
gen[B1] = {d1, d2, d3} kill[B1] = {d4, d5, d6, d7} gen[B2] = {d4, d5} kill [B2] = {d1, d2, d7} gen[B3] = {d6} kill [B3] = {d3} 30 gen[B4] = {d7} ENTRY kill [B4] = {d1, d4}
B1 d1: i := m-1
d2: j := n d3: a := u1
dove P un predecessore di B out[B] = gen[B] (in[B]-kill[B]) Second Iteration in[B] out[B] 000 0000 111 0000 111 0010 001 1110 000 1100 000 11 10 000 1100 001 0111
in[B] = out[P]
B2 d4: i := i+1
d5: j :=j - 1
Block
B1 B2 B3 B4 Block
B3
d6: a := u2
B4 d7: i := u3
EXIT Notation: d 1d2d3 d 4d5d6d7
B1 B2 B3 B4
Third Iteration in[B] out[B] 000 0000 111 0000 111 1110 001 1110 001 1110 000 11 10 001 1110 001 0111
15
gen[B1] = {d1, d2, d3} kill[B1] = {d4, d5, d6, d7} gen[B2] = {d4, d5} kill [B2] = {d1, d2, d7} gen[B3] = {d6} kill [B3] = {d3} 31 gen[B4] = {d7} ENTRY kill [B4] = {d1, d4}
dove P un predecessore di B out[B] = gen[B] (in[B]-kill[B]) Third Iteration in[B] out[B] 000 0000 111 0000 111 0010 001 1110 000 1100 000 11 10 000 1100 001 0111
in[B] = out[P]
Block
B1 B2 B3 B4 Block
B3
d6: a := u2
B4 d7: i := u3
EXIT Notation: d 1d2d3 d 4d5d6d7
B1 B2 B3 B4
Forth Iteration in[B] out[B] 000 0000 111 0000 111 1110 001 1110 001 1110 000 11 10 001 1110 001 0111
Esempio
32
Receive s fo 0 f1 1 If m <= 1 goto L3 I 2 If i <= m goto L2 return f2 f2 f0 +f1 fo f1 f1 f2 i i+1 goto L1 return m
16
Esempio
33
Receive s fo 0 f1 1 If m <= 1 goto L3 I 2 If i <= m goto L2 return f2 f2 f0 +f1 fo f1 f1 f2 i i+1 goto L1 return m
Blocco B1
Esempio
34
Receive s fo 0 f1 1 If m <= 1 goto L3 I 2 If i <= m goto L2 return f2 f2 f0 +f1 fo f1 f1 f2 i i+1 goto L1 return m
Blocco B2
17
Esempio
35
Receive s fo 0 f1 1 If m <= 1 goto L3 I 2 If i <= m goto L2 return f2 f2 f0 +f1 fo f1 f1 f2 i i+1 goto L1 return m
Blocco B3
Esempio
36
Receive s fo 0 f1 1 If m <= 1 goto L3 I 2 If i <= m goto L2 return f2 f2 f0 +f1 fo f1 f1 f2 i i+1 goto L1 return m
Blocco B4
18
Esempio
37
Receive s fo 0 f1 1 If m <= 1 goto L3 I 2 If i <= m goto L2 return f2 f2 f0 +f1 fo f1 f1 f2 i i+1 goto L1 return m
Blocco B5
Esempio
38
Receive m fo 0 f1 1 If m <= 1 goto L3 I 2 If i <= m goto L2 return f2 f2 f0 +f1 fo f1 f1 f2 i i+1 goto L1 return m
Blocco B6
19
39
entry
B1
B2 B5 B3
B4 B6
exit
Formalizing Analysis
40
I compilatori analizzano ogni blocc per derivare gli insiemi GEN e KILL,
20
41
42
21
43
Kill(B1) = {1,2,3,6,7} kill(B2) = {} Kill(B3) = {4} Kill(B4) ={} Kill(B5) ={} kill (B6) = {2,3,4,5,6,7,8}
Equazioni di Dataflow
44
22
Uso di algoritmi basati sulla ricerca del punto fisso Inizializzazione alla soluzione OUT[b] = 0000000 Applicare ripetitivamente le equazioni
IN[b] = OUT[b1] U ... U OUT[bn] OUT[b] = (IN[b] - KILL[b]) U GEN[b]
Fino al raggiungimento del punto fisso Fino a quando le equazioni non producono altri effetti utilizzare una worklist per tracciare lapplicazione di quali equazioni potra avere effetto.
Algoritmo 1) out(ENTRY) = ; 2) for (each basic block B other than ENTRY) out(B) = U; Necessit di un flag per verificare se a 3) while ( changes to any out occur) cambiato! Il valore 4) for ( each B other than ENTRY) iniziale del flag true . { in[B] = out[P]; P predecessor of B
out[B] =e_gen[B]
(in[B] e_kill[B]);
23
Live Variable Analysis DU and UD Chains Available Expressions Constant Propagation Constant Folding
48
Utilizzo dellanalisi dataflow per la analisi delle variabili vive (Liveness analysis)
Una variabile V viva alla fine di un blocco basico n, se c un cammino def-free da n ad un uso esterno di V in un nodo n.
live variable analysis problem - determinare l'insieme di variabili che sono vive all'uscita di ogni punto del programma Liveness analysis un analisi "backwards must", cio un analisi eseguita in ordine inverso .
24
Linsime delle variabili vive alla linea L2 {b,c}, ma linsieme delle variabiabili vive alla line L1 solo {b} dato che c aggiornata alla linea 2. Il valore di "a" non mai utilizzato peranto tale variabile non mai viva.
gen[B]: linsieme delle variabili definite nel blocco basico B prima di qualsiasi uso di tale variabile in B use[B]: linsieme delle variabili I cui valori possono essere usati prima di qualsiasi definizione della variabile.
25
dataflow equations
S successore di B
in [S ]
52
(out[B] gen[B]);
26
B2 d4: i := i+1
d5: j :=j - 1
B3
d6: a := u2
B4 d7: i := u3
Molte analisi dataflow richiedono di trovare il posto di utilizzo (use-sites) e il posto di definizione (definitionsites) di ogni variabile. Def-Use (D-U), e Use-Def (U-D) chains sono strutture dati efficenti in grado di mantenere tali informazioni
Quando un codice rappresentato in una forma Static Single-Assignment (SSA) (come accade nei moderni compilatori) non ce necessita di mantenere D-U e U-D chains.
27
UD Chain
55
Un UD chain una lista di tutte le definizioni che possono raggiungere un dato uso di una variabile.
... S1: v= ... ... Sm : v = ...
DU Chain
56
Una DU chain una lista di tutte gli usi che possono raggiungere da una data definizione di una variabile. DU Chain duale a una UD Chain.
.. . Sn: v =
S1: = v ...
Sk : = v ...
28
Dependence analysis Live variable analysis Alias analysis Analysis for various transformations
Available Expressions
58
(2) Dopo lultima valutazione prima di raggiungere p, non c una successiva assegnazione ad x o a y.
Diremo che un blocco basico uccide lespressione se puo assegnare x o y, e non ricalcola successivamente x+y.
29
B1
B2
B3
S3: C = 1
B4
lespressione A I cammini che portano a Si. generato in tutti * B disponibile allinizio delto non blocco basico B4?sua generazione in ogni ucciso dopo la cammino. Quindi la espressione ridondante pu essere eliminata.
B4
B1
S1: X = A * B S2: Z = X + C
B2
B3
S5: C = 1
B4
S6: T = A * B S7: V= D * T
Si. generato in tutti I cammini che portano a to B4 e non ucciso dopo la sua generazione in ogni cammino. Quindi la espressione ridondante pu essere eliminata.
30
61
B2
B3
S5: C = 1
B4
Si. generato in tutti I cammini che portano a to B4 e non ucciso dopo la sua generazione in ogni cammino. Quindi la espressione ridondante pu essere eliminata.
Detto U linsieme universale di tutte le espressioni che appaino in una o pi istruzioni in un programma.
gen[B]: insieme delle espressioni generate da B kill[B]: insieme delle espresioni in U uccise in B.
31
63
x= y+z
p S:
q S: aggiungi y+z a S; Cancella le espressioni che utilizzano x in S
S
a =b+ c b= a d c= b + c d= a - d
b+c
b+c , a - d a d, b + c
a-d
dataflow equations
in [B] =
P predecessor of B
out [P]
32
66
33
i = 32*48-1530
i= 6
Il constant folding pu essere implementato: Nel front end di un compilatore sullIR (prima che esso sia tradotto in codice a tre indirizzi) Nel back end, come aggiunta al constant propagation
Constant propagation
34
69
As long as the dataflow value domain is nice (e.g. semi-lattice) And each function specified by the dataflow equation is nice -- then iterative application of the dataflow equations at each node will eventually terminate with a stable solution (a fix point).
Muchniks book: Section 8.2, pp 223 For a good discussion: also read 9.3 (pp 618-632) in new Dragon Book
Algorithm Convergence
70
Intuitivamente si puo osservare che lalgoritmo converge ad un punto fisso poich linsieme mai decresce in dimenzione.
Si pu mostrare che il limite superiore nel numero delle iterazioni richieste per raggiungere il punto fisso uguale al numero di nodi nel grafo di flusso. Intuitivamente se una definizione raggiunge un punto essa pu raggiunge tale punto attraverso un cammino senza cicli e nessun cammino senza cicli pu essere pi lungo del numero di nodi del grafo.
Lesperienza suggerisce che il numero reale di iterazioni richieste per raggiungere il punto fisso sia minore di 5
35
Alcune note
71
Se data-flow framework raggiunge una "buona" condizione allora il punto fisso a ha una soluzione unica Lalgoritmo iterativo raggiunge il miglior La soluzione non dipende dallordine di calcolo Lalgoritmo pu scegliere un ordine per convergere rapidamente
4 2 1 3 3
1 2 4
Post ordine
Visita prima I figli
Postordine inverso
Visita prima I genitori
36