Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

1. Abgrenzung, Motivation, Einordnung 2. Grundlagen 3

Ähnliche Präsentationen


Präsentation zum Thema: "1. Abgrenzung, Motivation, Einordnung 2. Grundlagen 3"—  Präsentation transkript:

0 Code-Erzeugung Arne Kostulski ( )

1 1. Abgrenzung, Motivation, Einordnung 2. Grundlagen 3
1. Abgrenzung, Motivation, Einordnung 2. Grundlagen 3. Code-Repräsentation 4. Code-Erzeugung 5. Fazit und weiterführende Themen - zwei populäre Anwendungskontexte für den Begriff „Code-Erzeugung“

2 1. Abgrenzung, Motivation, Einordnung 2. Grundlagen 3
1. Abgrenzung, Motivation, Einordnung 2. Grundlagen 3. Code-Repräsentation 4. Code-Erzeugung 5. Fazit und weiterführende Themen

3 Abgrenzung und Motivation
Metaprogrammierung Templates: Generische Frames, Prototypen, Aspekte, Diagramme Zielsprache: Skripte, Stubs, Testcode, ORM-Klassen, GUI-Klassen Kompilation Optimierung nur optional von lesbar bis Nullen-Einsen-Folgen Motivation hier Kompilation  Effizienz durch Automatisierung

4 Einordnung innerhalb des Kompilierungsprozesses
Optimierung optional, parallel und/oder nach Zielcode-Erzeugung Analyse unabhängig, Synthese abhängig von Zielmaschine

5 Einordnung innerhalb des Kompilierungsprozesses
Optimierung optional, parallel und/oder nach Zielcode-Erzeugung Analyse unabhängig, Synthese abhängig von Zielmaschine

6 Einordnung innerhalb des Kompilierungsprozesses
hier schwerpunktmäßig… Ordnungsrahmen Zielgrößen Einflussgrößen: Zielmaschine, Praxis und Modellierung Code-Erzeugung vs. optimale Code-Erzeugung 1.

7 Einordnung innerhalb des Kompilierungsprozesses
3. 1. 2.

8 1. Abgrenzung, Motivation, Einordnung 2. Grundlagen. Zielgrößen
1. Abgrenzung, Motivation, Einordnung 2. Grundlagen * Zielgrößen * Entwurfsfaktoren * Kernaufgaben * Referenzmaschine 3. Code-Repräsentation 4. Code-Erzeugung 5. Fazit und weiterführende Themen - die Logik des Aufbaus erschließt sich aus den folgenden Folien

9 Zielgrößen Semantische Korrektheit Laufzeiteffizienz
Virtuelle Speichernutzung Physische Speichernutzung Kompilierzeit  Heuristiken für komplexe Optimierungsprobleme konträr Korrektheit Übereinstimmung der Programmfunktion von Zwischencode zu Zielcode absolut und höchste Prio LZ-Effizienz: Fähigkeiten der Zielmaschine ausnutzen Virtuelle + physische Speichernutzung: Kapazitäten der Zielmaschine Kompilierzeit: insbesondere beim Debugging, gegenläufig: während obere Ziele auch synergistisch sein können, zu Kzeit konträr Komplexität der Problemstellung häufig NP-schwer Korrektheit als NB, Laufzeit+Kompilierzeit als Zielwerte

10 Speicherhierarchie

11 Speicherhierarchie

12 Registerverwendung Aufgaben Ziel Architekturparameter Registeranzahl
Kernaufgabe Registerverwendung Aufgaben Registerzuteilung Registerauswahl Ziel Totale Lade- und Speicherzeiten minimieren Registertypen erwähnen Registerzuteilung: Welche Variablen in Register ablegen? Registerauswahl: In welches Register Variable ablegen?

13 Instruktionsselektion
Architekturparameter Befehlssatz Kernaufgabe Instruktionsselektion Aufgabe Auswahl von Instruktionskombination Ziel Minimiere totale Instruktionskosten! Beispiel Zwischencode: a := a + 1 Zielcode: LD R, a ADD R, R, #1 ST a, R 1 2 LD R, a INC a ST a, R 1 - Alternativen bei Beibehaltung der Programmsemantik - man kann LD, ADD und ST bestimmte Operationskosten zuordnen (je nach Zielmaschine), wenn INC geringer, dann vorteilhafter ∑ 4 ∑ 3

