Generowanie kodu pośredniego Java ML Pascal C C++ Alpha Pentium Sparc Java ML Pascal C C++ Alpha Pentium Sparc MIPS IR IR – intermediate representation.

Slides:



Advertisements
Podobne prezentacje
Tablice 1. Deklaracja tablicy
Advertisements

I część 1.
C++ wykład 2 ( ) Klasy i obiekty.
C++ wykład 4 ( ) Przeciążanie operatorów.
Egzamin.
Język C/C++ Funkcje.
Programowanie obiektowe
Prowadzący: mgr inż. Elżbieta Majka
Wykład 06 Metody Analizy Programów System Hoare
Wykład 6 Najkrótsza ścieżka w grafie z jednym źródłem
Wprowadzenie do języka skryptowego PHP – cz. 2
Języki programowania C++
typy całkowite (całkowitoliczbowe)
PROGRAMOWANIE STRUKTURALNE
PROGRAMOWANIE STRUKTURALNE
PROGRAMOWANIE STRUKTURALNE
Generator analizatorów składniowych
Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 7: Procedury i funkcje © Jan Kaczmarek.
Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 6: Tablice, rekordy, zbiory.
ODE Triggery. Wstęp n Triggery są trójką zdarzenie-warunek-akcja (event-condition- action). n Zdarzenia mogą być proste lub złożone, co zostanie omówione.
Programowanie imperatywne i język C Copyright, 2004 © Jerzy R. Nawrocki Wprowadzenie.
Programowanie imperatywne i język C
Programowanie imperatywne i język C Copyright, 2004 © Jerzy R. Nawrocki Wprowadzenie.
Podstawy informatyki Wirtotechnologia – Wskaźniki i referencje
Podstawy informatyki Rekurencja i rekurencja Grupa: 1A
Podstawy informatyki Powtórka Grupa: 1A Prowadzący: Grzegorz Smyk
Podstawy informatyki Rekurencja i rekurencja Grupa: 1A
Kurs Pascala – spis treści
Tablice Informatyka Cele lekcji: Wiadomości: Uczeń potrafi:
Ogólne jednostki programowe 1
Tablice jednowymiarowe 1
Java – programowanie obiektowe
nowe operatory & . (kropka) * operator rzutowy -> , (przecinek)
AWK Zastosowania Informatyki Wykład 1 Copyright, 2003 © Adam Czajka.
Programowanie imperatywne i język C Copyright, 2006 © Jerzy R. Nawrocki Wstęp do.
Podstawy programowania
Podstawy programowania II
O relacjach i algorytmach
Podstawy programowania
Podstawy programowania
Programowanie w języku Matlab
Programowanie strukturalne i obiektowe
A ctive S erver P ages Technologia dostępu do danych.
Funkcje w Pascalu Przypomnienie wiadomości o procedurach Prowadzący: Anna Kaleta Piotr Chojnacki.
TABLICE C++.
Wyrażenia w Turbo Pascalu.
Podstawy programowania w języku C i C++
Programowanie obiektowe – zastosowanie języka Java SE
Dziedziczenie Maciek Mięczakowski
Inicjalizacja i sprzątanie
Rozwiązanie zadań do zaliczenia I0G1S4 // indeks
Podstawy informatyki 2013/2014
Model relacyjny.
MOiPP Wykład 3 Matlab Przykłady prostych metod obliczeniowych.
Zajęcia I Organizacja zajęć Rejestracja i uruchamianie makr
Podstawy języka Instrukcje - wprowadzenie
Programowanie strukturalne i obiektowe C++
Model obiektowy bazy danych
Generowanie kodu pośredniego
Treści multimedialne - kodowanie, przetwarzanie, prezentacja Odtwarzanie treści multimedialnych Andrzej Majkowski informatyka +
Programowanie proceduralne Podstawy Programowania dla geoinformatyków Wykład 3 Rafał Witkowski, 2015.
Programowanie imperatywne i język C Copyright, 2007 © Jerzy R. Nawrocki Wstęp do.
Podsumowanie wiedzy MPDI2 sem.3 INFORMATYKA. tworzenie nowego pliku i katalogu, nawigacja po katalogach, listowanie zawartości katalogu, zmiana nazw,
Seminarium Dyplomowe: Metodyka i Techniki Programowania Autor: Bartłomiej Fornal.
Instrukcje warunkowe w php. Pętla FOR Czasem zachodzi potrzeba wykonania jakiejś czynności określoną ilość razy. Z pomocą przychodzi jedna z najczęściej.
Tryby adresowania i formaty rozkazów mikroprocesora
PHP jest językiem skryptowym służącym do rozszerzania możliwości stron internetowych. Jego składnia jest bardzo podobna do popularnych języków programowania.
Wstęp do programowania Wykład 2 Dane, instrukcje, program.
Wstęp do Informatyki - Wykład 6
Haskell Składnia funkcji.
Zapis prezentacji:

