TIE448 Kääntäjätekniikka, syksy 2009 Antti-Juhani Kaijanaho TIETOTEKNIIKAN LAITOS 23. marraskuuta 2009
Sisällys
Sisällys
Seuraava deadline Vaihe E tiistai 1.12. klo 10 koodigenerointi (ilman rekisteriallokaatiota) Vaihe F maanantai 14.12. klo 12 rekisteriallokaatio
Kääntäjän rakenne lähdeohjelma SELAAJA sanasjono JÄSENTÄJÄ rakennepuu VÄLIKOODIN GENEROIJA välikoodi KOHDEKOODIN GENEROIJA kohdeohjelma TARKASTAJA SOKERINPILKKOJA OPTIMOIJA OPTIMOIJA
Sisällys
-menetelmä Sethi & Ullman: The generation of optimal code for arithmetic expressions, Journal of the ACM, 1970. yleistys E-vaiheessa mainitusta Strahlerin (Ershovin) algoritmista soveltuu vain lausekepuille (ei DAG-esityksille) lokaalisti optimaalinen ei sovellu globaaliin allokointiin oletuksena k samanarvoista yleiskäyttöistä rekisteriä R 1,..., R k voidaan soveltaa puun sijasta puun tiilipeitolle
-laputus Syöte Puu (kullakin solmulla enintään kaksi lasta) Tulos Taulukko need : Solmut N. Algoritmi Käy puun solmut läpi jälkijärjestyksessä: Jos solmulla t ei ole lapsia, aseta need(t) := 1. Jos solmulla t on yksi lapsi t, aseta need(t) := need(t ). Jos solmulla t on lapset t 1 ja t 2 : Jos need(t 1 ) = need(t 2 ), aseta need(t) := 1 + need(n 1 ); muutoin aseta need(t) := max{need(t 1 ), need(t 2 )}.
-rekisteriallokaatio (1) Apufunktio Syöte Puu t, sen -laputus need, ja kokonaisluku n (0 n < k). Ensimmäisessä kutsussa n = 0. Tulos Puun laskeva käskyjono, joka laskee tuloksen rekisteriin reg(n, t). reg(n, t) = { R n+need(t) jos need(t) k n, R k n muuten. Algoritmi Rekursiivisesti seuraavien kalvojen mukaan.
-rekisteriallokaatio (2) Jos need(t) > k ja t:llä on kaksi lasta t 1 ja t 2 : Jos need(t 1 ) need(t 2 ): 1. Sovella rekursiivisesti parametreilla t = t 1 ja n = 0. 2. Generoi push R k. 3. Sovella rekursiivisesti parametreilla t = t 2 ja { 0, jos need(t n = 2 ) k, k need(t 2 ) 1 muutoin. 4. Generoi pop R k 1. 5. Generoi reg(n, t) := op(t)(r k 1, R k ). 1 Jos need(t 1 ) < need(t 2 ), sovella edellistä kohtaa t 1 ja t 2 keskenään vaihtaen. 1 Tässä op(t) valitsee t:lle pseudokäskyn, tai mikäli kyse on tiilestä, hakee tiiltä vastaavan pseudokäskyn.
-rekisteriallokaatio (3) Jos need(t) k ja t:llä on kaksi lasta t 1 ja t 2 : Jos need(t 1 ) = need(t 2 ): 1. Sovella rekursiivisesti parametreilla t = t 2 ja n = n + 1. 2. Sovella rekursiivisesti parametreilla t = t 1 ja n = n. 3. Generoi reg(n, t) := op(t)(reg(n, t 1 ), reg(n + 1, t 2 )) Jos need(t 1 ) < need(t 2 ): 1. Sovella rekursiivisesti parametreilla t = t 2 ja n = n. 2. Sovella rekursiivisesti parametreilla t = t 1 ja n = n. 3. Generoi reg(n, t) := op(t)(reg(n, t 1 ), reg(n, t 2 )) Jos need(t 1 ) > need(t 2 ), sovella edellistä kohtaa t 1 ja t 2 keskenään vaihtaen.
-rekisteriallokaatio (4) Jos t:llä on yksi lapsi t : 1. Sovella rekursiivisesti parametreilla t = t ja n = n. 2. Generoi reg(n, t) := op(t)(reg(n, t )). Jos t:llä ei ole lasta: 1. Generoi koodi, joka laittaa rekisteriin reg(n, t) solmun arvon.
Sisällys
-metodi Poletto & Sarkar: Linear Scan Register Allocation, ACM Transactions on Programming Languages and Systems, 1999. ei optimaalinen, mutta erittäin nopea käännösaikana ja tuottaa kohtuullisen tuloksen keskeinen käsite: elämäväli [i, j], missä i ja j ovat käskyjä [i, j] on muuttujan v elämäväli jos v ei ole elossa i:tä ennen eikä j:n jälkeen konservatiivinen eloisuuden approksimaatio Elämävälit on helppo laskea eloisuusanalyysin tuloksesta; ne oletetaan tunnetuksi. Oletetaan, että mikään rekisteriallokoitu muuttuja ei pakene, jolloin ainoa syy tallettaa se muistiin on rekisterien riittämättömyys.
: tietorakenteet Kullakin muuttujalla v on seuraavat attribuutit (joista osaa algoritmi muokkaa): start(v) on v:n elämävälin alkukäsky (ei muutu) end(v) on v:n elämävälin loppukäsky (ei muutu) reg(v) on rekisteri, joka on varattu v:lle (on aluksi tyhjä) loc(v) on muistipaikka aktivaatiotietueessa, joka on varattu v:lle (on aluksi tyhjä) Apumuuttujia ovat: R, joka on rekisterien joukko A, joka on sellaisten muuttujien joukko, joille on kullakin hetkellä varattu rekisteri A kannattaa esittää siten, että loppukäskyjen järjestys on helppo löytää. A:n koko A on aina enintään k (rekisterien lukumäärä).
: pääalgoritmi 1. Aseta R kaikkien rekisterien joukoksi. 2. Aseta A :=. 3. Kullekin muuttujalle v (start(v):n kasvavassa järjestyksessä): 3.1 Kullekin w A, jolle pätee end(w) < start(v): Aseta A := A {w}. Aseta R := R {reg(w)}. 3.2 Jos A = k, tee spill (seuraava kalvo). 3.3 Muutoin, tee seuraavaa: 3.3.1 Valitse r R. 3.3.2 Aseta R := R {r}. 3.3.3 Aseta reg(v) := r. 3.3.4 Aseta A := A {v}.
: spill 1. olkoon w A siten, että end(w) on suurin mahdollinen, ja tee seuraavaa: 2. Jos end(w) < start(v), tee seuraavaa: 2.1 Aseta reg(v) := reg(w). 2.2 Aseta loc(w):ksi seuraava vapaa aktivaatiotietueen muistipaikka. 2.3 Aseta A := A {w}. 2.4 Aseta A := A {i}. 3. Muutoin aseta loc(v):ksi seuraava vapaa aktivaatiotietueen muistipaikka.
Sisällys
Seuraava deadline Vaihe E tiistai 1.12. klo 10 koodigenerointi (ilman rekisteriallokaatiota) Vaihe F maanantai 14.12. klo 12 rekisteriallokaatio