14 Instruktionsanordnung
Architekturparameter Anzahl der Prozessorkerne Kernaufgabe Instruktionsanordnung Aufgabe Befehlsfolgen reorganisieren Ziele Code-Vereinfachung Bessere Registerausnutzung Parallelisierung unabhängiger Befehle - Parallelisierung: Heute Nachmittag

15 Kernaufgaben und ISA Instruction Set Architecture (ISA)
Complex Instruction Set Computer (CISC) Reduced Set Computer (RISC) Very Long Instruction Word (VLIW) Architekturparameter Registeranzahl Befehlssatz Anzahl der Prozessorkerne Kernaufgaben Registerzuteilung Instruktionsselektion Instruktionsanordnung

16 Abstrakte Zielmaschine - Zielsprache
Notation für Operationen: Bsp.: MUL R3, R1, R2 OP <destination>, <source>, <source>, mit <destination> = Ri | { Kleinbuchstabe } <source> = Ri | „#“ { Ziffer } OP = ADD | SUB | MUL | DIV Ausnahmen: LD R, x ST x, R - Drei-Adress-Operationen - Zielregister und Operandenregister nicht unbedingt disjunkt

17 Abstrakte Zielmaschine
Definition Zielsprache Universalregister: R1, …,Rn Administrative Register separat Adressierungen Repräsentant für viele Klassen von Zielmaschinen n wird für Beispiele gesetzt, am Schluss Generierungsmechanismen für allgemein n Register - Administrativ = Stackpointer hier unberücksichtigt

18 1. Abgrenzung, Motivation, Einordnung 2. Grundlagen 3
1. Abgrenzung, Motivation, Einordnung 2. Grundlagen 3. Code-Repräsentation * Basisblöcke * Flussgraphen * DAG 4. Code-Erzeugung 5. Fazit und weiterführende Themen

19 Code-Repräsentation: Basisblöcke
Strukturierung des Zwischencodes Kontrollfluss Variablenverwendung Basisblock Minimale Sequenz von Instruktionen Blockanfänge definiert durch: Die erste Instruktion des Zwischencodes. Jede direkte Nachfolge-Instruktion eines Sprunges. Jede Zielinstruktion eines (bedingen oder unbedingten) Sprungbefehls.

20 Code-Repräsentation: Basisblöcke
Beispiel a) Die erste Instruktion des Zwischencodes.

21 Code-Repräsentation: Basisblöcke
Beispiel a) Die erste Instruktion des Zwischencodes.

22 Code-Repräsentation: Basisblöcke
Beispiel b) Jede direkte Nachfolge-Instruktion eines Sprunges.

23 Code-Repräsentation: Basisblöcke
Beispiel b) Jede direkte Nachfolge-Instruktion eines Sprunges.

24 Code-Repräsentation: Basisblöcke
Beispiel c) Jede Zielinstruktion eines (bedingen oder unbedingten) Sprungbefehls.

25 Code-Repräsentation: Basisblöcke
Beispiel c) Jede Zielinstruktion eines (bedingen oder unbedingten) Sprungbefehls.

26 Code-Repräsentation: Basisblöcke
Ergebnis

27 Code-Repräsentation: Flussgraphen
gerichteter, zyklischer Graph G=(V,E) mit Knotenmenge V: Menge aller Basisblöcke (Block als Blackbox) Kantenmenge E: e(Bi, Bj) Є E genau dann, wenn: Bj folgt direkt auf Bi in der Programmfolge und Bi ohne unbedingten Sprung. Bj ist Ziel eines Sprungbefehls.

28 Code-Repräsentation: Flussgraphen
Beispiel: a) Bj folgt direkt auf Bi in der Programmfolge und Bi enthält keinen unbedingten Sprung.

29 Code-Repräsentation: Flussgraphen
Beispiel: b) Bj ist Ziel eines Sprungbefehls.