Generowanie kodu pośredniego Java ML Pascal C C++ Alpha Pentium Sparc Java ML Pascal C C++ Alpha Pentium Sparc MIPS IR IR – intermediate representation

Cechy kodu pośredniego Z poprzedniej strony wynikają różne ważne wnioski m.in. - nawet gdy nasz kompilator ma tylko jeden front-end i tylko jedną maszynę docelową to warto starannie dobrać sposób reprezentowania kodu pośredniego, - kod pośredni powinien być łatwy w produkcji, - powinno się zapewnić łatwą translację na kod realnej maszyny docelowej, - każda konstrukcja powinna mieć jasne i proste znaczenie (ma to znaczenie dla procesu ulepszania kodu) Kod pośredni w

Drzewa jako reprezentacja kodu Oczywiście, można uznać, że reprezentacją kodu jest drzewo składniowe. Kod pośredni w assign | | id a + | | * | | id b uminus | | id c * | | id b uminus | | id c a := b*-c + b*-c

Drzewa jako reprezentacja kodu II Oczywiście, można uznać, że reprezentacją kodu jest drzewo składniowe. Przestaje to być zaskakujące gdy drzewo takie zapiszemy liniowo. Kod pośredni w assign | | id a + | | * | | id b uminus | | id c * | | id b uminus | | id c 0 id b 1 id c 2 uminus 1 3 * id b 5 id c 6 uminus 1 7 * id a 10 assign

Dagi jako reprezentacja kodu Zamiast drzew możemy użyć dagów tzn directed acyclic graphs czyli grafów skierowanych acyklicznych. Kod pośredni w assign | | id a + | | * | | id b uminus | | id c 0 id b 1 id c 2 uminus 1 3 * id a 6 assign 9 8 7

“Czwórki” czyli kod trójadresowy Po udekorowaniu drzewa składniowego odpowiednimi atrybutami np. typy, offsety nazw lokalnych, apetyt na wielkości tymczasowe,... można zapisać drzewo (lub dag) w postaci liniowej. Kod czwórkowy jest ciągiem instrukcji o jednej operacji op i trzech adresach. Ogólna postać instrukcji jest: x := y op z x, y i z są stałymi, nazwami albo wygenerowanymi przez kompilator zmiennymi tymczasowymi bądź etykietami, op oznacza operator arytmetyczny, relacyjny bądź logiczny. Kod pośredni w

Repertuar instrukcji trójadresowych 1 instrukcje przypisania x := y op z 2 instrukcje przypisania x := op z 3 instrukcje kopiujące x := y 4 skoki bezwarunkowe goto L 5 skoki warunkowe if x oprel y goto L 6 instrukcje sekwencji wywołujących param x i call p, n oraz return y 7 operacje na tablicach x :=a[i] oraz a[i] := x 8 operacje na wskaźnikach x := &y, x := *y, *x :=y ____ Jest to przykład. Zestaw operatorów i repertuar instrukcji zależy od języka źródłowego i od zbioru maszyn docelowych. Kod pośredni w

Przykład Generowanie kodu pośredniego może odbywać się dzięki akcjom semantycznym operującym na atrybutach węzłów drzewa składniowego. Gramatyka S  id:=E E  E 1 +E 2 E  E 1 * E 2 E  - E 1 E  (E 1 ) E  id Atrybutami nieterminali niech będą E.pozycja i E.kod oraz S.kod. Metoda nowatymcz obiektu g klasy GeneratorTymcz zwraca w kolejnych wywołaniach nowe nazwy t 1, t 2,... Kod pośredni w

