signature GRAPH = sig structure S : ORD SET type node = S.Key.ord key type graph val succ: graph ->node ->S.set val pred: graph ->node ->S.

Podobne dokumenty
Wstęp do programowania. Różne różności

Problem 1 prec f max. Algorytm Lawlera dla problemu 1 prec f max. 1 procesor. n zadań T 1,..., T n (ich zbiór oznaczamy przez T )

Wstęp do programowania. Drzewa. Piotr Chrząstowski-Wachtel

INSTRUKCJA PUSTA. Nie składa się z żadnych znaków i symboli, niczego nie robi. for i := 1 to 10 do {tu nic nie ma};

structure foo :>PART ONE = struct exception NotImplemented datatype a tree= Leaf of a Node of a tree * a * a tree = raise NotImplemented ...

Sztuczna Inteligencja i Systemy Doradcze

Wstęp do Programowania potok funkcyjny

DIAGRAMY SYNTAKTYCZNE JĘZYKA TURBO PASCAL 6.0

Programowanie obiektowe i C++ dla matematyków

Grafem nazywamy strukturę G = (V, E): V zbiór węzłów lub wierzchołków, Grafy dzielimy na grafy skierowane i nieskierowane:

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

Opis: Instrukcja warunkowa Składnia: IF [NOT] warunek [AND [NOT] warunek] [OR [NOT] warunek].

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Funkcje w PL/SQL Funkcja to nazwany blok języka PL/SQL. Jest przechowywana w bazie i musi zwracać wynik. Z reguły, funkcji utworzonych w PL/SQL-u

Maszyna stanu State Machine

Wstęp do Programowania potok funkcyjny

Analiza algorytmów zadania podstawowe

Procedury i funkcje składowane

Laboratorium 10 Temat: Zaawansowane jednostki testowe. Operacje na plikach. Funkcje.

Indukowane Reguły Decyzyjne I. Wykład 3

procesów Współbieżność i synchronizacja procesów Wykład prowadzą: Jerzy Brzeziński Dariusz Wawrzyniak

Programowanie w Ruby

Wstęp do Programowania potok funkcyjny

structure foo :>PART TWO = struct exception NotImplemented datatype a tree = Leaf of a Node of a tree * a * a tree 1

Programowanie w Ruby

Wstęp do Programowania potok funkcyjny

Wstęp do programowania

Kurs języka Python Wykład 8. Przetwarzanie tekstu Wyrażenia regularne Biblioteka urllib Parsowanie html'a XML

Wstęp do Programowania potok funkcyjny

Język PL/SQL Procedury i funkcje składowane

Składowane procedury i funkcje

Zastosowanie CP-grafów do generacji siatek

Semantyka i Weryfikacja Programów - Laboratorium 3

XML extensible Markup Language 7

Procedury. int mult (int mcand, int mlier){ int product = 0; while (mlier > 0) { product = product + mcand; mlier = mlier -1; } return product; }

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Programowanie i struktury danych

Badania operacyjne: Wykład Zastosowanie kolorowania grafów w planowaniu produkcji typu no-idle

Algorytm obejścia drzewa poszukiwań i zadanie o hetmanach szachowych

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Podstawowe algorytmy i ich implementacje w C. Wykład 9

System operacyjny Linux

Tablice cz. I Tablice jednowymiarowe, proste operacje na tablicach

Język PL/SQL. Rozdział 5. Pakiety podprogramów. Dynamiczny SQL

Serwery Statefull i Stateless

Wstęp do programowania. Listy. Piotr Chrząstowski-Wachtel

Grafowe języki zapytań. Anna Kosieradzka

NS-2. Krzysztof Rusek. 26 kwietnia 2010

Ćwiczenia 2 IBM DB2 Data Studio

TEMAT : KLASY DZIEDZICZENIE

5. OKREŚLANIE WARTOŚCI LOGICZNEJ ZDAŃ ZŁOŻONYCH

Język programowania PASCAL

Ćwiczenia 9: Zarządzanie konfiguracją Zadania:

Podstawy programowania w Pythonie

w PL/SQL bloki nazwane to: funkcje, procedury, pakiety, wyzwalacze

Elementy języka C. ACprogramislikeafastdanceonanewlywaxeddancefloorbypeople carrying razors.

ASP.NET MVC. Podstawy. Zaawansowane programowanie internetowe Instrukcja nr 3

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec

Funkcje są prawdopodobnie najważniejszą częścią każdego poważnego programu (w każdym języku programowania).

Sortowanie topologiczne skierowanych grafów acyklicznych

Zaawansowane aplikacje WWW - laboratorium

Podstawy programowania

Klasy i obiekty cz II

Wykład 9 Funktory (moduły sparametryzowane)

Optimizing Programs with Intended Semantics

- nawiasy kwadratowe oznaczają, że to lista

Nazwa implementacji: Nauka języka Python wyrażenia warunkowe. Autor: Piotr Fiorek. Opis implementacji: Poznanie wyrażeń warunkowych if elif - else.

Języki programowania, wtorek , 12:15-13:45 Zadanie 11 - ostatnie

Analiza konstrukcji zawierających wskaźniki. Piotr Błaszyński

Pascal typy danych. Typy pascalowe. Zmienna i typ. Podział typów danych:

Listy powiązane zorientowane obiektowo

Wstęp do Informatyki i Programowania Laboratorium: Lista 0 Środowisko programowania

Zaawansowany kurs języka Python

Java Podstawy. Michał Bereta

Operatory logiczne. Podstawowe operatory logiczne, składanie wyrażeń z użyciem operatorów logicznych

Porządek dostępu do zasobu: procesory obszary pamięci cykle procesora pliki urządzenia we/wy

Algorytmy i Struktury Danych.

Wydział Zarządzania AGH. Katedra Informatyki Stosowanej. Instrukcje sterujące. Programowanie komputerowe

Programowanie obiektowe

Bazy danych wykład dwunasty PL/SQL, c.d. Konrad Zdanowski ( Uniwersytet Kardynała Stefana Bazy danych Wyszyńskiego, wykładwarszawa)

Przykładowe B+ drzewo

Wykład 5 funkcje i procedury pamiętane widoki (perspektywy) wyzwalacze

Podstawy programowania

Systemy operacyjne. Zajęcia 11. Monitory

POCZTA POLSKA. v Strona 1 z 9

Obsługa błędów w SQL i transakcje. Obsługa błędów w SQL

Porządek symetryczny: right(x)

Języki i techniki programowania Ćwiczenia 2

Przydatne sztuczki - sql. Na przykładzie postgres a.

Bloki anonimowe w PL/SQL

Obliczenia, zmienne. Proste działania, zmienne, rodzaje zmiennych, proste operacje i działania na zmiennych.

Problem Próby rozwiązania Maszyna stanów Inne zastosowania Podsumowanie. Maszyny stanów. Programowanie gier bez Unity, cz. 3.

BAZA DANYCH SIECI HOTELI

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Wykład 15. Literatura. Kompilatory. Elementarne różnice. Preprocesor. Słowa kluczowe

Część 4 życie programu

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

2.1. W architekturze MIPS, na liście instrukcji widzimy dwie instrukcje dotyczące funkcji: .text main: la $a0, string1 # drukuj pierwszy łańcuch

Algorytmy i struktury danych. Drzewa: BST, kopce. Letnie Warsztaty Matematyczno-Informatyczne

Transkrypt:

Zadanie domowe 6 Analiza żywotności kodu. W tym zadaniu zajmiemy się zaimplementowaniem analizatora żywotności dla programów pisanych w MIPS-ie. Załóżcie nowy katalog lab6 i skopiujcie do niego całą zawartość katalogu lab5. Następnie ściągnijcie plik www.math.us.edu.pl/ pgladki/teaching/2013-2014/tk lab6.zip i rozpakujcie go; w szczególności znajdziecie tam pliki graph.sig, graph.sml i liveness.sml. Zmodyfikujcie w odpowieni sposób plik sources.cm. Zaimplementujcie funkcję analyze w liveness.sml. Dodajcie linię kodu do Waszego pliku compile.sml która będzie wywoływać analizę żywotności dla każdej funkcji w Waszym Mips.program (w szczególności main, alloc, printint). Zdebugujcie poprzez sprawdzenie wyjścia diagnostycznego drukowanego przez Liveness.interference graph Prześlijcie mailem pliki README oraz liveness.sml. Termin zadania mija w czwartek, 23 stycznia. Proszę pamiętać o oznaczeniu maila tagiem [aghtk]. Moduł Graph Przeczytajcie dokładnie plik graph.sig. Zwróćcie uwagę, że różni się dość istotnie od pliku opisanego w Section 10.2 w podręczniku. signature GRAPH = sig structure S : ORD SET type node = S.Key.ord key type graph val succ: graph ->node ->S.set val pred: graph ->node ->S.set val adj: graph ->node ->S.set val newgraph: unit ->graph val mk edge: graph ->from: node, to: node ->unit val rm edge: graph ->from: node, to: node ->unit val nodes: graph ->S.set end 1

