TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 26. lokakuuta 2009

Samankaltaiset tiedostot
TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 27. lokakuuta 2009

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 9. marraskuuta 2009

Eloisuusanalyysi. TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 16. marraskuuta 2009 TIETOTEKNIIKAN LAITOS. Eloisuusanalyysi.

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 13. lokakuuta 2009

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 17. marraskuuta 2009

Muita rekisteriallokaatiomenetelmiä

semantiikasta TIE448 Kääntäjätekniikka, syksy 2009 Antti-Juhani Kaijanaho 5. lokakuuta 2009 TIETOTEKNIIKAN LAITOS Ohjelmointikielten staattisesta

Jäsennysalgoritmeja. TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 29. syyskuuta 2009 TIETOTEKNIIKAN LAITOS. Jäsennysalgoritmeja

Silmukkaoptimoinnista

Syntaksi. TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 22. syyskuuta 2009 TIETOTEKNIIKAN LAITOS. Syntaksi. Aluksi.

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

Ohjelmoinnin perusteet Y Python

4.2. ALIOHJELMAT 71. Tulosvälitteisyys (call by result) Tulosvälitteinen parametri kopioidaan lopuksi

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 7. joulukuuta 2009

Rajapinta (interface)

Java-kielen perusteet

ITKP102 Ohjelmointi 1 (6 op)

Ohjelmointi 2 / 2010 Välikoe / 26.3

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli

Jatkeet. TIES341 Funktio ohjelmointi 2 Kevät 2006

Ohjelmoinnin perusteet Y Python

Java kahdessa tunnissa. Jyry Suvilehto

13. Loogiset operaatiot 13.1

5/20: Algoritmirakenteita III

Aktivaatiotietue. Yleiskäsite funktio (aliohjelma) -mekanismin tarvitsemille tiedoille. Kehysosoitin (%fp) missä tiedot ovat

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2

Osoitin ja viittaus C++:ssa

1 Tehtävän kuvaus ja analysointi

Sisällys. 7. Oliot ja viitteet. Olion luominen. Olio Java-kielessä

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

Java-kielen perusteet

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin.

ITKP102 Ohjelmointi 1 (6 op)

7. Näytölle tulostaminen 7.1

Käännös, linkitys ja lataus

Sisällys. 16. Ohjelmoinnin tekniikkaa. Aritmetiikkaa toisin merkiten. Aritmetiikkaa toisin merkiten

Ohjelmoinnin perusteet Y Python

16. Ohjelmoinnin tekniikkaa 16.1

ITKP102 Ohjelmointi 1 (6 op)

Tieto ja sen osoite (3) Jakso 3 Konekielinen ohjelmointi (TTK-91, KOKSI) Osoitinmuuttujat. Tieto ja sen osoite (5)

Se mistä tilasta aloitetaan, merkitään tyhjästä tulevalla nuolella. Yllä olevassa esimerkissä aloitustila on A.

16. Ohjelmoinnin tekniikkaa 16.1

Sisällys. 17. Ohjelmoinnin tekniikkaa. Aritmetiikkaa toisin merkiten. for-lause lyhemmin

Mikä yhteyssuhde on?

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 5. marraskuuta 2015

13. Loogiset operaatiot 13.1

Ohjelmointi 1 / 2009 syksy Tentti / 18.12

Ohjelmoinnin peruskurssien laaja oppimäärä

Jakso 3 Konekielinen ohjelmointi (TTK-91, KOKSI)

Jakso 3 Konekielinen ohjelmointi (TTK-91, KOKSI)

Java-kielen perusteita

TIEA341 Funktio-ohjelmointi 1, kevät 2008

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

TIEA241 Automaatit ja kieliopit, kevät Antti-Juhani Kaijanaho. 12. tammikuuta 2012

ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti

Sisällys. JAVA-OHJELMOINTI Osa 7: Abstrakti luokka ja rajapinta. Abstraktin luokan idea. Abstrakti luokka ja metodi. Esimerkki

