Vorlesung compilertechnik sommersemester 2009
This presentation is the property of its rightful owner.
Sponsored Links
1 / 48

Vorlesung Compilertechnik Sommersemester 2009 PowerPoint PPT Presentation


  • 73 Views
  • Uploaded on
  • Presentation posted in: General

Vorlesung Compilertechnik Sommersemester 2009. Optimierung M. Schölzel. Einbettung der Optimierung in den Compiler. Gründe für die Optimierung:

Download Presentation

Vorlesung Compilertechnik Sommersemester 2009

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Vorlesung compilertechnik sommersemester 2009

Vorlesung CompilertechnikSommersemester 2009

Optimierung

M. Schölzel


Einbettung der optimierung in den compiler

Einbettung der Optimierung in den Compiler

  • Gründe für die Optimierung:

    • Vom Frontend generierter Zwischencode ist ineffizient, da er aus der Struktur des Quellprogramms entstanden ist und sich nicht an der Zielarchitektur orientiert.

    • Programmierer schreiben "verbesserungsfähigen" Quellcode.

Kontext-

prüfung

Zielcodeabhängige

Optimierungen

Backend

Quell-text

Zwischencode und

Symbol- tabelle

Ziel-code

Scanner

Parser

Zielcode-

erzeugung

Zielcodeunab-

hängige

Optimierungen

Frontend


Klassifizierung der optimierung

Klassifizierung der Optimierung

Eliminierung redun-

danter Berechnungen,

Berechnung konstanter

Ausdrücke

Eliminierung redun-

danter Berechnungen,

Berechnung konstanter

Ausdrücke,

Codeverschiebung

Maschinenunabhängig

Registerplanung,

Zielcodeauswahl

Registerplanung

Maschinenabhängig

Lokal

Global


Grundbegriffe 1