30 Code-Repräsentation: Blockoptimierung mit DAG
Innendarstellung eines Blocks gerichteter, azyklischer Graph (DAG) Ziele Registerausnutzung verbessern Code-Vereinfachung Toten Code eliminieren Elemente Operation Label Registerausnutzung durch neue Instruktionsanordnung verbessern Initiale Variable

31 Code-Repräsentation: Blockoptimierung mit DAG
DAG-Konstruktion a := b * c c := a + d b := a * b Erzeuge - Blatt / Blätter Operationssymbol Kanten Label suche nach b und c in Blätter und Labels, neue als Blätter erzeuge OP mit Kindknoten LR

32 Code-Repräsentation: Blockoptimierung mit DAG
DAG-Konstruktion a := b * c c := a + d b := a * b Erzeuge - Blatt / Blätter Operationssymbol Kanten Label Fall 4 nachträglichFüge a als Label an OP an.

33 Code-Repräsentation: Blockoptimierung mit DAG
DAG-Konstruktion a := b * c c := a + d b := a * b Erzeuge - Blatt / Blätter Operationssymbol Kanten Label Was nutzt mir ein DAG? – folgt!

34 Code-Repräsentation: Blockoptimierung mit DAG
Code-Vereinfachung a := b * c c := a + d b := a * b d := a + d , d a := b * c c := a + d b := a * b d := c Erzeuge - Blätter Operationssymbol Kanten Label Fall 4 nachträglichFüge a als Label an OP an.

35 Code-Repräsentation: Blockoptimierung mit DAG
Lebendigkeit von Variablen Eine Variable x ist lebendig in Anweisung Ai (1 ≤ i < n), wenn: x in Anweisung A1 ein Wert zugewiesen wird, x in Anweisung An als Operand benutzt bzw. gelesen wird, x zwischen A1 und An kein Wert zugewiesen wird. x hat bei Ai die nächste Verwendung in An, wenn An der erste Lesezugriff auf x nach A1 ist. Eine am Basisblockende lebendige Variable heißt live on exit. Einfach: - Ich brauche den Wert von x noch, wenn er noch gelesen wird, ohne vorher überschrieben zu werden. - Wurzel = Keine Operanden für Instruktionen, nur Schreibzugriff

36 Code-Repräsentation: Blockoptimierung mit DAG
Toter Code Instruktionen mit nicht benötigten Ergebnissen Beispiel c, d nicht live on exit Eliminierung: Streiche (iterativ) Wurzelknoten ohne lebendige Variablen Einfach: - Ich brauche den Wert von x noch, wenn er noch gelesen wird, ohne vorher überschrieben zu werden. Wurzel = Keine Operanden für Instruktionen, nur Schreibzugriff

37 1. Abgrenzung, Motivation, Einordnung 2. Grundlagen 3
1. Abgrenzung, Motivation, Einordnung 2. Grundlagen 3. Code-Repräsentation 4. Code-Erzeugung * Elementare Code-Erzeugung * Globale Registerzuteilung * Optimale Code-Erzeugung * Peephole-Optimierung 5. Fazit und weiterführende Themen

38 Elementare Code-Erzeugung
Register-Deskriptor Zuordnungen: Register  Variablennamen Adressen-Deskriptor Zuordnungen: Variablen  Speicheradresse Annahmen für Zielmaschine LD und ST explizit keine globalen Register Variablen mit nächster Verwendung am Blockanfang zu laden live on exit-Variablen zu speichern - explizit: wenn - Liste von Einträgen - Adresse sowohl Register als auch Hauptspeicher

39 Elementare Code-Erzeugung
Hilfsfunktion getReg getReg(B) mit Drei-Adress-Befehl B Für a := b OP c Lade nötige Variablen Führe den Befehl OP Ra, Rb, Rc aus. Fallunterscheidungen für Code-Erzeugung LD R, a ST a, R a := b OP c a := b

40 Elementare Code-Erzeugung
Beispiel: a := b * c Register-Deskriptor Adress-Deskriptor ¬live on exit live on exit Zwischencode Zielcode Regel R1 R2 R3 a b c d