Vertailulauseet. Ehtolausekkeet. Vertailulauseet. Vertailulauseet. if-lauseke. if-lauseke. Javan perusteet 2004

7. Oliot ja viitteet 7.1

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 30. marraskuuta 2015

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 2. marraskuuta 2009

11. Javan valintarakenteet 11.1

ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti

ITKP102 Ohjelmointi 1 (6 op)

Jakso 4 Aliohjelmien toteutus

Olio-ohjelmointi Javalla

Javan perusteita. Janne Käki

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan.

12. Javan toistorakenteet 12.1

Luokka Murtoluku uudelleen. Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista.

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

Ohjelmointi 2, välikoe

Tietotyypit ja operaattorit

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

12. Javan toistorakenteet 12.1

Olio-ohjelmointi Syntaksikokoelma

Sisältö. 2. Taulukot. Yleistä. Yleistä

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Aliohjelmatyypit (2) Jakso 4 Aliohjelmien toteutus

Aliohjelmatyypit (2) Jakso 4 Aliohjelmien toteutus

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Tietorakenneluokkia 2: HashMap, TreeMap

Ohjelmoinnin peruskurssi Y1

Listarakenne (ArrayList-luokka)

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli

4. Luokan testaus ja käyttö olion kautta 4.1

11. Javan toistorakenteet 11.1

Metodien tekeminen Javalla

ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti

1. Mitä tehdään ensiksi?

12. Monimuotoisuus 12.1

812341A Olio-ohjelmointi Peruskäsitteet jatkoa

Jakso 4 Aliohjelmien toteutus

815338A Ohjelmointikielten periaatteet

Pino S on abstrakti tietotyyppi, jolla on ainakin perusmetodit:

Tietorakenteet ja algoritmit

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 3. joulukuuta 2015

15. Ohjelmoinnin tekniikkaa 15.1

Monipuolinen esimerkki

Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö C-ohjelmassa

Transkriptio:

TIE448 Kääntäjätekniikka, syksy 2009 Antti-Juhani Kaijanaho TIETOTEKNIIKAN LAITOS 26. lokakuuta 2009

Sisällys

Sisällys

Seuraava deadline Vaihe D tiistai 10.11. klo 10 välikielen generointi

Kääntäjän rakenne lähdeohjelma SELAAJA sanasjono JÄSENTÄJÄ VÄLIKOODIN GENEROIJA KOHDEKOODIN GENEROIJA rakennepuu välikoodi kohdeohjelma TARKASTAJA SOKERINPILKKOJA OPTIMOIJA OPTIMOIJA

Välikoodin generointi tavoitteena muuttaa ohjelma muotoon, joka muistuttaa lopullista suorituskelpoista ohjelmaa muutamia yksinkertaistuksia välikielen generoinnin ja käsittelyn helpottamiseksi mahdollista kirjoittaa välikielelle tulkki ( virtuaalikone ) esim. testausta varten olennainen käsitteellinen jako: lokaali (hyppyjen välit) globaali eli aliohjelman sisäinen interproseduraalinen eli aliohjelmien välinen

Sisällys

klassikko: kolmiosoitekoodi (engl. three-address code) nelikot (engl. quadruples) kolmikot (engl. triples) välipuut ja -graafit (engl. intermediate trees / graphs) moderni: SSA (static single-assignment form) jatkeenvientikielet (engl. continuation-passing languages)...

Kolmiosoitekoodi Määritelmä Kolmiosoitekoodi on käskyjen jono. Käskyt ovat muotoa x := OP y z missä x, y ja z ovat operandeja ja OP on operaattori. Jotkin operandeista saattavat jäädä käyttämättä joillakin operaattoreilla. Huomautuksia Operaattorien joukko on välikieleen pultattu kiinni. Operandeja ovat vakiot, ohjelmoijan muuttujat, kääntäjän generoimat välitulokset ja viittaukset käskyjonossa oleviin käskyihin.

