Schauer

Werbung
Datenflussanalyse - Klassisch
Seminar “Progammanalyse” (SS 2009)
Referent: Lorenz Schauer
Vortrag: 24.06.2009
Agenda
Agenda
- Einleitung
- Einführung in die Sprache WHILE
- Die Intraprozedurale Analyse
- Available Expressions Analysis
- Reaching Definitions Analysis
- Very Busy Expressions Analysis
- Live Variables Analysis
- Live Variables Analysis - Richtigkeit
Folie 2
Einleitung
Was bedeutet “Datenflussanalyse”?
Ermittlung der Zusammenhänge zwischen einzelnen Stellen im Programm
und den darin berechneten Werten.
Typische Fragen sind:
o Was genau wird in dem Programmabschnitt berechnet?
o Wie und wo wird eine bestimmte Variable berechnet?
o Welche Werte kann sie annehmen?
o Welche Befehle beinflussen welche Variable zu welchem Zeitpunkt?
Folie 3
Einleitung
Datenflussanalyse – wie und wozu?
Wozu?
- Primär zur Codeoptimierung
- Gegebenenfalls zur Lösung von entstandenen Problemen
Wie?
- Programmcode analysieren und verstehen
(Hilfsmittel: Flussgraph)
- Datenflussprobleme erkennen und Gleichung aufstellen
- Code optimieren bzw. Probleme lösen
Folie 4
Einführung in WHILE
Die Sprache: WHILE
- Imperative Sprache
- Programmcode glieder sich in Blöcke
- Jeder Block besitzt ein eindeutiges Etikett (Label)
- Bezeichnen Zuweisungen und boolsche Bedingungen
- Haben intern keinen Datenfluss
Folgende Elemente werden definiert:
o Zuweisung
o Skip
o Bedingung
o Sequenz
o While-Schleife
l
[x := a]
l
[skip]
l
if [b] then S1 else S2
S1 ; S2
l
while [b] do S
Folie 5
Intraprozedurale Analyse
Intraprozedurale Analyse
- Beschäftigt sich mit Elementaraussagen
- Gliedert sich in mehrere Datenflussanalysen (spätere Folien)
- Unterscheidet Vorwärts- und Rückwärtsanalysen
Flussfunktionen (Um Flussgraph aufzustellen)
Fluss-Funktion: flow: Stmt
P(Lab x Lab)
R
Rückflussfunktion: flow : Stmt
P(Lab x Lab)
Beschreiben den Fluss zwischen den Lables der Aussagen
Folie 6
Intraprozedurale Analyse - Flussfunktion
Wie sieht der Flussgraph von folgendem Code aus ?
[ z : 1]1; while[ x  0]2 do([ z : z * y]3 ;[ x : x  1]4 )
Die Flussfunktion liefert folgende Menge an Werten:
{(1,2),(2,3),(3,4),(4,2)}
Damit können wir den nachfolgenden Graphen zeichnen…
Folie 7
Intraprozedurale Analyse - Flussgraph
[ z : 1]1; while[ x  0]2 do([ z : z * y]3 ;[ x : x  1]4 )
[z:=1]
[x>0]
no
yes
[z:=z*y]
[x:=x-1]
Folie 8
Available Expressions Analysis
Available Expressions Analysis
o Analyse Algorithmus (Vorwärtsanalyse)
o Beschreibt die Verfügbarkeit einzelner Ausdrücke an
bestimmten Programmstellen
o Frage: Welche Ausdrücke / Werte sind an einer bestimmten
Programmstelle gültig?
o Ziel: Codeoptimierung
o Beispiel:
[ x : a  b]1;[ y : a * b]2 ; while[ y  a  b]3 do([a : a  1]4 ;[ x : a  b]5 )
Folie 9
Available Expressions Analysis
Definition von kill- und gen-Funktionen
Kill-Funktion: Ausdruck ist killed, wenn eine der Variablen
verändert wird (Innerhalb des Blocks).
killAE : Blocks
P(AExp)
Gen-Funktion: Ausdruck wird im Programmbereich generiert und
keine Variable davon innerhalb des Blocks verändert.
genAE : Blocks
P(AExp)
Folie 10
Available Expressions Analysis
kill- und gen-Funktionen bei AEA
kill AE ([ x : a]l )  {a' AExp* | x  FV (a' )}
kill AE ([ skip]l )  {}
kill AE ([b]l )  {}
gen AE ([ x : a ]l )  {a' AExp(a) | x  FV (a ' )}
gen AE ([ skip]l )  {}
gen AE ([b]l )  AExp(b)
Folie 11
Available Expressions Analysis
Entry- & Exit-Funktionen
Durch diese beiden Funktionen wird die Analyse bestimmt:
AEentry , AEexit : Lab*  P( AExp* )
AEentry (l )  {}
Falls: l  init (S* )
AEentry (l )  { AEexit (l ' ) | (l ' , l )  flow( S* )}
AEexit (l )  ( AEentry (l ) \ kill AE ( B l ))  gen AE ( B l )
B l  blocks( S* )
Folie 12
Available Expressions Analysis – Beispiel1
Beispiel 1:
[ z : x  y]l ; while[true]l ' do[ skip]l ''
o Nur Block 1 generiert den Ausdruck: {x+y}
o Andere generieren / killen keine Ausdrücke
o Der Flussgraph sieht wie folgt aus:
[…] l
[…] l '
no
yes
l ''
[…]
Folie 13
Available Expressions Analysis – Beispiel1
Gesucht wird: größte Lösung der Gleichung für AEentry
[ z : x  y]l ; while[true]l ' do[ skip]l ''
Bestimmen der AE-Gleichungen:
AEentry (l )  {}
AEentry (l ' )  AEexit (l )  Aexit (l ' ' )
AEentry (l ' ' )  AEexit (l ' )
AEexit (l )  AEentry (l )  {x  y}
AEexit (l ' )  AEentry (l ' )
AEexit (l ' ' )  AEentry (l ' ' )
Folie 14
Available Expressions Analysis – Beispiel1
Wir erhalten:
AEentry (l ' )  {x  y}  AEentry (l ' )
Deutung:
o Es gibt 2 Lösungen für die Gleichung:
- {x+y}
- die leere Menge
o Informativ aber nur {x+y}
o {x+y} stellt die größte Lösung der Gleichung dar.
=> Der Ausdruck {x+y} ist jedesmal verfügbar, wenn
l’ betreten wird (hier: Schleifeneintritt)
Folie 15
Available Expressions Analysis – Beispiel2
Beispiel 2:
[ x : a  b]1;[ y : a * b]2 ; while[ y  a  b]3 do([ a : a  1]4 ;[ x : a  b]5 )
Aufstellen der kill & gen Funktionen:
gen AE (l )
kill AE (l )
l
---------------------------------------------------{}
{a  b}
1
{a * b}
2 {}
{a  b}
3 {}
4 {a  b, a * b, a  1} {}
{a  b}
5 {}
Folie 16
Available Expressions Analysis – Beispiel2
Aufstellen der AE-Funktionen:
AEentry (1)  {}
AEexit (1)  AEentry (1)  {a  b}
AEentry (2)  AEexit (1)
AEexit (2)  AEentry (2)  {a * b}
AEentry (3)  AEexit (2)  AEexit (5)
AEexit (3)  AEentry (3)  {a  b}
AEentry (4)  AEexit (3)
AEexit (4)  AEentry (4) \ {a  b, a * b, a  1}
AEentry (5)  AEexit (4)
AEexit (5)  AEentry (5)  {a  b}
[ x : a  b]1;[ y : a * b]2 ; while[ y  a  b]3 do([ a : a  1]4 ;[ x : a  b]5 )
Folie 17
Available Expressions Analysis – Beispiel2
Als Ergebnis erhält man folgende Tabelle:
AEentry (l )
l
AEexit (l )
---------------------------------------------{a  b}
1
{}
{a  b, a * b}
2
{a  b}
{a  b}
{a  b}
3
{}
{a  b}
4
{a  b}
{}
5
[x:=a+b]
[y:=a*b]
[y>a+b]
[a:=a+1]
[x:=a+b]
[ x : a  b]1;[ y : a * b]2 ; while[ y  a  b]3 do([ a : a  1]4 ;[ x : a  b]5 )
Folie 18
Available Expressions Analysis – Beispiel2
Deutung:
o Der Ausdruck a wird innerhalb der Schleife neu definiert
o Der Ausdruck {a+b} ist immer am Schleifeneingang verfügbar
o {a*b} nur beim ersten Schleifeneingang verfügbar
wird vor dem nächsten Durchlauf gekilled
Folie 19
Reaching Definition Analysis
Reaching Definition Analysis
o sehr ähnlich zur AE-Analyse (Vorwärtsanalyse)
o Frage: Welche Definition/Zuweisung ist bei einer
bestimmten Stelle im Programm gültig?
o Ziele: Kenntnis über die jeweilige Gültigkeit einer Zuweisung
o Beispiel: [ x : a  b]1;[ y : a * b]2 ; while[ y  a  b]3 do([a : a  1]4 ;[ x : a  b]5 )
Nach Label 2: (x,1),(y,2)
Nach Label 3: (x,1),(y,2),(a,4),(x,5)
Folie 20
Reaching Definition Analysis - Vorgehensweise
Vorgehensweise
o Definieren der killRD, genRD, RDentry und RDexit funktionen:
kill RD ([ x : a]l )  {( x, ?)}  {( x, l ' ) | B l '  asgm _ to _ x( S* )}
kill RD ([ skip]l )  {}
kill RD ([b]l )  {}
genRD ([ x : a ]l )  {( x, l )}
genRD ([ skip]l )  {}
genRD ([b]l )  {}
Folie 21
Reaching Definition Analysis - Vorgehensweise
RDentry (l )  {( x, ?) | x  FV ( S* )}
if
l  init ( S* )
 {RDentry (l ' ) | (l ' , l )  flow( S* )}
RDexit (l )  ( RDentry (l ) \ kill RD ( B l ))  genRD ( B l )
wo
B l  blocks( S* )
Folie 22
Reaching Definition Analysis - Beispiel
o Funktionen am Programmteil anwenden:
1
2
3
4
5
Beispiel: [ x : 5] ;[ y : 1] ; while[ x  1] do([ y : x * y] ;[ x : x  1] )
Es entsteht folgende Tabelle der kill & gen Funktionen:
genRD (l )
kill RD (l )
------------------------------------------------------------------------{( x,1)}
1 {( x, ?), ( x,1), ( x,5)}
{( y ,2)}
2 {( y , ?), ( y ,2), ( y ,4)}
{}
3 {}
{( y ,4)}
4 {( y , ?), ( y ,2), ( y ,4)}
5 {( x, ?), ( x,1), ( x,5)}
{( x,5)}
Folie 23
Reaching Definition Analysis - Beispiel
Damit ergibt sich für die RD Funktionen (1):
RDentry (l )
RDexit (l )
_______________________________________________________
( RDentry (1) \ {( x, ?), ( x,1), ( x,5)})  {( x,1)}
1 {( x, ?), ( y, ?)}
2 RDexit (1)
3 RDexit (2)  RDexit (5)
( RDentry (2) \ {( y, ?), ( y,2), ( y,4)})  {( y,2)}
4 RDexit (3)
( RDentry (4) \ {( y, ?), ( y,2), ( y,4)})  {( y,4)}
5 RDexit (4)
( RDentry (5) \ {( x, ?), ( x,1), ( x,5)})  {( x,5)}
RDentry (3)
[ x : 5]1;[ y : 1]2 ; while[ x  1]3 do([ y : x * y]4 ;[ x : x  1]5 )
Folie 24
Reaching Definition Analysis - Beispiel
Damit ergibt sich für die RD Funktionen (2):
RDexit (l )
RDentry (l )
_______________________________________________________
({( x, ?), ( y, ?)} \ {( x, ?), ( x,1), ( x,5)})  {( x,1)}
1 {( x, ?), ( y, ?)}
( RDexit (1) \ {( y, ?), ( y,2), ( y,4)})  {( y,2)}
2 ( RDentry (1) \ {( x, ?), ( x,1), ( x,5)})  {( x,1)}
3 ( RDentry (2) \ {( y, ?), ( y,2), ( y,4)})  {( y,2)} 
( RDentry (5) \ {( x, ?), ( x,1), ( x,5)})  {( x,5)}
RDexit (2)  RDexit (5)
4 RDentry (3)
( RDexit (3) \ {( y, ?), ( y,2), ( y,4)})  {( y,4)}
5 ( RDentry (4) \ {( y, ?), ( y,2), ( y,4)})  {( y,4)}
( RDexit (4) \ {( x, ?), ( x,1), ( x,5)})  {( x,5)}
[ x : 5]1;[ y : 1]2 ; while[ x  1]3 do([ y : x * y]4 ;[ x : x  1]5 )
Folie 25
Reaching Definition Analysis - Beispiel
Damit ergibt sich für die RD Funktionen (3):
RDexit (l )
RDentry (l )
_______________________________________________________
{( y, ?), ( x,1)}
1 {( x, ?), ( y, ?)}
2 ({( x, ?), ( y, ?)} \ {( x, ?), ( x,1), ( x,5)})  {( x,1)}
3 ({( y, ?), ( x,1)} \ {( y, ?), ( y,2), ( y,4)})  {( y,2)} 
({( y, ?), ( x,1)} \ {( y, ?), ( y,2), ( y,4)})  {( y,2)}
{( x,1), ( y,2)}  RDexit (5)
( RDentry (4) \ {( x, ?), ( x,1), ( x,5), ( y, ?), ( y,2), ( y,4)})
 {( y,4)}  {( x,5)}
4 RDentry (3)
({( x,1), ( y,2)}  RDexit (5) \ {( y, ?), ( y,2), ( y,4)})
5 ( RDentry (3) \ {( y, ?), ( y,2), ( y,4)})  {( y,4)}
 {( y,4)}
( RDexit (4) \ {( x, ?), ( x,1), ( x,5)})  {( x,5)}
[ x : 5]1;[ y : 1]2 ; while[ x  1]3 do([ y : x * y]4 ;[ x : x  1]5 )
Folie 26
Reaching Definition Analysis - Beispiel
Damit ergibt sich für die RD Funktionen (4):
RDexit (l )
RDentry (l )
_______________________________________________________
{( y, ?), ( x,1)}
1 {( x, ?), ( y, ?)}
2 {( y, ?), ( x,1)}
3 {( x,1), ( y,2), ( y,4), ( x,5)}
{( x,1), ( y,2)}
4 {( x,1), ( y,2), ( y,4), ( x,5)}
5 ( RDentry (3) \ {( y, ?), ( y,2), ( y,4)})  {( y,4)}
{( x,1), ( y,4), ( x,5)}
( RDexit (4) \ {( x, ?), ( x,1), ( x,5)})  {( x,5)}
{( x,1), ( y,2)}  RDexit (5)
[ x : 5]1;[ y : 1]2 ; while[ x  1]3 do([ y : x * y]4 ;[ x : x  1]5 )
Folie 27
Reaching Definition Analysis - Beispiel
Damit ergibt sich für die RD Funktionen (5):
RDentry (l )
RDexit (l )
_______________________________________________________
{( y, ?), ( x,1)}
1 {( x, ?), ( y, ?)}
2 {( y, ?), ( x,1)}
3 {( x,1), ( y,2), ( y,4), ( x,5)}
4 {( x,1), ( y,2), ( y,4), ( x,5)}
5 {( x,1), ( y,4), ( x,5)}
{( x,1), ( y,2)}
{( x,1), ( y,2), ( y,4), ( x,5)}
{( x,1), ( y,4), ( x,5)}
{( y,4), ( x,5)}
[ x : 5]1;[ y : 1]2 ; while[ x  1]3 do([ y : x * y]4 ;[ x : x  1]5 )
Somit sind alle RD-Funktionen aufgelöst.
Deutung: Man erkennt nun, welche Zuweisung an welcher Stelle existiert!
Folie 28
Very Busy Expressions Analysis
Very Busy Expressions Analysis
o Ein Ausdruck wird als „very busy“ bezeichnet, wenn:
- am Ende eines Labels sichergestellt ist, dass er im weiteren
Verlauf auf jeden Fall gebraucht wird.
=> Wichtig: Der Ausdruck muss verwendet bzw. betrachtet werden
bevor einer seiner Werte verändert wird!
o Es handelt sich um eine Rückwärtsanalyse
o Ziel: Codeoptimierung
Folie 29
Very Busy Expressions Analysis
Veranschaulichung und Analyse am Beispiel:
if [a  b]1 then([ x : b  a]2 ;[ y : a  b]3 )else ([ y : b  a]4 ;[ x : a  b]5 )
o Die Ausrücke {a-b} und {b-a} sind „very busy“ zum Zeitpunkt 1
o Um das Programm zu analysieren müssen wieder alle Funktionen
aufgestellt werden!
Folie 30
Very Busy Expressions Analysis
o Hier gleich angewendet (allgemeine Formeln nachlesen!)
l
killVB (l )
genVB (l )
1
2
{}
{}
{}
{b  a}
3
4
{}
{}
{a  b}
{b  a}
5
{}
{a  b}
o kill & gen Funktionen:
o VB Funktionen:
l
VBentry (l )
VBexit (l )
1
VBexit (1)
VBentry (2)  VBentry (4)
2 VBexit (2)  {b  a}
VBentry (3)
3
{a  b}
4 VBexit (4)  {b  a}
5
{a  b}
{}
VBentry (5)
{}
Folie 31
Very Busy Expressions Analysis
Nach Vereinfachung erhält man:
l
VBentry (l )
VBexit (l )
1 {a  b, b  a} {a  b, b  a}
2 {a  b, b  a}
{a  b}
3
{a  b}
4 {a  b, b  a}
5
{a  b}
{}
{a  b}
{}
o Deutung: Aus dieser Tabelle lässt sich nun jeder Ausdruck, der
zu einem bestimmten Zeitpunkt „very busy“ ist, ablesen.
Folie 32
Live Variables Analysis
Live Variables Analysis
o Eine Variable wird als „live“ bezeichnet, wenn:
- sie am Ende eines Labels einen Wert enthält, der später benötigt
werden könnte.
o Rückwärtsanalyse
o Verwendung:
- Dead code elimination
(Variable nicht live – Zuweisungsblock löschen)
- Registerzuweisung
Folie 33
Live Variables Analysis
Beispiel:
[ x : 2]1;[ y : 4]2 ;[ x : 1]3 ; (if [ y  x]4 then[ z : y]5 else[ z : y * y]6 ); [ x : z ]7
Frage: Welche variablen sind zu welchem Zeitpunkt „live“?
Antwort: x nach Label 1 ist nicht live
x nach Label 3 live
y nach Label 2 live
=> Erste Zuweisung ist Redundant, kann also gelöscht werden.
Folie 34
Live Variables Analysis
Definitionen der kill, gen und LV Funktionen:
kill LV ([ x : a ]l )  {x}
kill LV ([ skip]l )  {}
kill LV ([b]l )  {}
genLV ([ x : a ]l )  FV (a )
genLV ([ skip]l )  {}
genLV ([b]l )  FV (a )
LVexit (l ) 
{}
falls l  final ( S* )
 {LVentry (l ' ) | (l ' , l )  flow R ( S* )}
LVentry (l )  ( LVexit (l ) \ kill LV ( B l ))  genLV ( B l )
wo
B l  blocks( S* )
Folie 35
Live Variables Analysis
Analyse nach Aufstellen der gen, kill und LV Funktionen ergibt folgendes:
l
1
2
3
4
5
6
7
kill LV (l )
{x}
{ y}
{x}
genLV (l )

{x, y}
{ y}
{ y}
{z}
{z}
{z}
{x}



l
LVentry (l )
LVexit (l )
1
LVexit (1) \ {x}
LVentry (2)
2
LVexit (2) \ { y}
LVentry (3)
3
LVexit (3) \ {x}
LVentry (4)
4
LVexit (4)  {x, y} LVentry (5)  LVentry (6)
5 ( LVexit (5) \ {z})  { y}
LVentry (7)
6 ( LVexit (6) \ {z})  { y}
LVentry (7)
7
{z}

Folie 36
Live Variables Analysis
Durch einsetzten und vereinfachen erhält man wieder die Ergebnistabelle:
l
1
2
3
4
5
6
7
LVentry (l )
{}
{}
{ y}
{ x, y}
{ y}
{ y}
{ z}
LVexit (l )
{}
{ y}
{ x, y}
{ y}
{ z}
{ z}
{}
Deutung: - Alle „live“-Variablen bzgl ihrem Programmpunkt ablesbar
- Am Programmende sind alle Variablen tot – nicht „live“
Folie 37
Live Variables Analysis - Richtigkeit
Die Richtigkeit der Live Variables Analysis
o Um Richtigkeit zu zeigen, benutzen wir folgendes Theorem:
1.
falls  S ,  1    S ' ,  1' 
und  1 ~ N (init( S ))  2
  2' :  S ,  2    S ' ,  2' 
2.
falls  S ,  1    1'
  2' :  S ,  2    2'
dann
und  1' ~ N (init( S ' ))  2'
und  1 ~ N (init( S ))  2
und
dann
und  1' ~ X (init( S ))  2'
Folie 38
Live Variables Analysis - Richtigkeit
Veranschaulichung am Beispiel:
[ x : y  z ]l ,  1  , V1 = {y,z} und V2 = {x}
o  1 ~V 1  2   1 ( y)   2 ( y)   1 ( z )   2 ( z )
o  1 ~V 2  2   1 ( x)   2 ( x)
o [ x : y  z ]l ,  1    1'  [ x : y  z ]l ,  2    2'
o Nach Theorem und
 1 ~V 1  2   1' ~V 2  2'
folgt, dass wenn V2 nach dem Block live ist,
muss V1 davor live sein.
Folie 39
Servus
Vielen Dank für die Aufmerksamkeit!
Folie 40
Herunterladen