41 Elementare Code-Erzeugung
Register- Deskriptor Adress-Deskriptor ¬lebendig Blockende lebendig Blockende Zwischencode Zielcode Regel R1 R2 R3 a b c d 1. a := b * c 2. LD R1, b 1 b,R1 3. LD R2, c c, R2 a := b OP c (mit den Registern Ra, Rb, Rc) 4.1 Falls b bzw. c nicht im Register, führe LD Rb, b bzw. LD Rc, c aus. […] LD R, a 1.1 Der Inhalt von R im Register-Deskriptor ist durch a zu ersetzen 1.2 Füge im Adress-Deskriptor R zu a hinzu.

42 Elementare Code-Erzeugung
Register- Deskriptor Adress-Deskriptor ¬lebendig Blockende lebendig Blockende Zwischencode Zielcode Regel R1 R2 R3 a b c d 1. a := b * c 2. LD R1, b 1 b,R1 3. LD R2, c c, R2 4. MUL R2, R1, R2 3 c, a 4. a := b OP c (mit den Registern Ra, Rb, Rc) 4.1 Falls b bzw. c nicht im Register, führe LD Rb, b bzw. LD Rc, c aus. 4.2 Der Inhalt von Ra im Register-Deskriptor ist durch a zu ersetzen. 4.3 Der Inhalt von a im Adress-Deskriptor ist durch Ra zu ersetzen. 4.4 Entferne Ra von allen anderen Variablen im Adress-Deskriptor.

43 Elementare Code-Erzeugung
Register- Deskriptor Adress-Deskriptor ¬lebendig Blockende lebendig Blockende Zwischencode Zielcode Regel R1 R2 R3 a b c d 4. MUL R2, R1, R2 3 b,R1 c, R2 5. EXIT 6. ST a, R2 a, R2 b, R1 ST a, R Der Inhalt von a im Adress-Deskriptor ist durch R zu ersetzen.

44 Globale Register Problem Lösung Viele Hauptspeicherzugriffe ST a, R1
LD R1, a Lösung if … then goto …

45 Globale Register Beispiel Betrachte Variable b Lesezugriff LD R, a

46 Globale Register Beispiel Lösung Registerzuteilung?
Betrachte Variable b Lesezugriff LD R, a Schreibzugriff live on exit Lösung Registerinhalte überdauern Basisblöcke Registerzuteilung? Bewertung:

47 Graphfärbung Problem Lebensspanne für ideelle Register
Register voll Registerauswahl? Lebensspanne für ideelle Register Hier: Graph 2-fach färbbar Kollisionen unvermeidbar  Zwischenspeicherung

48 Instruktionsselektion
Idee: Alternative Instruktionskombinationen gleiche Semantik unterschiedliche Kosten

49 Optimale Code-Erzeugung
Ziel Code mit minimaler Registeranzahl Berücksichtigt Registerzuteilung Registerauswahl Instruktionsanordnung Basis Directed Acyclic Graph (DAG) Procedere: Annotiere Ershov-Nummern an Graph-Knoten Führe Generierungsalgorithmus aus

50 Optimale Code-Erzeugung
Ershov-Nummer für Knoten v: val(v) =

51 Optimale Code-Erzeugung
Ershov-Nummer für Knoten v: val(v) = 1 1 1

52 Optimale Code-Erzeugung
Ershov-Nummer für Knoten v: val(v) = 2 1 1 1

53 Optimale Code-Erzeugung
Ershov-Nummer für Knoten v: val(v) = 3 2 2 2 1 1 1

