Code-Optimierung Philipp Bergener Seminar „Übersetzung künstlicher Sprachen“ Agenda Einführung Grundlagen Datenflussanalyse Methoden zur Code-Optimierung Zusammenfassung 2 Ziele und Anforderungen Verbesserung des Codes, der bei direkter, „naiver“ Übersetzung entsteht Optimierungsmöglichkeiten Verbesserung der Ausführgeschwindigkeit Verringerung des Speicherbedarfs zur Laufzeit Verkleinerung des erzeugten Codes Anforderungen Semantik des Programms muss erhalten bleiben Aufwand für Optimierung muss sich lohnen 3 Systematisierung Nach Zeitpunkt für Code-Optimierung: • Nach Zwischen-Codeerzeugung: Eher allgemeine Methoden • Nach Maschinen-Codeerzeugung: Eher maschinenspezifisch Globale vs. lokale Optimierung • Lokal: Nur Ausschnitt (Basisblock) wird betrachtet • Global: Mehrere Basisblöcke werden betrachtet 4 Agenda Einführung Grundlagen Datenflussanalyse Methoden zur Code-Optimierung Zusammenfassung 5 Drei-Adress-Code Zur Darstellung des Zwischencodes Maximal 3 Adressen pro Befehl Typen von Befehlen • Zuweisung: x = y op z op: arithmetisch (+,-,*,/) oder logisch (AND, OR) • Kopieranweisungen: x = y • Unbedingte Sprünge: goto L (L Sprungmarke) • Bedingte Sprünge: if x goto L bzw. ifFalse x goto L oder if x relop y bzw. ifFalse x relop y (relop: <, ==, >, etc.) • Indizierte Kopieranweisungen: x = a[i] bzw. a[i] = x a[i]: Speicherstelle i Einheiten hinter a 6 Basisblöcke und Flussgraphen Basisblöcke Strukturieren den Code Eigenschaften eines Basisblocks: Kann nur durch die erste Anweisung betreten werden Wird ohne Sprünge durchlaufen. Sprünge nur in der letzten Anweisung Ein Basisblock beginnt Bei der ersten Codezeile Bei Zeilen, die Ziel von Sprüngen sind Bei Zeilen, die auf Sprünge folgen Flussgraphen stellen Kontrollfluss grafisch dar Basisblöcke sind Knoten 2 zusätzliche Knoten Eingang und Ausgang 7 Beispiel: Binäre Suche public Ingeger binsearch(Integer k) { Integer m,l,r; //Anfang l = 0; r = N-1; do { m = (l+r)/2; if(k < a[m]) r = m-1; else l = m+1; while((k != a[m])||(l<r)); //Ende ... end Eingang B1 l = 0 r = N-1 B2 t1 = l+r m = t1/2 t2 = 8*m t3 = a[t2] ifFalse k<t3 goto B4 B3 r = m-1 goto B5 B5 t4 = 8*m t5 = a[t4] ifFalse k==t5 goto B2 B6 if l<r goto B2 Ausgang 8 B4 l = m+1 Agenda Einführung Grundlagen Datenflussanalyse Methoden zur Code-Optimierung Zusammenfassung 9 Datenflussanalyse Viele Optimierungsansätze brauchen Informationen über Datenfluss im Programm Programm ist eine Folge von Zuständen Zustand: unter anderem aktuelle Werte der Variablen Anweisungen sind Zustandsübergänge Durch Sprünge sind Zustände nicht immer eindeutig Nur der für ein Problem relevante Teil des Zustandes betrachtet Es wird nicht unterschieden auf welchem Pfad ein Programmpunkt erreicht wird 10 Bestandteile eines Datenflussproblems Datenflussproblem ist 4-Tupel (D, V, ^, F) Datenflussrichtung D {Vorwärts, Rückwärts} Gibt an ob Informationen mit oder gegen Informationsfluss fließen Domäne V relevanter Teil des Zustandes Konfluenzoperator ^ (z.B. ) Zum Übergang zwischen Blöcken Menge von Transferfunktionen F F: V V Für ganze Basisblöcke 11 Verfügbare Definitionen Fragestellung: Welche Definition für eine Variable ist an einem bestimmten Programmpunkt gültig Datenflussrichtung: D = Vorwärts Domäne: Potenzmenge der Menge aller Definitionen Konfluenzoperator: , also IN[B] = P Vorgänger von BOUT[P] Transferfunktion: • genB: Menge generierter Definitionen in Block B • killB: Menge gelöschter Definitionen in Block B • Dann OUT[B] = genB (IN[B] - killB) 12 Verfügbare Definitionen ... B1 l = 0 r = N-1 (d1) (d2) gen[B1]={d1, d2} kill[B1]={d7,d8} B2 ... B3 r = m-1 goto B5 (d7) B4 l = m+1 ... 13 gen[B3]={d7} kill[B3]={d2} (d8) gen[B4]={d8} kill[B4]={d1} Aktive Variablen Eine Variable x ist aktiv an Punkt p, wenn der Wert von x in p entlang eines Pfades von p an benutzt kann und wird. Andernfalls ist sie passiv. Datenflussrichtung: D = Rückwärts Domäne: Potenzmenge der Menge aller Variablen Konfluenzoperator: , also OUT[B] = P Nachfolger von BIN[P] Transferfunktion: • defB: Menge der Variablen, die in Block B definiert werden • useB: Menge der Variablen, die in B benutzt werden (bevor sie neu definiert werden) • Dann: IN[B] = useB (OUT[B] - defB) 14 Verfügbare Ausdrücke Ein Ausdruck der Form x op y ist an einem Punkt p verfügbar, wenn der Ausdruck auf jedem Pfad zu p berechnet wird und weder x noch y danach überschrieben werden Datenflussrichtung: D = Vorwärts Domäne: Potenzmenge der Menge aller Ausdrücke Konfluenzoperator: also IN[B] = P Vorgänger von BOUT[P] Transferfunktion: • e_genB: Menge aller Ausdrücke, die in B (neu) berechnet werden • e_killB: Menge aller Ausdrücke, die in B ungültig werden • Dann: OUT[B] = e_genB (IN[B] - e_killB) 15 Halbverband Ein Datenflussproblem bildet einen Halbverband Eigenschaften eines Halbverbands: x^x=x x^y=y^x x ^ (y ^ z) = (x ^ y) ^ z x, y, z V Halbverbände haben oberstes Element T mit T ^ x = x x V Für : T = Für : T = Basismenge der Potenzmenge 16 Algorithmus zum Lösen von Datenflussproblemen Zusätzlich noch Startmenge v (meist ) OUT[Eingang]=vEingang; for(jeden Block B außer Eingang) OUT[B] = T; while(min. ein OUT wird geändert) for(jeden Block B außer Eingang) { IN[B]=^P Vorgänger von pOUT[P]; OUT[B]=fB(IN[B]); } Für D = Rückwärts IN und OUT vertauschen Ausgang statt Eingang 17 Agenda Einführung Grundlagen Datenflussanalyse Methoden zur Code-Optimierung Zusammenfassung 18 Eliminierung gemeinsamer Teilausdrücke Gemeinsamer Teilausdruck: Vorkommen von Ausdruck E der schon einmal berechnet wurde und sich nicht mehr geändert hat. Ziel: wiederholte Berechnungen des gleichen Ausdrucks vermeiden Ermitteln mit Verfügbaren Ausdrücken Eliminierung • Teilausdruck in Hilfsvariable speichern • Dann statt Teilausdruck Hilfsvariable verwenden 19 Eliminierung gemeinsamer Teilausdrücke ... ... B2 t1 = l+r m = t1/2 t2 = 8*m t3 = a[t2] ifFalse k<t3 goto B4 B3 r = m-1 goto B5 B4 l = m+1 B5 t4 = 8*m t5 = a[t4] ifFalse k==t5 goto B2 ... 20 B2 t1 = l+r m = t1/2 h1 = 8*m t2 = h1 t3 = a[t2] ifFalse k<t3 goto B4 B3 r = m-1 goto B5 B4 l = m+1 B5 t4 = h1 t5 = a[t4] ifFalse k==t5 goto B2 ... Weitergabe von Kopien Durch andere Optimierungsverfahren entstehen Kopien der Form x = y Ziel: y anstelle von x benutzen Dadurch kann die Kopieranweisung überflüssig werden Lösung mit Verfügbaren Definitionen: • Ersetzung ist in p möglich, wenn x und y noch gleichen Wert besitzen • Dazu müssen sowohl die Definition x = y als auch die Definition für y, die in x = y galt, gültig in p sein • Außerdem dürfen keine anderen Definitionen x und y p erreichen 21 Weitergabe von Kopien 22 ... B2 t1 = l+r m = t1/2 h1 = 8*m t2 = h1 t3 = a[t2] ifFalse k<t3 goto B4 B2 t1 = l+r m = t1/2 h1 = 8*m t2 = h1 t3 = a[h1] ifFalse k<t3 goto B4 B3 r = m-1 goto B5 B3 r = m-1 goto B5 B4 l = m+1 ... B4 l = m+1 B5 t4 = h1 t5 = a[t4] ifFalse k==t5 goto B2 B5 t4 = h1 t5 = a[h1] ifFalse k==t5 goto B2 ... ... Eliminierung von totem Code Toter Code: • Anweisungen, die nie erreicht werden • Zuweisungen, die nie benutzt werden Entsteht durch andere Optimierungen oder (selten) durch Programmierfehler Identifizierung über aktive Variablen Beispiel: L1: 23 x = true ... //Hier keine Zuweisungen an x if x goto L1 a = b + c //Toter Code b = 2 * c Optimierung von Schleifen Programme verbringen einen Großteil ihrer Zeit in Schleifen Optimierung von Schleifen daher besonders wichtig 2 Ansätze zur Optimierung von Schleifen Export schleifeninvarianter Variablen Eliminierung von Induktionsvariablen 24 Optimierung von Schleifen Identifikation von Schleifen Dominator: Knoten d dominiert Knoten n (d dom n), wenn jeder Pfad im Flussgraph von Eingang zu n über d führt Rückwärtskante: Kante n → d mit d dom n Natürliche Schleife einer Rückwärtskante n → d: Alle Knoten von denen n erreicht werden kann ohne durch d zu laufen 25 Optimierung von Schleifen Eingang B1 l = 0 r = N-1 B2 t1 = l+r m = t1/2 t2 = 8*m t3 = a[t2] ifFalse k<t3 goto B4 B3 r = m-1 goto B5 B4 l = m+1 B5 t4 = 8*m t5 = a[t4] ifFalse k==t5 goto B2 B6 if l<r goto B2 Ausgang 26 Optimierung von Schleifen Eingang B1 l = 0 r = N-1 B2 t1 = l+r m = t1/2 t2 = 8*m t3 = a[t2] ifFalse k<t3 goto B4 B3 r = m-1 goto B5 B4 l = m+1 B5 t4 = 8*m t5 = a[t4] ifFalse k==t5 goto B2 B6 if l<r goto B2 Ausgang 27 Optimierung von Schleifen Eingang B1 l = 0 r = N-1 B2 t1 = l+r m = t1/2 t2 = 8*m t3 = a[t2] ifFalse k<t3 goto B4 B3 r = m-1 goto B5 B4 l = m+1 B5 t4 = 8*m t5 = a[t4] ifFalse k==t5 goto B2 B6 if l<r goto B2 Ausgang 28 Optimierung von Schleifen Export schleifeninvarianter Variablen: Variable ist schleifeninvariant, wenn in Schleife keine Zuweisung an sie erfolgt Ein Ausdruck ist schleifeninvariant, wenn er nur aus schleifeninvarianten Variablen besteht Diese sollen aus der Schleife herausgezogen werden while (i < max) do x := 3*y schleifeninvariant z := x+j j := i*2 i := i+1 end 29 //3*y ist Optimierung von Schleifen Eliminierung von Induktionsvariablen Induktionsvariable, die sich bei jedem Schleifendurchlauf um den gleichen, konstanten Wert ändert Diese sollen (bis auf eine) eliminiert werden x := 3*y x := 3*y while (i < max) do j := 2*i z := x+j j := i*2 i := i+1 end 30 while (j < 2*max) do z := x+j j := j+2 end i := max Konstantenfaltung Konstanten verbessern die Lesbarkeit von Programmen Auf Ebenen des Zwischencodes nicht nötig Daher: Variablen, die an einer Stelle immer den gleichen Wert haben durch diesen ersetzen Ausdrücke, die nur aus Konstanten bestehen, können dann ebenfalls berechnet werden Ermittlung von Konstanten auch mit Datenflussanalyse möglich 31 Konstantenfaltung Beispiel: N = 10 ... x = 2 y = N*x //Konstante //Wert in nächster Anweisung immer gleich //N und x können ersetzt werden N = 10 ... x = 2 y = 10*2 //Ausdruck kann jetzt berechnet werden 32 Algebraische Umformungen Ersetzen von langsameren Befehlen durch schnellere Ausnutzen von mathematischen Gesetzen Beispiele • • • • • 33 x*2n → x shiftl n x + 0 oder x * 1 → x x2 → x*x 2*x → x+x x/4 → x * 0,25 Agenda Einführung Grundlagen Datenflussanalyse Methoden zur Code-Optimierung Zusammenfassung 34 Zusammenfassung Direkt übersetzter Code kann noch weiter optimiert werden Es gibt verschiedene Ansätze zur Optimierung Datenflussanalyse bildet eine wichtige Grundlage für viele dieser Ansätze Es gibt weitere Optimierungsmethoden, z.B. • für Maschinen-Code • für OO-Sprachen 35 Fragen Vielen Dank für die Aufmerksamkeit Fragen? 36