Operaattorityypit Operaattoreita ovat binääriset laskentaoperaattorit, esim. x := y + z unaariset laskentaoperaattorit, esim. x := y kopiointioperaattori x := y ehdoton hyppy GOTO x ehdolliset hypyt, esim. GOTO x IF y z aliohjelmakutsuun liittyvät käskyt PARAM y, x := CALL y z indeksoitu luku, x := y[z] indeksoitu kirjoitus x[y] := z osoittimen tähtäys x := y osoittimen ottaminen x := &y osoittimet kautta sijoitus x := y

Esimerkki for (int i = 0; i < n; i++) { rv = 10*rv + a[i] - 48; muuttuu muotoon 0: i := 0 1: GOTO 8 IF i >= n 2: t1 := a[i] 3: t2 := t1-32 4: t3 := 10 * rv 5: rv := t2 + t3 6: i := i + 1 7: GOTO 1

Esitystapa: nelikot Määritelmä Nelikko on kolmiosoitekoodin käskyä esittävä tietue, jossa on kentät operaattorille ja kullekin kolmelle operandille. Huomioita Engl. quadruple tai quad Lähes joka käskylle joutuu luomaan uuden, väliaikaisen muuttujan. Käskyjä voi siirtää paikasta toiseen varsin vaivattomasti.

Esimerkki OP result arg1 arg2 0 := i 0 1 GOTO IF 8 i n 2 :=[] t1 a i 3 t2 t1 32 4 t3 10 rv 5 + rv t2 t3 6 + i i 1 7 GOTO 1

Operandien esittäminen Operandi esitetään viittauksena sitä kuvaavaan tietueeseen. suora osoitin (esim. C:ssä tai Javassa) tai symboli, joka viittaa symbolitauluun. Operandin tietueessa esitetään kaikki takapään tarvitsema tieto siitä. Oliokielessä helppoa: tehdään tietueesta abstrakti luokka. Takapää sitten perii sen ja täydentää tarvitsemansa.

Kolmikot Määritelmä Kolmikko on kolmiosoitekoodin käskyä esittävä tietue, jossa on kentät operaattorille ja kahdelle operandille. Viittaus käskyn tulokseen tehdään viittaamalla itse käskyyn. Huomioita engl. triple Erillisiä väliaikaismuuttujia tarvitaan harvoin. Käskyn siirtäminen vaatii tarkkuutta, jotta viittaukset sen tulokseen eivät mene rikki. helppo tapa korjata: käskyjonossa on vain viittaus kolmikkoon, ei itse kolmikkoa näin esim. jos kolmikot ovat Java-olioita ja ne tallennetaan taulukkoon

Esimerkki OP arg1 arg2 (0) := i 0 (1) i n (2) GOTO IF (11) (1) (3) :=[] a i (4) (3) 32 (5) 10 rv (6) + (4) (5) (7) := rv (6) (8) + i 1 (9) := i (8) (10) GOTO (1)

Kolmikot Javassa public class Routine {... public Rand addtriple(op rator, Rand src1, Rand src2) { Triple rv = new Triple(rator, src1, src2); triples.add(rv); return rv; private final ArrayList<Triple> triples; public final class Triple extends Rand { public Op rator; public Rand rand1; public Rand rand2; public Triple(Op rator, Rand rand1, Rand rand2) { this.rator = rator; this.rand1 = rand1; this.rand2 = rand2;

Puutulkinta Kolmiosoitekoodin kolmikkoesitys voidaan tulkita metsäksi. Onnistuu myös hieman hankalammin nelikkoesityksessä. Kukin käsky on jonkin puun solmu. Solmun lapsisolmut ovt ne käskyt, joihin solmukäsky viittaa datakäyttöä varten poislukien siis hyppykäskyjen kohdeviittaukset Lausekkeet toteuttava kolmiosoitekoodi tulkittuna puuksi on olennaisesti sen rakennepuu. Sama ei päde lauseille ja määrittelyille.

Suunnatut syklittömät graafit (DAG) Kolmikkoesitystä generoitaessa voidaan pyrkiä poistamaan toistoa. Ideana laittaa generoidut käskykolmikot myös hajautustauluun, josta ne voidaan hakea operaattorin ja kahden operandin avulla. Kun meinataan generoida jokin käsky, katsotaan ensin, löytyykö se hajautustaulusta. Jos löytyy, käytetään löytynyttä käskyä eikä generoida uutta. Tuloksena olevan kolmikkoesityksen puutulkinta ei ole enää puu vaan DAG. Sivuvaikutukset monimutkaistavat: Jos generoidaan sivuvaikuttava käsky...... niin hajautustaulusta pitää poistaa ne käskyt, joiden laskemaan arvoon ko. sivuvaikutus saattaa vaikuttaa.

SSA engl. static single-assignment kolmiosoitekoodin muunnelma, jossa muuttujaan ei voi sijoittaa - sen voi vain alustaa lähdekielen muuttujasta x useita versioita x 1, x 2,...; joka lähdekielen sijoitus luo uuden version ongelma: mitä tehdään, jos sama muuttuj alustetaan eri tavalla eri suorituspoluilla? ratkaisu: ns Φ-funktio käsky x 7 := Φ(x 6, x 5 ) alustaa x 7 :n joko x 6 :llä tai x 5 :llä Φ(x 6, x 7 ) on sallittu vain, jos molemmat eivät koskaan tule alustetuksi samalla ohjelman suorituskerralla yksinkertaistaa opimointianalyysien ja -muunnoksien oikeellisuustarkastelua SSA:sta lisää esim. Appel luku 19

CPS engl. continuation-passing style esitystapa, jossa kaikki funktiokutsut ovat häntäkutsuja kaikki hypyt, silmukat ym. esitetään funktiokutsuina suosittu innokkaiden funktiokielten kääntäjissä ekvivalentti SSA:n kanssa

Sisällys

Kolmiosoitekoodin Kolmiosoitekoodia generoidaan kullekin aliohjelmalle erikseen. Kunkin aliohjelman kolmiosoitekoodi generoidaan ko. aliohjelman omaan käskyjonoon. Ideana on käydä aliohjelman rakennepuu jälkijärjestyksessä läpi. Tässäkin tarvitaan symbolitaulua, joka yhdistää muuttujat niitä esittäviin operandeihin.

Lausekkeet Lauseke laskee arvon, joten arvo pitää tallettaa johonkin. Kaksi vaihtoehtoa: Lausekkeen generoijalle kerrotaan, mihin lausekkeen tulos pitää tallettaa. Lausekkeen generoija tallettaa tuloksen uuteen väliaikaismuuttujaan ja palauttaa tiedon tästä muuttujasta kutsujalleen. Seuraavassa oletetaan jälkimmäinen tapa.

Binääriset laskentaoperaattorit Lasketaan ensiksi vasen operandi ja otetaan tulos talteen. Lasketaan sitten oikea operandi ja otetaan tulos talteen. Generoidaan ko. operaattorin toteuttava käsky. public class EvalGen implements ExpressionVisitor<Rand> {... public Rand visit(additionexpression e) { Rand lrand = e.lrand.accept(this); Rand rrand = e.rrand.accept(this); return r.addtriple(op.add, lrand, rrand);... private final Routine r;

Binääriset laskentaoperaattorit Lasketaan ensiksi vasen operandi ja otetaan tulos talteen. Lasketaan sitten oikea operandi ja otetaan tulos talteen. Generoidaan ko. operaattorin toteuttava käsky. public class EvalGen implements ExpressionVisitor<Rand> {... public Rand visit(additionexpression e) { Rand lrand = e.lrand.accept(this); Rand rrand = e.rrand.accept(this); return r.addtriple(op.add, lrand, rrand);... private final Routine r;

Muuttujanviittaus lausekkeessa Haetaan symbolitaulusta muuttujan esitys operandina. Ei generoi koodia. public class EvalGen implements ExpressionVisitor<Rand> {... public Rand visit(variableexpression e){ return (Rand)symtab.lookup(e.name);... private final SymbolTable symtab;

Totuusarvolausekkeet Totuusarvolausekkeilla on kaksi erilaista käyttötarkoitusta: if-, while- ym. lauseiden testinä, jolloin lausekkeen arvo määrittää, minne hypätään; totuusarvon laskemiseen esim. argumentiksi antamista tai paluuarvona palauttamista varten. Totuusarvolausekkeet voidaan kääntää kahdella tavalla: generoidaan suoraan hypyt lasketaan totuusarvo niin kuin mikä tahansa muu arvo

Totuusarvolausekkeet hyppyinä Annetaan generoijalle tieto siitä, minne pitää hypätä, jos tulos on tosi, ja minne pitää hypätä jos tulos on epätosi. public class BranchGen implements ExpressionVisitor<Void> { public BranchGen(Routine r, SymbolTable symtab, Target iftrue, Target iffalse) { this.r = r; this.symtab = symtab; this.iftrue = iftrue; this.iffalse = iffalse;... public Void visit(notequalexpression e){ EvalGen eg = new EvalGen(r, symtab); Rand lrand = e.lrand.accept(eg); Rand rrand = e.rrand.accept(eg); Rand tst = r.addtriple(op.sub, lrand, rrand); r.addtriple(op.jnz, iftrue, tst); r.addtriple(op.jump, iffalse, null); return null;... public Void visit(logicalandexpression e){ Target next = r.newtarget(); e.lrand.accept(new BranchGen(r, symtab, next, iffalse)); r.settarget(next); e.rrand.accept(new BranchGen(r, symtab, iftrue, iffalse)); return null;

If-lause public class StatementGen implements StatementVisitor<Void> {... public Void visit(ifstatement st){ Target thn = r.newtarget(); Target els = r.newtarget(); Target end = r.newtarget(); st.tst.accept(new BranchGen(r, symtab, thn, els)); r.settarget(thn); st.thn.accept(this); r.addtriple(op.jump, end, null); r.settarget(els); st.els.accept(this); r.settarget(end); return null;...

Backpatching Hypyt taaksepäin ovat helppoja: hyppykäskyyn voidaan saman tien kirjoittaa kohdekäskyn sijainti käskytaulukossa. Entäpä hypyt eteenpäin? Tarvitaan backpatching-tekniikkaa: Hypyn kohdetta ilmaisemaan luodaan abstrakti kohdeolio (r.newtarget()) Kohdeoliota voidaan käyttää hypyn kohteena. Jos hyppy oli taaksepäin, kohdeolio tietää, minne hypätään, ja kaikki on helppoa. Jos hyppy on eteenpäin, kirjataan hyppykäsky ylös ja laitetaan sen kohteeksi jotain hyödytöntä. Kun kohdeoliolle annetaan sijainti (r.settarget(thn)), käydään korjaamassa muistiin kirjattujen hyppykäskyjen kohteet.

private final HashMap<Target, Set<Triple> > unresolvedtargets; private final HashMap<Target, Triple> resolvedtargets; private final ArrayList<Triple> triples; private Triple nexttriple = new Triple(); public Target newtarget() { Target rv = new Target(); unresolvedtargets.put(rv, new TreeSet<Triple>()); return rv; public void settarget(target tgt) { for (Triple t : unresolvedtargets.get(tgt)) t.rand1 = nexttriple; unresolvedtargets.remove(tgt); resolvedtargets.put(tgt, nexttriple); public Rand addtriple(op rator, Rand src1, Rand src2) { Triple rv = nexttriple; nexttriple = new Triple(); rv.set(rator, src1, src2); triples.add(rv); return rv; public Rand addtriple(op rator, Target tgt, Rand src) { Triple tpl = resolvedtargets.get(tgt); Triple rv = (Triple)addTriple(rator, tpl, src); if (tpl == null) { Set<Triple> tpls = unresolvedtargets.get(tgt); tpls.add(rv); return rv; public void finishgeneration(variable rv) { nexttriple.set(op.return, null, null); triples.add(nexttriple); nexttriple = null;

Sisällys

Seuraava deadline Vaihe D tiistai 10.11. klo 10 välikielen generointi