Grundbegriffe (1)

  • S = (N,E,q,s) sei ein Steuerflussgraph.

  • N = {b0,…,bn} sind die Basisblöcke im Steuerflussgraphen, wobei ir0(bi),…,ir#(bi)(bi) die Folge der 3-Adress-Code-Anweisungen in bi ist.

  • Über b0 = q wird S betreten und über b1 = s (z.B. return) verlassen.

  • Eine Programmposition ist ein Tupel (i,j) wobei damit die Position unmittelbar vor der 3-Adress-Code-Anweisung irj(bi) gemeint ist.

  • Mit (0,0) wird Startposition und mit (1,0) Stoppposition bezeichnet.

  • Ein Pfad  im Steuerflussgraphen von Programmposition (i,j) zur Programmposition (m,n) ist eine Folge 0,…,k von 3-Adress-Code-Anweisungen, für die gilt:

    • 0…k kann in 3-Adress-Code-Folgen 0…c = 0…k zerlegt werden, so dass:

      • z= ir0(baz)…ir#(baz)(baz) für 1  z < c und

      • (0 = irj(ba0)…ir#(ba0)(ba0) und c= ir0(bac)…irn-1(bac) falls c > 0) oder (0 = irj(ba0)…irn-1(ba0) falls c = 0) und

      • (ba0, ba1),(ba1, ba2),…,(bac-1, bac)  E


Beispiel

Beispiel

0

3

0: Function f:

1: t0 := 1

2: fak = t0

3: while_0_cond:

4: t1 := n

5: t2 := 0

6: t3 := t1 > t2

7: t4 := not t3

8: if t4 then while_0_end

9: t5 := fak

10: t6 := n

11: t7 := t5 * t6

12: fak := t7

13: t8 := n

14: t9 := 1

15: t10 := t8 – t9

16: n := t10

17: goto while_0_cond

18: while_0_end:

19: t11 := fak

20: return t11

t0 := 1

4

fak = t0

6

t1 := n

7

t2 := 0

8

t3 := t1 > t2

9

t4 := not t3

10

if t4 then 21

11

21

t5 := fak

t11 := fak

12

22

t6 := n

f = t11

13

1

t7 := t5 * t6

return f

14

fak := t7

15

t8 := n

16

t9 := 1

17

t10 := t8 – t9

18

n := t10


Qualit t des modells

Qualität des Modells

  • Steuerflussgraph modelliert alle möglichen Abarbeitungspfade des Programms, unabhängig davon, ob alle diese Pfade bei der Ausführung des Programms betreten werden können.

  • Falls Turingmaschine i auf Eingabe i nach n Schritten stoppt, dann gibt es eine Eingabe n, so dass 4 nach 2 ausgeführt wird, sonst nicht.

0

Eingabe von n

2

if (TMi(i)n) then 4

3

4

1


Grundbegriffe 2

Grundbegriffe (2)

  • Verwendung einer Variablen v:Eine Variable v wird in der Zwischencodeanweisung iri(j) verwendet, falls iri(j) eine der Formen x := v, x :=  v, x := y v, x := v y, x := @v, @v := x, return v, if v then goto label, x := (Type) v, x := call f(…,v,…) hat.

  • Definition einer Variablen v:Eine Variable v wird in der Zwischencodeanweisung iri(j) definiert, falls iri(j) eine der Formen v := … hat.

  • Eine definierende Anweisung für v ist eine Anweisung, die v definiert.

  • Eine verwendende Anweisung für v ist eine Anweisung, die v verwendet.

  • Erreichende Definition: Die Definition einer Programmvariablen v erreicht eine Verwendung von v, falls es einen Pfad im Steuerflussgraphen von dieser Definition zur Verwendung gibt, auf dem keine andere Definition von v liegt.


Beispiel erreichende definitionen

Beispiel Erreichende Definitionen

0

3

t0 := 1

4

fak = t0

6

t1 := n

7

0

t2 := 0

8

3

t3 := t1 > t2

t0 := 1

9

t4 := not t3

4

fak = t0

10

6

if t4 then while_0_end

t1 := n

7

11

21

t2 := 0

t11 := fak

t5 := fak

8

12

22

t3 := t1 > t2

t6 := n

kgv = t11

9

13

1

t4 := not t3

t7 := t5 * t6

return kgv

10

14

if t4 then while_0_end

fak := t7

Definition zu einer Verwendung ist in unverzweigtem Steuerfluss einfach zu finden.

15

t8 := n

16

t9 := 1

17

t10 := t8 – t9

18

n := t10

Definition zu einer Verwendung ist bei Verzweigungen im Steuerfluss schwieriger zu finden.


Grundidee datenflussanalyse am beispiel der erreichenden definitionen

Grundidee Datenflussanalyse am Beispiel der Erreichenden Definitionen

Es gibt eingehende Informationen I in einen Knoten: I = in(2)

0

t2 := 2

Durch die Anweisung(en) in einem Knoten werden Informationen zerstört: I := I – Kill(2)

1

t1 := 1

in(2) = {(t2,0),(t1,1)}

Kill(2) = {(t1,i) | i }

2

t1 := n

Gen(2) = {(t1,2)}

Durch die Anweisung(en) in einem Knoten werden neue Informationen generiert: I := IGen(2)

out(2) = {(t2,0),(t1,2)}

3

t3 := t1 > t2

Es entstehen ausgehende Informationen an einen Knoten: out(2)

4

if t3 then while_0_end


Transferfunktion f r einen basisblock

Transferfunktion für einen Basisblock

  • Steuerfluss in einem Basisblock i mit den Anweisungen ir0(i),…,ir#i(i) ist bekannt.

  • Damit ist die Transferfunktion für diesen Basisblock:

  • Vereinfachung der Transferfunktion zu out(i) = (in(i) – kill(i))  gen(i).

in(i)

- Kill(0)  Gen(0)

0

t2 := 2

1

- Kill(1)  Gen(1)

t1 := 1

2

- Kill(2)  Gen(2)

t1 := n

- Kill(3)  Gen(3)

3

t3 := t1 > t2

- Kill(4)  Gen(4)

4

if t3 then while_0_end

out(i)


Datenflussanalyse bei verzweigungen im steuerflussgraphen

Datenflussanalyse bei Verzweigungen im Steuerflussgraphen

  • Ausgehende Informationen out(i) gelangen zu jedem Steuerflussnachfolger von i.

  • Treffen Informationen von mehreren Steuerflussvorgängern zusammen, müssen diese zu einer eingehenden Information zusammengefasst werden.

Transformiert eingehende Informationen

t3 := t1 + t2

Ausgehende Informationen I

I

Transformiert eingehende Informationen

I

t0 := t1 – t9

t2 := t3 * t5

Transformiert eingehende Informationen

Hier müssen Informationen kombiniert werden


Grundprinzip datenflussanalyse

Grundprinzip Datenflussanalyse

  • Informationen I breiten sich entweder mit oder gegen den Steuerfluss aus.

  • Für jeden Knoten b gibt es:

    • Eingehenden Informationen: in(b),

    • ausgehende Informationen: out(b),

    • erzeugte Informationen: gen(b),

    • zerstörte Informationen: kill(b).

  • Abhängig von der Ausbreitungsrichtung der Informationen sind:

    • Vorwärtsanalyse:

      • in(b) = out(b1)  out(b2)  …  out(bn), wobei die bi die Steuerflussvorgänger von b sind und

      • out(b) = (in(b) – kill(b))  gen(b) (Transferfunktion genannt)

    • Rückwärtsanalyse:

      • out(b) = in(b1)  in(b2)  …  in(bn), wobei die bi die Steuerflussnachfolger von b sind und

      • in(b) = (out(b) – kill(b))  gen(b) (Transferfunktion genannt)

  • Durch den Steuerflussgraphen wird eine Mengengleichungssystem definiert.

  • Falls der Steuerflussgraph Zyklen enthält, ist das Mengengleichungssystem rekursiv; Lösung durch Fixpunktiteration.


Information erreichende definitionen

Information Erreichende Definitionen

  • An einer Programmposition (i,j) interessiert für eine Variable v, an welchen Programmpositionen der Wert der Variablen v definiert und bis zur Position (i,j) nicht mehr verändert wurde.

  • Menge aller Informationen: (()V)

  • Vorwärtsanalyse mit  := 

  • gen(bi) := {((i,j),v) | irj(i) ist letzte Definition von v in bi}

  • kill(bi) := {((m,n),v) | m, n   und bi enthält eine Definition von v}

gen(b2) = {((2,0),t0), ((2,1),t1), ((2,2),t2)}

kill(b3) = {((m,n),t0), ((m,n),t1), ((m,n),t2)}

in(b2) =

in(b3) =

in(b4) =

in(b1) =

{((2,0),t0), ((2,1),t1), ((2,2),t2)}

{((2,0),t0), ((2,1),t1), ((2,2),t2)} 

{((4,0),t3), ((4,1),t4), ((4,2),t2)}

{((2,1),t1), ((2,2),t2), ((3,1),t0), ((2,0),t0),

((4,0),t3), ((4,1),t4), ((4,2),t2)}

{((2,0),t0), ((2,1),t1), ((2,2),t2)}

{((2,0),t0), ((2,1),t1), ((2,2),t2)} 

{((4,0),t3), ((4,1),t4), ((4,2),t2)}

{((3,1),t0)} 

{((4,0),t3), ((4,1),t4), ((4,2),t2)}

b0

t0 := a

t1 := b

t2 := t0 + t1

b2

gen(b3) = {((3,1),t0)}

kill(b3) = {((m,n),t0)}

out(b0) =

out(b2) =

out(b3) =

out(b4) =

{((2,0),t0), ((2,1),t1), ((2,2),t2)}

{((3,1),t0)}

{((4,0),t3), ((4,1),t4), ((4,2),t2)}

{((2,0),t0), ((2,1),t1), ((2,2),t2)}

{((2,1),t1), ((2,2),t2), ((3,1),t0)}

{((2,0),t0), ((2,1),t1)} 

{((4,0),t3), ((4,1),t4), ((4,2),t2)}

b3

t0 := t2 – t0

t0 := b

b4

t3 := t2

t4 := t3 * t2

t2 := t2 – t4

b1

gen(b4) = {((4,0),t3), ((4,1),t4), ((4,2),t2)}

kill(b4) = {((m,n),t3), ((m,n),t4), ((m,n),t2)}


Information lebendige variablen

Information Lebendige Variablen

  • An einer Programmposition (i,j) interessiert für eine Variable v, ob es einen Pfad zu einer Programmposition gibt, an der v verwendet wird, ohne auf diesem Pfad definiert zu werden.

  • Menge aller Informationen: (V)

  • Rückwärtsanalyse mit  := 

  • gen(bi) := {v | irj(i) ist Verwendung von v und für alle 0  k < j gilt: irk(i) ist keine Definition von v}

  • kill(bi) := {v | v wird in bi definiert}

gen(b2) = {a,b}

kill(b2) = {t0,t1,t2}

b0

in(b0) = in(b2)

in(b2) = (in(b3)  in(b4) – kill(b2))  gen(b2)

in(b3) = (in(b1) – kill(b3))  gen(b3)

in(b4) = ((in(b4)  in(b1)) – kill(b4))  gen(b4)

b2

t0 := a

t1 := b

t2 := t0 + t1

gen(b4) = {t2}

kill(b4) = {t2,t3,t4}

gen(b3) = {b, t2, t0}

kill(b3) = {t0}

b3

t0 := t2 – t0

t0 := b

b4

t3 := t2

t4 := t3 * t2

t2 := t2 – t4

b1

gen(b4) = 

kill(b4) = 


Kopier konstanten popagierung

Kopier- / Konstanten-Popagierung

  • Ersetze die Verwendung der Variablen y in einer Anweisung iri(j) durch zfalls:

    • auf allen Pfaden von Programmposition (0,0) zur Programmposition (j,i), eine Anweisung irn(m) = "y := z" existiert und

    • es auf allen Pfaden von Positionen (m,n+1) zur Position (j,i) keine definierende Anweisung für y und z gibt.

  • Nach der Ersetzung kann es sein, dass die Variable y nicht mehr benutzt wird.

  • z darf eine Variable (copy propagation) oder Konstante (constant propagation) sein.

  • Constant Folding: Ersetze Zwischencodeanweisungen der Form x := y  z bzw. x :=  z durch x := k, falls y und z konstant sind und k das Ergebnis der Operation  ist.

t0 := 8

y := t0

t0 := 7

x := t0

t1 := x

t2 := y

t3 := t1 + t2

z := t3

t1 := x

t2 := y

t3 := t1 + t2

z := t3

y darf durch t0 ersetzt werden

y darf nicht durch t0 ersetzt werden

t0 := y

t1 := x


Information f r kopier konstanten propagierung

Information für Kopier-/Konstanten-Propagierung

  • Berechnung der Information Erreichende Kopien RC(x) = in(x) für Knoten x im Steuerflussgraphen S = (N,E,q,s) durch eine Datenflussanalyse mit den Parametern:

    • Menge aller Informationen: ({x:=y | x:=y ist Kopierbefehl im Programm})

    • Vorwärtsanalyse mit  := 

    • gen(bi) := {x:=y | x:=y ist Zwischencodebefehl irk(bi) und in allen Zwischencodebefehlen irk+1(bi)… ir#bi(bi) wird weder x noch y definiert}

    • kill(bi) := {x:=z | x wird in Block bi definiert und x:=z ist Kopieranweisung im Programm}  {z:=x | x wird in Block bi definiert und z:=x ist Kopieranweisung im Programm}

2:

t0 := 8

y := t0

"t0:=8","y:=t0"

"t0:=8","y:=t0"

3:

t0 := 7

x := t0

t1 := x

t2 := y

t3 := t1 + t2

z := t3

4:

t1 := x

t2 := y

t3 := t1 + t2

z := t3

"t1:=x","t2:=y","z:=t3"

1:

t0 := y

t1 := x


Kopier konstanten propagierung im basisblock

Kopier-/Konstanten-Propagierung im Basisblock

  • In einem Basisblock b wird die Verwendung von x in Anweisung i durch y ersetzt, falls:

    • x := y in(b) und in allen Anweisungen k mit 0  k < i weder x noch y definiert werden oder

    • Anweisung j < i die Form x := y hat und in allen Anweisungen k mit j < k < i weder x noch y definiert werden.

  • Diese Ersetzung muss gegebenenfalls wiederholt werden, bis keine weiteren Ersetzungen möglich sind.

2:

t0 := 8

y := t0

2:

t0 := 8

y := 8

"t0:=8","y:=t0"

Erneute Informationssammlung ergibt, dass y durch 8 ersetzt werden darf

"t0:=8","y:=t0"

3:

t0 := 7

x := t0

t1 := x

t2 := y

t3 := t1 + t2

z := t3

4:

t1 := x

t2 := y

t3 := t1 + t2

z := t3

3:

t0 := 7

x := 7

t1 := 7

t2 := y

t3 := 7 + y

z := t3

4:

t1 := x

t2 := 8

t3 := x + 8

z := t3

t1 := x

t2 := t0

t3 := t1 + t2

z := t3

"t1:=x","t2:=y","z:=t3"

1:

t0 := y

t1 := x

1:

t0 := y

t1 := x


Eliminierung toten codes

Eliminierung toten Codes

  • Eine Zwischencodeanweisung iri(j) = "x := e" kann aus dem Zwischencode entfernt werden, falls

    • für alle Programmpositionen (m,n) an denen x verwendet wird und alle Pfade von (j,i+1) nach (m,n) gilt: x wird auf diesen Pfaden definiert. Dabei ist e ein beliebiger Ausdruck des Zwischencodes oder

    • kein Pfad von (0,0) nach (j,i) existiert.

  • Es kann neuer toter Code entstehen.

2:

t0 := 8

y := 8

Darf nicht gestrichen werden.

3:

t0 := 7

x := 7

t1 := 7

t2 := 8

t3 := 7 + 8

z := 15

4:

t1 := x

t2 := 8

t3 := t1 + 8

x := t3

Kann gestrichen werden.

1:

t0 := 8

t1 := x


Information zur eliminierung toten codes

Information zur Eliminierung toten Codes

  • Berechnung der Information Lebendig: LE(x) = out(x) für Knoten x im Steuerflussgraphen S = (N,E,q,s) durch eine Datenflussanalyse mit den Parametern:

    • Menge aller Informationen: (V)

    • Rückwärtsanalyse mit  := 

    • gen(bi) := {v | irj(i) ist Verwendung von v und für alle 0 k < j gilt: irk(i) ist keine Definition von v}

    • kill(bi) := {v | v wird in bi definiert}

2:

t0 := 8

y := 8

"x"

3:

t0 := 7

x := 7

t1 := 7

t2 := 8

t3 := 7 + 8

z := 15

4:

t1 := x

t2 := 8

t3 := t1 + 8

x := t3

"x"

"x"

1:

t0 := 8

t1 := x


Eliminierung toten codes im basisblock

Eliminierung toten Codes im Basisblock

  • Entferne die Anweisung x := expr an Position i im Basisblock b, falls:

    • x an Position j > i definiert wird und für alle Anweisungen irk(b) mit i < kj gilt: irk(b) verwendet x nicht oder

    • x out(b) und in keiner Anweisung irk(b) mit i < k < #b wird x verwendet.

  • Durch das Entfernen einer Anweisung x := expr entfällt die Verwendung der Variablen in expr.

  • Konsequenz: Wiederholung der Eliminierung toten Codes erforderlich.

2:

t0 := 8

y := 8

2:

"x"

3:

t0 := 7

x := 7

t1 := 7

t2 := 8

t3 := 7 + 8

z := 15

4:

t1 := x

t2 := 8

t3 := t1 + 8

x := t3

3:

x := 7

4:

t1 := x

t3 := t1 + 8

x := t3

"x"

"x"

1:

t0 := 8

t1 := x

1:

t0 := 8

t1 := x


Weitere anwendung der information lebendig

Weitere Anwendung der Information Lebendig

  • Registerallokation:

    • Treffen der Spill-Entscheidung in Basisblöcken.

    • Bestimmung der zu sichernden Variablen am Ende eines Basisblocks.

    • Globale Registerallokation durch Graphfärbung:

      • Konstruktion eines Interferenzgraphen

        • Variablen sind Knoten

        • Eine Kante zwischen zwei Knoten existiert gdw. es eine Programmposition gibt, an der beide Variablen lebendig sind.

      • Färbung des Interferenzgraphen liefert eine Registerallokation (Jede Farbe entspricht einem Prozessorregister).

      • Details…


Globale eliminierung gemeinsamer teilausdr cke

Globale Eliminierung gemeinsamer Teilausdrücke

  • Die Zuweisung iri(j) = "x := e" mit dem Ausdruck e kann durch x := t ersetzt werden, falls:

    • auf allen Pfaden von Programmposition (0,0) zur Programmposition (j,i), eine Anweisung irn(m) = "y := e" existiert und

    • es auf allen Pfaden von Positionen (m,n) zur Position (j,i) keine definierenden Anweisungen für die Verwendungen in e gibt und

    • an allen Positionen (m,n+1) die Anweisung "t := y" eingefügt wird.

  • Konsequenz: Es entstehen neue Kopierbefehle.

y := 4 * i

x := 6 * j

Hier darf 6 * j ersetzt werden.

j := j +1

m := 5 * y

n := 6 * j

x := x * 5

i := i + 1

Hier darf 6 * j nicht ersetzt werden.

n := 6 * j

m := i + 1


Information zur globalen eliminierung gemeinsamer teilausdr cke

Information zur globalen Eliminierung gemeinsamer Teilausdrücke

  • Berechnung der Information Verfügbare Ausdrücke AE(x) = in(x) für Knoten x im Steuerflussgraphen S = (N,E,q,s) durch eine Datenflussanalyse mit den Parametern:

    • Menge aller Informationen: ({e | e ist Ausdruck in einem Zwischencodebefehl})

    • Vorwärtsanalyse mit  := 

    • gen(bi) := {e | irj(i) hat die Form x := e und für alle jk < #bi gilt: irk(i) definiert keine in e verwendete Variable}

    • kill(bi) := {e | Variable im Ausdruck e wird in bi definiert}

6*j

2:

y := 4 * i

x := 6 * j

4*i, 6*j

3:

j := j +1

4:

m := 5 * y

n := 6 * j

x := x * 5

i := i + 1

1:

n := 6 * j

m := i + 1


Globale eliminierung gemeinsamer teilausdr cke in basisbl cken

Globale Eliminierung gemeinsamer Teilausdrücke in Basisblöcken

  • Ersetze die Anweisung x := e an Position i im Basisblock b durch x := t falls:

    • die Anweisung irj(b) die Form y := e hat und j < i und für alle Anweisungen irk(b) mit jk < i gilt: irk(b) definiert keine Variable, die in e verwendet wird oder

    • e in(b) und in keiner Anweisung irk(b) mit 0 k < i wird eine Variable definiert, die in e verwendet wird.

  • Nach den Anweisungen y := e, die e berechnen, wird t := e eingefügt (t ist neue Variable).

  • Durch Ersetzung mit x := t entstehen neue Kopieranweisungen.

  • Konsequenz: Wiederholung der Copy-/Constant-Propagation erforderlich.

y := 4 * i

x := 6 * j

t := x

6*j

2:

y := 4 * i

x := 6 * j

4*i, 6*j

3:

j := j +1

4:

m := 5 * y

n := 6 * j

x := x * 5

i := i + 1

j := j +1

m := 5 * y

n := t

x := x * 5

i := i + 1

1:

n := 6 * j

m := i + 1

n := 6 * j

m := i + 1


Entfernen schleifeninvarianter berechnungen

Entfernen schleifeninvarianter Berechnungen

  • Es sei L die Menge der Knoten des Steuerflussgraphen, die auf einem Zykel liegen und d Lder einzige Knoten der nicht zu L gehört und eine Kante zu einem Knoten in L besitzt (d dominiert L).

  • Eine Anweisung iri(j) = "x := e" kann im Block bj Ldurch x := t ersetzt und am Ende des Blocks d t := e eingefügt werden, falls kein Block in L eine Definition einer Verwendung in e enthält.

  • Um eine spekulative Ausführung von e zu vermeiden, Einfügen eines neuen Basisblocks auf der Kante von d nach L und Einfügen von t := e in diesen neuen Basisblock.

y := 4 * i

x := 6 * j

t := x

5*y ist schleifeninvariant

i und x sind nicht schleifeninvariant

j := j +1

m := 5 * y

n := t

x := x * 5

i := i + 1

n := 6 * j

m := i + 1


Informationen zum finden schleifeninvarianter berechnungen

Informationen zum Finden schleifeninvarianter Berechnungen

  • Berechnung der Information Erreichende Definiton RD(x) = in(x) für Knoten x im Steuerflussgraphen S = (N,E,q,s) durch eine Datenflussanalyse mit den Parametern:

    • Menge aller Informationen: (()V)

    • Vorwärtsanalyse mit  := 

    • gen(bi) := {((i,j),v) | irj(i) ist letzte Definition von v in bi}

    • kill(bi) := {((m,n),v) | (m,n) ist Programmposition und bi enthält eine Definition von v}

y := 4 * i

x := 6 * j

t := x

((2,0),y),((2,1),x),((2,2),t),

((4,0),m),((4,1),n),((4,2),x),((4,3),i)

2:

((2,0),y),((2,1),x),((2,2),t)

3:

j := j +1

4:

m := 5 * y

n := t

x := x * 5

i := i + 1

((2,0),y),((2,1),x),((2,2),t),((3,0),j),

((4,0),m),((4,1),n),((4,2),x),((4,3),i)

1:

n := 6 * j

m := i + 1


Entfernen schleifeninvarianter berechnungen in l

Entfernen schleifeninvarianter Berechnungen in L

  • Finde in L Anweisungen der Form x := e, wobei e nur Konstanten und Variablen v enthält, die außerhalb der Blöcke von L definiert wurden.

  • Ersetze x := e durch x := inv (inv ist neue Variable) und füge am Ende von d die Anweisung inv := e ein.

  • Es entstehen neue Kopieranweisungen.

  • Konsequenz: Wiederholung von Konstanten- und Kopierpropagierung.

y := 4 * i

x := 6 * j

t := x

inv := 5 * y

y := 4 * i

x := 6 * j

t := x

((2,0),y),((2,1),x),((2,2),t),

((4,0),m),((4,1),n),((4,2),x),((4,3),i)

2:

3:

j := j +1

4:

m := 5 * y

n := t

x := x * 5

i := i + 1

j := j +1

m := inv

n := t

x := x * 5

i := i + 1

1:

n := 6 * j

m := i + 1

n := 6 * j

m := i + 1


Weitere anwendung der information erreichende definitionen

Weitere Anwendung der Information Erreichende Definitionen

  • Erkennung der Benutzung einer Variablen vor ihrer Definition.

  • Definiere out(b0) := {((0,0),v) | v hat Verwendung im Steuerflussgraph}.

  • Berechne Erreichende Definitionen.

  • Falls bei einer Verwendung von v die Information ((0,0),v) vorhanden ist, dann kann es einen Pfad zu dieser Verwendung geben, auf dem v nicht initialisiert wird.


Strength reduction in schleifen

Strength-Reduction in Schleifen

  • Es sei L die Menge der Blöcke einer Schleife und d der Schleifenkopf (Dominator von L)

  • Suchen einer Variablen i (Induktionsvariablen), die in jedem Schleifendurchlauf um eine Konstante c erhöht wird.

  • Suchen nach einer Berechnung y := f(i), wobei f(i + c) – f(i) = di

  • Statt f(i) in jeder Iteration zu berechnen, wird in jeder Iteration zu ydi addiert.

i := 0

y := 4 * i

x := 6 * j

x' := x

m := 5 * y

n := x'

i ist Induktionsvariable und x schleifeninvariant. Dann wird z in jeder Iteration um 2*x größer.

j := j +1

z := x * i

i := i + 2

n := 6 * j

m := i + 1


Strength reduction im schleifenk rper

Strength-Reduction im Schleifenkörper

  • Finden von Anweisungen der Form z := invi oder z := iinv, wobei i eine Induktionsvariable ist, die in jedem Schleifendurchlauf um cexpr erhöht wird und inv schleifeninvariant ist.

  • Füge am Ende von d ein:

    • dz := invcexpr und nz := invi

  • Im Schleifenkörper :

    • Füge nach der Anweisung i := i + cexpr die Anweisung nz := nz + dz ein und

    • ersetze z := invi durch z := nz.

  • Dadurch kann nz selbst wieder zu einer Induktionsvariablen werden. Konsequenz: Wiederholung der Strength-Reduction.

i := 0

y := 4 * i

x := 6 * j

x' := x

m := 5 * y

n := x'

dz := x * 2

nz := x * i

i := 0

y := 4 * i

x := 6 * j

x' := x

m := 5 * y

n := x'

i ist Induktionsvariable und x schleifeninvariant. Dann wird z in jeder Iteration um 2*x größer.

j := j +1

z := x * i

i := i + 2

j := j +1

z := nz

nz := nz + dz

i := i + 2

nz und z sind Induktions-variable.

n := 6 * j

m := i + 1

n := 6 * j

m := i + 1


Komplexbeispiel matrixmultiplikation

Komplexbeispiel: Matrixmultiplikation

innerLoop:

t0 := &c

t1 := j

t2 := n

t3 := t1*t2

t4 := i

t5 := t3+t4

t6 := t0+t5

t7 := @t6

t8 := &a

t9 := j

t10:= n

t11:= t9*t10

t12:= k

t13:= t11+t12

t14:= t8+t13

t15:= @t14

t16:= &b

t17:= k

t18:= n

t19:= t17*t18

t20:= i

t21:= t19+t20

t22:= t16+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

t26 := &c

t27 := j

t28 := n

t29 := t27*t28

t30 := i

t31 := t29+t30

t32 := t26+t31

@t32:= t25

Quelltext für Matrixmultiplikation:

for(i = 0; i < n; i = i+1) {

for(j = 0; j < n; j = j+1) {

c[j][i] = 0.0;

for(k = 0; k < n; k = k+1) {

c[j][i] = c[j][i] + a[j][k] * b[k][i]

}

}

}

Erzeugter Zwischencode


Konstanten und kopierpropagierung und eliminierung toten codes

Konstanten- und Kopierpropagierung und Eliminierung toten Codes

innerLoop:

t0 := &c

t1 := j

t2 := n

t3 := t1*t2

t4 := i

t5 := t3+t4

t6 := t0+t5

t7 := @t6

t8 := &a

t9 := j

t10:= n

t11:= t9*t10

t12:= k

t13:= t11+t12

t14:= t8+t13

t15:= @t14

t16:= &b

t17:= k

t18:= n

t19:= t17*t18

t20:= i

t21:= t19+t20

t22:= t16+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

t26 := &c

t27 := j

t28 := n

t29 := t27*t28

t30 := i

t31 := t29+t30

t32 := t26+t31

@t32:= t25

innerLoop:

t3 := j*n

t5 := t3+i

t6 := &c+t5

t7 := @t6

t11:= j*n

t13:= t11+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

t29 := j*n

t31 := t29+i

t32 := &c+t31

@t32:= t25

innerLoop:

t3 := j*n

t5 := t3+i

t6 := &c+t5

t7 := @t6

t11:= j*n

t13:= t11+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

t29 := j*n

t31 := t29+i

t32 := &c+t31

@t32:= t25

Copy-/Constant-Propagation

und anschließende

Dead-Code-Elimination


Common subexpression elimination

Common Subexpression Elimination

innerLoop:

t3 := j*n

t5 := t3+i

t6 := &c+t5

t7 := @t6

t11:= j*n

t13:= t11+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

t29 := j*n

t31 := t29+i

t32 := &c+t31

@t32:= t25

innerLoop:

t3 := j*n

s1 := t3

s0 := t3

t5 := t3+i

t6 := &c+t5

t7 := @t6

t11:= s0

t13:= t11+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

t29:= s1

t31 := t29+i

t32 := &c+t31

@t32:= t25

innerLoop:

t3 := j*n

t5 := t3+i

t6 := &c+t5

t7 := @t6

t13:= t3+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

t31 := t3+i

t32 := &c+t31

@t32:= t25

innerLoop:

t3 := j*n

t5 := t3+i

t6 := &c+t5

t7 := @t6

t13:= t3+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

t32 := &c+t5

@t32:= t25

innerLoop:

t3 := j*n

t5 := t3+i

t6 := &c+t5

t7 := @t6

t13:= t3+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

@t6:= t25

Eliminierung des gemeinsamen Teilausdrucks j*n

Eliminierung des gemeinsamen Teilausdrucks t3+i und anschließende Kopierpropagierung

und anschließende

Eliminierung toten Codes

Eliminierung des gemeinsamen Teilausdrucks &c+t5 und anschließende Kopierpropagierung

und anschließende

Eliminierung toten Codes

Kopierpropagierung

und anschließende

Eliminierung toten Codes

c[j][i] = c[j][i] + a[j][k] * b[k][i]


Schleifeninvariante ausdr cke entfernen

Schleifeninvariante Ausdrücke entfernen

k := 0

inv0 := j*n

k := 0

inv0 := j*n

k := 0

k := 0

innerLoopTest:

t53:= k<n

if t53 then innerLoop

goto innerLoopEnd innerLoop:

t3 := j*n

t5 := t3+i

t6 := &c+t5

t7 := @t6

t13:= t3+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

@t6:= t25

t35:= k+1

k := t35

goto innerLoopTest

innerLoopEnd:

...

t53:= k<n

if t53 then 3

t53:= k<n

if t53 then 3

t53:= k<n

if t53 then 3

t3 := j*n

t5 := t3+i

t6 := &c+t5

t7 := @t6

t13:= t3+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

@t6:= t25

t35:= k+1

k := t35

t3 := inv0

t5 := t3+i

t6 := &c+t5

t7 := @t6

t13:= t3+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

@t6:= t25

t35:= k+1

k := t35

t5 := inv0+i

t6 := &c+t5

t7 := @t6

t13:= inv0+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

@t6:= t25

t35:= k+1

k := t35

...

...

...

for(k = 0; k < n; k = k+1) {

c[j][i] = c[j][i] + a[j][k] * b[k][i]

}


Schleifeninvariante ausdr cke entfernen1

Schleifeninvariante Ausdrücke entfernen

k := 0

inv0:= j*n

inv1:= inv0+i

inv2:= &c+inv1

k := 0

inv0 := j*n

k := 0

inv0:= j*n

inv1:= inv0+i

t53:= k<n

if t53 then 3

t53:= k<n

if t53 then 3

t53:= k<n

if t53 then 3

t5 := inv0+i

t6 := &c+t5

t7 := @t6

t13:= inv0+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

@t6:= t25

t35:= k+1

k := t35

t6 := &c+inv1

t7 := @t6

t13:= inv0+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

@t6:= t25

t35:= k+1

k := t35

t7 := @inv2

t13:= inv0+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

@inv2:= t25

t35:= k+1

k := t35

...

...

...


Bestimmung der induktionsvariablen

Bestimmung der Induktionsvariablen

k := 0

inv0:= j*n

inv1:= inv0+i

inv2:= &c+inv1

k := 0

inv0:= j*n

inv1:= inv0+i

inv2:= &c+inv1

t53:= k<n

if t53 then 3

t53:= k<n

if t53 then 3

t7 := @inv2

t13:= inv0+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

@inv2:= t25

t35:= k+1

k := t35

t7 := @inv2

t13:= inv0+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

@inv2:= t25

t35:= k+1

k := t35

...

...


Strength reduction

Strength-Reduction

k := 0

inv0:= j*n

inv1:= inv0+i

inv2:= &c+inv1

d := 1*n

nn := k*n

k := 0

inv0:= j*n

inv1:= inv0+i

inv2:= &c+inv1

t53:= k<n

if t53 then 3

t53:= k<n

if t53 then 3

t7 := @inv2

t13:= inv0+k

t14:= &a+t13

t15:= @t14

t19:= k*n

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

@inv2:= t25

t35:= k+1

k := t35

t7 := @inv2

t13:= inv0+k

t14:= &a+t13

t15:= @t14

t19:= nn

nn := nn + d

t21:= t19+i

t22:= &b+t21

t23:= @t22

t24:= t15*t23

t25:= t7+t24

@inv2:= t25

t35:= k+1

k := t35

cexpr für k ist 1

...

...


Rahmenwerk zur datenflussanalyse dfa

Rahmenwerk zur Datenflussanalyse (DFA)

  • DFA-Rahmenwerk: (D, I, , F) besteht aus:

    • Der Richtung D der Analyse (vorwärts oder rückwärts)

    • Einem Halbverband (I, ), d.h. für alle x, y, z  I

      • x  x = x

      • x  y = y  x

      • x  (y  z) = (x  y)  z

      • es ex. ein   I, so dass für alle x  I gilt   x = x

    • Einer Menge F, die für jeden Basisblock des Steuerflussgraphen eine Transferfunktion f : I  I enthält, die monoton und stetig ist.

  • Induzierte Ordnung auf I: x  y gdw. x  y = y

  • Voraussetzungen für den Fixpunktsatz von Tarski und Knaster sind erfüllt. Damit existiert der kleinste Fixpunkt und kann durch Iteration berechnet werden, weil:

    • (I, ) ist eine vollständig geordnete Menge, weil für alle x, y  I gilt: x  y ist kleinste oberer Schranke von x und y.

    • Jedes f F ist monoton und stetig.


I ist eine geordnete menge

(I,) ist eine geordnete Menge

  • Reflexivität:x  x gilt wegen x  x = x.

  • Antisymmetrisch:x  y und y  x  x  y = y und y  x (= x  y) = x  x = y.

  • Transitivität:x  y und y  z  x  y = y und y  z = z  z = (x  y)  z = x  (y  z) = x  z  x  z.


I ist eine vollst ndig geordnete menge

(I,) ist eine vollständig geordnete Menge

  • Wir zeigen: Für alle x, y  I ist z = x  y die kleinste obere Schranke von x und y:

    • x  z  x  z = x  (x  y) = (x  x)  y) = x  y = z.

    • y  z  y  z = y  (x  y) = y  (y  x) = (y  y)  x) = y  x = x  y = z.

    • Angenommen x  u und y  u, dann x  u = u und y  u = u und z  u = u  u = u  u = x  u  y  u = x  u  y = z  u  z  u

  • Damit ist für jede endliche nicht leere Kette K  I mit K = {k1, k2, k3,…,kn} k1 k2  k3  …  kn die kleinste obere Schranke von K.


Fixpunktiteration

Fixpunktiteration

  • Es ist der Fixpunkt einer Funktion F(out(b0),…,out(bm)) = F((out(b0),…,out(bm))) bzw. (in(b0),…,in(bm)) = F((in(b0),…,in(bm))) gesucht.

  • Durch den Steuerflussgraphen wird für jede Komponente out(bi) bzw. in(bi) eine Mengengleichung erzeugt:

    • Vorwärtsanalyse:out(bi) = fi(out(bk1)…out(bkn)), wobei bk1,…,bkn die Steuerflussvorgänger von bi sind und 0  kj m.

    • Rückwärtsanalyse:in(bi) = fi(in(bk1)…in(bkn)), wobei bk1,…,bkn die Steuerflussvorgänger von bi sind und 0  kj m.

  • Wir schreiben kurz: (b0,…,bm) = F((b0,…,bm)) und abstrahieren von der Richtung.

  • Die induzierte Ordnung auf I wird zu einer Ordnung auf Im+1 erweitert:(a0,…,am)  (b0,…,bm) gdw. j: 0  j  m  aj  bj. Analog wird der Operator  für einen Vektor erweitert.

  • Unter der Voraussetzung, dass die Transferfunktionen fi monoton und stetig sind, ist es F auch (Beweis folgt).


Monotonie von f

Monotonie von F

  • F monoton gdw. aus (a0,…,am)  (b0,…,bm) folgt F(a0,…,am)  F(b0,…,bm).

  • a = (a0,…,am)  (b0,…,bm) = b gdw. i: ai  bi.

  • Für jedes ai und bi gilt nun:

    • Es seien ak1,…,akn bzw. bk1,…,bkndie Komponenten in a bzw. b, die den in/out-Resultaten der Steuerflussvorgänger/-nachfolger von ai bzw. bi entsprechen.

    • Wegen akj  bkj ist ak1…akn bk1…bkn. (Bew. durch Induktion; im Schritt: a b  ab = b und a' b'  a'b' = b'  bb' = ab a'b' = (aa')  (bb')  (aa')  (bb')).

    • Wegen der Monotonie der Transferfunktion fi gilt dann fi(ak1…akn) fi(bk1…bkn)

  • Und damit F(a0,…,am)  F(b0,…,bm)


Stetigkeit von f

Stetigkeit von F

  • F stetig gdw. F(a0,…,am) F(b0,…,bm) = F(a0b0,…,ambm).

  • Es seien ai' und bi' die i-ten Komponenten des Resultats von F(a) bzw. F(b), d.h.: b'i = fi(bk1,…,bkn ) und a'i = fi(ak1,…,akn)

  • Wegen der Stetigkeit von fi gilt: a'i  b'i= fi(ak1,…,akn)fi(bk1,…,bkn) = fi(ak1)… fi(akn)fi(bk1)…fi(bkn) = fi(ak1) fi(bk1)…fi(akn)fi(bkn) = fi(ak1bk1)…fi(aknbkn) = fi(ak1bk1,…,aknbkn).

  • fi(ak1bk1,…,aknbkn) ist auch die i-te Komponente des Resultats von F(a0b0,…,ambm)


Ende der optimierung

Ende der Optimierung

Ende der Vorlesung


Beispiel steuerflussgraph interferenzgraph

Beispiel Steuerflussgraph/Interferenzgraph

d := 0

a := 1

c := 3

(d)

(a,d)

(a,d,c)

u

v

t

w

e

f := c

(a,c,f,d)

d:= d+1

r := 2*d

s := 3*c

t := r+s

e := t+5

d:= a+f

u := c

v := u+1

w := v+1

e := v

(c,d)

(c,d,r)

(d,s,r)

(d,t)

(d,e)

(c,d)

(d,u)

(d,v)

(d,w)

(d,e)

a

d

s

f

c

r

z

c:= d+3

a := e*c

(d,c)

(d,c,a)

z:= a+d

(z)


F rbung des interferenzgraphen

Färbung des Interferenzgraphen

u

  • Gesucht Färbung I : V  R mit I(u)  I(v) gdw. {u,v}  E, wobei R die Menge der Prozessorregister ist.

  • Finden einer Färbung durch schrittweises Entfernen von Knoten v mit adjazenten Kanten, falls v mit echt weniger als |R| Knoten adjazent ist:

    • Falls kein Knoten mit weniger als |R| Nachbarn existiert, dann Spillentscheidung treffen.

    • Falls I zum leeren Graphen reduziert wurde, Einfügen der Knoten mit Kanten in umgekehrter Reihenfolge und Färben der Knoten.

v

t

w

e

s

a

d

f

c

r

z

I = (V, E), R = {0,1,2}

w

w

v

v

u

u

t

t

e

e

a

a

d

d

s

s

d4

d4

c

f

f

c

r

r

z

z

w

v

u

t

e

d4

z

d1

d2

d3

s

r

c

f

a

d1

d1

d2

d2

d3

d3


Spillen

Spillen

Spillen von d

d := 0

@&d := d

a := 1

c := 3

(d)

()

(a,d)

(a,c)

d := 0

a := 1

c := 3

(d)

(a,d)

(a,d,c)

f := c

(a,c,f)

f := c

(a,c,f,d)

d1 := @&d

d1:= d1+1

@&d := d1

r := 2*d

s := 3*c

t := r+s

e := t+5

d2 := a+f

@&d := d2

u := c

v := u+1

w := v+1

e := v

(c,d1)

(c,d1)

(c)

(c,r)

(s,r)

(t)

(e)

(c,d2)

(c)

(u)

(v)

(w)

(e)

d:= d+1

r := 2*d

s := 3*c

t := r+s

e := t+5

d:= a+f

u := c

v := u+1

w := v+1

e := v

(c,d)

(c,d,r)

(d,s,r)

(d,t)

(d,e)

(c,d)

(d,u)

(d,v)

(d,w)

(d,e)

d3 := @&d

c:= d3+3

a := e*c

(d3,c)

(c)

(c,a)

c:= d+3

a := e*c

(d,c)

(d,c,a)

d4 := @&d

z:= a+d

(d4)

(z)

z:= a+d

(z)


Auswahl der spillvariablen

Auswahl der Spillvariablen

  • Falls ein Interferenzgraph nicht weiter reduziert werden kann, dann wird aus den verbleibenden Knoten der ausgewählt, für denminimal ist. Dabei sind DefUse(v) alle Programmpositionen, an denen v verwendet/definiert wird. und deepth(p) die Schachtelungstiefe der innersten Schleife, die die Programmposition p enthält.

  • Vor/nach allen Verwendungen/Definitionen von v wird Spillcode in den Zwischencode eingefügt.

  • Interferenzgraph muss neu konstruiert werden.

  • Es können mehrere solcher Iterationen erforderlich sein, bis eine Färbung des Interferenzgraphen gefunden wird.

  • Variablen zwischen deren Definition und Verwendung keine anderen Variablen sterben, werden nicht gespillt.


  • Login