2 Grafy bazują na abstrakcji ORD SET z biblioteki SML/NJ. Węzeł to po prostu dowolny typ porządkowy, którego relacja porządkująca dana jest przez S.compare. Dla grafów interferencji rejestrów, używamy node=mips.reg (to znaczy S=Mips.RegSet). Niech IG będzie wystąpieniem sygnatury GRAPH w której IGS=Mips.RegSet, to znaczy mamy dany graf rejestrów. W ML-u opisujemy go następująco: structure IG: GRAPH where S=Mips.RegSet i na tym etapie powinniście zauważyć, że dokładnie ta linia pojawia się w sygnaturze LIVENESS. Aby skonstruować strukturę IG, stosujemy funktor OrdGraph z graph.sml w następujący sposób: structure IG = Graph(Mips.RegSet i możecie zauważyć, że zostało to już zrobione w liveness.sml. Mając dany graf g możemy skonstruować zbiór wszystkich jego węzłów IG.nodes(g). Możemy teraz uzyskać zbiór wszystkich następników węzła n (to znaczy węzłów x, dla których istnieje krawedź od n do x) wywołując IG.succgn. Podobnie można wywołać zbiór wszystkich poprzedników węzła n poprzez IG.predgn, oraz wszystkie węzły sąsiadujące (czyli następniki razem z poprzednikami) przez IG.adjgn, co z kolei jest równoważne wywołaniu IG.S.union(IG.predgn, IG.succgn) (i, przy okazji, IG.S.union to to samo, co Mips.RegSet.union). Grafy mogą być modyfikowane destruktywnie za pomocą operatorów mk edge oraz rm edge. Chcąc stworzyć nowy, pusty graf, wywołujemy IG.newGraph(). Chcąc teraz dodać krawędź (x, y), wywołujemy IG.mk edge{from = x, to = y}; jeśli krawędź taka już istnieje, wywołanie to nie będzie miało żadnego efektu. Chcąc z kolei usunąć krawędź (x, y) wywołujemy IG.rm edge{from = x, to = y} i, podobnie, jeśli nie ma już tej krawędzi, wywołanie nie przyniesie żadnego efektu. Pytania i odpowiedzi: Pyt.: Dla grafów interferencji potrzebujemy przecież grafów nieskierowanych, a ten jest skierowany... Odp.: Aby dodać krawędź, możecie wybrać dowolny kierunek. Dla zapytań wykorzystajcie funkcję adj. Pyt.: Czy w grafie mogą pojawić się węzły, do których nie prowadzą żadne krawędzie? Odp.: Tak. Pyt.: Jak dodać węzeł, do którego nic nie prowadzi? Odp.: Na przykład poprzez IG.succgx. Pyt.: Ale to mało eleganckie... Odp.: Cóż... https://www.youtube.com/watch?v=mgbjg4gcehq Moduł Liveness Waszym zadaniem będzie zaimplementowanie analizy żywotności. W liveness.sml znajdziecie następującą sygnaturę: signature LIVENESS = sig structure IG: GRAPH where S=Mips.RegSet val analyze: mention: Mips.reg ->unit, interfere: Mips.reg ->Mips.reg ->unit -> Mips.funcode ->unit val interference graph: Mips.funcode ->IG.graph

3 val printgraph: (string->unit) ->IG.graph ->unit end Funkcja analyze przyjmuje na wejściu listę podstawowych bloków i ma zgłosić wszystkie zmienne, jakie się pojawiają i wszelkie interferencje pomiędzy nimi. Robi to wywołując mention na każdym rejestrze i pseudorejestrze jaki jest w dowolnej chwili użyty przez dowolną instrukcję wewnątrz bloku oraz wywołując interf ere na każdej parze rejestrów które nie mogą być alokowane do tego samego rejestru. Oczywiście można wielokrotnie wywoływać mention na tej samej zmiennej, czy też, odpowiednio, interf ere na tej samej parze zmiennych. Przeanalizujcie funkcję interf erence graph i zobaczcie, że działa na zasadzie wywoływania analyze z funkcją interferencji, która dodaje nową krawędź do grafu interferencji. Algorytm Zamiast używać Alogorithm 10.4 z podręcznika słowo w słowo, proponuję zastosować następującą wariację przy czym lojalnie uprzedzam, że jest to tylko szkic, będziecie mieli sporo pracy i sporo decyzji do podjęcia dotyczących wykończenia szczegółów i optymalnego zaimplementowania Waszych pomysłów w ML-u. Niech n przebiega po zbiorze etykiet bloków. Niech live at będzie Symbol.table, która odwzorowuje etykiety na zbiory rejestrów (Mips.RegSet.set). Niech block(n) będzie listą instrukcji, które składają się na blok etykietowany przez n. Niech nextblock(n) będzie następną etykietą po n. for each n live at[n] := {} repeat changed := false for each n new = compute live in(block( n ), live at[nextblock( n )]) if new <>live at[n] then changed := true live at[n] := new until not changed Porównując powyższe z Algorithm 10.4 zobaczycie, że live at[n] spełnia tę samą fukncję, co in[n]. Algorytm compute live in(il, live at end), gdzie il jest listą instrukcji, działa mniej więcej tak: compute live in(i::rest, live at end) = let live out = compute live in(rest, live at end) in

4 if i is a straight-line instruction then return (use(i) + (live out - def(i))) else if i is a conditional branch to label L then return (use(i) + ((live at[l] + live out) - def(i))) else if i is an unconditional branch to label L then return (use(i) + (live at[l] - def(i))) compute live in(nil, live at end) = return live at end Use i def Funkcja M ips.instr def use może okazać się bardzo pomocna, jako że jej zadaniem jest zliczanie use i def w instrukcjach. Jal instruction def-use: Zauważmy, że Mips.instr def use nie raportuje w pełni użycia use i def w instrukcji Jal. Dzieje się tak, ponieważ te konkretne use i def zależą od tego, w jaki sposób klient mips.sml wybierze metodę implementacji konwencji procedura-wywołanie. Będziecie musieli potraktować tę instrukcję jak przypadek specjalny. Właściwie do zastosowanie use to rejestry actual-parameter ($a0), a właściwe def to rejestry caller-save, return-address i return-result ($v0). System call def-use: Instrukcja system call MIPS-a ma różne use i def w zależności od wartości $v0. Sugerowałbym założyć, że instrukcja syscall jest zawsze bezpośrednio poprzedzana przez load immediate instrukcji ustalającej $v0. Następnie można zastosować taką sztuczkę: compute live in(m.li(r, i)::m.syscall::rest, live out) => if r = Mips.reg "$v0" then (case M.syscall def use (M.immed2int i) of SOME use,def =>(use + (live out - def)) NONE =>ErrorMsg.impossible "Unknown Syscall") else ErrorMsg.impossible "Syscall not preceded by li $v0" Zgłaszanie interferencji Powyższy szkic algorytmu nie uwzględnia tego, że algorytm musi zgłaszać interferencje. Na stronie 222 w podręczniku (tuż przed Section 10.2) znajdziecie kryteria określające jakie interferencje należy zgłaszać. Debuggowanie Wydaje się, że najwygodniej jest wypluć zawartość live at w następującym formacie:

5 LIVENESS: gt gt: $a0 $s0 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $ra L4: $x27 $x28 $x29 $x30 $x31 $x32 $x33 $x34 $x35 L3: $x27 $x28 $x29 $x30 $x31 $x32 $x33 $x34 $x35 $x41 L6: $x27 $x28 $x29 $x30 $x31 $x32 $x33 $x34 $x35 L5: $x27 $x28 $x29 $x30 $x31 $x32 $x33 $x34 $x35 $x44 L2: $x27 $x28 $x29 $x30 $x31 $x32 $x33 $x34 $x35 L1: $x27 $x28 $x29 $x30 $x31 $x32 $x33 $x34 $x35 $x39 L8: $x27 $x28 $x29 $x30 $x31 $x32 $x33 $x34 $x35 L7: $x27 $x28 $x29 $x30 $x31 $x32 $x33 $x34 $x35 $x48 gt.epilog: $v0 $s0 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $ra