Przykład c.d. Produkcja Reguła semantyczna S  id:=E S.kod := E.kod ^ gen( id.pozycja ':=' E.pozycja E  E 1 +E 2 E.pozycja := g.nowatymcz; E.kod := E 1.kod ^ E 2.kod ^ gen(E.pozycja ':=' E 1.pozycja '+' E 2.pozycja) E  E 1 * E 2 E.pozycja := g.nowatymcz; E.kod := E 1.kod ^ E 2.kod ^ gen(E.pozycja ':=' E 1.pozycja '*' E 2.pozycja) E  - E 1 E.pozycja := g.nowatymcz; E.kod := E 1.kod ^ gen(E.pozycja ':=' '-' E 2.pozycja) E  (E 1 ) E.pozycja := E 1.pozycja; E.kod := E 1.kod E  id E.pozycja := id.pozycja; R.kod := ' ' Kod pośredni w

Przykład - zastosowanie Zastosowanie tych produkcji wraz z odpowiadającymi im regułom semantycznym daje dla drzewa składniowego ze str. 3 następujący ciąg instrukcji kodu pośredniego t1 := - c t2 := b * t1 t3 := - c t4 := b * t3 t5 := t2 + t4 a := t5 Uwaga. W większości kompilatorów kod taki zapisywany jest na pliku. Kod pośredni w

Kod instrukcji sterujących Zobaczmy jak wygląda generowanie kodu pośredniego dla instrukcji while. Potrzebne nam są teraz dwa atrybuty: S.początek i S.wyjście. Produkcja Reguła semantyczna S  while E do S 1 S.początek := nowaEtykieta; S.wyjście := nowaEtykieta; S.kod := gen(S.początek ':') ^ E.kod ^ gen('if' E.pozycja=0 'goto' S.wyjście) ^ S1.kod ^ gen('goto' S.początek) ^ gen(S.wyjście ':') Daje to następujący obraz Kod pośredni w

Kod instrukcji sterujących II Kod pośredni w S.początek: S.wyjście: E.kod if E.pozycja = 0 goto S.wyjście S 1.kod goto S.początek

Metoda genkod w obiektach-węzłach Jest oczywiste, że tworząc kod pośredni przy pomocy metod programowania obiektowego jesteśmy skłonni raczej posłużyć się metodami wirtualnymi niż wykorzystywać reguły semantyczne. Istota algorytmu pozostaje bez zmian, inaczej tylko go zapisujemy. W każdej podklasie klasy Expression deklarujemy odpowiednią metodę genkod w taki sposób, że w klasach Suma i Iloczyn pojawią się metody genkod różniące się wygenerowaną instrukcją trójadresową: gen(E.pozycja ':=' E 1.pozycja '+' E 2.pozycja) w węźle sumy, i gen(E.pozycja ':=' E 1.pozycja '*' E 2.pozycja) w węźle iloczynu. Kod pośredni w

Szkic obiektowego generowania kodu class Expression () { Expression left, right; KodPośredni kod; Adres pozycja; void genkod(){} } // Expression; class Suma extends Expression() { void genkod() { left.gencod(); right.gencod(); t = g.nowaTymczas; gen('t := left.pozycja '+' right.pozycja); } } // Suma class Iloczyn extends Expression () { // podobnie } Kod pośredni w

Oszczędne używanie nazw tymczasowych Możemy przyjąć, że szafujemy nazwami tymczasowymi bez ograniczeń, że jest ich dowolnie dużo do naszej dyspozycji. Tak postępujemy w przypadku kompilatorów optymalizujących bo... Możliwe są dwa podejścia: najpierw wygenerować wiele nazw tymczasowych, a potem umieszczać kilka nazw tymczasowych pod jednym adresem – sprowadza się to do kolorowania pewnego grafu. Inne podejście polega na obserwacji, że wiele nazw tymczasowych jest tworzonych dla jednokrotnego wykorzystania. Przykład oblicz wartość wyrażenia E1 i zapisz w t1 oblicz wartość wyrażenia E2 i zapisz w t2 t3 := t1 + t2 Te zmienne nie będą używane w żadnym innym miejscu programu! Kod pośredni w

Przykład dyscypliny stosowej Rozpatrzmy instrukcję x := a*b+c*d-e*f Przyjmijmy, że zmienne tymczasowe mają tę samą szerokość. Utrzymujemy licznik zmiennych tymczasowych L. Za każdym razem gdy potrzebna jest nowa zmienna użyjemy nazwy $L. Za każdym razem gdy użyjemy zmiennej tymczasowej zmniejszamy licznik o jeden L := L-1. Instrukcja Wartość L 0 $0:=a*b 1 $1:=c*d 2 $0:=$0+$1 1 użyto dwu zmiennych jako argumentów $1:=e*f 2 $0:=$0-$1 1 x := $0 0 Kod pośredni w

Adresowanie elementów w tablicy W niemal każdym języku programowania elementy w tablicy zajmują kolejne miejsca w pamięci. Wynika stąd, że można szybko do nich dotrzeć element jego adres A[i] baza+(i – lower(A) * w gdzie baza – adres pamięci zarezerwowanej dla tablicy w - szerokość elementu w tablicy A, zależy od typu, lower(A) – dolne ograniczenie indeksów tablicy A UWAGA. Kompilator, który nie dodaje sprawdzenia zakresu indeksu i jest niedobrym produktem. Dlaczego? Jak to zrobić? Kod pośredni w

Adresowanie tablic dwuwymiarowych W wielu kompilatorach tablice dwuwymiarowe umieszczane są w tablicy jednowymiarowej. Zachodzą wtedy dwa wypadki: tablica przechowywana jest wierszami np. Pascal, C, albo A[i,j] ma adres baza+((i-dół wierszy )*n2+j-dół kolumn )*w gdzie n2 = góra kolumn – dół kolumn +1 baza = adres początku tablicy w pamięci, tablica przechowywana jest kolumnami np. Fortran. A[i,j] baza+((j-dół kolumn )*n1+i-dół wierszy )*w Zauważ, że zastosowano schemat Hoernera, co jest ważne w przypadku tablic więcej wymiarowych. Kod pośredni w

Adresowanie tablic dwuwymiarowych II W Loglanie i w Javie tablice są obiektami pewnego rodzaju. Tablice jednowymiarowe adresuje się tak samo. Tablice dwu- i więcej wymiarowe traktuje się jak tablice jednowymiarowe tablic o n-1 wymiarach. Czyli zapis A[i,j] jest skrótem dla A[i][j] Kod pośredni w

Tworzenie kodu dla wyrażeń logicznych Kod pośredni w

Instrukcje sterujące Kod pośredni w

Wyra żeniia logiczne realizowane przez skoki warunkowe Kod pośredni w

Backpatching p Kod pośredni w

Wywołania procedur Rozważmy gramatykę instrukcji procedury S  call id ( Elist) Elist  Elist, E | E Jak pamiętamy z poprzedniego wykładu instrukcja procedury tłumaczy się na sekwencję wywołującą złożoną z ciągu poleceń obliczających kolejne parametry aktualne i przekazujących je instrukcją param x, oraz z instrukcji call p, n która wywołuje procedurę biblioteki wspomagania przetwarzania (run-time system, lub maszyna wirtualna). Polecenie call ma dwa argumenty: pierwszym jest informacja związana z nazwą procedury, drugim jest liczba n przekazywanych argumentów. Kod pośredni w

Wywołania procedur II Rozpatrzmy prosty przykład: instrukcja procedury postaci id(E, E,...,E) załóżmy, że parametry są przekazywane przez referencję trzeba więc wygenerować kod pośredni prowadzący do obliczenia tych argumentów, które nie są nazwami prostymi, a po nich umieścić instrukcje param, po jednej dla każdego argumentu. Można to zrobić posługując się kolejką. Akcja semantyczna dla Elist -> Elist będzie zawierała krok zapamiętujący atrybut E.pozycja w kolejce kolejka. Akcja semantyczna dla S -> call id (Elist) wygeneruje instrukcję param dla każdego elementu z kolejka Kod pośredni w

Wywołania procedur III p Kod pośredni w

p p Kod pośredni w