54 Optimale Code-Erzeugung
gencode-Algorithmus gencode(v, b) if v hat Kindknoten vl, vr mit label(vl) = label(vr) then 1.1 k := label(vl) 1.2 Rb+k := gencode(vr, b+1) 1.3 Rb+k-1 := gencode(vl, b) 1.4 print(name(v), Rb+k, Rb+k-1, Rb+k) else if v hat Kindknoten vl, vr mit label(vl) < label(vr) then 2.1 k := label(vr) 2.2 Rb+k-1 := gencode(vr, b) 2.3 m := label(vl) 2.4 Rb+m-1 := gencode(vl, b) 2.5 print(name(v), Rb+k-1, Rb+m-1, Rb+k-1) else if v hat Kindknoten vl, vr mit label(vl) > label(vr) then 3.1 k := label(vl) 3.2 Rb+k-1 := gencode(vl, b) 3.3 m := label(vr) 3.4 Rb+m-1 := gencode(vr, b) 3.5 print(name(v), Rb+k-1, Rb+k-1, Rb+m-1) else // v ist Blattknoten 4.1 print(„LD“, Rb, name(v)) Beispiel f Regel Code v b vl vr k R1 R2 R3 a) k := label(v1) v1 1 v2 v3 3 b) R3:= gencode(v1, 1) 1.1 k := label(v2) 2 1.2 R3 := gencode(v3, 2)    3.1 k := label(v4) v4 v5    3.2 R3 := gencode(v4, 2)       1.1 k := label(v6) v6 v7       1.2 R3 := gencode(v7, 3) -          4.1 print(„LD“, R3, c) c0       1.3 R2 := gencode(v6, 2) print(„LD“, R2, b) b0       1.4 print(„MUL“, R3, R2, R3) a    3.3 m := label(v5) // m := 1    3.4 R2 := gencode(v5, 2)       4.1 print(„LD“, R2, d) d0    3.5 print(„ADD“, R3, R2, R3) d 1.3 R2 := gencode(v2, 1)    2.1    2.2 R2 := gencode(v4, 2)

55 Optimale Code-Erzeugung
gencode Regel Code v b vl vr k R1 R2 R3 3 2 2 LD R3, c LD R2, b 2 1 - laufe größere Teilbäume entlang 1 1

56 Optimale Code-Erzeugung
3 2 2 MUL“, R3, R2, R3 2 1 1 1

57 Optimale Code-Erzeugung
3 3 2 2 2 2 2 2 1 1 1 1 1 1

58 Peephole Optimization
Problem Komplexität Idee Lokale Suche im “Gucklock” Beispiel Viele Hauptspeicherzugriffe ST a, R1 LD R1, a c := a * b d := a + d e := c + d a := b * c ST a, R1 LD R1, a

59 1. Abgrenzung, Motivation, Einordnung 2. Grundlagen 3
1. Abgrenzung, Motivation, Einordnung 2. Grundlagen 3. Code-Repräsentation * Basisblöcke * Flussgraphen 4. Code-Erzeugung 5. Fazit und weiterführende Themen

60 Fazit Gelöst Ansätze Offen Elementare Codeerzeugung
Erzeugung mit minimaler Registeranzahl Ansätze Registerverwendung Instruktionsselektion Instruktionsanordnung Offen Erweiterte Heuristiken Parallelisierung Just-In-Time-Compilation

61 Diskussion

62 BACKUP Code-Repräsentation DAG-Konstruktion
Für jeden Drei-Adress-Befehl der Form a := b OP c eines Basisblocks B: Suche nach Vorkommen von b und c in Blättern, Knoten und Labels des Graphs (dies entspricht einer vorigen Benutzung der Variablen). Erzeuge für nicht existierende Variablen neue Blätter mit ihrem Variablennamen und dem Index 0 als Kennzeichnung der Erstverwendung. Erzeuge für OP einen Knoten mit dem Operationssymbol und setze b als linken, c als rechten Kindknoten für OP. Füge a als Label an OP an.

63 Elementare Code-Erzeugung
BACKUP Elementare Code-Erzeugung Eintragung in die Deskriptoren LD R, a 1.1 Der Inhalt von R im Register-Deskriptor ist durch a zu ersetzen. 1.2 Füge im Adress-Deskriptor R zu a hinzu. ST a, R Der Inhalt von a im Adress-Deskriptor ist durch R zu ersetzen. a := b OP c (mit den Registern Ra, Rb, Rc) 3.1 Falls b bzw. c nicht im Register, führe LD Rb, b bzw. LD Rc, c aus. 3.2 Der Inhalt von Ra im Register-Deskriptor ist durch a zu ersetzen. 3.3 Der Inhalt von a im Adress-Deskriptor ist durch Ra zu ersetzen. 3.4 Entferne Ra von allen anderen Variablen im Adress-Deskriptor. a := b (mit den Registern Ra, Rb) 4.1 Falls b nicht im Register, führe LD Rb, b aus (siehe 1.). 4.2 Der Inhalt von Rb im Register-Deskriptor ist durch a zu ergänzen. 4.3 Der Inhalt von a im Adress-Deskriptor ist durch Rb zu ersetzen.

64 Elementare Code-Erzeugung
BACKUP Elementare Code-Erzeugung Register-Deskriptor Adress-Deskriptor ¬lebendig Blockende lebendig Blockende Zwischencode Zielcode Regel R1 R2 R3 a b c d 1. a := b * c 2. LD R1, b 1 b,R1 3. LD R2, c c,R2 4. MUL R2, R1, R2 3 5. c := a + d 6. LD R3, d 7. ADD R3, R2, R3 8. EXIT 9. ST c, R1 c,d c,R1 10. ST d, R3 d,R3

65 Elementare Code-Erzeugung
BACKUP Elementare Code-Erzeugung Register-Deskriptor Adress-Deskriptor ¬lebendig Blockende lebendig Blockende Zwischencode Zielcode Regel R1 R2 R3 a b c d 10. ST d, R3 c,d c,R1 d,R3 11. MUL R1, R2, R1 3 b,R1 12. EXIT 13. ST c, R1 14. 15.

66 Optimale Codeerzeugung
BACKUP Optimale Codeerzeugung Funktionsaufruf: a) k := label(vroot) b) Rk := gencode(vroot, 1) Funktionsdeklaration: gencode(v, b) 1. if v hat Kindknoten vl, vr mit label(vl) = label(vr) then 1.1. k := label(vl) 1.2. Rb+k := gencode(vr, b+1) 1.3. Rb+k-1 := gencode(vl, b) 1.4. print(name(v), Rb+k, Rb+k-1, Rb+k) 2. else if v hat Kindknoten vl, vr mit label(vl) < label(vr) then 2.1. k := label(vr) 2.2. Rb+k-1 := gencode(vr, b) 2.3. m := label(vl) 2.4. Rb+m-1 := gencode(vl, b) 2.5. print(name(v), Rb+k-1, Rb+m-1, Rb+k-1) 3. else if v hat Kindknoten vl, vr mit label(vl) > label(vr) then 3.1. k := label(vl) 3.2. Rb+k-1 := gencode(vl, b) 3.3. m := label(vr) 3.4. Rb+m-1 := gencode(vr, b) 3.5. print(name(v), Rb+k-1, Rb+k-1, Rb+m-1) 4. else // v ist Blattknoten 4.1. print(„LD“, Rb, name(v))

67 Optimale Codeerzeugung
BACKUP Optimale Codeerzeugung Regel Code v b vl vr k R1 R2 R3 a) k := label(v1) v1 1 v2 v3 3 b) R3:= gencode(v1, 1) 1.1 k := label(v2) 2 1.2 R3 := gencode(v3, 2)    3.1 k := label(v4) v4 v5    3.2 R3 := gencode(v4, 2)       1.1 k := label(v6) v6 v7       1.2 R3 := gencode(v7, 3) -          4.1 print(„LD“, R3, c) c0       1.3 R2 := gencode(v6, 2) print(„LD“, R2, b) b0       1.4 print(„MUL“, R3, R2, R3) a    3.3 m := label(v5) // m := 1    3.4 R2 := gencode(v5, 2)       4.1 print(„LD“, R2, d) d0    3.5 print(„ADD“, R3, R2, R3) d 1.3 R2 := gencode(v2, 1)    2.1    2.2 R2 := gencode(v4, 2)

68 Optimale Codeerzeugung
BACKUP Optimale Codeerzeugung siehe Schritte 6-12 mit b=1 .    2.3 m := label(v6) // m := 1 v2 1 v6 v4 2 b0 a d    2.4 R1 := gencode(v6, 1)       4.1 print(„LD“, R1, b) -    2.5 print(„MUL“, R2, R1, R2) c 1.4 print(„ADD“, R3, R2, R3) v1 v3 e


Herunterladen ppt "1. Abgrenzung, Motivation, Einordnung 2. Grundlagen 3"

Ähnliche Präsentationen


Google-Anzeigen