Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions...

193

Transcript of Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions...

Page 1: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar
Page 2: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar
Page 3: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

Creative Commons License Deed Reconeixement-No comercial-Sense obres derivades 3.0 Espanya

Vostè és lliure de: Copiar, distribuir i comunicar públicament l’obra.

Sota els següents condicionants:

Reconeixement. S’ha de referenciar aquesta obra a Mª Antonia Mozota - Enginyeria La Salle (Semipresencial) No comercial. No es pot utilitzar aquesta obra per a finalitats comercials. Sense obres derivades. No es pot alterar, transformar o generar una obra derivada a partir d’aquesta.

• Quan reutilitzeu o distribuïu l'obra, heu de deixar ben clar els termes de la llicència de l'obra. • Alguna d'aquestes condicions pot no aplicar-se si obteniu el permís del titular dels drets d'autor. • No hi ha res en aquesta llicència que menyscabi o restringeixi els drets morals de l'autor.

Els drets derivats d'usos legítims o altres limitacions reconegudes per llei no queden afectats per l'anterior

Això és un resum fàcilment llegible del text legal (la llicència completa) disponible en els idiomes següents:

Català Castellà Basc Gallec

Page 4: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

Crèdits

Autor: Mª Antonia Mozota

Editor: Lluís Vicent

Coordinació lingüística: Sara Laso

Revisió lingüística: Christian Lara

Maquetació: Víctor Miras

Disseny de portada: Víctor Miras

Aquesta edició ha comptat amb el suport de l’Agència de Gestió d’Ajuts Universitaris i de Recerca (AGAUR) de la Generalitat de

Catalunya en la Convocatòria d’ajuts a l’edició i la difusió de llibres de text o manuals universitaris i llibres cientificotècnics, en suport

paper o en suport electrònic, escrits en llengua catalana (DILL 2009)

ISBN: 978-84-937712-0-1

Page 5: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

1

Índex

SESSIÓ 1: L'analitzador semàntic i les classes d'identificadors .................................... 5 

1 L'anàlisi semàntica .................................................................................................. 6 

1.1 L'analitzador semàntic ................................................................................................. 6 1.1.1 L'analitzador semàntic ................................................................................................................ 6 

1.2 Identificadors, atributs i verificacions ........................................................................... 7 1.2.1 Classes i verificacions .................................................................................................................. 7 1.2.2 Constants .................................................................................................................................... 8 

SESSIÓ 2: Identificadors de variables, tipus, funcions i procediments ........................ 11 1.2.3 Variables ................................................................................................................................... 11 1.2.4 Funcions i procediments ........................................................................................................... 12 1.2.5 Tipus.......................................................................................................................................... 13 

SESSIÓ 3: Descriptors d'identificadors per Babel ....................................................... 15 1.2.6 Treball ....................................................................................................................................... 15 

SESSIÓ 4: La taula de símbols ................................................................................... 17 

1.3 La Taula de símbols .................................................................................................... 17 1.3.1 La taula de símbols ................................................................................................................... 17 

SESSIÓ 5: La taula de símbols per Babel .................................................................... 19 1.3.2 Treball ....................................................................................................................................... 19 

SESSIÓ 6: Tipus: equivalència, conversió i verificacions ............................................. 21 

1.4 Anàlisi semàntica de tipus .......................................................................................... 21 1.4.1 Equivalència de tipus ................................................................................................................ 21 1.4.2 Conversió de tipus .................................................................................................................... 22 1.4.3 Verificació semàntica de tipus .................................................................................................. 23 1.4.4 Problemes ................................................................................................................................. 24 

1.5 Anàlisi semàntica en declaracions .............................................................................. 24 1.5.1 Anàlisi semàntica en declaracions ............................................................................................ 24 1.5.2 Problemes ................................................................................................................................. 26 

SESSIÓ 7: Expressions ............................................................................................... 27 

1.6 Anàlisi semàntica d'expressions ................................................................................. 27 1.6.1  Anàlisi semàntica d'expressions .............................................................................................. 27 1.6.2 Problemes ................................................................................................................................. 29 

SESSIÓ 8: Instruccions ............................................................................................... 31 

1.7 Anàlisi semàntica d'instruccions ................................................................................. 31 1.7.1 Instruccions simples .................................................................................................................. 31 1.7.2 Instruccions compostes ............................................................................................................ 33 

SESSIÓ 9: Problemes ................................................................................................. 37 1.7.3 Problemes ................................................................................................................................. 37 

SESSIÓ 10: Organització de la memòria .................................................................... 39 

2 Generació de codi .................................................................................................. 40 

Page 6: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

2

2.1 Introducció ................................................................................................................ 40 2.1.1 Introducció ................................................................................................................................ 40 

2.2 Organització de la memòria ....................................................................................... 41 2.2.1 Àrees d'ubicació de dades ........................................................................................................ 41 

SESSIÓ 11: Àrees d'ubicació de dades ....................................................................... 45 2.2.2 Variables globals i l'àrea global ................................................................................................. 45 2.2.3 Funcions i l'àrea de la pila ......................................................................................................... 49 

SESSIÓ 12: Treballs recomanats ................................................................................ 51 2.2.4 Treballs recomanats ................................................................................................................. 51 

SESSIÓ 13: Representació de tipus de dades simples ................................................. 53 

2.3 Representació de les dades ........................................................................................ 53 2.3.1 Tipus de dades simples ............................................................................................................. 53 

SESSIÓ 14: Representació de tipus de dades estructurades ....................................... 57 2.3.2 Tipus de dades estructurades ................................................................................................... 57 

SESSIÓ 15: Representació de tipus de dades estructurades ....................................... 61 2.3.3 Treballs recomanats ................................................................................................................. 61 

SESSIÓ 16: Expressions aritmètiques ......................................................................... 63 

2.4 Generació de codi per les expressions ........................................................................ 63 2.4.1 Expressions aritmètiques .......................................................................................................... 63 

SESSIÓ 17: Expressions lògiques ............................................................................... 69 2.4.2 Expressions lògiques ................................................................................................................. 69 2.4.3 Treballs recomanats ................................................................................................................. 70 

SESSIÓ 18: Instruccions simples ................................................................................ 73 

2.5 Generació de codi per les instruccions simples ........................................................... 73 2.5.1 Assignació ................................................................................................................................. 73 2.5.2 Lectura i escriptura ................................................................................................................... 74 2.5.3 Altres ......................................................................................................................................... 75 2.5.4 Treballs recomanats ................................................................................................................. 75 

SESSIÓ 19: Condicionals i llaços ................................................................................ 77 

2.6 Generació de codi per les instruccions condicionals i llaços ........................................ 77 2.6.1 Si_llavors_sino .......................................................................................................................... 77 2.6.2  Mentre i repetir ....................................................................................................................... 78 

SESSIÓ 20: Condicionals i llaços ................................................................................ 81 2.6.3 Per_fer ...................................................................................................................................... 81 2.6.4 Segons ....................................................................................................................................... 82 

SESSIÓ 21: Treballs i problemes ................................................................................ 85 2.6.5 Treballs i problemes ................................................................................................................. 85 

SESSIÓ 22: Funcions i procediments .......................................................................... 87 

2.7 Generació de codi per funcions i procediments .......................................................... 87 2.7.1 Funcions i procediments ........................................................................................................... 87 2.7.2 La pila d’execució ...................................................................................................................... 89 2.7.3 Tasques a implementar ............................................................................................................ 92 

SESSIÓ 23: Paràmetres ............................................................................................. 95 

Page 7: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

3

2.7.4 Paràmetres ............................................................................................................................... 95 2.7.5 Esquemes de traducció ............................................................................................................. 96 

SESSIÓ 24: Variables no locals .................................................................................. 99 

2.8 Accés a variables ........................................................................................................ 99 2.8.1 Accés a variables locals ............................................................................................................. 99 2.8.2 Accés a variables no locals ...................................................................................................... 100 2.8.3 Treballs ................................................................................................................................... 101 

SESSIÓ 25: Una introducció ..................................................................................... 103 

3 Optimització ........................................................................................................ 104 

3.1 Introducció .............................................................................................................. 104 3.1.1 L’optimitzador de codi ............................................................................................................ 104 3.1.2 Tipus d’optimització i propietats ............................................................................................ 104 

3.2 Estructura del compilador amb optimització ............................................................ 105 3.2.1 Models .................................................................................................................................... 105 

SESSIÓ 26: Llenguatges intermedis i MIR ................................................................ 107 

3.3 Llenguatges intermedis ............................................................................................ 107 3.3.1 Avantatges i decisions............................................................................................................. 107 3.3.2 Tipus de llenguatges intermedis ............................................................................................. 108 

3.4 El llenguatge MIR ..................................................................................................... 109 3.4.1 Sintaxi i semàntica .................................................................................................................. 109 

3.5 De Babel a MIR ........................................................................................................ 110 3.5.1 Expressions i crides a funcions ................................................................................................ 110 3.5.2 Instruccions ............................................................................................................................. 111 3.5.3 Problemes ............................................................................................................................... 113 

SESSIÓ 27: Anàlisi del codi i diagrama de blocs ....................................................... 115 

3.6 Un exemple .............................................................................................................. 115 3.6.1 Un exemple ............................................................................................................................. 115 

3.7 Tipus de codi i ordre de les optimitzacions ............................................................... 116 3.7.1 Tipus de codi i ordre de les optimitzacions ............................................................................ 116 

3.8 Etapes d'un optimitzador ......................................................................................... 117 3.8.1 Anàlisi del flux de control ....................................................................................................... 117 3.8.2 Anàlisi del flux de dades ......................................................................................................... 118 3.8.3 Transformacions ..................................................................................................................... 118 

SESSIÓ 28: Transformacions preservant funcionalitat ............................................. 121 

3.9 Optimitzacions early ................................................................................................ 121 3.9.1 Avaluació d’expressions constants ......................................................................................... 121 3.9.2 Simplificacions algebraiques i reassociació ............................................................................ 122 

3.10 Transformacions preservant funcionalitat .............................................................. 123 3.10.1 Eliminació de subexpressions comunes ................................................................................ 123 3.10.2 Propagació de còpia .............................................................................................................. 124 3.10.3 Eliminació de codi mort ........................................................................................................ 124 

SESSIÓ 29: Codi invariant, reducció de forces i variables d’inducció ........................ 127 

3.11 Optimització de llaços ............................................................................................ 127 

Page 8: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

4

3.11.1 Moviment de codi invariant ................................................................................................. 127 3.11.2  Reducció d’operacions ......................................................................................................... 128 3.11.3  Eliminació de variables d’inducció ....................................................................................... 130 

3.12 Comptant operacions ............................................................................................. 131 3.12.1 Comptant operacions ........................................................................................................... 131 

SESSIÓ 30: Compiladors comercials i llenguatges intermedis .................................. 133 

3.13 Casos d’estudi ........................................................................................................ 133 3.13.1 Compiladors comercials i optimització ................................................................................. 133 3.13.2 Altres llenguatges intermedis ............................................................................................... 134 

ANNEXOS ............................................................................................................... 137 

I El llenguatge Babel ............................................................................................... 137 

1. Aspectes lexicogràfics ................................................................................................ 137 

2 Sintaxi ......................................................................................................................... 138 

3 Semàntica ................................................................................................................... 141 

II La taula de símbols .............................................................................................. 145 

1 Introducció ................................................................................................................. 145 

2  Funcionalitats ............................................................................................................ 145 2.1 Objectiu ..................................................................................................................................... 145 2.2 Tipus de Identificadors .............................................................................................................. 145 2. 3 Descriptors ................................................................................................................................ 147 

3 Implementació ............................................................................................................ 152 

4 Com utilitzar la taula de símbols ................................................................................. 153 

III Problemari ......................................................................................................... 155 

CAPITOL 1:  L’ANÀLISI SEMÀNTICA ................................................................................. 155 

CAPITOL 2: GENERACIÓ DE CODI .................................................................................... 160 

CAPITOL 3:  OPTIMITZACIÓ DE CODI .............................................................................. 167 

Bibliografia ............................................................................................................ 185 

Glossari .................................................................................................................. 187 

Page 9: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

5

SESSIÓ 1: L'analitzador semàntic i les classes d'identificadors

FITXA DE LA SESSIÓ Nom: L'analitzador semàntic i les classes d'identificadors Tipus: teòrica Format: no presencial Durada: 3 hores Treball a lliurar: no

PRECEDENTS Fins ara hem estudiat les fases següents del procés de la compilació: l'anàlisi lexicogràfica i l'anàlisi sintàctica. També hem estudiat les gramàtiques d'atributs i els esquemes de traducció com formalismes bàsics per a la construcció de compiladors dirigits per sintaxi.

OBJECTIUS Introduir la fase d'anàlisi semàntica d'un compilador i classificar els diferents tipus d'identificadors que poden haver-hi en els llenguatges de programació.

Page 10: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

6

CONTINGUTS En aquesta sessió estudiarem les tasques d'un analitzador semàntic i per a cadascuna de les classes d'identificadors veurem les diferents verificacions semàntiques per realitzar.

1 L'anàlisi semàntica

1.1 L'analitzador semàntic

1.1.1 L'analitzador semàntic L'analitzador semàntic és la fase del compilador que verifica les definicions dels identificadors i les seves utilitzacions, verifica que cada expressió té un tipus correcte i tradueix eventualment l'entrada a una representació intermèdia per poder generar un millor codi.

Tasques de l'analitzador semàntic

Una de les principals tasques de l'analitzador semàntic és verificar que la utilització de cada identificador sigui coherent amb la seva declaració. Per poder fer aquestes verificacions en context d'utilització, s'ha d'haver guardat prèviament la informació sobre la declaració de l'identificador (context de declaració). Tota la informació de la declaració d'un identificador (constant, variable o funció) es guarda en una taula anomenada Taula de Símbols o Taula Semàntica. La creació de la taula de símbols és una de les altres tasques que ha de fer l'analitzador semàntic. Cada instrucció té una semàntica que s'ha de verificar i això també és una tasca de l'analitzador semàntic.

Verificacions i accions semàntiques respecte l'ús dels identificadors

Les verificacions i les accions semàntiques es divideixen en dos grups: aquelles que han de fer-se en context de declaració, és a dir, quan s'estan declarant els identificadors i aquelles que han de fer-se en context d'utilització, és a dir, quan s'utilitzen els identificadors.

Verificacions i accions en context de declaració

En context de declaració per cada identificador, normalment en la majoria de llenguatges, s'ha de:

Page 11: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

7

1. Verificar que l'identificador que estem declarant no estigui ja declarat en el context actual.

2. Si no està declarat, inserir-lo en la taula de símbols. Segons la classe d'identificador, s'han de fer altres verificacions, a més d'aquestes.

Verificacions en context d'utilització

Per cada ocurrència d'un identificador s'ha de: 1. Verificar que estigui declarat dintre de l'abast i 2. Verificar que la utilització sigui consistent amb la seva declaració.

Verificacions d'instruccions

Verificar que l'expressió utilitzada com condició en la instrucció "Si.....llavors" sigui de tipus lògic i verificar que la part esquerra d'una assignació no sigui un identificador de constant, són alguns exemples de les verificacions que s'han de fer a les instruccions.

Taula de símbols

La taula de símbols és una estructura de dades que contindrà els identificadors declarats amb els seus atributs (tipus, el paràmetre, tipus de paràmetre,...). La taula de símbols és clau per fer les verificacions semàntiques. En pròximes sessions explicarem en detall les possibles estructures de dades per implementar-la i la informació precisa que ha de contenir.

Esquemes de traducció

Les verificacions i accions semàntiques són implementades a la pràctica amb esquemes de traducció. Més endavant, a l'hora d'explicar les diferents verificacions semàntiques utilitzarem els esquemes de traducció.

1.2 Identificadors, atributs i verificacions

1.2.1 Classes i verificacions Els diferents identificadors que poden haver-hi en un llenguatge de programació s'agrupen en classes. Cada classe d'identificador representa un conjunt d'informació (els atributs de la classe). A continuació estudiarem les diferents classes i quines verificacions comuns es fan per totes les classes.

Page 12: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

8

Classes

En general, un identificador pot denotar: una constant, una variable, un tipus (definit per l'usuari), una funció, un procediment, un camp d'un registre o una etiqueta. Aquestes són les classes d'identificador.

Verificacions i accions semàntiques comunes per tots els identificadors

Per cada classe especificarem quina és la informació necessària que hem de guardar en la taula de símbols per poder fer les verificacions oportunes. Anomenarem aquesta informació, el descriptor de l'identificador. En context de declaració de qualsevol identificador s'ha de: 1. Verificar que l'identificador no estigui declarat prèviament en el context actual. 2. Crear el descriptor de l'identificador amb els seus atributs i guardar-lo en la taula de símbols en el context actual. En context d'utilització de qualsevol identificador s'ha de: 1. Verificar que l'identificador estigui declarat en l'abast i 2. Verificar que la utilització sigui coherent amb la declaració.

1.2.2 Constants

Què és una constant?

Podem diferenciar les constants que tenen un nom, és a dir, que estan denotades per un identificador de les constants literals que són representacions de valors (per exemple, “2”, “7.8”,...). Aquestes últimes són identificades per l'analitzador lexicogràfic i aquest torna un token específic per cada tipus de constant. Les primeres són identificades per l'analitzador lexicogràfic com identificadors, és a dir, com token ID. Una constant és un objecte de dades que té un nom donat per un identificador. Aquest nom està lligat a un mateix valor dins l'abast de la constant. El valor de la constant es pot determinar en temps de compilació, és a dir, el valor és estàtic. Poden haver-hi constants definides per l'usuari mitjançant una declaració i constants prèviament definides pel llenguatge.

Page 13: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

9

Verificacions en context de declaració

L'identificador d'una constant tindrà com tipus el tipus de l'expressió que determina el valor. La verificació que s'ha de fer és: verificar que l'expressió definint el valor de la constant sigui una expressió estàtica.

Verificacions en context d'utilització

Una constant pot ser utilitzada en qualsevol context en què es pot utilitzar un identificador del tipus de la constant. La verificació que s'ha de fer és: verificar que no estigui en un context en el qual li sigui assignat un valor.

Informació a guardar en la taula de símbols

Per a una constant, els atributs per guardar són: 1. El tipus del valor. 2. El valor.

RESUM Les classes d'identificadors que s'han de considerar són: les constants, les variables, les funcions, els procediments i els tipus. El descriptor de cada identificador conté la informació necessària per a les verificacions semàntiques. Cada classe d'identificador té un model de descriptor diferent. Per a tots els identificadors s'han de fer verificacions comuns tant en context de declaració com en context d'utilització. Cada classe d'identificadors pot tenir altres verificacions específiques per fer.

Page 14: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

10

Page 15: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

11

SESSIÓ 2: Identificadors de variables, tipus, funcions i procediments

FITXA DE LA SESSIÓ Nom: Identificadors de variables, tipus, funcions i procediments. Tipus: teòrica Format: no presencial Durada: 3 hores Treball a lliurar: no

PRECEDENTS En la sessió anterior hem classificat els identificadors i per a alguns d'ells hem definit les verificacions que s'han de realitzar tant en context de declaració com en context d'utilització. Per cada identificador hem definit el seu descriptor.

OBJECTIUS Completar l'estudi dels diferents identificadors, els seus descriptors i les verificacions que s'han de realitzar.

CONTINGUTS En aquesta sessió estudiarem els identificadors de variables, tipus, funcions i procediments.

1.2.3 Variables

Què és una variable?

Una variable és un objecte de dades amb nom. Una variable és modificable en execució. Els paràmetres formals actuen com variables dins la funció o del procediment.

Verificacions en context de declaració

La variable tindrà com tipus el tipus donat en la declaració. Els tipus poden ser simples o compostos i els estudiarem més endavant. La verificació que s'ha de fer és: 1. En els llenguatges que permeten inicialitzar la variable amb un valor, aquest ha de ser del tipus corresponent.

Page 16: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

12

Verificacions en context d'utilització

Les verificacions que s'han de fer depenen directament del tipus de la variable. Si el tipus és simple, la utilització ha de ser adequada amb el corresponent tipus. Si la variable denota un subscrit d'un array, aleshores, s'ha de verificar que: 1. L'identificador sigui un identificador de tipus array. 2. El nombre d'índexs sigui correcte segons la declaració. 3. Cada expressió representant un índex sigui del tipus adequat. Si la variable denota un camp d'un registre, s'ha de verificar que l'identificador sigui de tipus registre, que el camp sigui un nom de camp correcte i que el tipus del camp sigui aquell esperat.

Informació que s'ha de guardar en la taula de símbols

Els atributs mínims que s'han de guardar en la taula de símbols pels identificadors de classe “variable” són: 1. El tipus de l'identificador. 2. Si és paràmetre o no. 3. El mode de pas de paràmetre. 4. El desplaçament (aquest camp s'utilitza en la generació de codi).

1.2.4 Funcions i procediments

Què és una funció?

Una funció o un procediment és un subprograma que defineix un nou context. Els paràmetres són considerats variables locals.

Verificacions i accions en context d'utilització

Una funció o procediment és utilitzat quan es crida. Per tant, en el moment de la crida s'ha de verificar que: 1. L'identificador sigui un identificador de funció o de procediment. 2. El nombre de paràmetres reals sigui igual al nombre de paràmetres formals. 3. Cada paràmetre real sigui del tipus esperat. 4. Cada paràmetre real sigui compatible amb el mode de pas del corresponent paràmetre formal. Quan la funció retorn s'ha de verificar, en el cas d'una funció, que el valor retornat sigui del tipus esperat.

Page 17: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

13

Informació que s'ha de guardar en la taula de símbols

Els atributs que s'han de guardar en la taula de símbols pels identificadors de classe “funció/procediment” són: 1. El tipus del valor que retorna (en cas de funció). 2. Nombre de paràmetres. 3. Llista de paràmetres amb el tipus i el mode de pas. Cadascun dels paràmetres té els mateixos atributs que una variable. 4. El desplaçament del resultat (aquest camp s'utilitza en la generació de codi). 5. El nom de l'etiqueta (aquest camp s'utilitza en la generació de codi).

1.2.5 Tipus

Què és un identificador de tipus?

Els llenguatges de programació tenen un conjunt de tipus predefinits, en què cadascun té un identificador. Aquests identificadors són reconeguts per l'analitzador lexicogràfic que torna com token, per exemple, TIPUS_SIMPLE i com lexema el tipus concret, per exemple SENCER. Per definir nous tipus, els llenguatges tenen constructors que permeten definir tipus compostos. Alguns exemples de constructors són: ARRAY, RECORD,... Quan es defineix un nou tipus es pot optar normalment per donar-li un nom, és a dir, utilitzar un identificador per al nou tipus o no donar-li nom. En el primer cas, els identificadors de tipus han de ser tractats com la resta dels identificadors, és a dir, han de ser guardats en la taula de símbols amb els seus atributs i fer les verificacions pertinents. En el segon cas, guardarem el descriptor del tipus sense nom.

Verificacions i accions en context de declaració

En el cas de tipus definits per l'usuari amb nom s'ha de crear el descriptor corresponent al tipus. En el cas de tipus sense nom s'ha de crear el descriptor corresponent al tipus però sense nom.

Verificacions en context d'utilització

S'utilitzen els noms de tipus quan es declaren les variables o uns altres tipus. Les verificacions són les estàndards.

Page 18: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

14

Informació que s'ha de guardar en la taula de símbols

Per als tipus simples predefinits (identificadors predefinits) el descriptor pot ser molt simple o fins i tot pot guardar informació com el mínim i el màxim valor possible si el tipus és ordenat. Per als tipus compostos, variarà segons el tipus.

RESUM Els descriptors de les variables, funcions, procediments i tipus contenen informació per fer l'anàlisi semàntica però també tenen informació que serà d'utilitat a l'hora de la generació de codi. En el cas dels identificadors de tipus, per a cada tipus hi ha un descriptor diferent.

Page 19: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

15

SESSIÓ 3: Descriptors d'identificadors per Babel

FITXA DE LA SESSIÓ Nom: Descriptors d'identificadors per Babel Tipus: de problemes Format: no presencial Durada: 2 hores Treball a lliurar: no

PRECEDENTS En les sessions anteriors hem fet un recorregut teòric per les diferents classes d'identificadors i per a cadascuna hem definit el descriptor corresponent.

OBJECTIUS L'objectiu d'aquesta sessió és que l'estudiant adquireixi els coneixements necessaris sobre els descriptors que s'utilitzaran a l'hora d'implementar la fase d'anàlisi semàntica del compilador pel llenguatge BABEL (annex).

1.2.6 Treball

Descriptors en Babel

Estudieu els descriptors definits per la implementació de la taula de símbols per a l'anàlisi semàntica del llenguatge BABEL.

RESUM Hem estudiat els descriptors definits per la implementació de l'anàlisi semàntica de BABEL.

Page 20: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

16

Page 21: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

17

SESSIÓ 4: La taula de símbols

FITXA DE LA SESSIÓ Nom: La taula de símbols Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no

PRECEDENTS En les sessions anteriors hem estudiat els descriptors dels diferents identificadors. Recordeu que aquesta informació es guardarà en una estructura de dades anomenada taula de símbols.

OBJECTIUS Mostrar les diferents formes d'implementar la taula de símbols.

CONTINGUTS Estudiarem algunes de les possibles estructures de dades per la taula de símbols. Estudiarem el cas particular en què els llenguatges permeten una estructura de blocs ja que els diferents abasts que poden tenir els identificadors han de ser considerats a l'hora de dissenyar la taula de símbols.

1.3 La Taula de símbols

1.3.1 La taula de símbols Una de les tasques fonamentals de l'anàlisi semàntica és la construcció de la taula de símbols. La taula de símbols conté tots els descriptors dels identificadors declarats i s'utilitza durant l'anàlisi semàntica per verificar la seva bona utilització. Podem organitzar-la mantenint els identificadors ordenats o no. L'organització està també condicionada pel fet que el llenguatge tingui o no estructura de blocs.

Operacions

La taula de símbols és una estructura de dades dinàmica que ha de permetre les següents operacions: 1. Inserir un nou descriptor d'identificador. 2. Cercar un identificador i si hi és, recuperar el seu descriptor. 3. Modificar el descriptor d'un identificador.

Page 22: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

18

Organització no ordenada

La manera més fàcil d'organitzar una taula de símbols és mantenir una seqüència lineal dels identificadors podent-la implementar amb un array o una llista amb punters.

Organització ordenada

Una manera alternativa d'organització és mantenir els identificadors de forma ordenada. Entre les possibles implementacions podem tenir: una taula ordenada en un array, una taula ordenada en un arbre binari o una taula de hash.

Organització per llenguatges amb estructura de blocs

Totes les organitzacions estudiades fins ara consideren que tots els identificadors estan definits i s'utilitzen en un únic context. Aquesta característica està lligada als llenguatges que no són de blocs. Molts llenguatges de programació tenen estructura de blocs, això vol dir que poden haver-hi diferents contexts de declaració. Cada context defineix un abast per als identificadors declarats en ell. Els contexts són imbricats. A l'hora de dissenyar la taula ha de considerar-se aquest fet.

RESUM La taula de símbols és una estructura de dades que és creada durant l'anàlisi semàntica de les declaracions i utilitzada durant l'anàlisi semàntica de la utilització dels identificadors. La taula de símbols pot ser organitzada mantenint o no els identificadors ordenats. L'abast dels identificadors ha de ser reflectida en l'organització de la taula de símbols.

Page 23: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

19

SESSIÓ 5: La taula de símbols per Babel

FITXA DE LA SESSIÓ Nom: La taula de símbols per Babel Tipus: pràctica Format: no presencial Durada: 3 hores Treball a lliurar: no

PRECEDENTS En les sessions anteriors hem estudiat les possibles organitzacions de la taula de símbols i els diferents descriptors que podem definir per als identificadors.

OBJECTIUS Els objectius d'aquesta sessió són: estudiar l'organització de la taula de símbols per al llenguatge BABEL.

CONTINGUTS Es proposa un treball dirigit per prendre contacte amb l'organització de la taula de símbols.

1.3.2 Treball

Organització de la taula de símbols per Babel

Recordeu que el compilador del llenguatge Babel és d'una sola passada i té estructura de blocs. Per a la implementació de la taula de símbols s'utilitza un comptador del nombre de blocs. Aquest comptador s'incrementa quan s'obra un nou context (bloc) i es decrementa quan se'n surt. Cada bloc té una taula i en un punt específic de l'anàlisi semàntica, es tenen tantes taules (empilades) com blocs oberts. Estudieu en detall l'organització de la taula de símbols (annex) proposada per al llenguatge BABEL.

RESUM Hem proposat diferents treballs per prendre contacte amb la taula de símbols que s'utilitza per realitzar la fase dl'anàlisi semàntica de la pràctica.

Page 24: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

20

Page 25: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

21

SESSIÓ 6: Tipus: equivalència, conversió i verificacions

FITXA DE LA SESSIÓ Nom: Tipus: equivalència, conversió i verificacions Tipus: teòrica Format: no presencial Durada: 3 hores Dedicació: 3 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Aho1985]

PRECEDENTS En les sessions precedents hem estudiat detalladament els identificadors, els seus descriptors i com els podem guardar en la taula de símbols.

OBJECTIUS Estudiar la verificació de tipus i l'impacte de la conversió i de l'equivalència sobre l'anàlisi semàntica. Estudiar més en detall les verificacions i accions semàntiques que s'han de fer en context de declaració per cada cas en particular.

CONTINGUTS En aquesta sessió estudiarem les verificacions de tipus que s'han de fer considerant la conversió i l'equivalència. Veurem les accions i verificacions en context de declaració. Una de les verificacions semàntiques més importants és verificar que els operands d'una expressió siguin del mateix tipus o de tipus convertibles. Aquesta verificació considera l'equivalència de tipus i la conversió de tipus.

1.4 Anàlisi semàntica de tipus

1.4.1 Equivalència de tipus Una de les verificacions semàntiques més importants és verificar que els operands d'una expressió siguin del mateix tipus o de tipus convertibles. El mateix tipus vol dir de tipus equivalents. Els llenguatges de programació que permeten definir nous tipus han d'especificar quins són considerats equivalents. Hi ha dos conceptes d'equivalència: l'equivalència estructural i l'equivalència per nom. L'equivalència de tipus s'implementa, generalment, en la taula de símbols.

Page 26: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

22

Equivalència estructural

Dos tipus són equivalents estructuralment si, i només si, les seves definicions són idèntiques.

[Aho1985] p353- p355

Equivalència per nom

Dos tipus són equivalents per nom si han estat definits utilitzant el mateix nom de tipus. En els casos en què es defineixen tipus sense nom, cada tipus definit és considerat diferent.

[Aho1985] p356- p359

1.4.2 Conversió de tipus Una de les verificacions semàntiques més importants és verificar que els operands d'una expressió siguin del mateix tipus o de tipus convertibles. Un tipus convertible vol dir que els valors de les variables d'aquest tipus poden ser transformats en valors d'altres tipus. Un exemple n'és la conversió de sencers a reals. La definició del llenguatge ha d'especificar quines conversions són legals. La conversió s'utilitza en l'anàlisi semàntica per determinar quines expressions són legals i en la fase de generació de codi per generar les instruccions que en temps d'execució faran la conversió. Hi ha dos tipus de conversions: les conversions implícites i les explícites.

Conversions implícites

Les conversions implícites són fetes automàticament pel compilador i són anomenades coercions.

[Aho1985] p359- p360

Conversions explícites

Les conversions explícites són fetes pel programador. Els llenguatges estan normalment proveïts d'un conjunt de funcions predefinides per fer-ho.

[Aho1985] p359- p360

Page 27: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

23

1.4.3 Verificació semàntica de tipus

Verificació estàtica i dinàmica de tipus

Verificar tipus significa comprovar que cada operació rebi els tipus d'operands permesos. Algunes verificacions de tipus poden fer-se en temps de compilació (verificació estàtica) i altres han de fer-se en temps d'execució (verificació dinàmica). La verificació estàtica de tipus permet al compilador generar codi més eficient. Certs llenguatges com Lisp i Prolog han estat especialment dissenyats per requerir verificació dinàmica.

Verificació de tipus en expressions

Tota expressió utilitzada en un programa ha de tenir un tipus. Aquest tipus es determina durant l'anàlisi semàntica. El tipus d'una expressió depèn dels tipus dels seus operands i de la conversió de tipus. Si l'operand és un identificador prèviament declarat, el tipus està guardat en la taula de símbols. Si l'operand és una constant, el tipus ja ha estat determinat durant l'anàlisi lexicogràfica i el token així ho reflecteix. Per determinar el tipus d'una expressió mitjançant un esquema de traducció necessitem un atribut sintetitzat que anomenarem tipus per tal que propagui el tipus.

[Aho1985] p350-p351

Verificació de tipus en instruccions

La verificació de tipus en instruccions es limita a la verificació dels tipus de les expressions involucrades. Això vol dir que l'expressió utilitzada ha de ser del tipus esperat. Les regles semàntiques de cadascuna de les instruccions han de definir el tipus de les expressions. En pròximes sessions estudiarem en detall l'anàlisi semàntica de les instruccions. En llenguatges d'expressions, és a dir, en llenguatges en què totes les construccions són considerades expressions, tot torna un valor i per tant un tipus. Un exemple d'aquest tipus de llenguatge és C.

Errors i la seva recuperació

En la verificació del tipus d'una expressió, ens podem trobar amb les següents situacions d'error: 1. Un identificador utilitzat no està declarat i per tant no té un tipus. 2. Una barreja de tipus no és legal.

Page 28: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

24

En les dues situacions donarem un error semàntic. Però aquests dos errors es propaguen ja que en el primer cas, com que no està declarat, no té tipus i per tant no podem donar tipus a l'expressió en què apareix. En el segon cas, com que el tipus no és l'adequat, aleshores l'expressió en què apareix tampoc no té un tipus definit. La recuperació d'errors permet continuar amb l'anàlisi semàntica i no produir errors en cascada.

1.4.4 Problemes

Esquema de traducció per a verificacions de tipus sense conversió. Problema resolt

Consulteu el problema 1.4 del problemari.

Esquema de traducció per a verificacions de tipus amb conversió

Feu el problema 1.5 del problemari.

1.5 Anàlisi semàntica en declaracions

1.5.1 Anàlisi semàntica en declaracions

Accions i verificacions generals per a totes les classes d'identificadors

La taula de símbols s'omple en context de declaració per poder-la utilitzar en context d'utilització. Abans d'inserir un identificador, s'ha de verificar que no estigui ja declarat. A continuació comentem les accions i verificacions que hem de considerar quan estem compilant un llenguatge imperatiu amb estructura de blocs. - Quan s'obre i quan es tanca un context:

1. Actualitzar el comptador de bloc. - Quan es declara un nou identificador:

1. Verificar que l'identificador que s'està declarant no estigui en la taula de símbols en el context actual.

Page 29: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

25

2. Inserir l'identificador declarat en la taula de símbols amb tots els seus atributs. 3. Implementar l'equivalència de tipus si és el cas.

Verificacions en context de declaració de constants

Considereu la gramàtica següent en la qual es declaren identificadors de constants. decl_constants CONST llista_decl_constants decl_constants ε llista_decl_constants ID = exp ; llista_decl_constants llista_decl_constants ID = exp ; Recordeu que el tipus del ID que estem declarant com una constant serà del tipus de l'expressió, l'atribut tipus ens el pujarà. L'expressió ha de ser estàtica, és a dir, el seu valor s'ha de poder calcular en temps de compilació. És_estàtica i valor són atributs sintetitzats que seran donats per l'anàlisi semàntica de l'expressió.

Verificacions en context de declaració de variables

Considereu el fragment de gramàtica següent en el qual es declaren variables i els seus tipus: decl_variables VAR llista_decl_variables decl_variables ε llista_decl_variables llista_ids : tipus ; llista_decl_variables llista_decl_variables llista_ids : tipus ; tipus TIPUS_SIMPLE tipus VECTOR [ exp .. exp ] DE TIPUS_SIMPLE En la declaració de VECTOR, les expressions definint el rang de l'índex han de ser estàtiques, de tipus simple, les dues expressions han de ser del mateix tipus i el valor de l'expressió representant el límit inferior ha de ser més petit (o igual) que el que representa el límit superior. Per realitzar aquestes verificacions s'han d'utilitzar els atributs tipus, és_estàtica i valor.

Page 30: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

26

Verificacions en context de declaració de funcions

Considereu el fragment de gramàtica següent en el qual es declaren funcions: decl_funcions FUNCIO ID llista_parametres : TIPUS_SIMPLE ; bloc ; decl_funcions decl_funcions ε llista_parametres ε llista_parametres ( parametres ) parametres llista_idsp : tipus ; parametres parametres llista_idsp : tipus ; llista_idsp REF llista_id llista_idsp VAL llista_id llista_idsp llista_id llista_id ID , llista_id llista_id ID Recordeu que la declaració d'una funció obre un nou context de declaració. El ID representant el nom de la funció ha de ser inserit en el context actual abans d'obrir el nou. Els paràmetres són considerats variables locals. Així doncs cadascun dels paràmetres s'inserirà dues vegades en la taula de símbols. En el context actual (abans d'obrir un de nou) estaran inserits lligats al ID de la funció, i en el nou context estaran inserits com variables locals.

1.5.2 Problemes

Esquema de traducció per l'anàlisi semàntica en context de declaració

Feu el problema 1.6 del problemari.

RESUM La conversió i l'equivalència de tipus s'han de considerar durant l'anàlisi semàntica. La verificació de tipus és fonamental en l'anàlisi semàntica de les expressions. Per cada classe d'identificador hem definit les verificacions particulars que s'han de fer quan es declaren.

Page 31: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

27

SESSIÓ 7: Expressions

FITXA DE LA SESSIÓ Nom: Expressions Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no

PRECEDENTS En la sessió anterior hem vist en detall les verificacions que s'han de fer en context de declaració.

OBJECTIUS Estudiar en detall les verificacions i les accions semàntiques que s'han de fer en context d'utilització dels identificadors en les expressions.

CONTINGUTS

1.6 Anàlisi semàntica d'expressions

1.6.1 Anàlisi semàntica d'expressions

Verificació d'identificadors declarats

Una expressió està formada per operands simples. Per cada identificador utilitzat hem de verificar que estigui declarat en l'abast actual i que la seva utilització sigui consistent amb la seva declaració. Per cada classe d'operand simple donem a continuació les verificacions semàntiques que s'han de fer. - Un identificador de variable i un identificador de constant: 1. Ha d'estar declarat en l'abast actual. - Una crida a una funció: 1. L'identificador ha d'estar declarat en l'abast actual. 2. Fer les verificacions en context d'utilització donades anteriorment. - Un accés a un element d'un vector i un accés a un camp d'un registre: 1. L'identificador ha d'estar declarat en l'abast actual. 2. Fer les verificacions en context d'utilització donades anteriorment.

Page 32: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

28

Atributs mínims necessaris

En les sessions anteriors hem vist la necessitat de mantenir almenys tres atributs sintetitzats que s'han de calcular en el context d'expressions. Aquests atributs s'utilitzen en context de declaració i alguns en el mateix context d'utilització. Aquest atributs són: Tipus, retorna el tipus de l'expressió. És_estàtica, retorna cert si l'expressió és estàtica, és a dir, si el seu valor pot ser calculat en temps de compilació. Valor, si l'expressió és estàtica retorna el valor de l'expressió.

Càlcul dels atributs a nivell d'operands

El tipus d'una expressió depèn directament dels tipus dels seus operands. Els operands simples més comuns que poden aparèixer en una expressió i els atributs corresponents són: - Un identificador de variable: 1. Tipus: el tipus que apareix en el descriptor de l'identificador en la taula de símbols. 2 .És_estàtica: fals. 3. Valor: cap. - Un identificador de constant: 1.Tipus: el tipus que apareix en el descriptor de l'identificador en la taula de símbols. 2. És_estàtica: cert. 3. Valor: el valor que apareix en el descriptor de l'identificador en la taula de símbols. - Una constant: 1. Tipus: el tornat segons el token. 2. És_estàtica: cert. 3. Valor: el lexema del token. - Una crida a una funció: 1. Tipus: el tipus que retorna la funció en el descriptor en la taula de símbols. 2. És_estàtica: fals. 3. Valor: cap. - Un accés a un element d'un vector: 1. Tipus: el tipus dels elements de l'identificador en la taula de símbols. 2. És_estàtica: fals. 3. Valor: cap. - Un accés a un camp d'un registre: 1. Tipus: el tipus del camp de l'identificador de registre en la taula de símbols. 2. És_estàtica: fals. 3. Valor: cap.

Page 33: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

29

Operadors

Si l'expressió és simple, és a dir, només té un operand, els atributs estan determinats com hem explicat en el concepte anterior. Si l'expressió és més complexa, és a dir, conté operadors binaris, els atributs de l'expressió han de ser calculats considerant-los. Tipus: el tipus d'una expressió binària es calcula considerant l'equivalència i la conversió de tipus com hem fet en sessions anteriors. És_estàtica: en una expressió binària, si els dos operands són estàtics, l'expressió també ho serà. Si algun dels dos operands no és estàtic, l'expressió tampoc ho serà. Valor: si l'expressió és estàtica, el valor de l'expressió es calcularà considerant els valors dels operands, la classe d'operador i l'associativitat definida en la semàntica del llenguatge.

1.6.2 Problemes

Esquema de traducció per a l'anàlisi semàntica d'expressions. Problema resolt

Consulteu el problema resolt 1.7 del problemari.

Esquema de traducció per a l'anàlisi semàntica d'expressions

Feu el problema 1.8 del problemari.

RESUM Per a tots els identificadors utilitzats en les expressions hem de verificar que estiguin declarats i que la seva utilització sigui adequada per la seva declaració. Els atributs tipus, és_estàtica i valor han de ser calculats a nivell d'expressió. El càlcul dels atributs tipus, és_estàtica i valor depèn de: la conversió i equivalència de tipus, del tipus dels operands i dels operadors.

Page 34: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

30

Page 35: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

31

SESSIÓ 8: Instruccions

FITXA DE LA SESSIÓ Nom: Instruccions Tipus: teòrica Format: no presencial Durada: 3 hores Treball a lliurar: no

PRECEDENTS En la sessió anterior hem vist en detall les verificacions semàntiques que s'han de fer en expressions.

OBJECTIUS Estudiar en detall les verificacions i les accions semàntiques s'han de fer en cada instrucció.

CONTINGUTS

1.7 Anàlisi semàntica d'instruccions

1.7.1 Instruccions simples Una instrucció és simple si no involucra altres instruccions. L'assignació és la instrucció simple més utilitzada.

Assignació

L'assignació és la instrucció bàsica per canviar els valors de les variables. Tots els llenguatges de programació tenen una instrucció d'assignació. Alguns, com C, tenen diferents instruccions d'assignació. Sintaxi: La sintaxi canvia segons el llenguatge però la més general és: instr variable OP_ASSIGNACIO expr variable és la part esquerra, OP_ASSIGNACIO és l'operador d'assignació (:=. =. <--, etc.) i expr és la part dreta. Semàntica: L'expressió s'avalua i el resultat és assignat a la variable. Aquesta semàntica considera que els tipus de la variable i de l'expressió són simples. Quan es permet

Page 36: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

32

l'assignació entre tipus compostos (per exemple en ADA) es diu que l'assignació és múltiple. Verificacions semàntiques i atributs: Els tipus de l'expressió i de la variable han de ser iguals o convertibles. En la majoria dels llenguatges de programació els tipus han de ser simples però en alguns llenguatges es permet l'assignació entre tipus compostos. Per fer aquesta verificació es pot utilitzar l'atribut tipus. La variable de la part esquerra no pot ser un identificador de constant. Per fer aquesta verificació es pot utilitzar l'atribut és_estàtica.

Crida a procediment

Quan el llenguatge de programació té procediments, aleshores la crida a un procediment és una instrucció. L'anàlisi semàntica d'aquesta crida és pràcticament igual que la crida d'una funció amb la diferència que en el primer cas com no treballem amb el tipus ja que no torna un resultat.

Retorn de funció

Quan el llenguatge té funcions, la instrucció retorn permet retornar el control a qui ha cridat la funció i retornar un valor. Sintaxi: La sintaxi canvia segons el llenguatge però la més general és: instr --> RETORNAR expr Semàntica: L'expressió s'avalua i és el resultat que torna la funció. El control del programa torna a qui ha cridat la funció. Verificacions semàntiques i atributs: El tipus de l'expressió ha de ser del mateix tipus que el tornat per la funció. Dins d'una funció es necessita almenys un retorn. Alguns llenguatges no verifiquen l'existència d'un retornar ja que si no el troben el control arriba a la fi de la funció i és aquí quan es produeix el retorn. En aquests casos s'ha de decidir el valor que torna la funció.

Altres instruccions simples

Altres instruccions simples que poden trobar-se en diferents llenguatges de programació són: Break, Continue, Exit, Goto, etc. L'anàlisi semàntica d'aquestes instruccions depèn evidentment de la seva semàntica en el llenguatge que les utilitza. Algunes estan lligades a les instruccions d'iteració i han de ser tractades considerant-ho. En particular estudiarem la instrucció goto conjuntament amb les etiquetes en una pròxima sessió.

Page 37: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

33

1.7.2 Instruccions compostes Una instrucció composta és aquella que està formada per un conjunt d'instruccions que s'executen en un ordre determinat.

Instruccions condicionals

Les instruccions condicionals permeten definir camins alternatius depenent del valor d'una expressió. La instrucció condicional més utilitzada en els llenguatges de programació és el Si_llavors_sino (If_then_else). L'altra instrucció condicional que permeten la majoria dels llenguatges, amb petites diferències, és la instrucció case.

Si_llavors_sino (If_then_else)

Aquesta instrucció canvia la seqüència de control depenent del valor d'una expressió lògica. Sintaxi: La sintaxi canvia segons el llenguatge però la més general és: instr SI expr LLAVORS linstr SINO linstr FSI instr SI expr LLAVORS linstr FSI linstr representa una llista d'instruccions. Semàntica: L'expressió s'avalua, si el resultat és cert s'executen les instruccions que hi han després del LLAVORS, si el resultat és fals s'executen les instruccions després del SI NO o en el segon cas les que hi ha després de la mateixa instrucció SI. Verificacions semàntiques i atributs: El tipus de l'expressió ha de ser lògic. Per fer aquesta verificació es pot utilitzar l'atribut tipus.

Case

Aquesta instrucció canvia la seqüència de control depenent del valor d'una expressió de tipus simple. Sintaxi: La sintaxi canvia segons el llenguatge. A continuació donem una sintaxi. instr SEGONS expr DE llista_de_casos cas_sino FISEGONS llista_de_casos llista_de_ctes : linstr ; llista_de_casos llista_de_casos ε

Page 38: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

34

llista_de_ctes constant , llista_de_ctes llista_de_ctes constant cas_sino SINO : linstr cas_sino ε linstr representa una llista d'instruccions. Semàntica: L'expressió s'avalua i s'executen les instruccions associades a la llista de constants (cas) que conté el valor donat per l'expressió. Després el control salta a la pròxima instrucció rere el case. Si no hi ha cap llista de constants que continguin el valor de l'expressió, s'executa la instrucció corresponent al cas SINO. Verificacions semàntiques i atributs: El tipus de l'expressió ha de ser simple. Els valors en les llistes dels casos han de ser del mateix tipus que l'expressió i cada valor només pot aparèixer en un sol cas.

Instruccions d'iteració

Les instruccions d'iteració ens permeten repetir un conjunt d'instruccions. El nombre de vegades que iterem sobre les instruccions pot ser controlat de diferents maneres. Cada una d'aquestes maneres dóna peu a un tipus d'instrucció d'iteració diferent. Alguns exemples són: Repetir_fins (Repeat), Mentre_fer (While. DoWhile), Per_fer (For), etc. A continuació donem la semàntica d'algunes d'aquestes instruccions.

Repetir_fins (Repeat) i Mentre_fer (While. DoWhile)

Les dues instruccions permeten repetir un conjunt d'instruccions. El nombre de vegades que es repetiran depèn del valor d'una expressió lògica. Sintaxi: La sintaxi canvia segons el llenguatge. A continuació donem una sintaxi. instr REPETIR linstr FINS expr instr MENTRE exp FER linstr linstr representa una llista d'instruccions. Semàntica: En el cas del repetir, el conjunt d'instruccions s'executa una vegada i a continuació s'avalua l'expressió. Si el valor és cert, surt del llaç i s'executa la instrucció que hi ha després del fins. Si el valor de l'expressió és fals, el control torna a la primera instrucció que hi ha després de la paraula clau repetir.

Page 39: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

35

En el cas del mentre, primer s'avalua l'expressió. Si el valor és fals, surt del llaç i s'executa la instrucció que hi ha després de la instrucció . Si el valor de l'expressió és cert, el control entra al llaç, després d'executar l'última instrucció dins del llaç, el control torna a avaluar l'expressió. Verificacions semàntiques i atributs: El tipus de les expressions ha de ser lògic.

Per_fer (For)

La instrucció per_fer (for) permet executar un conjunt d'instruccions un nombre de vegades controlades per una variable (la variable d'iteració). Sintaxi: La sintaxi canvia segons el llenguatge. A continuació donem una sintaxi. instr PER variable := expr A expr FER linstr linstr representa una llista d'instruccions. Semàntica: La primera expressió s'avalua i li és assignat el valor a la variable (nomenada variable de control) . La instrucció s'executa, s'incrementa el valor de la variable en 1 (en alguns llenguatges podem indicar un altre increment o decrement). Si el valor de la variable és més gran que el valor de la segona expressió, el control surt del llaç. Si no, es torna a executar el llaç, incrementant cada vegada la variable. La semàntica varia segons el llenguatge ja que podem calcular la segona expressió d'una sola vegada abans d'entrar en el llaç o cada vegada que s'executa el llaç. Un altre aspecte que fa la diferència entre llenguatges, és que alguns no deixen modificar la variable de control i en d'altres no fa falta declarar la variable de control, ja que es considera local al llaç, etc. Verificacions semàntiques i atributs: El tipus de les expressions i el de la variable han de ser simples i han de ser el mateix. En alguns llenguatges només poden ser de tipus sencer i en d'altres, com en PASCAL, poden ser de qualsevol tipus simple però ordenat.

RESUM Les instruccions poden ser simples o compostes. Per a l'anàlisi semàntica de pràcticament totes les instruccions és molt important l'atribut tipus ja que ens permet conèixer el tipus de les expressions involucrades. Cada llenguatge defineix la semàntica de les instruccions. És indispensable conèixer-la per poder realitzar l'anàlisi semàntica i més tard per poder generar codi correcte.

Page 40: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

36

La instrucció per_fer és la que més varia d'un llenguatge a un altre. L'anàlisi semàntica es fa mitjançant esquemes de traducció.

Page 41: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

37

SESSIÓ 9: Problemes

FITXA DE LA SESSIÓ Nom: Problemes Tipus: de problemes Format: no presencial Durada: 2 hora Treball a lliurar: no

PRECEDENTS Hem estudiat les diferents instruccions simples i compostes que poden tenir els llenguatges de programació imperatius.

OBJECTIUS Adquirir pràctica en l'anàlisi semàntica de diferents instruccions mitjançant esquemes de traducció.

CONTINGUTS Proposem alguns problemes perquè analitzin semànticament diferents instruccions.

1.7.3 Problemes

Llenguatges de programació i les seves instruccions

Feu el problema 1.9 del problemari.

Esquema de traducció per a l'anàlisi semàntica d'instruccions simples. Problema resolt

Consulteu el problema resolt 1.10 del problemari.

Esquema de traducció per a l'anàlisi semàntica de la instrucció “mentre”. Problema resolt

Consulteu el problema resolt 1.11 del problemari.

Page 42: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

38

Esquema de traducció per a l'anàlisi semàntica de les instruccions “loop” i “break”

Feu el problema 1.12 del problemari.

Esquema de traducció per a l'anàlisi semàntica de la instrucció “segons”

Feu el problema 1.13 del problemari.

Esquema de traducció per a l'anàlisi semàntica d'una instrucció “per_fer”

Feu el problema 1.14 del problemari.

RESUM Hem proposat diferents problemes per fer l'anàlisi semàntica d'instruccions.

Page 43: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

39

SESSIÓ 10: Organització de la memòria

FITXA DE LA SESSIÓ Nom: Organització de la memòria Tipus: teòrica Format: no presencial Durada: 1 hora Treball a lliurar: no Material:

o Bibliografia bàsica: [Aho1985]

PRECEDENTS Fins ara hem estudiat les fases següents del procés de la compilació: l'anàlisi lexicogràfica, l'anàlisi sintàctica i l'anàlisi semàntica.

OBJECTIUS Donar una introducció a la fase de generació de codi i estudiar les diferents àrees en les quals es pot organitzar la memòria.

Page 44: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

40

CONTINGUTS

2 Generació de codi

2.1 Introducció

2.1.1 Introducció

Fases d'un compilador

Com hem estudiat en el capítol 2, un compilador es composa d'un conjunt de fases. Cada fase té una tasca específica. Fins ara hem estudiat les fases d'anàlisi lexicogràfica, sintàctica i semàntica. En aquest capítol veurem detalladament la fase de generació de codi i deixarem per al pròxim capítol les fases de generació de codi intermedi i d'optimització.

Generació de codi intermedi

Generar codi intermedi per poder després optimitzar, implica utilitzar un llenguatge intermedi. Hi ha diferents llenguatges intermedis segons el tipus d'optimització a realitzar. Els llenguatges intermedis es divideixen en llenguatges de representació intermèdia d'alt nivell (HIR), de baix nivell (LIR) i de nivell intermedi (MIR). En el pròxim capítol els estudiarem.

[Aho1985] p12-p14 (“Intermediate code generation”)

Optimització de codi

L'optimitzador de codi millora el codi intermedi. La millora sempre va adreçada al temps d'execució. Poden fer-se diferents optimitzacions de diferents complexitats. Algunes són molt fàcils i d'altres molt difícils. En pròximes sessions estudiarem l'optimització de codi en més detall.

[Aho1985] p14-p15 (“Code optimization”)

Generació de codi

La fase de generació de codi comporta: - L'organització de la memòria. - La representació de dades en memòria.

Page 45: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

41

- La generació de codi per expressions i instruccions. L'organització de la memòria determina de quines àrees disposarem en la memòria per guardar les variables locals i globals (estàtiques i dinàmiques) i els contextos de les crides a procediments. El dissenyador haurà de prendre decisions sobre com s'organitza la memòria, això depèn directament de la definició del llenguatge de programació que estem compilant. La representació de dades en memòria especifica per a cadascun dels tipus de dades com es guardaran en memòria les variables corresponents, és a dir, en quin format. La generació de codi per expressions, instruccions simples i instruccions compostes genera codi en llenguatge assemblador o codi de màquina. Tant des del punt de vista teòric com des del punt de vist pràctic generarem codi en llenguatge assemblador MIPS. Per poder provar els programes generats disposarem del simulador SPIM (http://pages.cs.wisc.edu/~larus/spim.html) de MIPS.

[Aho1985]p15 (“Code generation”)

2.2 Organització de la memòria

2.2.1 Àrees d'ubicació de dades L'organització de la memòria està determinada per la naturalesa del llenguatge font que es compila.

Àrees

Es distingeixen tres possibles àrees: - l'àrea global. - l'àrea de la pila. - l'àrea del heap. Depenent de les característiques del llenguatge a compilar, la memòria podria organitzar-se en una àrea, dues àrees o tres àrees. El següent esquema mostra una subdivisió típica de la memòria. A més a més de les àrees de dades, durant l'execució del programa també hi serà el codi.

Page 46: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

42

[Aho1985] p396-p397

L'àrea de la pila

L'àrea de la pila s'utilitza per ubicar les variables locals. La pila creix quan es fa una crida a una funció o procediment i decreix quan es retorna d'una funció o d'un procediment. Cada crida obre un nou context (frame) alhora que reserva memòria en la pila per contenir les variables locals. En pròximes sessions estudiarem en detall la crida a una funció o a un procediment. Per gestionar la pila s'utilitzen dos punters (registres) : - El registre SP (stack pointer) apunta a la pròxima adreça de memòria lliure - El registre FP (frame pointer) apunta a la base del context actual (frame) Veurem l'ús i la gestió d'aquests registres en les pròximes sessions.

L'àrea global

L'àrea global s'utilitza per ubicar els objectes declarats estàticament com les variables globals, les constants i les variables estàtiques. Per gestionar l'àrea global s'utilitza un punter (registre) anomenat GP (global pointer). En pròximes sessions, parlarem de les diferents possibilitats de tractar les variables globals.

L'àrea del heap

L'àrea del heap s'utilitza per ubicar els objectes declarats dinàmics i que per tant no s'adapten a una estructura de pila.

Page 47: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

43

RESUM La memòria pot organitzar-se en tres àrees diferents: l'àrea global, l'àrea de la pila i l'àrea del heap. Les característiques del llenguatge de programació a compilar determinarà quines àrees hem de tenir en memòria i per tant quines àrees haurà de gestionar el compilador.

Page 48: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

44

Page 49: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

45

SESSIÓ 11: Àrees d'ubicació de dades

FITXA DE LA SESSIÓ Nom: Àrees d'ubicació de dades Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Aho1985]

PRECEDENTS En la sessió anterior hem vist l'objectiu de la fase de generació de codi i hem estudiat de manera molt general les diferents àrees en què pot ser organitzada la memòria depenent de les característiques del llenguatge a compilar.

OBJECTIUS Estudiar cadascuna de les àrees en les quals pot organitzar-se la memòria. Estudiar on seran, durant l'execució d'un programa, les variables globals, les variables locals i els paràmetres de les funcions. Introduir els registres que es necessitaran per gestionar la memòria durant l'execució d'un programa.

CONTINGUTS

2.2.2 Variables globals i l'àrea global

Ubicació en memòria

Si el llenguatge de programació té variables globals i procediments, és a dir, si hem de generar codi per crides a procediments, aleshores haurem de gestionar l'àrea de la pila. Per tant, com hem vist en la sessió anterior les variables globals poden ser ubicades en una àrea només per elles (l'àrea global) o poden ser ubicades en el fons de la pila (l'àrea de la pila). En aquest últim cas, les crides als procediments s'empilaran sobre les variables globals. Esquemàticament,

Page 50: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

46

Desplaçament i representació

Com es pot observar en els esquemes anteriors, les variables globals estaran ubicades a partir d'una certa adreça de memòria donada per un registre el qual s'inicialitzarà al començament de l'execució del programa. L'adreça d'una variable en temps d'execució serà el valor del registre base més el seu desplaçament. El desplaçament és doncs una adreça relativa a una base. Si ens hem fixat en com està organitzada la memòria en MIPS, haurem vist que les adreces de la pila van de més grans a més petites, això vol dir que els desplaçaments dintre de la pila seran negatius. En canvi, les adreces del segment data van de més petites a més grans. En aquest últim cas els desplaçaments seran positius. És molt important, alhora de generar codi, tenir en compte l'organització de la memòria per poder determinar com es fa l'accés a les variables globals. El descriptor de cada identificador en la taula de símbols té un camp per guardar el desplaçament. El desplaçament es calcula en les declaracions ja que el desplaçament d'una variable depèn directament del desplaçament i del tipus de la variable anterior en memòria. Cada tipus tindrà una representació en memòria. En la pròxima sessió estudiarem les diferents representacions de les dades. Calcular el desplaçament per a les variables globals vol dir inicialitzar un comptador en 0 i per cada declaració de variable sumar el número de bytes que ocupa de manera que s'obtingui així el desplaçament de la pròxima variable.

Reserva d'espai en memòria

El nombre total de bytes que ocupen les variables globals és conegut en temps de compilació. El comptador del desplaçament ens dóna efectivament aquest nombre. Una de les tasques del programa principal (main) és reservar l'espai en memòria per les variables globals. Això vol dir que en compilació hem de generar el codi per fer-ho.

Page 51: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

47

Generació de codi per reservar espai utilitzant l'àrea global

En MIPS no fa falta inicialitzar cap registre ja que es proporciona el registre $gp (global pointer) ja inicialitzat ( 10008000H). Disposem de 64K adreçables dels quals 32 K es poden adreçar amb desplaçaments positius i 32K amb desplaçaments negatius. Recordeu que l'adreçament en MIPS és : d($r), en què d és el desplaçament (de 16 bits) i $r és el registre base (32 bits).

Generació de codi per reservar espai utilitzant l'àrea de la pila

1. Inicialitzar el punter de pila. El simulador SPIM inicialitza el registre $sp que serveix com registre per adreçar la pila per tant no cal inicialitzar-lo. 2. Inicialitzar el registre que s'utilitzarà com a registre base. Utilitzarem el registre $sp per apuntar sempre la primera adreça lliure de la pila, així, hem de tenir un altre registre ($fp) que apuntarà a la base de la pila. Utilitzarem també aquest registre, com hem comentat anteriorment, en les crides a funcions. Podem inicialitzar el registre $fp amb el valor del registre $sp. 3. Reservar espai, és a dir, actualitzar el punter de pila $sp restant-li el nombre total de bytes que ocupen les variables globals. Després d'aquests tres passos la memòria queda:

D'ara endavant suposem que les variables globals estan en el fons de la pila i que les adrecem utilitzant el registre $fp.

Page 52: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

48

Estructura del programa principal (main)

El codi generat ha de ser en aquest ordre: main: inicialitzar $fp

reservar memòria per a variables globals decreixent al registre $sp codi del programa principal epíleg

Accés a una variable global

L'accés a una variable es fa mitjançant el registre base i el seu desplaçament. En el cas d'utilitzar el registre $gp, l'accés a memòria és d($gp) en què d és el desplaçament que té la variable. En el cas d'utilitzar el registre $fp, l'accés a memòria és d($fp) en què d és el desplaçament que té la variable. Més endavant, quan haurem estudiat les variables locals, farem la distinció entre variables locals i no locals i, depenent de l'abast, haurem de saber buscar on són en memòria. Utilitzarem el que s'anomena la cadena estàtica. L'accés a variables no locals dins d'una funció no serà directa.

Exemple

Sigui el fragment següent de codi en Babel: Var x, y : sencer; Inici

x := y + 2 fi. Els desplaçaments serien: dx = 0 i dy = -4, considerant que els sencers ocupen 4 bytes. L'espai de memòria que ocuparien les variables és de 8 bytes. L'accés a x seria 0($fp) i l'accés a y seria –4($fp). El codi generat per aquest programa seria: main: MOVE $fp, $sp

SUB $sp, $sp , 8 LW $8, -4($fp) LI $9, 2 ADD $8, $8, $9 SW $8, 0($fp)

...

Page 53: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

49

2.2.3 Funcions i l'àrea de la pila

Llenguatges amb estructura de blocs

En llenguatges amb estructures de blocs i amb funcions o procediments recursius, s'ha d'administrar l'àrea de la pila. Cada execució d'un bloc (funció o procediment), ha de tenir la seva àrea de dades en la qual s'emmagatzemaran les variables locals. Aquests requeriments de memòria s'han de fer dinàmicament quan hi ha una crida i s'han d'alliberar dinàmicament quan hi ha un retorn.

Estructura d'un frame

La pila d'execució s'organitza en blocs anomenats frames. Cada frame és un context i està relacionat amb la crida d'un procediment o funció.

Page 54: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

50

Un frame conté: - Una localitat de memòria per guardar la cadena estàtica, que estudiarem més endavant. Aquesta informació és opcional ja que només és requerida si el llenguatge és de blocs. - Una localitat per guardar la cadena dinàmica, aquesta serveix per a saber quina és la base del frame anterior i poder així recuperar el context en el qual estàvem abans de cridar la funció. - Una localitat per guardar l'adreça de retorn, és a dir, l'adreça de la instrucció del programa objecte que s'haurà d'executar després de retornar. La resta del frame conté les variables locals, els paràmetres i altres informacions necessàries durant l'execució del procediment o de la funció. En pròximes sessions estudiarem detalladament la generació de codi de les crides i dels retorns.

Desplaçament de paràmetres i variables locals

Com hem vist en el concepte anterior, la cadena dinàmica guarda l'ordre de les crides i les bases dels frames corresponents. Per tant el registre $fp sempre apunta al frame actual. Els desplaçaments de les variables locals i dels paràmetres (considerats evidentment variables locals) seran relatius al registre $fp. Cada funció o procediment és un bloc, per tant el comptador de desplaçaments s'haurà d'inicialitzar en cadascuna de les declaracions corresponents. Ja veurem més endavant que aquest comptador s'inicialitzarà en un valor determinat.

RESUM El desplaçament de les variables és una adreça relativa a un registre base. El desplaçament d'una variable es calcula en temps de compilació en la seva declaració i es guarda en el seu descriptor en la taula de símbols. En la generació de codi s'utilitza el desplaçament per poder accedir a la variable. Els desplaçaments poden ser positius o negatius. L'àrea global de MIPS ens permet adreçar fins 64K. La pila d'execució s'organitza en blocs anomenats frames. Cada frame és un context i està relacionat amb la crida d'un procediment o d'una funció.

Page 55: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

51

SESSIÓ 12: Treballs recomanats

FITXA DE LA SESSIÓ Nom: Treballs recomanats Tipus: de problemes Format: no presencial Durada: 1 hora Treball a lliurar: no Material:

o Bibliografia bàsica: [Larus1998]

OBJECTIUS Estudiar en detall l'organització de la memòria en MIPS i determinar quines àrees de memòria hem de tenir per a la compilació del llenguatge Babel.

CONTINGUTS

2.2.4 Treballs recomanats

Organització de la memòria en MIPS

El simulador SPIM distingeix tres segments en memòria: el segment pila, el segment data i el segment text . Estudieu per a cada segment, quin és el seu objectiu i quins registres hi estan associats.

[Larus1998]

Les àrees de memòria en Babel

Babel permet funcions, variables locals i globals. En canvi, no té variables dinàmiques. Per tant, necessitem dues àrees: la global i la pila. Consulteu i estudieu les diferents maneres d'organitzar la memòria per compilar el llenguatge Babel.

Page 56: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

52

Page 57: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

53

SESSIÓ 13: Representació de tipus de dades simples

FITXA DE LA SESSIÓ Nom: Representació de tipus de dades simples Tipus: teòrica Format: no presencial Durada: 1 hora Treball a lliurar: no

PRECEDENTS En la sessió anterior hem estudiat l'organització de la memòria.

OBJECTIUS Estudiar com es representen en memòria els valors de tipus simples i la seva relació amb el llenguatge assemblador amb el que generarem codi.

CONTINGUTS El compilador ha de decidir, en funció del llenguatge que es compila, com es representen en memòria els tipus de dades sobre l'ordinador per al qual es compila. En algunes ocasions, el hardware ens proporciona una solució òbvia però en d'altres casos el compilador haurà de decidir la representació considerant sempre les facilitats que aporta el llenguatge assemblador.

2.3 Representació de les dades

2.3.1 Tipus de dades simples La majoria dels llenguatges assembladors proporcionen una representació per als tipus simples i un conjunt d'operacions ja implementades. El implementador del compilador doncs, ha d'estudiar bé el llenguatge assemblador de què disposa i aprofitar-ne les característiques.

Sencers i reals

La majoria dels llenguatges de programació d'alt nivell tenen els tipus simples: sencer i real. La majoria dels llenguatges assembladors proporcionen una representació interna per als sencers i una per als reals i a més a més proporcionen un conjunt d'operacions i de registres per operar sobre dades d'aquests tipus.

Page 58: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

54

Els valors sencers, normalment són representats en complement a 1 o en complement a 2 i ocupen una paraula de memòria (els LONG n'ocupen dues). Per exemple, en MIPS un sencer ocupa 32 bits (4 bytes ). MIPS disposa de 32 registres (numerats de $0 a $31) de 32 bits dels quals un subconjunt (del $8 al $25) és de propòsit general i pot ser utilitzat per fer operacions entre sencers. Una variable sencera ocuparà doncs 4 bytes. Els valors reals, normalment són representats en punt flotant i ocupen una paraula de memòria. Per exemple, en MIPS un real simple ocupa 32 bits (4 bytes ). MIPS disposa de 32 registres ($f0 a $f31) de 32 bits que permeten operar amb aritmètica real simple o de doble precisió. Una variable real simple ocuparà doncs 4 bytes.

Lògic

Els valors d'una variable de tipus lògic poden ser: cert i fals. Aquests valors poden ser representats mitjançant un sol bit, per exemple el 0 pot representar el fals i l'1 el cert. Molts compiladors opten per representar els valors cert i fals amb una paraula o byte de memòria. En aquests casos, la representació del cert i del fals és escollida depenent de les operacions predefinides en el llenguatge assemblador. L'objectiu és facilitar la implementació de les operacions lògiques del llenguatge d'alt nivell que estem compilant. Dues possibles representacions que podem comentar són: - Representar el fals com un 0, és a dir una paraula plena de 0's i el cert com una paraula amb un 1. - Representar el fals com un 0, és a dir una paraula plena de 0's i el cert com una paraula plena d'1's. Com els tipus simples són considerats normalment ordenats, s'imposa un ordre entre els valors fals i cert. En la majoria dels llenguatges l'ordre és fals < cert.

Caràcter

Cada caràcter té un codi ASCII que pot ser representat en un byte. Normalment els llenguatges assembladors ofereixen aquesta possibilitat. En alguns casos pot ser més fàcil representar un tipus caràcter en una paraula.

Altres tipus simples

Entre d'altres tipus simples podem esmentar: el tipus enumerat, el tipus subrange i el tipus punter.

Page 59: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

55

Els valors de tipus enumerats solen ésser representats com els sencers ja que els valors es transformen en sencers. Cada valor doncs pot ésser representat en una paraula. Els valors de tipus subrange, es representen com els valors del tipus original. Recordeu que un tipus subrange és la restricció d'un tipus simple. Els valors de tipus punter són adreces de memòria. Normalment són representats en una paraula de memòria però això depèn directament del sistema d'adreçament que tingui. Atès que alguns valors, per exemple el –1, no poden ser valors d'adreces de memòria, se n'escull un, d'aquests, per representar el NIL.

RESUM Per representar en memòria els valors de tipus simples s'han de considerar tant les representacions que ofereix el llenguatge assemblador com les operacions a implementar.

Page 60: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

56

Page 61: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

57

SESSIÓ 14: Representació de tipus de dades estructurades

FITXA DE LA SESSIÓ Nom: Representació de tipus de dades estructurades Tipus: teòrica Format: no presencial Durada: 1.5 hores Treball a lliurar: no

PRECEDENTS En la sessió anterior hem estudiat com es representen en memòria els valors de tipus simple.

OBJECTIUS Estudiar la representació en memòria dels valors de tipus estructurats.

CONTINGUTS

2.3.2 Tipus de dades estructurades Els llenguatges assembladors no tenen cap tipus de dades estructurades prèviament definides. Per tant, el compilador ha de decidir com representar els tipus estructurats, com per exemple els vectors (array) i les estructures (struct). La representació és molt important ja que en depèn l'accés als elements individuals.

Vectors d'una dimensió (array)

Els vectors d'una dimensió són normalment representats utilitzant blocs continus de memòria. Cada element ocupa exactament el mateix nombre de paraules i depèn evidentment del seu tipus. Considerem la declaració de variable següent: Var A: vector [M..N] de sencer; Aquesta declaració permet especificar els límits inferior i superior dels índexs del vector. L'objectiu és guardar només el desplaçament del primer element del vector com el desplaçament de la variable. L'accés a qualsevol element del vector es fa utilitzant l'índex, el desplaçament del primer element i una fórmula que ens donarà el desplaçament de l'element. La fórmula d'accés és: A[e] = dAo + (e-M)* ts

Page 62: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

58

En què e és una expressió i el seu valor ha de ser entre M i N. dAo és el desplaçament de la variable A (del primer element), M és el límit inferior i ts és el nombre de bytes que ocupa un element del vector en memòria. Si apliquem distributivitat i associativitat obtenim la següent fórmula: A[e] = dAo + e*ts -M* ts A[e] = dAo -M* ts + e*ts La part dAo -M* ts és constant per A i no depèn de l'expressió e. Dit d'una altra manera, es pot calcular en temps de compilació i fins i tot es pot guardar en el descriptor de la variable com el seu desplaçament.

Vectors de dues dimensions

Els vectors de dues dimensions són representats utilitzant blocs continus de memòria com en el cas d'una dimensió però ho podem fer per files o per columnes. Cada element ocupa exactament el mateix nombre de paraules i depèn evidentment del seu tipus. Considerem la declaració de variable següent: Var A: vector [M1..N1, M2..N2] de sencer; Aquesta declaració permet especificar els límits inferior i superior dels índexs de cada dimensió del vector. La fórmula d'accés és: A[e1,e2] = dAo + (e1-M)* (N2-M2+1)*ts + (e2 – M2) * ts Com en el cas d'una dimensió, si manipulem la fórmula podem arribar a obtenir una expressió que depengui d'una part constant i d'altres parts, involucrant les expressions e1 i e2.

Verificació dinàmica d'accés a un element

El compilador ha de generar codi per verificar en execució que quan s'accedeix a un element d'un vector, els valors dels índexs estiguin dins el rang M..N (límit inferior.. límit superior). En cas d'error, el codi ha de preveure-ho, donar un missatge d'error i avortar el programa.

Registres (struct)

Molts llenguatges de programació tenen registres (struct, record, etc.). Els registres són tipus de dades estructurades però, a diferència dels vectors, cada element pot ser d'un tipus diferent. La representació es fa utilitzant blocs consecutius de memòria. L'accés a un element es fa mitjançant el seu nom (nom del camp) per tant els desplaçaments de cadascun dels elements són coneguts en temps de compilació. El desplaçament del primer camp és 0 i els següents desplaçaments es calculen sumant

Page 63: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

59

el desplaçament i el nombre de bytes que ocupa el camp anterior. El desplaçament de la variable és el que li pertoca. La fórmula d'accés a un camp és: A.x = dAo + dx dAo és el desplaçament de la variable A i dx és el desplaçament del camp x respecte a dAo.

Altres tipus estructurats

Uns altres tipus estructurats que podem estudiar són els conjunts, les cadenes, les unions, etc.

RESUM Cada tipus estructurat ha de ser representat en memòria de la manera més adient per poder accedir als seus elements en execució. Algunes de les fórmules d'accés tenen parts constants que poden ser calculades en compilació i milloren així el codi generat.

Page 64: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

60

Page 65: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

61

SESSIÓ 15: Representació de tipus de dades estructurades

FITXA DE LA SESSIÓ Nom: Treballs recomanats Tipus: de problemes Format: no presencial Durada: 1 hora Dedicació: 1.30 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Larus1998]

OBJECTIUS Estudiar en detall com es representen els tipus simple i estructurats de Babel en MIPS. Estudiar la generació de codi per l'accés a elements de tipus estructurats.

CONTINGUTS

2.3.3 Treballs recomanats

Tipus simples en MIPS

Consulteu, en el llenguatge MIPS, els registres per operar amb sencers i els registres per operar amb reals. Consulteu-hi les operacions que hi ha per sumar, restar, dividir i multiplicar sencers i reals. Estudieu com es faria una conversió de sencer a real. Consulteu, del llenguatge MIPS, les operacions que hi ha per operar sobre tipus lògic. Estudieu com es faria el AND, el OR i el NOT tot considerant dues representacions diferents del tipus lògic.

[Larus1998]

Representació de tipus simples en Babel

Estudieu els diferents tipus simples que ofereix el llenguatge Babel. Per a cadascun dels tipus preneu una decisió de com representar-lo en memòria. No us oblideu de mirar les operacions relacionades amb els tipus.

Page 66: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

62

Representació de tipus estructurats en Babel

Estudieu els tipus estructurats que ofereix el llenguatge Babel. Per a cadascun dels tipus preneu una decisió de com representar-los en memòria.

Generació de codi per a l'accés a un element d'un vector

Indiqueu com generaríeu codi en MIPS per accedir a un element d'un vector d'una dimensió.

Generació de codi per a l'accés a un camp d'un registre

Indiqueu com generaríeu codi en MIPS per accedir a un camp d'un registre (struct).

Page 67: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

63

SESSIÓ 16: Expressions aritmètiques

FITXA DE LA SESSIÓ Nom: Expressions aritmètiques Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Aho1985]

PRECEDENTS En les sessions anteriors hem estudiat tant l'organització de la memòria com la representació de dades.

OBJECTIUS Estudiar com es genera codi per a expressions aritmètiques.

CONTINGUTS

2.4 Generació de codi per les expressions

2.4.1 Expressions aritmètiques Generar codi per una expressió vol dir generar una seqüència d'instruccions en llenguatge assemblador que correspongui a l'avaluació de l'expressió. La generació de codi es fa mitjançant un esquema de traducció però abans hem de comentar alguns aspectes a considerar.

Aspectes a considerar

Per generar codi per a expressions hem de tenir en compte els següents aspectes: 1. L'avaluació de les expressions ha de respectar la prioritat i l'associativitat dels operadors. 2. S'ha d'implementar l'equivalència i la conversió de tipus segons la definició del llenguatge. 3. L'avaluació es fa utilitzant normalment registres, per tant haurem de gestionar-los.

Page 68: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

64

4. Considerarem que el valor resultant de l'avaluació d'una expressió sempre queda en un registre.

Gestió de registres i temporals

L'avaluació d'una expressió es farà sobre registres, per tant hem de gestionar-los ja que disposem d'un nombre finit. En particular, recordeu que en MIPS disposem des del registre $8 fins al registre $25. Gestionar registres implica dues funcions, demanar_registre i alliberar_registre. Aquestes funcions s'han d'implementar i utilitzar durant la generació de codi. Més endavant donarem un exemple i veurem clarament el seu funcionament. Des del punt de vista teòric i per als exemples que donarem, suposarem que les tenim implementades com procediments i les utilitzarem de la següent manera: d_reg (R) a_reg (R) R serà el número de registre que ens dóna el procediment d_reg o el número de registre que alliberem amb el procediment a_reg. Si hem d'implementar operacions sobre sencers i sobre reals haurem de gestionar tant els registres d'aritmètica sencera com els registres d'aritmètica flotant. Si es gestionen bé els registres és difícil que s'acabin, però en algunes ocasions, depenent dels programes, es podrien esgotar els registres, aleshores la gestió de registres ha de preveure aquest inconvenient i gestionar temporals en memòria. A continuació es mostra un arbre de derivació per a una expressió. En cada no terminal hi ha el número de registre en què ha quedat el resultat de l'expressió. Fixeu-vos-hi que només es necessiten 3 registres i que després d'avaluar l'expressió, el valor quedaria en el registre 8. Els registres 9 i 10 s'hauran alliberat.

Page 69: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

65

Generació de codi per operands

En una expressió hi ha operands i operadors. En el nivell més baix de l'arbre de derivació tenim el següents operadors: - Un identificador. - L'accés a un element d'un vector. - Una constant. - L'accés a un camp d'un registre (struct). - Una crida a una funció. Per a cadascun d'aquests operadors hem de determinar quin codi generem i com l'adrecem . A continuació estudiarem cada cas i comentarem com s'ha de generar codi.

Identificadors com operands

factor ID Durant l'anàlisi semàntica hem verificat que l'identificador ID estigués declarat, per tant tenim el seu descriptor. L'id pot ser l'identificador d'una variable de tipus simple o l'identificador d'una constant. Depenent del cas haurem de generar un load de memòria a registre o un load inmediate del valor de la constant a registre. Quan hem de fer un load des de memòria hem d'adreçar bé la variable en qüestió. L'adreça de memòria serà de la forma: dv($reg). En què dv és el desplaçament de la variable (tenim aquesta informació en la taula de símbols) i $reg és el registre base. Com les variables poden ser locals o no locals el registre base pot canviar. Veurem com es genera el codi per accedir a les variables locals i no locals en pròximes sessions.

Constants com operands

factor CTE_REAL factor CTE_SENCER factor CTE_LOGIC ..... El cas de les constants és simple. El lexema del token corresponent conté el valor per tant podem fer un load inmediate del valor a un registre. Evidentment hem de considerar el tipus corresponent per determinar si s'utilitza un registre d'aritmètica sencera o d'aritmètica flotant en el cas dels números. En el cas de la constant lògica és aquí quan hem de carregar el cert o el fals en un registre considerant però la seva representació. En els llenguatges assembladors, el valor que es pot carregar a un registre amb un load inmediate esta limitat. En el cas de les màquines RISC es disposa de 16 bits.

Page 70: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

66

Una crida a una funció com operand

factor ID( llista_expressions) El codi a generar per una crida de funció és complexe i requereix estudiar-lo en profunditat; està lligat a la generació de codi per funcions i per la instrucció retornar. Ho estudiarem en pròximes sessions.

L'accés a un element d'un vector com operand

factor ID[ llista_expressions ] Per accedir a un element d'un vector hem d'utilitzar la fórmula donada en sessions anteriors. La generació de codi consisteix a: - generar codi per cada una de les expressions que actuen com índexs del vector. - generar codi per accedir a l'adreça de l'element que es vol, és a dir, implementar la fórmula estudiada. - generar codi per carregar el contingut de l'adreça calculada amb la fórmula en un registre. Com en el cas dels id's de variables de tipus simple, l'adreça del vector dependrà també de si p és local o no local.

L'accés a un camp d'un registre com operand

factor ID.ID Per accedir a un camp d'un registre hem d'utilitzar la fórmula donada en sessions anteriors. La generació de codi consisteix a: - generar codi per accedir a l'adreça del camp, és a dir, implementar la fórmula estudiada. - generar codi per carregar el contingut de l'adreça calculada amb la fórmula en un registre.

Esquema de traducció i atributs

Durant l'anàlisi semàntica d'expressions hem utilitzat els atributs sintetitzats: tipus, és_estàtica i valor. Per a la generació de codi utilitzarem els atributs, també sintetitzats, codi i registre L'atribut codi portarà el codi generat. Aquest atribut serà de tipus cadena de caràcters i anirem concatenant el codi que generem en les diferents parts de la gramàtica d'expressions.

Page 71: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

67

En la majoria del casos, el codi es genera en l'ordre que s'haurà d'executar, per tant en lloc d'utilitzar un atribut podem escriure directament en el fitxer de manera que generem el fitxer amb el programa en assemblador. L'atribut registre portarà el registre que hem utilitzat durant la generació de codi d'una expressió per deixar el resultat de la seva avaluació. Aquest atribut serà de tipus sencer. Podeu consultar l'esquema de traducció per a una gramàtica d'expressions simple en la l'exercici 2.14 del problemari.

Conversió de tipus

Com hem estudiat en una sessió anterior la conversió de tipus ha de ser tractada en l'anàlisi semàntica i en la fase de generació de codi. En aquesta última fase és en la qual s'ha de generar el codi necessari per fer explícitament la conversió en temps d'execució. Podeu consultar l'exemple de la referència que genera codi intermedi per expressions simples i assignació considerant la conversió de sencer a real.

[Aho1985] p485-p487

RESUM El codi generat ha de respectar l'associativitat i la prioritat dels operadors. La generació de codi per a expressions aritmètiques comporta la gestió dels registres. A l'hora de generar codi s'ha de considerar cada tipus d'operand i si la variable involucrada és local o no local. La conversió de tipus s'implementa en la generació de codi per a expressions.

Page 72: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

68

Page 73: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

69

SESSIÓ 17: Expressions lògiques

FITXA DE LA SESSIÓ Nom: Expressions lògiques Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Aho1985]

PRECEDENTS En la sessió anterior hem estudiat com es genera codi per expressions aritmètiques.

OBJECTIUS Estudiar com es genera codi per a expressions lògiques, és a dir, expressions que utilitzen operadors lògics (AND, OR, NOT,...) o operadors relacionals (>, <, >=, =, ...).

CONTINGUTS

2.4.2 Expressions lògiques Les expressions lògiques s'utilitzen per calcular valors lògics o com condició en les instruccions condicionals (Si_llavors_sino) o de llaç (Repetir, Mentre, ...). Per tant, poden ser de dues maneres: - expressions amb operadors lògics sobre operands de tipus també lògic. - expressions amb operadors relacionals sobre operands de tipus simples i ordenats.

[Aho1985] p488

Formes de traducció

La generació de codi per avaluar una expressió lògica es pot fer de dues maneres: 1. Representant els valors cert i fals com números (això es el que hem fet en la sessió de representació de les dades) i implementar les operacions lògiques directament amb les operacions que ofereix el llenguatge assemblador com en el cas de les expressions aritmètiques. 2. Implementar les expressions lògiques com un flux de control. És a dir, un valor estarà representat per una posició assolida dins el programa.

[Aho1985] p489 (Methods of Translating Boolean Expressions)

Page 74: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

70

Tipus d'avaluació

La semàntica del llenguatge determina si les expressions lògiques han de ser avaluades totalment o es poden avaluar parcialment optimitzant així l'avaluació. Si el llenguatge permet aquesta última, aleshores és més fàcil d'implementar l'avaluació utilitzant el flux de control. L'avaluació parcial de l'expressió s'anomena circuit curt (short circuit)

[Aho1985] p490-p491 (Short Circuit Code)

Exemples

En les referències trobareu un exemple de generació de codi utilitzant els operadors lògics i un exemple de generació de codi utilitzant el flux de control.

[Aho1985] p490 (Figura 8.20), p494 (Figura 8.24)

Esquema de traducció i atributs

La generació de codi per a expressions lògiques és molt semblant a la generació de codi per a expressions aritmètiques si considerem l'avaluació de tota l'expressió mitjançant els operadors lògics donats pel llenguatge assemblador. Els atributs que utilitzarem seran els mateixos que en el cas de les expressions aritmètiques: tipus, és_estàtica, valor, codi i registre. Podeu consultar l'esquema de traducció per a una gramàtica d'expressions lògiques simple en l'exercici 2.15 del problemari. En aquest exercici s'implementa l'avaluació total de l'expressió mitjançant els operadors lògics proveïts pel llenguatge assemblador.

2.4.3 Treballs recomanats

Gestió de registres

Implementeu les funcions demanar_registre i alliberar_registre en Java, considerant que s'han de gestionar tant els registres d'aritmètica sencera com els registres d'aritmètica flotant.

Load's en MIPS

Estudieu els diferents tipus de load's que té el llenguatge assemblador MIPS.

Page 75: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

71

Operadors lògics i relacionals en MIPS

Estudieu les diferents instruccions per operar amb el tipus lògic que té el llenguatge assemblador MIPS. Estudieu com implementaríeu els operadors relacionals.

RESUM La generació de codi per expressions lògiques es pot fer utilitzant operadors lògics del llenguatge assemblador o mitjançant el flux de control. L'avaluació d'una expressió lògica pot ser total o parcial. Aquesta última és coneguda com el circuit curt. La semàntica del llenguatge ha de definir quina mena d'avaluació s'ha de fer.

Page 76: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

72

Page 77: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

73

SESSIÓ 18: Instruccions simples

FITXA DE LA SESSIÓ Nom: Instruccions simples Tipus: teòrica Format: no presencial Durada: 3 hores Treball a lliurar: no

PRECEDENTS Hem vist com generar codi per operands simples i expressions.

OBJECTIUS Estudiar la generació de codi per l'assignació, les instruccions de lectura i escriptura i altres instruccions simples.

CONTINGUTS

2.5 Generació de codi per les instruccions simples

2.5.1 Assignació

Sintaxi

La instrucció més simple i més utilitzada per als llenguatges de programació és l'assignació. Aquesta instrucció permet modificar el contingut d'una variable en memòria. Hem estudiat la semàntica de l'assignació en sessions anteriors. Per estudiar com es genera codi per a ella, suposarem la següent sintaxi: instr variable := expr en què variable pot ser: - un identificador de variable de tipus simple. - l'accés a un element d'un vector. - l'accés a un camp d'un registre. En cap cas pot ser l'identificador d'una constant.

Page 78: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

74

Codi a generar

El codi que s'ha de generar és molt simple. El valor de l'expressió s'ha d'emmagatzemar (fer un store) en l'adreça corresponent de la variable. Recordeu que el codi generat per una expressió deixa el valor d'aquesta en un registre. En temps de compilació tenim el número del registre en l'atribut registre.

Càlcul de l'adreça

En la sessió d'expressions aritmètiques hem comentat els diferents tipus d'operands que poden haver-hi i per a cadascun d'ells hem explicat com es calcula la seva adreça. En el cas de l'assignació, la variable de la part esquerra és un subconjunt d'aquests operands. La diferència principal és que en el cas de les expressions, a nivell d'operand, es calcula l'adreça i es genera un load a registre i en el cas de la variable només volem calcular l'adreça, ja que l'objectiu és fer un store en aquesta adreça.

Esquema de traducció

L'esquema de traducció per a la instrucció d'assignació és molt senzill. Podeu consultar-lo en l'exercici 2.16 del problemari.

2.5.2 Lectura i escriptura Tots els llenguatges de programació tenen instruccions per llegir i escriure valors de tipus simple. La implementació d'aquestes instruccions es fa normalment utilitzant les primitives de lectura i escriptura del llenguatge assemblador. En el cas de MIPS la lectura i escriptura de sencers, reals i strings es fa mitjançant crides al sistema (SYSCALL).

Lectura

Normalment es poden llegir tipus simples. Com exemple, explicarem com es llegeixen els sencers, el reals i els strings en MIPS. La lectura utilitza els registres reservats $a0, $a1, $v0, $f0 i $f12. El procés general és: - carregar en el registre $v0 el codi del servei de lectura que es vol (per exemple 5 per llegir un sencer i 6 per llegir un float). - fer SYSCALL. - recuperar el valor llegit del registre $v0 en el cas de sencers i del registre $f0 en el cas de reals.

Page 79: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

75

Escriptura

Normalment es poden escriure tipus simples. Com exemple, explicarem com s'escriuen els sencers, el reals i els strings en MIPS. L'escriptura utilitza els registres reservats: $a0, $v0 i $f12. El procés general és: - carregar en el registre $v0 el codi del servei d'escriptura que es vol (per exemple 1 per escriure un sencer i 2 per escriure un float). - carregar en el registre $a0 el sencer que es vol escriure o en $f12 si el que es vol escriure és un real. - fer SYSCALL

2.5.3 Altres Entre altres instruccions simples podem esmentar: el goto, el retornar, el break, l'exit, etc. El goto està en desús però molts llenguatges l'inclouen ja que en ocasions es necessita, sobre tot pel tractament i la recuperació d'errors. La implementació del goto és fàcil, recordeu que el que és difícil és la verificació semàntica. Un goto es tradueix directament en un branch incondicional a una etiqueta. Tots els llenguatges assembladors proporcionen aquesta mena de salts. Les etiquetes també estan permeses pel llenguatge assemblador i només hem de saber quina és la seva sintaxi per poder generar etiquetes en compilació. Estudiarem la instrucció retornar en la generació de codi per funcions. Altres instruccions com break i exit estan relacionades amb llaços, per tant la generació de codi per aquesta mena d'instrucció ha de considerar-se quan es genera codi per a la instrucció de llaç corresponent.

2.5.4 Treballs recomanats

Store's en MIPS

Estudieu les diferents instruccions de tipus store que permet el llenguatge assemblador MIPS.

Syscall's i missatges d'error en execució

Doneu el codi MIPS que es generarà per donar a l'usuari el missatge d'error que es produeix quan un índex esta fora dels límits.

Page 80: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

76

Lectura i escriptura de valors de tipus caràcter i lògic.

Doneu el codi MIPS que es generarà per escriure i llegir valors de tipus caràcter i de tipus lògic.

RESUM La instrucció simple més utilitzada és l'assignació. Generar codi per una assignació vol dir generar un store. La generació de codi per a les instruccions d'escriptura i de lectura es fa mitjançant les crides al sistema del llenguatge assemblador.

Page 81: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

77

SESSIÓ 19: Condicionals i llaços

FITXA DE LA SESSIÓ Nom: Condicionals i llaços Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no

PRECEDENTS En la sessió anterior hem estudiat la generació de codi per instruccions simples.

OBJECTIUS Estudiar com es genera codi per instruccions condicionals i de llaç.

CONTINGUTS En aquesta sessió expliquem com es genera codi per la instrucció If_then_else i per les instruccions de llaç while i repeat.

2.6 Generació de codi per les instruccions condicionals i llaços

2.6.1 Si_llavors_sino

Sintaxi

La instrucció Si_llavors_sino és una instrucció condicional que tenen tots els llenguatges de programació imperatius. Aquesta instrucció permet modificar el flux de control del programa segons el valor de l'expressió condicional. Hem estudiat la seva semàntica en sessions anteriors. Per estudiar com es genera codi per a ella, suposarem la següent sintaxi: instr SI expr LLAVORS linstr SINO linstr FSI instr SI expr LLAVORS linstr FSI

Generació de codi

Per cada instrucció i abans de generar el codi, farem una mena d'esquema en una mena de pseudocodi que ens ajudarà a saber exactament l'ordre del codi, les etiquetes que necessitem i els salts.

Page 82: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

78

Per a la instrucció Si_llavors_sino l'esquema serà el següent:

Codi avaluant l'expressió Si expr.reg = 0 llavors saltar a ET1 Codi representant la llista d'instruccions del sino Saltar a ET2

ET1: Codi representant la llista d'instruccions del llavors ET2: En aquest esquema hem suposat que el cert és 1 i el fals és 0.

Gestió d'etiquetes

Com podem observar en l'esquema donat anteriorment, necessitem dues etiquetes i disposar d'una instrucció de salt condicional i d'una instrucció de salt incondicional. Cada etiqueta dintre d'un programa a de ser única, per tant, hem de gestionar els noms de les etiquetes durant la generació de codi per assegurar que cada vegada utilitzem una de nova. En els exemples utilitzem la rutina demanar_etiqueta que ens tornarà un nom nou d'etiqueta (d_etiq(E)). Disposarem d'un nou atribut anomenat etiqueta pels casos en què necessitem pujar o baixar el nom de l'etiqueta.

Esquema de traducció

Podeu consultar l'esquema de traducció per la instrucció si_llavors_sino en l'exercici 2.17 del problemari.

2.6.2 Mentre i repetir

Sintaxi

Tots els llenguatges de programació imperatius tenen alguna instrucció d'iteració controlada pel valor d'una expressió lògica. Com exemples d'aquesta mena d'instruccions hem estudiat la semàntica del mentre i del repetir en sessions anteriors. Sigui la següent sintaxi: instr MENTRE exp FER linstr instr REPETIR linstr FINS expr

Page 83: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

79

Generació de codi

Per a la instrucció mentre l'esquema serà el següent: ET1: Codi avaluant l'expressió

Si expr.reg = 0 llavors saltar a ET2 Codi representant la llista d'instruccions linstr Saltar a ET1

ET2: En aquest esquema hem suposat que el cert és 1 i el fals és 0.

Esquema de traducció

Podeu consultar els esquemes de traducció per a la instrucció mentre en l'exercici 2.18 del problemari.

RESUM La generació de codi per instruccions condicionals i d'iteració es fa mitjançant etiquetes i salts condicionals i/o incondicionals. La generació de codi per instruccions condicionals i d'iteració necessita gestionar el nom de les etiquetes.

Page 84: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

80

Page 85: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

81

SESSIÓ 20: Condicionals i llaços

FITXA DE LA SESSIÓ Nom: Més condicionals i llaços Tipus: teòrica Format: no presencial Durada: 1 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Aho1985]

PRECEDENTS En la sessió anterior hem estudiat la generació de codi per a les instruccions condicionals i d'iteració.

OBJECTIUS Estudiar la generació de codi per a instruccions més complexes d'iteració i condicionals.

CONTINGUTS En aquesta sessió expliquem com es genera codi per a les instruccions per_fer i segons.

2.6.3 Per_fer

Sintaxi

La majoria dels llenguatges de programació imperatius tenen una instrucció d’iteració controlada pel valor d’una expressió numèrica i que es fa un número finit de vegades. Com exemple d’aquesta mena d’instruccions hem estudiat la semàntica del per_fer en sessions anteriors. Sigui la següent sintaxi: instr PER variable := expr A expr FER linstr

Generació de codi

Com hem vist durant l’anàlisi semàntica poden haver-hi algunes diferencies semàntiques entre els diferents llenguatges. Aquestes diferències són molts importants a l’hora de generar codi ja que les hem de considerar.

Page 86: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

82

Per a la instrucció per_fer un possible esquema és el següent:

Codi avaluant la primera expressió (expr1) Variable <-- expr1.reg

ET1: Codi avaluant la segona expressió (expr2) Si variable > exp2.reg saltar a ET2 Codi representant a la llista d’instruccions linstr Variable <-- Variable + 1 Saltar a ET1

ET2: En aquest esquema hem suposat que la primera expressió s’avalua una sola vegada i que la segona expressió s’avalua en cada iteració.

2.6.4 Segons

Sintaxi

Molts llenguatges de programació imperatius tenen una instrucció condicional composta tipus case. Com exemples d’aquesta mena d’instruccions hem estudiat la semàntica del per_fer en sessions anteriors. Sigui la següent sintaxi: instr SEGONS expr DE llista_de_casos cas_sino FISEGONS llista_de_casos llista_de_ctes : linstr ; llista_de_casos llista_de_casos ε llista_de_ctes constant , llista_de_ctes llista_de_ctes constant cas_sino SINO : linstr cas_sino ε

Generació de codi

Per a la instrucció segons podem donar diferents esquemes. La referència mostra dos possibles esquemes. Quan hi ha aquesta possibilitat hem d’avaluar quin seria el més fàcil d’implementar des del punt de generació de codi.

[Aho1985] p497-500

Page 87: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

83

RESUM La generació de codi per la instrucció per_fer a de considerar la semàntica que defineix el llenguatge respecte a quan s’avaluen les expressions involucrades. La generació de codi per la instrucció segons pot basar-se en dos esquemes diferents. A l’hora d’implementar-la s’ha de tenir en compte quin és el més senzill.

Page 88: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

84

Page 89: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

85

SESSIÓ 21: Treballs i problemes

FITXA DE LA SESSIÓ Nom: Treballs i problemes Tipus: de problemes Format: no presencial Durada: 2 hores Treball a lliurar: no

OBJECTIUS Estudiar en detall la generació de codi per instruccions condicionals i de llaços.

CONTINGUTS

2.6.5 Treballs i problemes

Gestió d’etiquetes

Implementeu la funció demanar_etiqueta en Java.

Salts condicionals i incondicionals en MIPS

Estudieu els diferents tipus de salts que té el llenguatge assemblador MIPS.

Generació de codi per a la instrucció repetir

Doneu l’esquema general per a la instrucció repetir i l’esquema de traducció per a la generació de codi (exercici 2.21 del problemari).

Generació de codi per a la instrucció per_fer

Doneu l’esquema general per a la instrucció per_fer i l’esquema de traducció per a la generació de codi (exercici 2.22 del problemari).

Generació de codi per a la instrucció segons

Doneu l’esquema general per a la instrucció segons i l’esquema de traducció per a la generació de codi (exercici 2.23 del problemari).

Page 90: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

86

Page 91: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

87

SESSIÓ 22: Funcions i procediments

FITXA DE LA SESSIÓ Nom: Funcions i procediments Tipus: teòrica Format: no presencial Durada: 3 hores Treball a lliurar: no

OBJECTIUS Estudiar en detall la generació de codi per a funcions i procediments considerant la gestió de la memòria.

CONTINGUTS

2.7 Generació de codi per funcions i procediments

2.7.1 Funcions i procediments

Funcions i procediments

Com hem vist en l’anàlisi semàntica, la majoria dels llenguatges de programació disposen de funcions i/o procediments. Una funció o procediment defineix un nou context (abast) . Considereu el següent fragment de programa:

En aquest programa hi ha un procediment A i un fragment de programa que crida A.

Page 92: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

88

El codi a generar

Si considerem que estem compilant en una sola passada, el codi que es generarà per a l’exemple donat seguirà el següent esquema:

En aquest esquema distingim tres parts molts importants: - la crida al procediment - el retorn del procediment - l’entrada al procediment Per a cadascuna d‘elles hem de generar el codi necessari per gestionar la pila. A continuació estudiarem quines tasques s’han de realitzar en cada cas.

La crida a una funció

Les tasques a realitzar quan es crida una funció (o procediment) poden dividir-se en tres parts: 1. Les tasques a realitzar abans de saltar a executar la funció. 2. El salt a la funció. Per saltar a la funció necessitem conèixer l’etiqueta del codi corresponent. 3. Les tasques a realitzar quan es retorni de la funció. A efectes didàctics i per poder referir-nos a cada una d’aquestes parts, utilitzarem la següent convenció. El frame des d’on es fa la crida l’anomenaren “el que crida” i utilitzarem les sigles DAR (de criDAR). Cada una de les tasques anteriors seran: 1. DARa, identificarà les tasques abans de criDAR. 2. DARs, identificarà el salt. 3. DARd, identificarà les tasques després de criDAR.

Dins d’una funció

Les tasques a realitzar quan una funció (o procediment) és cridada poden dividir-se en dues parts:

Page 93: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

89

1. Les tasques a realitzar quan s’entra a la funció. 2. Les tasques a realitzar per retornar al codi que l’ha cridat. A efectes didàctics i per poder referir-nos a cadascuna d’aquestes parts, utilitzarem la següent convenció. El frame que és cridat l’anomenaren “el cridat” i utilitzarem les sigles DAT (de criDAT). Cadascuna de les tasques anteriors seran: 1. DATe, identificarà les tasques a l’entrada de la funció. 2. DATs, identificarà les tasques a la sortida, és a dir, quan es retorna.

2.7.2 La pila d’execució

La pila d’execució

La pila d’execució s’organitza en frames. Cada frame és un context i està relacionat amb la crida a un procediment. Cada vegada que es crida un procediment es crea en memòria un nou frame. En un moment donat de l’execució per a cada crida a procediment feta i no acabada (no s'ha executat el retorn) hi ha un frame en memòria. La manera d’organitzar la pila depèn de les característiques del llenguatge. Per poder doncs decidir com gestionarem els frames, quina informació guardarem i quin codi generarem, ens hem de plantejar, entre d’altres, les següents qüestions: 1. Els procediments poden ser recursius? 2. Pot un procediment utilitzar variables no locals? 3. Pot passar-se un procediment com a paràmetre?

Revisió del concepte de frame

Com hem estudiat durant l’anàlisi semàntica, l’execució d’una funció o procediment obre un nou context (frame) en la pila d’execució per poder mantenir entre d’altres coses les variables locals. A continuació donem l’esquema general d’un frame.

Page 94: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

90

Registres SP i FP

Com ja hem comentat en sessions anteriors, per gestionar la pila s’utilitzen dos punters (registres) : - El registre SP (stack pointer) apunta la pròxima adreça de memòria lliure. - El registre FP (frame pointer) apunta la base del context actual (frame). Durant l’execució d’una funció o procediment, el registre $fp es manté i s’utilitza com a registre base per accedir a variables locals i paràmetres. Una vegada finalitzada la funció (o procediment), el $fp serà actualitzat amb la informació de la cadena dinàmica. El registre $sp també es manté durant l’execució de la funció i s’utilitza en el moment d’una crida a una funció (o procediment) per disposar d’una nova àrea de memòria actualitzant el registre $fp amb $sp. Els dos registres es modifiquen quan es crida una funció. En el següent esquema mostrem com es mouen els registres abans i després d’una crida a funció o procediment.

Page 95: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

91

Cadena estàtica (CE)

La cadena estàtica, anomenada també textual link o lexical scope, és l’adreça de la base del context (frame), que correspon al frame més immediat segons l’abast estàtic. S’utilitza per a l’accés a variables no locals. Més endavant estudiarem com es calcula i com s’utilitza. La cadena estàtica només s’utilitza quan el llenguatge té estructura de blocs.

Cadena dinàmica (CD)

La cadena dinàmica d’un frame, anomenada també link dinàmic és l’adreça de la base del frame anterior. Dit d’una altra manera, guarda l’adreça del context que ha cridat el frame actual. Es per aquest motiu que s’anomena dinàmica ja que depèn de l’execució. S’utilitza per poder restablir el context quan retorna la funció. El restabliment consisteix a actualitzar el registre $fp amb el valor de la cadena dinàmica.

Adreça de retorn (AR)

L’adreça de retorn és l’adreça de la instrucció del codi que s’ha d’executar quan es torni de la funció o del procediment associats al frame actual. L’adreça de retorn es guarda quan es crida una funció o procediment i es recupera per saltar al codi corresponent quan la funció o el procediment s’acaben.

Page 96: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

92

2.7.3 Tasques a implementar En apartats anteriors hem diferenciat dos contexts diferents: el del que crida (DAR) i el del que és cridat (DAT). Tant la crida com el retorn d’una funció han de ser implementats, és a dir, hem de generar codi per, en execució, gestionar de forma correcta la pila. En primer lloc i abans de veure en detall el codi que s’ha de generar, estudiarem totes les tasques que s’han de fer. Després determinarem quan s’han de fer i qui ha de fer-les. És a dir, volem relacionar les tasques amb DARa, DARs, DARd, DATe i DATs. Algunes de les tasques poden fer-se indistintament en un lloc o en un altre.

Tasques a fer

A continuació domen una llista exhaustiva de tasques a fer relacionades amb la crida i el retorn d’una funció o d’un procediment. Les tasques no estan en cap ordre predefinit. En els pròxims apartats les agruparem. Codificarem cada tasca per poder referir-la més endavant. T1. Calcular i guardar la cadena estàtica CE. T2. Guardar la cadena dinàmica CD (salvar el registre $fp actual). T3. Guardar l’adreça de retorn AR. T4. Actualitzar $fp. T5. Salvar els registres. - s’han de salvar els registres ja que el procediment que és cridat pot utilitzar-los. T6. Restaurar els registres. T7. Empilar els paràmetres. - el DAR coneix la definició del procediment. - el DAR coneix els paràmetres reals. T8. Saltar a l’etiqueta del codi del procediment. T9. Saltar (tornar) a l’adreça de retorn. T10. Reservar espai en el frame per variables locals. T11. Reservar espai en el frame pel valor de retorn. T12. Alliberar l’espai de memòria (el frame) quan es torna d’un procediment (actualitzar el registre $sp). T13. Restaurar el registre $fp. A continuació donem una manera possible de repartir les tasques entre el DAR i el DAT però no és l’única.

Tasques del context que crida (DAR)

L’estat de la pila abans de fer una crida és el següent:

Page 97: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

93

Les tasques que poden fer-se en el context del que crida són de la T1 a la T8. Recordeu que la CE només s’utilitza si el llenguatge és de blocs. En les pròximes sessions estudiarem com es calcula. Les tasques T1, T2 i T3 són les relatives a la creació del nou frame. Per guardar els valors en memòria es pot utilitzar el registre $sp. Si hem utilitzat el registre $sp per empilar, aleshores l’actualització del $fp per tal que apunti al nou frame es pot fer amb el valor del $sp. Els registres es poden salvar en memòria abans de crear el nou frame. Els registres es poden restaurar després de tornar. Per empilar els paràmetres és necessari conèixer com es passen (per valor, per referència,...). Resumint: DARa : T5, T1,T2, T3, T4, T7 DARs : T8 DARd : T6

Tasques del context que és cridat (DAT)

Podeu consultar l’estat de la pila a l’entrada del procediment en la referència donada. Les tasques que poden fer-se en el context del que és cridat són de la T9 la T13. La reserva d’espai per a les variables locals inclou també l’espai pels paràmetres ja que recordeu que són considerats com variables locals. En el cas d’una funció també hem de reservar espai per guardar el valor que retorna. Reservar espai vol dir sumar-li al registre $sp el que calgui per deixar espai en la pila d’execució.

Page 98: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

94

Resumint: DATe : T10 i T11 DATs : T12, T13 i T9

RESUM Cada funció o procediment defineix un nou context. Hem de generar codi per a la crida a una funció o procediment, per al retorn de la funció o per al procediment i per a l’entrada de la funció o del procediment. Aquest codi es genera seguint uns protocols. Un context és un frame. La pila d’execució s’organitza en frames. Cada crida a una funció o procediment genera un nou frame en la pila d’execució. Un frame conté la cadena estàtica, la cadena dinàmica, l’adreça de retorn, els paràmetres, les variables locals i si cal el valor de retorn.

Page 99: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

95

SESSIÓ 23: Paràmetres

FITXA DE LA SESSIÓ Nom: Paràmetres Tipus: teòrica Format: no presencial Durada: 3 hores Treball a lliurar: no

PRECEDENTS En la sessió anterior hem estudiat en detall quin codi hem de generar en la crida d’una funció o d’un procediment.

OBJECTIUS Estudiar la generació de codi que hem de fer quan es crida una funció o un procediment amb paràmetres.

CONTINGUTS

2.7.4 Paràmetres

Paràmetres formals i reals

Els paràmetres formals són els definits i els utilitzats quan es declara una funció o un procediment. Els paràmetres reals o actuals són els que s’utilitzen en la crida. La generació de codi ha de tenir en compte els paràmetres per: 1. Reservar l’espai necessari dins el frame. La reserva d’espai depèn del tipus i de la forma de pas (valor, referència,...) de cada paràmetre. 2. Empilar els paràmetres reals en el moment de la crida en el frame. El que s’empila depèn també de la forma de pas de paràmetres (valor, referència,...). 3. Generar codi dins del procediment per a l’accés als paràmetres. Això depèn també de la forma de pas.

Pas de paràmetres

Els mecanismes més coneguts per passar paràmetres són: el pas per referència i el pas per valor. A continuació comentarem cadascun d’aquests i veurem com hem de generar codi, tant en la crida al procediment com en l’accés al paràmetre.

Page 100: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

96

Una altra forma de passar paràmetres és l’anomenada valor-resultat. Aquest mecanisme és una barreja dels altres dos.

Pas de paràmetre per valor

Passar un paràmetre per valor vol dir que el valor del paràmetre real serà copiat en l’espai reservat en memòria pel paràmetre formal en el moment de la crida. Els paràmetres formals per valor són tractats dins el procediment com variables locals des del punt de vista d’accés. És a dir, podem accedir al seu valor utilitzant el registre $fp. En la crida hem de generar el codi necessari per copiar el valor o els valors en el cas de tipus estructurats (array’s, struct’s, ...).

Pas de paràmetre per referència

Passar un paràmetre per referència vol dir que el paràmetre formal tindrà l’adreça del paràmetre real. Aquesta adreça ha de guardar-se en l’espai de memòria reservat. Fixeu-vos que sempre reservarem una paraula de memòria per contenir una adreça. L’accés als paràmetres formals per referència es farà utilitzant un adreçament indirecte. En la crida hem de generar el codi necessari per guardar l’adreça de memòria del paràmetre real.

Funcions i procediments com paràmetres

Molts llenguatges de programació permeten passar com paràmetres funcions o procediments. Això significa que el paràmetre formal és un procediment i per tant quan s’utilitzi es cridarà el procediment passat com paràmetre. Aleshores per poder generar codi per a aquesta crida hem de conèixer l’adreça del codi (l’etiqueta). Si el llenguatge té estructura de blocs també hem de passar en el moment de la crida la seva cadena estàtica.

2.7.5 Esquemes de traducció A continuació donem esquemes generals per a la generació de codi en cadascuna de les parts de la gramàtica relacionades amb funcions i/o procediments.

Page 101: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

97

En declaració

Quan es declara un procediment o funció, la generació de codi ha d’incloure: 1. La generació de l’etiqueta corresponent a la primera instrucció del procediment. Aquesta etiqueta ha de ser única i s’utilitzarà per saltar quan es cridi el procediment. El nom de l’etiqueta es guarda com un atribut en el seu descriptor de la taula de símbols. 2. La generació de codi corresponent a DATe. 3. La generació de codi del cos del procediment.

(Exercici 2.24)

En la crida

Quan es crida un procediment o una funció, la generació de codi ha d’incloure: 1. La generació de codi corresponent a DARa, DARs i DARd. 2. Considerar la forma de pas de paràmetres quan s’empilen.

(Exercici 2.25)

En el retorn

En el retorn d’un procediment o funció, la generació de codi ha d’incloure el codi corresponent a DATs.

(Exercici 2.26)

RESUM La majoria dels llenguatges de programació tenen dos mecanismes de pas de paràmetres: per valor i per referència. Alguns llenguatges permeten passar funcions i/o procediments com paràmetre. La manera en què es passen els paràmetres influeix directament sobre la generació de codi. En el cas del pas per valor, en el moment de la crida s’empila el valor. En el cas del pas per referència s’empila l’adreça del paràmetre real.

Page 102: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

98

Page 103: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

99

SESSIÓ 24: Variables no locals

FITXA DE LA SESSIÓ Nom: Variables no locals Tipus: teòrica Format: no presencial Durada: 3 hores Treball a lliurar: no

PRECEDENTS En la sessió anterior hem estudiat com es genera codi quan es fan crides amb paràmetres.

OBJECTIUS En aquesta sessió estudiarem l’accés a les variables locals, els paràmetres i a les variables no locals. Estudiarem també com és calcula i s’utilitza la cadena estàtica.

CONTINGUTS

2.8 Accés a variables

2.8.1 Accés a variables locals Les variables locals són: - les variables declarades localment dins una funció o un procediment. - els paràmetres.

Adreça relativa de les variables locals

Com hem estudiat en una sessió precedent cada variable pot ser adreçada mitjançant un registre base i un desplaçament. Els desplaçaments de les variables són relatius a la base del frame al que pertanyen (en què han estat declarades). El registre base és el punter de la base del frame, és a dir, el registre $fp. Per accedir al contingut d’una variable local haurem de saber si és una variable pròpiament dita o és un paràmetre.

Page 104: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

100

Accés a variables locals

L’accés a una variable local que no és paràmetre es fa directament sumant el desplaçament dv al registre, apuntant la base del frame actual. És a dir, dv($fp) serà l’adreça de la variable en memòria.

Accés a paràmetres par valor

L’accés a un paràmetre passat per valor es fa com si fos una variable local. És a dir, dp($fp) serà l’adreça del paràmetre en memòria.

Accés a paràmetres par referència

L’accés a un paràmetre passat per referència es fa mitjançant una indirecció sobre la seva adreça de memòria. És a dir, el contingut de dp($fp) serà l’adreça del contingut del paràmetre en memòria.

2.8.2 Accés a variables no locals

Variables no locals

Les variables no locals són les variables declarades en un context diferent del que les usa. Els llenguatges amb estructures de bloc permeten aquesta possibilitat. Aleshores l’ordre de declaració de blocs defineix l’abast de les variables. Aquest abast és estàtic, és a dir, pot ser establert en temps de compilació. Com hem vist en sessions precedents, cada frame conté la cadena estàtica que dóna la base del frame anterior segons l’abast estàtic. En la crida a una funció o procediment hem de generar codi per calcular la cadena estàtica i guardar-la en el frame nou que se està creant. Quan tinguem que accedir a una variable no local generarem codi per utilitzar la cadena estàtica i calcular l’adreça corresponent.

Càlcul de la cadena estàtica

El càlcul de la cadena estàtica ha de fer-se quan es genera codi per a la crida a una funció o un procediment. Sigui la crida p(...). Sigui Np el número de bloc en què el procediment p està declarat. Sigui Nc el número de bloc en què el procediment p és cridat.

Page 105: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

101

El número Nc – Np + 1 ens dóna el número de vegades que hem de pujar per la cadena estàtica del frame actual per trobar la cadena estàtica del nou frame que hem de crear.

Utilització de la cadena estàtica

Si dins d’una funció o procediment hem d’accedir a una variable no local, aleshores utilitzarem la cadena estàtica emmagatzemada en el frame actual per trobar la base del frame en què està la variable. Sigui x la variable no local que volem accedir. Sigui Nu el número de bloc en què s’utilitza la variable x. Sigui Nd el número de bloc en què ha sigut declarada. El número Nu – Np ens dóna el número de vegades que hem de pujar per la cadena estàtica del frame actual per trobar el frame (adreça base) en el qual està la variable.

2.8.3 Treballs

Indireccionament en MIPS

Determineu com faríeu l’accés al valor d’un paràmetre passat per referència en MIPS.

RESUM Les variables locals i els paràmetres per valor s’accedeixen directament utilitzant el seu desplaçament i l’adreça del frame actual com base. Els paràmetres per referència s’accedeixen fent una indirecció sobre l’adreça del paràmetre. Les variables no locals s’accedeixen mitjançant la cadena estàtica que ha sigut calculada en el moment de la crida.

Page 106: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

102

Page 107: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

103

SESSIÓ 25: Una introducció

FITXA DE LA SESSIÓ Nom: Una introducció Tipus: teòrica Format: no presencial Durada: 2 hores Dedicació: 2 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Aho1985] [Muchnick1997]

PRECEDENTS Fins ara hem estudiat les fases següents del procés de la compilació: l’anàlisi lexicogràfica, l’anàlisi sintàctica, l’anàlisi semàntica i la generació de codi.

OBJECTIUS Donar una introducció a l’optimització de codi.

Page 108: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

104

CONTINGUTS En aquesta sessió estudiarem les tasques de l’optimitzador de codi, els tipus d’optimització i les seves propietats. Veurem els diferents models d’optimitzador en un compilador multipassada.

3 Optimització

3.1 Introducció

3.1.1 L’optimitzador de codi

Optimitzar codi

L’optimització és normalment una fase d’un compilador multipassada que optimitza codi escrit en un llenguatge intermedi. Un esquema general n’és:

El codi intermedi facilita les tasques de l’optimitzador i augmenta la portabilitat del compilador.

3.1.2 Tipus d’optimització i propietats Les diferents optimitzacions poden classificar-se en dos grups: les optimitzacions independents de la màquina per a la qual compilem i les dependents.

Independents de la màquina

Les optimitzacions independents de la màquina poden ser sobre codi font, sobre l’arbre sintàctic o sobre codi intermedi. Entre les optimitzacions sobre codi font hi ha el càlcul de constants i la simplificació d’algunes expressions ( per exemple: x + 0 per x ).

Page 109: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

105

Las optimitzacions sobre l’arbre sintàctic són transformacions dels arbres que representen expressions en què s’apliquen les propietats d’associativitat, commutativitat i distributivitat. La finalitat n’és optimitzar posteriorment registres, temporals i fins i tot tipus d’operació en llenguatge assemblador (per exemple, ús d’operacions immediates). Les optimitzacions sobre codi intermedi són transformacions del codi intermedi en el mateix codi intermedi. Aquestes són les que estudiarem en detall en el curs.

Dependents de la màquina

Les optimitzacions depenent de la màquina es fan en el moment de generar codi en llenguatge assemblador tot tractant d’optimitzar-lo.

Propietats de les optimitzacions

Les optimitzacions són un conjunt de transformacions però cada transformació que es fa ha de complir amb les condicions següents: 1. Tota transformació ha de preservar el significat del programa. 2. Tota transformació ha de millorar el temps d’execució en mitjana. 3. L’esforç per implementar la transformació ha de ser recompensat.

[Aho1985] p586-587

3.2 Estructura del compilador amb optimització

3.2.1 Models

Model d’optimització de baix nivell

El codi font és traduït en un llenguatge intermedi de baix nivell i totes les optimitzacions es fan sobre aquest codi. Com veurem més endavant hi ha diferents llenguatges intermedis. Amb finalitats educatives citarem el llenguatge LIR (Lower Intermediate Representation) definit i utilitzat en la referència donada. El LIR treballa amb registres i adreces de memòria, les instruccions call són molt detallades i són molt a prop de la màquina.

Page 110: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

106

El model d’optimització de baix nivell s’utilitza en els següents compiladors comercials: - IBM per POWER i powerPC. - HP per PA-RISC.

[Muchnick1997] p7-p11 (Figura 1.5a)

Model d’optimització mixt

El codi font es tradueix en un llenguatge intermedi de nivell mitjà i les optimitzacions (independents de la màquina) es fan sobre aquest. Després es tradueix a LIR per fer-hi les optimitzacions respectives. Com veurem més endavant hi ha diferents llenguatges intermedis de nivell mitjà. Amb finalitats educatives citarem el llenguatge MIR (Medium Intermediate Representation) definit i utilitzat en la referència donada. Aquest model és més portable ja que pot adaptar-se a una nova arquitectura i generar millor codi. Està orientat a la filosofia front end - back end. i s’utilitza en els següents compiladors comercials: - SUN per SPARC. - Digital per Alpha. - Silicon Graphics per MIPS.

[Muchnick1997] p7-p11 (Figura 1.5b)

RESUM Les optimitzacions poden ser independents o dependents de la màquina. Ens hem interessat especialment en les primeres. Totes les optimitzacions han de preservar la funcionalitat. La fase de l’optimització ha de millorar el codi. Hi ha dos models de compilador multipassada amb optimitzador: el model de baix nivell i el model mixt.

Page 111: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

107

SESSIÓ 26: Llenguatges intermedis i MIR

FITXA DE LA SESSIÓ Nom: Llenguatges intermedis i MIR Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Muchnick1997]

PRECEDENTS En la sessió anterior hem donat les idees principals de l’optimització de codi. Hem vist la necessitat de tenir un llenguatge intermedi per expressar el programa font i poder així fer-ne les optimitzacions.

OBJECTIUS Introduir els diferents tipus de llenguatges intermedis.

CONTINGUTS En aquesta sessió estudiarem els llenguatges intermedis de baix nivell, d’alt nivell i de nivell mitjà. Estudiarem, com a exemple de llenguatge intermedi de nivell mitjà, el llenguatge MIR (Medium Intermediate Representation).

3.3 Llenguatges intermedis

3.3.1 Avantatges i decisions

Avantatges

Entre els principals avantatges de tenir un llenguatge intermedi podem citar: 1. Augmenta la portabilitat del compilador. 2. Facilita l’optimització.

Page 112: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

108

Decisions

A l’hora d’utilitzar un llenguatge intermedi ens hem de plantejar, com a mínim, les següents qüestions: 1. Escollim un llenguatge intermedi existent? O en dissenyem un de nou?. 2. Considerar els tipus d’optimitzacions a fer. 3. Decidir el model d’optimització (mixt o de baix nivell). 4. Considerar la màquina per a la qual compilem.

[Muchnick1997] p67-p69

3.3.2 Tipus de llenguatges intermedis

Llenguatge intermedi d’alt nivell

Els llenguatges intermedis d’alt nivell s’utilitzen en les primeres etapes del compilador o en preprocessadors. L’arbre abstracte es pot considerar una representació intermèdia d’alt nivell, un altre exemple són els grafs acíclics de dependències (anomenats DAG’s). Un exemple d’aquest tipus de llenguatge és el codi HIR (High-level Intermediate Representation).

[Muchnick1997] p69-p71

Llenguatge intermedi de nivell mitjà

Els llenguatges intermedis de nivell mitjà són dissenyats per poder representar les característiques de la majoria dels llenguatges de programació però de forma independent de la màquina. Una altra característica que han de tenir és la de permetre generar codi eficient per a diferents arquitectures. Permeten representar variables, temporals i redueixen les estructures de control complexes a salts condicionals o incondicionals. Totes les optimitzacions que estudiarem i farem seran sobre un llenguatge de nivell mitjà anomenat MIR (Medium Intermediate Representation) que estudiarem en aquesta mateixa sessió.

[Muchnick1997] p71

Page 113: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

109

Llenguatge intermedi de baix nivell

Els llenguatges intermedis de baix nivell són molt semblants als llenguatges assembladors i hi ha, en la majoria dels casos, una correspondència un a un entre les instruccions. Normalment són dependents de la màquina i utilitzats en les últimes fases per optimitzar al màxim. Aquests llenguatges utilitzen registres i adreçaments de tipus simple. Un exemple d’aquest tipus de llenguatge és el codi LIR (Low-level Intermediate Representation).

[Muchnick1997] p71-p72, p80 (Taula 4.5)

3.4 El llenguatge MIR

3.4.1 Sintaxi i semàntica

Sintaxi i semàntica

La sintaxi del llenguatge MIR és definida mitjançant una gramàtica en forma Backus Naur estesa (XBNF). La semàntica és explicada en el llibre de referència.

[Muchnick1997] p74-p75 (Taules 4.1, 4.2 i 4.3)

Característiques

Les característiques principals del llenguatge són: - totes les expressions són amb un operand o amb dos operands. - les estructures de control són salts incondicionals o condicionals. - els temporals es denoten amb t1, t2,.... i els noms estan reservats. - les etiquetes es denoten amb L1, L2,...i els noms també estan reservats.

[Muchnick1997] p73-p76

Un exemple

Abans de veure en detall com es tradueix un programa Babel en MIR, proposem estudiar un exemple de com es tradueix codi C en MIR.

[Muchnick1997] p77 (Figura 4.6)

Page 114: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

110

3.5 De Babel a MIR

3.5.1 Expressions i crides a funcions

Expressions

Tota expressió amb més d’un operador ha de convertir-se en un subconjunt d’expressions binàries. Cadascuna d’aquestes expressions es calcularà mitjançant temporals. Els temporals s’identifiquen per t1, t2,...sense reutilitzar-ne els noms. Per exemple, la següent instrucció d’assignació amb una expressió complexa a la dreta: x := y * (z + 2 ) es tradueix en: t1 <-- z + 2 x <-- y + t1

Accés a un element d’un vector d’una dimensió

L’accés a un element d’un vector es fa calculant l’adreça de l’element com es feia en generar codi. Sigui la següent declaració de vector: Var A : vector [li, ls] de tipus1 La fórmula que calcula l’adreça de A[i] és: dA[i] = dA0 + (i - li)*ts en què ts és el número de bytes que ocupa un element de tipus1. Distribuint ts la fórmula esdevé: dA[i] = dA0 +i*ts - li*ts en MIR:

t1 <-- addr A t2 <-- i* ts t3 <-- t1 + t2 t4 <-- li* ts t5 <-- t3 – t4

A t5 hi tenim l’adreça de A[i]. Si volem accedir al seu contingut utilitzarem l’operador *. Per exemple, si fem:

*t5 <-- 2

Page 115: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

111

estaríem guardant el valor 2 en A[i]. Per convenció utilitzarem ts en les expressions, és a dir, no la substituirem pel seu valor ja que així queda independent de la màquina. En canvi, el límit inferior li és una constant, per tant, la substituirem pel seu valor.

Crides a funcions

La traducció d’una crida a una funció es fa mitjançant la instrucció CallInst que permet donar el nom de la funció, els paràmetres i els tipus dels paràmetres. El pas de paràmetres (valor o referència) es fa mitjançant la instrucció receive al començament del cos de la funció. En el cas d’una funció, a la part esquerra es dóna del temporal en què es guarda el valor de retorn. El cas de la crida a un procediment, es fa com en el cas de la funció però, com que no torna cap valor, a la part esquerra de la instrucció s’hi posa call. Torneu a mirar l’exemple proposat en la referència però fixant-vos bé en les crides i en les primeres instruccions dels procediments.

[Muchnick1997] p77 (Figura 4.6)

3.5.2 Instruccions A continuació comentem com es faria la traducció d’algunes de les instruccions de Babel.

Assignació

La instrucció assignació: var := exp es tradueix segons el següent esquema: - S’ha de generar el codi MIR necessari per avaluar l’expressió considerant que l’expressió no pot tenir més d’un operador. - Si la variable representa l’accés a un element d’un vector, s’ha de generar el codi MIR corresponent al càlcul de l’adreça tal com hem explicat anteriorment. - Es genera la instrucció d’assignació.

(Exercici 3.3 resolt)

Page 116: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

112

Condicionals

La instrucció condicional:

si exp llavors inst1 si no inst2 fsi es tradueix segons el següent esquema:

If ! exp goto L1 inst1 goto L2

L1: inst2 L2: Si us heu fitxat en la sintaxi del llenguatge MIR, les expressions relacionals estan amb un operand o amb dos operands. Per tant, si l’expressió en Babel és més complexa s’haurà d’avaluar mitjançant subexpressions i utilitzant temporals.

(Exercici 3.4 resolt)

Mentre

La instrucció mentre:

mentre exp fer inst1 es tradueix segons el següent esquema:

L1: if !exp goto L2 inst1 goto L1

L2:

Com en el cas anterior, l’expressió s'ha d’avaluar per parts, si és complexa.

(Exercici 3.5 resolt)

Altres instruccions

Altres instruccions que val la pena citar són: Retornar expr: Es tradueix directament en la instrucció return. Aquesta última accepta només un operand. Si l’expressió és de més d’un operand s’haurà d’avaluar en subexpressions. Llegir(id1,id2,…): Es tradueix com un call.

call llegir, (id1,tipus1;id2, tipus2;…)

Page 117: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

113

Escriure(exp1,exp2,…): Es tradueix com un call, però com que es poden escriure expressions, aquestes han de ser avaluades abans per poder escriure el valor.

t1 <-- exp1 t2 <-- exp2 … call escriure, (t1,tipus1;t2,tipus2,….)

3.5.3 Problemes

Accés a un element d’un vector de dues dimensions

Traduïu el fragment de programa donat en MIR.

(Exercici 3.1)

La instrucció per_fer

Doneu com es traduiria la instrucció per_fer.

(Exercici 3.2)

La instrucció repetir

Doneu com es traduiria la instrucció repetir.

(Exercici 3.6)

RESUM Els llenguatges intermedis poden classificar-se en: llenguatges de baix nivell, llenguatges de nivell mitjà i llenguatges d’alt nivell. El llenguatge MIR (Medium-level Intermediate Representation) és un exemple de llenguatge de nivell mitjà. Aquest llenguatge és el que utilitzarem per fer les optimitzacions.

Page 118: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

114

Page 119: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

115

SESSIÓ 27: Anàlisi del codi i diagrama de blocs

FITXA DE LA SESSIÓ Nom: Anàlisi del codi i diagrama de blocs Tipus: teòrica Format: no presencial Durada: 2 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Muchnick1997]

PRECEDENTS En la sessió anterior hem estudiat el llenguatge MIR.

OBJECTIUS Introduir l’anàlisi del flux de dades i poder així construir el diagrama de blocs d’un programa MIR. Aquest és el primer pas per poder fer les optimitzacions.

CONTINGUTS En aquesta sessió donarem primer un exemple de traducció a MIR i després començarem a analitzar el programa MIR generat utilitzant les tècniques bàsiques que formen part de la teoria de l’optimització.

3.6 Un exemple

3.6.1 Un exemple Abans de començar a estudiar les diferents optimitzacions que podem fer-li a un programa escrit en codi MIR, farem la traducció d’un fragment de codi a codi MIR.

Un fragment de codi

Consideri el següent fragment de codi:

Page 120: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

116

Var a: vector[0..5] de sencer; i, x, j : sencer;

inici i:= 2 ; Mentre i <= 5 fer inici

x:= a[i] ; a[0] := x ;

j := i –1 ; Mentre x < a[j] fer Inici

a[j+1] := a[j]; j := j –1:

fi; a[j+1] := x; i := i +1:

fi; fi. Aquest codi correspon a una implementació de l’algorisme d’ordenació de la bombolla.

La traducció a MIR

En l’exercici 3.8a) trobareu la traducció a MIR del fragment de programa anterior. Aquest exemple és molt important ja que l’utilitzarem al llarg de tot el capítol.

3.7 Tipus de codi i ordre de les optimitzacions

3.7.1 Tipus de codi i ordre de les optimitzacions

Ordre de les optimitzacions

En el diagrama proposat en la referència es mostra tot l’univers d’optimitzacions relacionant-les amb el tipus de llenguatge i presentant-les en l’ordre en què han de ser fetes. Si ens fixem en el diagrama observem que dues de les optimitzacions són comunes a pràcticament totes les altres. Aquestes són: la propagació de constants i les simplificacions algebraiques. Això es deu al fet que quan es fan les altres optimitzacions es genera codi susceptible sempre d’aplicar-li aquestes. De totes les optimitzacions nosaltres estudiarem les relacionades amb el bloc C.

[Muchnick1997] p11-p14 (Figura 1.7)

Page 121: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

117

Tipus de codi on es fan les optimitzacions

Les optimitzacions marcades amb A s’apliquen típicament sobre codi font o codi intermedi d’alt nivell. Les optimitzacions marcades amb B i C es fan típicament sobre codi intermedi de nivell mitjà i en algunes ocasions sobre codi intermedi de baix nivell. Les optimitzacions del bloc D s’apliquen comunament sobre codi intermedi de baix nivell. Finalment, les presentades en el bloc E són optimitzacions que operen sobre objectes relocalitzables. Al llarg d’aquest capítol utilitzarem com llenguatge intermedi de nivell mitjà el llenguatge MIR.

[Muchnick1997] p11-p14 (Figura 1.7)

3.8 Etapes d'un optimitzador

3.8.1 Anàlisi del flux de control

Per què són importants els blocs?

L’objectiu de l’anàlisi del flux de control és identificar els anomenats blocs i construir a partir d’ells un diagrama en què estigui reflectit el flux de control del programa. Una vegada tinguem identificats els blocs ens podem referir a optimitzacions locals i optimitzacions globals. Entenent per locals les que poden fer-se dins d’un mateix bloc i per globals les que actuen considerant més d’un bloc. Un altre aspecte que assolirem serà la identificació de llaços. Tractarem els llaços en pròximes sessions.

Bloc bàsic

Informalment un bloc és un fragment de codi seqüencial que ha de ser executat començant per la primera instrucció de la seqüència i només pot acabar (sortir) per l’última. Dit d’una altra manera, no hi ha la possibilitat “d’entrar“ al bloc ni de sortir del bloc pel mig.

[Muchnick1997] p173

Identificació de blocs bàsics

La primera instrucció d’un bloc bàsic pot ser: - el punt d’entrada de la rutina - una instrucció amb una etiqueta - una instrucció que estigui després d’un if, d’un salt o d’un retornar

Page 122: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

118

Aquestes instruccions són anomenades “leaders”. Cada leader serà la primera instrucció d’un bloc bàsic. Per identificar els blocs bàsics hem de: 1. Identificar els “leaders”. 2. Per cada “leader” incloure en el seu bloc bàsic totes les instruccions des del leader fins el pròxim leader sense incloure aquest. A partir dels blocs podem construir el graf del flux de control del programa.

[Muchnick1997] p170 (Figura 7.2), p172 (Figura 7.4)

Un exemple

En l’exercici 3.8b) podeu trobar, per l’exemple de codi MIR que hem donat abans, la construcció del graf de flux de control.

3.8.2 Anàlisi del flux de dades L’objectiu de l’anàlisi del flux de dades és obtenir informació sobre com el programa manipula les seves dades. Com veurem més endavant la majoria de les optimitzacions poden fer-se si es compleixen certs requisits. Per exemple, per fer propagació de còpia cap de les dues variables involucrades poden canviar de valor. L’anàlisi del flux de dades es fa sobre el flux de control i crea diferents estructures de dades pràcticament específiques a cada optimització. En el curs no veurem aquestes estructures ja que només volem fer una introducció a l’optimització.

3.8.3 Transformacions Cada optimització és una transformació del codi. Les diferents transformacions que podem fer es divideixen en: locals i globals. Una transformació és local si es pot fer considerant només les instruccions d’un bloc bàsic. Una transformació és global si necessitem considerar més d’un bloc. Moltes transformacions poden fer-se de manera local i de manera global. Normalment es fan primer les locals. Al llarg de les pròximes sessions estudiarem en detall un conjunt de transformacions. Totes les transformacions han de preservar la funcionalitat.

Page 123: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

119

RESUM Diferents optimitzacions poden ser aplicades en un ordre específic sobre diferents nivells de llenguatges intermedis. L’anàlisi del flux de control dóna com resultat un diagrama de blocs bàsics. Les transformacions preserven la funcionalitat i poden ser locals i/o globals.

Page 124: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

120

Page 125: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

121

SESSIÓ 28: Transformacions preservant funcionalitat

FITXA DE LA SESSIÓ Nom: Transformacions preservant funcionalitat Tipus: teòrica Format: no presencial Durada: 3 hores Dedicació: 3 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Muchnick1997]

PRECEDENTS En sessions anteriors hem introduït els conceptes bàsics per fer optimitzacions.

OBJECTIUS Estudiar un conjunt d’optimitzacions que s’apliquen principalment sobre codi de nivell mitjà tot preservant la funcionalitat.

CONTINGUTS En aquesta sessió presentem en primer lloc les optimitzacions anomenades matineres que poden ser aplicades en qualsevol moment, és a dir, a diferència de totes les altres no han de fer-se en un ordre. Aquestes optimitzacions són les que apareixen en el diagrama donat en la sessió anterior , com les rutines accessibles des de les altres optimitzacions. En segon lloc estudiem un grup d’optimitzacions que depenen del flux de dades i que poden ser aplicades de forma local o de forma global.

3.9 Optimitzacions early

3.9.1 Avaluació d’expressions constants

Optimització

L’avaluació d’expressions constants (constant folding) és una optimització aplicada de forma local a una expressió. L’optimització consisteix a substituir les constants pels seus valors, determinar si l’expressió que involucra la constant és estàtica i, si ho és, aleshores avaluar-la substituint l’expressió pel seu valor. Aquesta optimització ja l’havíem comentat en els capítols d’anàlisi semàntica i de generació de codi.

[Muchnick1997] p329-p331

Page 126: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

122

Quan s’aplica?

Cada vegada que es faci una transformació en el codi podem aplicar aquesta optimització. Aquesta optimització es pot considerar implementada com una rutina que actua localment a nivell de les expressions.

Un exemple

Consulteu l’exercici 3.8c).

3.9.2 Simplificacions algebraiques i reassociació

Optimització

Les simplificacions algebraiques utilitzen propietats dels operadors o combinacions particulars d’operador i operand per simplificar les expressions. La reassociació es refereix a la utilització de propietats algebraiques específiques com l’associativitat, la commutativitat i la distributivitat per dividir una expressió en parts: constants, invariants del llaç i variables. Aquesta optimització és molt útil sobretot quan es genera codi intermedi de nivell mitjà a partir del codi font i particularment en les fórmules d’accés als vectors. Cada operador binari té un conjunt d’expressions que donen sempre un valor constant combinant qualsevol operand amb l’element identitat de l’operador. A continuació en mostrem uns exemples: i + 0 = 0 + i = i – 0 = i i * 1 = 1 * i = i / 1 = i

[Muchnick1997] p333-p335

Quan s’aplica?

Cada vegada que es faci una transformació en el codi, involucrant una expressió, podem aplicar aquesta optimització. Aquesta optimització es pot considerar implementada com una rutina que actua localment a nivell de les expressions.

Un exemple

Consulteu l’exercici 3.8c).

Page 127: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

123

3.10 Transformacions preservant funcionalitat

3.10.1 Eliminació de subexpressions comunes

Definició de subexpressió comuna

Una ocurrència d’una expressió en un programa és una subexpressió comuna si hi ha una altra ocurrència de l’expressió que la precedeix en l’ordre d’execució i els operands de l’expressió no canvien de valor entre les dues avaluacions.

[Muchnick1997] p378

Optimització

Consideri el següent fragment de programa: v1 <-- exp1 ... ... v2 <-- exp1 ... L’optimització consisteix en : 1. Generar un nou temporal i assignar-li la subexpressió comuna ( ti <-- exp1). 2. Inserir immediatament després la instrucció v1 <-- ti. 3. Eliminar v1 <-- exp1. 4. Canviar la instrucció v2 <-- exp1 per v2 <-- ti.

[Muchnick1997] p379 (Figura 13.1)

Quan s’aplica?

Aquesta optimització es pot aplicar sobre codi intermedi de nivell mitjà o de baix nivell. Primer s’aplica localment a cada bloc i després globalment. Es pot iterar tantes vegades com sigui necessari.

Un exemple

Consulteu l’exercici 3.8d).

Page 128: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

124

3.10.2 Propagació de còpia

Optimització

La propagació de còpia és una transformació que, donada una assignació x <--y substitueix les subseqüents utilitzacions de x per y sempre que no hagin canviat els valors ni de x ni de y. Consideri el següent fragment de programa: v1 <-- v2 ... v3 <-- a + v1 ... L’optimització consisteix en : Canviar l’assignació v3 <-- a + v1 per v3 <-- a + v2

[Muchnick1997] p357 (Figura 12.23)

Quan s’aplica?

Aquesta optimització es pot aplicar sobre codi intermedi de nivell mitjà o de baix nivell. Primer s’aplica localment a cada bloc i després globalment. Es pot iterar totes les vegades que es necessiti. L’eliminació de subexpressions comunes genera còpies simples.

Un exemple

Consulteu l’exercici 3.8e).

3.10.3 Eliminació de codi mort

Codi mort

Una variable és viva en un punt del programa si el seu valor és utilitzat després, si no és morta en aquest punt. Codi mort o inútil és el que calcula un valor que mai serà utilitzat. Si a una variable local li és assignat un valor mort , la variable i la instrucció que assigna a la variable són mortes si la variable no és utilitzada en cap camí del flux d’execució.

[Muchnick1997] p592-p595

Page 129: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

125

Optimització

La identificació de codi mort es pot fer mitjançant l’anàlisi del flux de dades o utilitzant una estructura de dades específica. L’optimització consisteix en l’eliminació de les instruccions considerades mortes.

[Muchnick1997] p593 (Figura 18.18)

Quan s’aplica?

Es pot aplicar sobre codi intermedi de qualsevol nivell però el codi mort es genera per l’aplicació d’altres optimitzacions. Per exemple, la propagació de codi genera codi mort.

Un exemple

Consulteu l’exercici 3.8f).

RESUM L’avaluació d’expressions constants i la simplificació d’expressions algebraiques són dues optimitzacions que poden fer-se en qualsevol moment considerant-les rutines que poden ser cridades després d’altres optimitzacions. Les transformacions que preserven funcionalitat són: l’eliminació de subexpressions comunes, la propagació de còpia i l’eliminació de codi mort. L’eliminació de subexpressions comunes pot generar còpies simples i la propagació de còpia pot generar codi mort.

Page 130: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

126

Page 131: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

127

SESSIÓ 29: Codi invariant, reducció de forces i variables d’inducció

FITXA DE LA SESSIÓ Nom: Codi invariant, reducció de forces i variables d’inducció Tipus: teòrica Format: no presencial Durada: 3 hores Dedicació: 4 hores Treball a lliurar: no Material:

o Bibliografia bàsica: [Muchnick1997]

PRECEDENTS En la sessió anterior hem estudiat les optimitzacions que podíem fer a nivell de bloc.

OBJECTIUS Estudiar les diferents optimitzacions que poden fer-se a nivell de llaços amb la finalitat de millorar el temps d’execució.

CONTINGUTS En primer lloc amb l’ajuda del diagrama de blocs identificarem els llaços per determinar on fem les optimitzacions. En segon lloc identificarem el codi invariant, és a dir, el codi que no depèn del llaç i que per tant el podem treure fora. En tercer lloc identificarem les anomenades variables d’inducció bàsiques i les dependents. Per aquestes variables reduirem, si és possible, les operacions. Finalment estudiarem la possibilitat d’eliminar algunes de les variables d’inducció utilitzades.

3.11 Optimització de llaços

3.11.1 Moviment de codi invariant

Identificació de llaços

El primer pas per poder fer qualsevol de les optimitzacions d’aquesta sessió és identificar els llaços. La identificació dels llaços es fa amb l’ajuda del diagrama de blocs obtingut per l’anàlisi de flux de control.

Page 132: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

128

Optimització

Aquesta optimització reconeix els càlculs dins dels llaços que produeixen el mateix valor en cada iteració. Aleshores, aquests càlculs són invariants i per tant poden estar fora del llaç. Fora del llaç vol dir posar les instruccions en el bloc anterior a l’entrada del llaç. La identificació dels càlculs invariants és simple. Una instrucció és invariant si : - els seus operands són constants. - totes les definicions dels operands que intervenen són fora del llaç - les definicions del operands que intervenen són dins del llaç però totes són invariants.

[Muchnick1997] p397

Quan s’aplica?

Es pot aplicar sobre codi intermedi de qualsevol nivell.

Un exemple

Consulteu l’exercici 3.8g).

3.11.2 Reducció d’operacions Aquesta optimització identifica primer les variables d’inducció i després tracta de reduir la força de les operacions ( per exemple canviar multiplicacions per sumes). Una vegada feta aquesta reducció podrem, potser, eliminar algunes de les variables d’inducció.

Variables d’inducció bàsiques i dependents

Distingim entre dos tipus de variables d’inducció: les bàsiques i les dependents. Una variable d’inducció és una variable en la qual els seus valors formen una progressió aritmètica sobre una part del programa, normalment en un llaç.

Variable d’inducció bàsica

Una variable i és anomenada variable d’inducció bàsica si està explícitament modificada per la mateixa constant en cada iteració del llaç. Una variable d’inducció té una de les següents equacions: i <-- i + d o i <-- d + i

Page 133: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

129

en què d és un sencer i és constant en el llaç. Cada variable d’inducció bàsica i defineix una classe anomenada la classe i.

[Muchnick1997] p426

Variable d’inducció dependent

Una variable j és anomenada variable d’inducció dependent si el seu valor depèn d’una variable d’inducció bàsica o d’una altra variable d’inducció dependent. Les assignacions que poden generar variables d’inducció dependents són: j <-- i * e j <-- e * i j <-- i + e j <-- i - e j <-- e + i j <-- e - i j <-- - i en què i és una variable d’inducció (bàsica o dependent) i e és una constant en el llaç. Cada variable d’inducció dependent té una equació lineal associada de la forma: j <-- b * i + c en què b i c són constants i i és una variable d’inducció (bàsica o dependent). Si i no és bàsica, aleshores i té una equació lineal de la forma: i <-- b1 * i1 + c1 en què i1 és una variable d’inducció bàsica i per tant j té l’equació lineal següent: j <-- b * (b1 * i1 + c1) + c j <-- b * b1 * i1 + b *c1 + c Cada variable d’inducció dependent pertany a la classe d’una variable d’inducció bàsica.

[Muchnick1997] p428-p429

Algorisme de reducció

Una vegada identificades les variables d’inducció bàsiques i les seves respectives classes, considerant les variables d’inducció dependents, podem aplicar l’algorisme de reducció d’operacions. Aquest algorisme posa cada variable d’inducció dependent en funció d’ella mateixa canviant els productes per sumes. Això fa que la variable d’inducció dependent no sigui dependent d'una variable bàsica. Si arribem a fer-ho per a totes les variables dependents, aleshores la bàsica corresponent podria passar a ser codi mort.

Page 134: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

130

Podeu consultar l’algorisme en la referència donada.

[Muchnick1997] p435-436

Quan s’aplica?

S’aplica normalment sobre codi intermedi de nivell mitjà.

Un exemple

Consulteu l’3xercici 3.8h).

3.11.3 Eliminació de variables d’inducció Després de reduir les operacions podem, en alguns casos, eliminar variables d’inducció. Les variables d’inducció que podem eliminar són bàsiques, dependents i fins i tot noves variables introduïdes per l’algorisme de reducció.

Quines variables podem eliminar?

Una variable d’inducció podrà ser eliminada si no és necessària per al programa. Si es compleix alguna de les situacions següents, aleshores podem eliminar la variable en qüestió: 1. La variable no contribueix en cap càlcul. 2. La variable es torna inútil com a resultat d’altres transformacions, com la reducció d’operacions. 3. La variable ha estat creada durant l’algorisme de reducció i ara és inútil com a resultat d’una altra reducció. 4. La variable només s’utilitza en la condició per sortir del llaç i pot ser reemplaçada per una altra variable d’inducció en aquest context. Això es coneix com el reemplaçament del test d’un condicional que veurem a continuació.

[Muchnick1997] p447

Reemplaçament del test d’un condicional

Sigui i una variable d’inducció bàsica en què el seu valor només s’utilitza en la condició de sortida del llaç, aleshores, aquesta variable pot ser eliminada però haurem de substituir el test per un altre equivalent i que depengui d’una variable d’inducció dependent. La idea principal de l’algorisme és trobar una condició equivalent.

Page 135: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

131

[Muchnick1997] p448-450

Un exemple

Consulteu l’exercici 3.8i).

3.12 Comptant operacions

3.12.1 Comptant operacions En general és indecidible quin efecte tindrà un conjunt d’optimitzacions sobre un programa. Les optimitzacions poden optimitzar espai o temps. Algunes optimitzacions que busquen reduir el temps, decrementen també l'espai. En canvi altres, que no hem estudiat, decrementen espai en detriment del temps. Com hem vist en les primeres sessions d’aquest capítol hi ha moltes optimitzacions. Algunes més importants que d’altres. Escollir les més adients en un model de compilador amb optimitzador és difícil. Sobretot perquè moltes d’aquestes optimitzacions són difícils d’implementar i porten molt de temps. Com a petit exercici podem comptar el número d’operacions que té el programa abans d’optimitzar i després d’optimitzar-lo. Aquests comptes ens donen una idea del que pot fer un optimitzador. A efectes de l’exemple (Exercici 3.8j) comptarem les sumes i les restes juntes per un costat i els productes i les divisions per l’altre. Després podem comparar i tenir així una idea global de com hem millorat.

RESUM Les optimitzacions sobre llaços es fan per etapes: identificació de llaços, moviment de codi invariant, identificació de variables d’inducció, reducció de forces i finalment eliminació de variables d'inducció.

Page 136: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

132

Page 137: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

133

SESSIÓ 30: Compiladors comercials i llenguatges intermedis

FITXA DE LA SESSIÓ Nom: Compiladors comercials i llenguatges intermedis Tipus: teòrica Format: no presencial Durada: 1 hora Treball a lliurar: no Material:

o Bibliografia bàsica: [Muchnick1997]

PRECEDENTS En les sessions precedents a aquest capítol hem estudiat els models d’optimitzador que podem implementar i un conjunt d’optimitzacions que es poden implementar.

OBJECTIUS Estudiar alguns dels compiladors comercials i altres llenguatges intermedis.

CONTINGUTS En primer lloc es presenten alguns compiladors comercials i es destaca sobretot l’estructura del compilador, el model escollit d’optimitzador i les optimitzacions implementades. Aquesta sessió és de caràcter divulgatiu.

3.13 Casos d’estudi

3.13.1 Compiladors comercials i optimització A continuació comentem tres compiladors comercials.

Compiladors SPARC de Sun

Sun proveeix compiladors per diferents llenguatges: C, C++, Fortran77 i Pascal. El compilador consisteix en un front end que genera codi intermedi propi (Sun IR). Després optimitza aquest codi produint de nou codi Sun IR. Finalment té un mòdul que genera codi relocalitzable. Com en la majoria dels compiladors comercials, hi ha la possibilitat de demanar que no optimitzi. A més suporta quatre nivells d’optimització.

[Muchnick1997] p708-p716

Page 138: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

134

Compiladors IBM XL per POWER i PowerPC

Els compiladors per a les arquitectures POWER i PowerPc de IBM són coneguts com la família XL i inclouen compiladors per C, Fortran77, Pascal, C++ i PL.8. La família XL implementa un model d’optimitzador de baix nivell. Utilitza el seu propi llenguatge intermedi anomenat XIL.

[Muchnick1997] p716-p725

Compiladors Digital Equipment per Alpha

Els compiladors disponibles per Alpha són Fortran 90, Ansi C, C++, Ada, Cobol, Pascal, PL/1 i Bliss. Cada compilador té el mateix front end que genera el seu propi codi intermedi anomenat CIL. Després hi ha un back end per a cada compilador. La primera fase del back end consisteix a traduir el codi CIL a un altre codi intermedi EIL. L’optimitzador transforma aquest codi una altra vegada en codi EIL. Finalment el generador de codi genera codi relocalitzable. El model d’optimitzador implementat és el mixt. Els compiladors proveeixen sis nivells d’optimització.

[Muchnick1997] p716-p725

3.13.2 Altres llenguatges intermedis Com hem vist, cada compilador comercial defineix el seu propi llenguatge intermedi. Això també passa en els compiladors que no són amb finalitats comercials.

Alguns

Entre d’altres llenguatges intermedis citem els següents: P-code, llenguatge intermedi produït pel compilador de Pascal-P. És un tipus de llenguatge assemblador per una màquina hipotètica amb arquitectura de pila. U-Code, llenguatge intermedi universal per Pascal, és una generalització del P-code per facilitar l’optimització. Hpcode, llenguatge intermedi basat en una arquitectura de pila i utilitzat per HP en alguns dels seus compiladors per RISC. Suporta els llenguatges Ada, COBOL, Pascal i C++. WAM , llenguatge intermedi per Prolog compilat. FLIC, llenguatge intermedi funcional. AIDA, llenguatge intermedi per ADA.

Page 139: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

135

RESUM Els compiladors comercials tenen el seu propi llenguatge intermedi. Tots els compiladors comercials implementen optimitzacions. Existeixen molts llenguatges intermedis. Cada compilador defineix pràcticament el seu llenguatge intermedi.

Page 140: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

136

Page 141: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

137

ANNEXOS

I El llenguatge Babel

El llenguatge Babel és un llenguatge de programació imperatiu que és fa servir per a la part pràctica de l’assignatura. No és sensitiu a minúscules i majúscules.

1. Aspectes lexicogràfics

a) Identificadors. No són sensitius a minúscules/majúscules. Comencen obligatòriament amb una lletra. Només poden contenir lletres, dígits i _ (underscore). Tenen una grandària màxima de 32 caràcters.

b) Constants lògiques. Només pot ser CERT o FALS.

c) Constants senceres. Les constants senceres són sense signe.

d) Constants cadenes. Constants strings que denoten un conjunt de caràcters

entre cometes dobles (per exemple: “hola”). Són vàlids tots aquells caràcters imprimibles.

e) Operadors relacionals. Els operadors relacionals són: == , > , < , >= , <= , <>

(diferent).

f) Operadors lògics. AND, OR i NOT.

g) Operadors aritmètics. +, - , * , /

h) Operadors de cadenes: & (concatenació)

i) Tipus predefinits. Hi ha dos tipus simple predefinits: SENCER i LOGIC.

j) Paraules claus. Totes les paraules clau (per exemple: llavors, funcio, ...) són paraules reservades.

k) Separadors. Els espais (blancs) són significatius i actuen com separadors. A

més a més d’aquests, pot haver en qualsevol punt del programa d’entrada tabuladors i salts de línia.

l) Comentaris. Els comentaris començant per // i acabant amb un salt de línia.

Per tant, no poden ocupar més d’una línia. Els comentaris han de ser reconeguts. Els comentaris poden contenir qualsevol caràcter imprimible.

m) Símbols especials. Són símbols especials : (, ), [, ], .. , , , ; , : , etc.

n) Constructors de tipus compostos : VECTOR, CADENA

Page 142: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

138

2 Sintaxi La sintaxi del llenguatge ve representada pels següents diagrames de Conway.

Page 143: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

139

Page 144: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

140

Page 145: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

141

3 Semàntica La semàntica donada no és exhaustiva, si hi ha algun cas que no estigui especificat, se n’ha de proposar una.

• Declaració de constants: - Si la constant es declara a través d’algun identificador, aquest ha d’existir

com constant en el bloc actual o en els que la niuen. - L'expressió a què s’inicialitza la constant ha de ser estàtica, és a dir,

avaluada en temps de compilació. El tipus de la constant és el tipus de l’expressió.

- Es poden declarar constants de tipus simple o constants cadenes.

• Declaració de funcions: - El retorn de la funció es fa quan l’execució del programa troba el fifunc o

quan s’executa la instrucció retornar. - Cada funció com a mínim ha de tenir una instrucció RETORNAR. - Si es volen passar paràmetres per valor s’ha d’utilitzar la paraula clau val.

També es pot utilitzar ref en el cas de pas per referència. - Cada funció defineix un nou context, és a dir, un nou abast.

• Declaració de constants, variables i funcions:

- No pot existir un altre identificador amb el mateix nom en el mateix bloc.

• Ús d’identificadors : - Tot identificador de constant, variable i funció utilitzat ha d’estar prèviament

declarat en el bloc en què s’utilitza o en el bloc principal . S’ha de tenir en compte unes altres verificacions (segons el context i el tipus en què aquest identificador es faci servir) que es tracten en l’apartat de instruccions i expressions.

• Tipus simples:

- Sencer: és un tipus simple i ordenat. El seu rang ve determinat directament per la màquina per a la qual es compila.

- Logic: és un tipus simple i ordenat (fals < cert).

• Tipus compostos : - Vectors estàtics d’1 dimensió.

les expressions que defineixen els límits de la dimensió han de ser estàtiques.

límit inferior ≤ límit superior. els límits han de ser de tipus sencer representació interna a escollir no es pot operar sobre vectors l’accés a un element del vector es fa mitjançant [ ]

- Cadenes estàtiques de caràcters (strings) l’expressió que defineix la grandària màxima ha de ser estàtica i de tipus sencer. representació interna a escollir. la funció trim (<exp>) : <exp> ha de ser de tipus cadena. En execució aquesta funció torna una cadena que és igual a la cadena original sense espais ni per davant ni per darrere.

Page 146: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

142

• Conversions i equivalències

- Amb els tipus compostos VECTOR i CADENA es defineix una equivalència estructural.

- No hi ha conversions implícites entre tipus simples.

• Expressions - Tota expressió té un tipus. - Tots els operands que intervenen en una expressió han de ser del mateix

tipus. - Quan tenim una expressió que representa una crida a funció cal verificar:

que el nombre de paràmetres reals i formals és el mateix que el tipus de cada paràmetre real és el mateix que el del formal no es poden passar per referència constants o expressions compostes

de qualsevol tipus. - En l’accés a una casella d’un vector verificar que el tipus de l’índex és el

mateix que el dels límits del vector. Si l’índex és estàtic cal verificar en compilació que esta dins els límits

- En expressions en què apareguin operadors relacionals el tipus dels operands ha de ser el mateix, i només pot ser simple.

- La prioritat dels operadors està definida en la sintaxi - L’associativitat d’operadors d’igual prioritat és a l’esquerra - Etc.

• Instruccions

- <variable> = <exp> La part esquerra i dreta de l'assignació ha de ser del mateix tipus. Es

permet l’assignació de tipus compostos cadena. En la part esquerra no pot haver un identificador de constant. <variable> += <exp> és equivalent semànticament à:

<variable> = <variable> + <exp> <variable> -= <exp> és equivalent semànticament à:

<variable> = <variable> - <exp> <variable> &= <exp> és equivalent semànticament à:

<variable> = <variable> & <exp>

- llegir (<llista_variables>) Només es poden llegir variables de tipus simple.

- escriure (<llista_expressio>)

Les expressions han de ser de tipus simple. Com cas especial es permet escriure constants cadenes.

- si <expressio> llavors <llistainst1> si no <llistainst2> fisi

L'expressió ha de ser de tipus lògic. L'expressió s'ha d’avaluar en temps d’execució. Si és certa

s’executaran les instruccions de <llistainst1> saltant-nos posteriorment les de la part del si no, en cas contrari s’executarà <llistainst2>.

Aquesta instrucció no pot ser ambigua en cas de sís niats.

- si <expressio> llavors <llistainst1> fisi L'expressió ha de ser de tipus lògic.

Page 147: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

143

L'expressió s’ha d’avaluar en temps d’execució. Si és certa s’executaran les instruccions de <llistainst1> en cas contrari salta a la instrucció després del fisi

Aquesta instrucció no pot ser ambigua en cas de sís niats.

- cicle <llistainst> ficicle S’executa la llista d’instruccions En arribar a ficicle es torna a executar

lla llista d’instruccions i així successivament.

- surtcicle L’execució salta al codi immediatament posterior al primer ficicle que

troba. No pot haver hi un surtcicle fora d’un cicle-ficicle

- retornar <expressio>

El tipus de la expressió ha de ser el que retorni la funció.

- per id = <exp>1 a <exp>2 fer <llista_inst> fiper id ha de ser de tipus sencer. <exp>1 i <exp>2 han de ser expressions de tipus sencer. S’assigna el valor <exp>1 a id i es comprova si el valor de l’id és més

gran que la <exp>2. Si és més gran, s’executa la instrucció que hi ha després de fiper. Si no és més gran, s’executen les instruccions <llista_inst>. L’id s’incrementa en 1. Es torna à comparar el valor de l’id amb l’expressió <exp>2 i així successivament.

Page 148: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

144

Page 149: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

145

II La taula de símbols

1 Introducció La taula de símbols es una estructura de dades que s’utilitza en la fase 3 i 4 del compilador Babel. Aquesta estructura guarda la informació de les variables, funcions, constants i tipus que es defineixen en el codi. Aquesta taula de símbols genèrica ha estat dissenyada per poder ser utilitzada per diferents definicions del llenguatge Babel. Aquest llenguatge es defineix cada any acadèmic, per tant poden haver-hi funcionalitats que no es facin servir enguany.

2 Funcionalitats

2.1 Objectiu La taula de símbols es una estructura de dades que manté la informació de tots els identificadors declarats en un programa, organitzats segons les regles d’abast del llenguatge.

2.2 Tipus de Identificadors Els tipus de identificadors que podem trobar en un programa són:

• Constants • Variables • Tipus • Funcions i/o procediments

Per simplificar la implementació de Babel, no es permet la declaració d’identificadors de tipus. Per tant, la nostra taula de símbols només ha de mantenir la informació relativa als identificadors de constants, variables i funcions / procediments. Tot i això, Babel permet declarar tipus sense nom i, a més a més, té un conjunt de tipus predefinits. Per tant, la taula de símbols també permet tenir informació sobre els tipus.

Page 150: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

146

Estructura de Blocs

L’estructura de blocs que es fa servir en la taula de símbols es la següent:

Exemple de l’estructura de blocs

A continuació tenim un exemple de com estaria la taula de símbols en punt concret de la compilació d’un programa:

Const MAX = 10, MIN = -10; Var X, Y, Z sencer; Procediment OrdenarVector(v1 : array de sencers) Const TEXTE = “hola mon”; Var i, j sencer; Funcio Maxim(a : sencer, b : sencer) .... *(Punt representat) .... FiFuncio ... FiProcediment ...

Taula de Símbols

Llista Variables

Llista Funcions

Llista Constants

Var 1 Var 2 …

Funció1 Procediment2 …

Node1

Constant1 Constant2 …

Llista Blocs

Parametre Parametre

BLOC3

BLOC2

B L O C 1

Page 151: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

147

La representació és la següent:

2. 3 Descriptors

Introducció

Un descriptor es un conjunt d’atributs (informació) necessària per poder fer la verificació semàntica (fase 3) de l’ús dels identificadors i per poder generar codi (fase 4). A continuació analitzarem la informació necessària per a tots els descriptors de identificadors que suporta el llenguatge Babel.

Bloc 1

Llista Constants

Llista Variables

Llista Funcions

Max Min

X Y Z

OrdenaVector

Bloc 2

Llista Constants

Llista Variables

Llista Funcions

TEXTE

Maxim

v1

Bloc 3

Llista Constants

Llista Variables

Llista Funcions

a b

a b

v1

i j

Page 152: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

148

Descriptor d’Identificador de Constant

Nom Funció del Camp Tipus de Dada Nom Nom identificatiu de la constant String Tipus Tipus de dades que conté la

constant ITipus

Valor Valor que té la constat. El tipus del valor ha de ser coherent amb el tipus de la constant.

Object

Descriptor d’Identificador de Variable

Nom Funció del Camp Tipus de Dada Nom Nom identificatiu de la variable String Tipus Tipus de dades que es podrà

emmagatzemar en la variable ITipus

Desplaçament Número de bytes respecte al punter (global o de frame) en què es guarda la variable en memòria

int

Descriptor d’Identificador de Paràmetre

Nom Funció del Camp Tipus de Dada Nom Nom identificatiu de la variable String Tipus Tipus de dades que es podrà

emmagatzemar en la variable ITipus

Desplaçament Número de bytes respecte al punter (global o de frame) en què es guarda la variable en memòria

int

tipusPas Indica el tipus de pas que rep el parametri

TipusPasParametre

Descriptor d’Identificador de Procediment

Nom Funció del Camp Tipus de Dada Nom Nom identificatiu del procediment String

Page 153: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

149

llistaParametres Llista ordenada dels paràmetres del procediment

Llista de Paràmetre

Etiqueta Nom de l’etiqueta String tamanyFrame Grandària en bytes del frame del

procediment int

Descriptor d’Identificador de Funció

Nom Funció del Camp Tipus de Dada Nom Nom identificatiu de la funció String Tipus Tipus de dades que retornarà la

funció ITipus

llistaParametres Llista ordenada dels paràmetres de la funció Llista de Parametre

Desplaçament Desplaçament entre el frame pointer i el valor de retorn de la funció

int

Descriptor d’Identificador de Tipus Indefinit

Nom Funció del Camp Tipus de Dada Nom Nom identificatiu tipus indefinit String

Descriptor d’Identificador de Tipus Simple

Aquest descriptor es fa servir per a tots els tipus simples (sencer, real, booleà, ...). Nom Funció del Camp Tipus de Dada Nom Nom identificatiu tipus simple String tamany Número de bytes que ocupen

aquests tipus de dades. int

maxim Valor màxim que pot assolir aquest tipus Object

minim Valor mínim que pot assolir aquest tipus

Object

Descriptor d’Identificador de Tipus Cadena

Nom Funció del Camp Tipus de Dada Nom Nom identificatiu tipus simple String Tamany Número de bytes que ocupen

aquests tipus de dades. int

Longitud Longitud màxima que pot tenir el int

Page 154: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

150

tipus

Descriptor d’Identificador de Tipus Struct

Nom Funció del Camp Tipus de Dada Nom Nom identificatiu tipus simple String Tamany Número de bytes que ocupen

aquests tipus de dades. int

llistaCampStruct Llista del camps que conté el struct Llista de CampStruct

Descriptor d’Identificador de Camp Struct

Nom Funció del Camp Tipus de Dada Nom Nom identificatiu tipus simple String Tipus Tipus de dada que guarda aquest

camp del struct ITipus

Desplaçament Desplaçament del camp respecte de la primera posició del struct int

Descriptor d’Identificador de Tipus Array

Nom Funció del Camp Tipus de Dada Nom Nom identificatiu tipus simple String tipusElements Tipus de dada que guarda aquest

array ITipus

llistaDimensions Llista de les dimensions del array Llista de DimensioArray

Descriptor d’Identificador de Dimensió Array

Nom Funció del Camp Tipus de Dada

tipusLimit Tipus de dada que es far servir com a índex del array en aquesta dimensió

ITipus

limitInferior Límit inferior d’aquesta dimensió del array

Object

limitSuperior Límit superior d’aquesta dimensió del array Object

Page 155: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

151

Page 156: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

152

3 Implementació

Diagrama de Classes

El diagrama de classes, per poder emmagatzemar tota aquesta informació, és el següent:

Taula de Símbols

Page 157: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

153

Tipus

Llegenda

Cursiva: Classe o funció abstracta o interfície +: Variable o funció pública -: Variable o funció privada *: Variable que és una llista, array, conjunt o qualsevol estructura de dades que pugui contenir més d’un element.

: Herència

: Agregació, es pot indicar la cardinalitat com per exemple 1..N, per defecte és 1..1

4 Com utilitzar la taula de símbols La taula de símbols està formada per un conjunt d’arxius java. Tots aquests arxius estan en el package taulasimbols, és a dir, que estan dintre del directori taulasimbols. Aquest directori (el directori sencer, no el contingut) s’ha de copiar en el directori en què es troba l’arxiu de JavaCC (l’arxiu .jj). Per poder fer servir aquestes classes aquí teniu un exemple de com importar el package:

Page 158: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

154

PARSER_BEGIN(ParserBabel) import taulasimbols.*; public class ParserBabel {(...)} La línia que ens interessa és import taulasimbols.*;. Aquesta línia s’ha d’afegir en tots els fitxers de totes les classes que operin amb algun element de la taula de símbols. La resta del procés de compilació segueix sent la mateixa: javacc <nom fitxer>.jj javac *.java java <nom fitxer> <fitxer babel>

Page 159: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

155

III Problemari

CAPITOL 1: L’ANÀLISI SEMÀNTICA

PRO 1.1 Taula de símbols

Estudieu els descriptors definits per la implementació de la taula de símbols per a l’anàlisi semàntica del llenguatge BABEL.

PRO 1.2 lmplementació de la taula de símbols

Recordeu que el compilador del llenguatge Babel és d’una sola passada i amb estructura de blocs. Per a la implementació de la taula se símbols s’utilitza un comptador del número de blocs. Aquest comptador s’incrementa quan s’obre un nou context (bloc) i és decrementa quan se’n surt. Cada bloc té una taula i en un punt específic de l’anàlisi semàntica, h ha tantes taules (empilades) com blocs oberts. Estudieu en detall l’organització i la implementació de la taula de símbols proposada per al llenguatge BABEL.

PRO 1.3 Programari de la taula de símbols

Instal·leu el programari de la taula de símbols i feu diferents proves d’inserció i de cerca d’identificadors de diferents tipus.

PRO 1.4 Verificació de tipus. Resolt

Per a la següent gramàtica, doneu un esquema de traducció o una gramàtica d’atributs que determini el tipus de l’expressió. Considereu que no hi ha conversió implícita de tipus. Utilitzeu l’atribut sintetitzat tipus. exp --> exp OPER_ARIT exp exp --> CTE_INTEGER exp --> CTE_REAL exp --> ID exp --> ( exp )

Page 160: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

156

Solució exp --> exp1 OPER_ARIT exp2, Si (exp1.tipus = “sencer” and exp2.tipus = “sencer”)

llavors exp.tipus := “sencer”

sino Si (exp1.tipus = “real” and exp2.tipus =

“real”) llavors exp.tipus := “real”

sino “Error semàntic, els tipus de les dues expressions no són iguals o no són de tipus vàlids” fisi

fisi exp --> CTE_INTEGER, exp.tipus := “sencer” exp --> CTE_REAL , exp.tipus := “real” exp --> ID , exp.tipus := ID.tipus exp --> ( exp1 ) , exp.tipus := exp1.tipus La notació ID.tipus significa que recuperarem el tipus del ID del seu descriptor en la taula de símbols.

PRO 1.5 Conversions

Modifiqueu l’exercici anterior considerant la conversió implícita de sencer a real.

PRO 1.6 Anàlisi semàntica en context de declaració

Per a la següent gramàtica: decl_constants --> CONST llista_decl_constants decl_constants --> ε llista_decl_constants --> ID = exp ; llista_decl_constants llista_decl_constants --> ID = exp ; decl_variables --> VAR llista_decl_variables decl_variables --> ε llista_decl_variables --> llista_ids : tipus ; llista_decl_variables llista_decl_variables --> llista_ids : tipus ; tipus --> TIPUS_SIMPLE tipus --> VECTOR [ exp .. exp ] DE TIPUS_SIMPLE decl_funcions --> FUNCIO ID llista_parametres : TIPUS_SIMPLE ; bloc ; decl_funcions decl_funcions --> ε llista_parametres --> ε llista_parametres --> ( parametres )

Page 161: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

157

parametres --> llista_idsp : tipus ; parametres parametres --> llista_idsp : tipus ; llista_idsp --> REF llista_id llista_idsp --> llista_id llista_id --> ID , llista_id llista_id --> ID Doneu un esquema de traducció indicant exactament on es fan les següents accions i verificacions semàntiques: Inserir el descriptor d’una variable en la taula de símbols Inserir el descriptor d’una funció en la taula de símbols Verificar que s’hi pot inserir un paràmetre Verificar que els límits d’un vector són legals Incrementar el número de bloc Decrementar el número de bloc Doneu dues verificacions i/o accions més que han de fer-se i que no hem esmentat.

PRO 1.7 Anàlisi semàntica d’expressions. Resolt

Donada la següent gramàtica reduïda d’expressions, calcular els atributs tipus, és_estàtica i valor mitjançant un esquema de traducció. exp --> exp1 OPER_ARIT exp2 exp --> CTE_INTEGER exp --> CTE_REAL exp --> ID exp --> ( exp1 ) Solució exp --> exp1 OPER_ARIT exp2,

Si (exp1 tipus tipus = “sencer” and exp2.tipus = “sencer”) llavors exp.tipus := “sencer”

sino Si (exp1.tipus = “real” and exp2.tipus = “real”) llavors exp.tipus := “real” sino “Error semàntic, els tipus de les dues expressions no són iguals o no són de tipus vàlids” fisi

fisi Si (exp1.és_estàtica = “si” and exp2.és_estàtica = “si”) llavors

exp. és_estàtica = “si” exp.valor:= exp1.valor operador exp1.valor sino exp. és_estàtica = “no” exp.valor:= “indefinit”

fisi

Page 162: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

158

exp --> CTE_INTEGER, exp.tipus := “sencer” exp.és_estàtica := “si” exp.valor:= CTE_INTEGER.lexema exp --> CTE_REAL , exp.tipus := “real” exp.és_estàtica := “si” exp.valor:= CTE_REAL.lexema exp --> ID , exp.tipus := ID.tipus Si ID és un id constant llavors

exp.és_estàtica := “si” exp.valor:= ID.valor sino Si ID és un id variable llavors

exp.és_estàtica := “no” exp.valor:= “indefinit”

fisi fisi

exp --> ( exp1 ) , exp.tipus := exp1.tipus

exp.és_estàtica := exp1.és_estàtica exp.valor:= exp1.valor CTE_INTEGER.lexema és una notació per indicar el valor de la constant. Recordeu que el lexema és el valor. ID.valor és na notació per indicar el valor de la constant ID. Aquest valor està en el descriptor del ID en la taula de símbols. Fixeu-vos-hi que l’atribut valor només te sentit quan l’expressió és estàtica, és a dir, quan el valor de l’expressió es pot calcular en temps de compilació. En el cas de les operacions aritmètiques, el càlcul del valor es fa utilitzant l’operador corresponent.

PRO 1.8 Anàlisi semàntica d’expressions

Donada una gramàtica d’expressions, verifiqueu que els operands simples estiguin prèviament declarats en l’abast actual i que en el cas de crida a funció i d’accés a un element d’un vector la utilització sigui correcta mitjançant un esquema de traducció.

PRO 1.9 Anàlisi semàntica i llenguatges de programació

Escolliu un llenguatge de programació conegut amb el qual programeu. Feu una llista amb les diferents instruccions simples i compostes que permet el llenguatge. Estudieu per a cada instrucció simple la seva semàntica i penseu com faríeu l’anàlisi semàntica.

Page 163: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

159

PRO 1.10 Anàlisi semàntica de l’assignació. Resolt

Donada una gramàtica per l’assignació, doneu un esquema de traducció per analitzar semànticament la instrucció. inst variable := expr variable ID ID[expr] Solució inst variable := expr ,Si variable.tipus<> expr.tipus llavors

“ERROR semàntic, els tipus no són els mateixos” sino Si tipus no és simple llavors

“ERROR semàntic, no es permet l’assignació de tipus compostos”

fisi fisi

variable ID , variable.tipus:=ID.tipus ID[expr] , variable.tipus:= ID.tipus (tipus dels elements del vector) En aquest exemple no permetem assignació de valors de tipus compostos però hi ha llenguatges de programació en què es poden assignar tipus compostos, com per exemple vectors o registres (struct).

PRO 1.11 Anàlisi semàntica de la instrucció while. Resolt

Donada una gramàtica per a la instrucció mentre, doneu un esquema de traducció per analitzar-la semànticament. inst MENTRE expr FER inst Solució inst MENTRE expr FER inst, Si expr.tipus <> “lògic” llavors

“ERROR semàntic, el tipus de l’expressió no és lògic”

PRO 1.12 Anàlisi semàntica de les instruccions loop i break.

Utilitzant la gramàtica proposada en aquest exercici, doneu un esquema de traducció per verificar les regles semàntiques especificades. programa llista_inst llista_inst inst llista_inst llista_inst ε

Page 164: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

160

inst LOOP llista_inst POOL; inst BREAK CTE_INTEGER; inst ....... altres instruccions Les regles semàntiques són:

1. En les instruccions BREAK, el número ha de ser > 0 2. Cada instrucció BREAK n ha d’estar dins d’almenys n LOOP’s 3. Cada instrucció LOOP pot tenir dins, com màxim, una instrucció BREAK

PRO 1.13 Anàlisi semàntica de la instrucció case

Determineu els atributs necessaris per analitzar semànticament la instrucció segons el que hem estudiat en el curs. Proposeu un esquema de traducció per fer l’anàlisi semàntica.

PRO 1.14 Anàlisi semàntica de la instrucció for

Estudieu la instrucció for del llenguatge de programació en el que programeu sovint. Digueu quina és la seva semàntica i escriviu un esquema de traducció per fer les verificacions semàntiques corresponents.

CAPITOL 2: GENERACIÓ DE CODI

PRO 2.1 Segments de memòria en MIPS

El simulador SPIM distingeix tres segments en memòria: el segment pila, el segment data i el segment text . Estudieu per a cada segment quin és el seu objectiu i quins registres hi tenen associats.

PRO 2.2 Àrees de memòria

Babel permet funcions, variables locals i globals. En canvi, no té variables dinàmiques. Per tant, necessitem dues àrees: la global i la pila. Consulteu i estudieu les diferents maneres d’organitzar la memòria per compilar el llenguatge Babel.

Page 165: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

161

PRO 2.3 Tipus simples en MIPS

Consulteu, del llenguatge MIPS, els registres per operar amb sencers i els registres per operar amb reals. Consulteu les operacions que hi ha per sumar, restar, dividir i multiplicar sencers i reals. Estudieu com es faria una conversió de sencer a real. Consulteu, del llenguatge MIPS, les operacions que hi ha per operar sobre tipus lògic. Estudieu com es faria el AND, el OR i el NOT tot considerant dues representacions diferents per al tipus lògic.

PRO 2.4 Tipus simples de Babel

Estudieu els diferents tipus simples que ofereix el llenguatge Babel. Per a cadascun dels tipus preneu una decisió de com representar-lo en memòria. No us oblideu de mirar les operacions relacionades amb els tipus.

PRO 2.5 Tipus estructurats de Babel

Estudieu els tipus estructurats que ofereix el llenguatge Babel. Per a cadascun dels tipus preneu una decisió de com representar-los en memòria.

PRO 2.6 Generació de codi

Indiqueu com generaríeu codi en MIPS per accedir a un element d’un vector d’una dimensió.

PRO 2.7 Generació de codi

Indiqueu com generaríeu codi en MIPS per accedir a un camp d’un registre (struct).

PRO 2.8 Gestió de registres

Implementeu les funcions demanar_registre i alliberar_registre en Java, tot considerant que s’han de gestionar tant els registres d’aritmètica sencera com els registres d’aritmètica flotant.

Page 166: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

162

PRO 2.9 Llenguatge assemblador MIPS

Estudieu els diferents tipus de load’s que té el llenguatge assemblador MIPS.

PRO 2.10 MIPS

Estudieu les diferents instruccions per operar amb el tipus lògic que té el llenguatge assemblador MIPS. Estudieu com implementaríeu els operadors relacionals.

PRO 2.11 Llenguatge assemblador MIPS

Estudieu les diferents instruccions de tipus store que permet el llenguatge assemblador MIPS.

PRO 2.12 Llenguatge assemblador MIPS

Doneu el codi MIPS que es generarà per donar al usuari el missatge d’error que es produeix quan un índex esta fora dels límits.

PRO 2.13 Llenguatge assemblador MIPS

Doneu el codi MIPS que es generarà per escriure i llegir valors de tipus caràcter i de tipus lògic.

PRO 2.14 Generació de codi. Resolt

Genereu codi per expressions aritmètiques. Sense conversió. Utilitzeu l’atribut sintetitzat reg que conté el número de registre en què s’ha guardat el resultat de l’avaluació de l’expressió. Utilitzeu el procediment gc per escriure el codi que generem en un fitxer. Hem d’assegurar que el codi s’escriu en l’ordre que cal.

Page 167: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

163

E E1 + T , gc(“ADD “&E1.reg&”,”&E1.reg&”,”&T.reg); E.reg:=E1.reg;

alliberar_registre(T.reg) E T, E.reg:=T.reg T T1 * F, gc(“MULT “&T1.reg&”,”&T1.reg&”,”&F.reg); T.reg:=T1.reg;

alliberar_registre(F.reg)

T F, T.reg := F.reg F (E), F.reg := E.reg F ID, demanar_registre(R);

gc(“LW “&R&”,”&did &”($fp)”); F.reg := R F CTE_SENCER, demanar_registre(R);

gc(“LI “&R&”, CTE_SENCER.lexema); F.reg := R Hem considerat que les variables són locals. El cas de variables no-locals està relacionat amb la cadena estàtica que veurem més endavant. Utilitzem la notació did per indicar el desplaçament de l’identificador.

PRO 2.15 Generació de codi. Resolt

Genereu codi per expressions lògiques considerant que les expressions s’avaluen totalment. E E1 OR T , E T, T T1 AND F, T F, T NOT F, F (E); F ID, F CTE_BOOL, La generació de codi per les expressions lògiques es pot fer de la mateixa manera que la generació de codi per expressions aritmètiques. La majoria dels llenguatges

Page 168: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

164

assembladors tenen operacions lògiques implementades però s’ha de tenir en compte la representació dels valors del tipus lògic en memòria per assegurar-nos que funcionen com esperem.

PRO 2.16 Assignació. Resolt

Genereu codi per a la instrucció assignació. inst variable := expr , gc(“SW “&exp.reg&”,variable.dir); alliberar_registre(exp.reg) variable ID ,variable.dir := did($fp) (cas local) ID[expr] , ............. Hem utilitzat un atribut sintetitzat dir que té l’adreça de la variable en qüestió. L’adreça es calcula en el no terminal variable i depèn de la localitat i del tipus de l’ID. Com exemple hem posat el cas de variable local.

PRO 2.17 Condicional. Resolt

Genereu codi per a la instrucció condicional. inst SI expr LLAVORS linst SINO linst FSI inst SI expr LLAVORS linst L’esquema general en pseudocodi és el donat en la sessió corresponent:

codi avaluant l’expressió Si exp.reg = 0 llavors anar a E1 codi representant la llista d’instruccions del sino

anar a E2 E1: codi representant la instrucció del llavors E2: En aquest esquema hem considerat que el cert és 1 i el fals és 0. L’esquema de traducció és el següent: inst SI expr LLAVORS demanar_etiqueta(E1); demanar_etiqueta(E2); gc(“BEQZ “&exp.reg&”,”&E1); linst gc(“B ”&E2); gc(E1&”:”);

SINO linst FSI gc(E2&”:”);

Page 169: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

165

Determineu on es pot alliberar el registre utilitzat per avaluar l’expressió.

PRO 2.18 Llaç mentre. Resolt

Genereu codi per la instrucció mentre. inst MENTRE expr FER linst L’esquema general en pseudocodi és el donat en la sessió corresponent: E1: codi avaluant l’expressió

Si exp.reg = 0 llavors anar a E2 codi representant la llista d’instruccions linst anar a E1

E2: En aquest esquema hem considerat que el cert és 1 i el fals és 0. L’esquema de traducció és el següent: inst MENTRE demanar_etiqueta(E1); gc(E1&”:”)

expr FER demanar_etiqueta(E2);

gc(“BEQZ “&exp.reg&”,”&E2);

linst gc(“B ”&E1); gc(E2&”:”);

Determineu on es pot alliberar el registre utilitzat per avaluar l’expressió.

PRO 2.19 Implementació

Implementeu la funció demanar_etiqueta en Java.

PRO 2.20 Llenguatge assemblador MIPS

Estudieu els diferents tipus de salts que té el llenguatge assemblador MIPS.

PRO 2.21 Generació de codi

Doneu l’esquema general per a la instrucció repetir i l’esquema de traducció per a la generació de codi.

Page 170: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

166

inst REPETIR linst FINS expr

PRO 2.22 Generació de codi

Doneu l’esquema general per a la instrucció per_fer i l’esquema de traducció per a la generació de codi. inst PER ID:= expr A expr FER linst

PRO 2.23 Generació de codi

Doneu l’esquema general per a la instrucció segons i l’esquema de traducció per a la generació de codi. instr SEGONS expr DE llista_de_casos cas_sino FISEGONS llista_de_casos llista_de_ctes : linstr ; llista_de_casos llista_de_casos ε llista_de_ctes constant , llista_de_ctes llista_de_ctes constant cas_sino SINO : linstr cas_sino ε

PRO 2.24 Declaració de funcions. Resolt

Quan es declara un procediment o funció, la generació de codi ha d’incloure: 1. La generació de l’etiqueta corresponent a la primera instrucció del procediment. Aquesta etiqueta ha de ser única i s’utilitzarà per saltar quan es cridi al procediment. El nom de l’etiqueta es guarda com un atribut en el seu descriptor de la taula de símbols. Es pot utilitzar el procediment demanar_etiqueta. 2. La generació de codi corresponent a DATe. Aquest codi s’ha de generar abans d’entrar al bloc de la funció. La principal tasca a fer és la reserva d’espai en la pila d’execució per a les variables locals, els paràmetres i el valor de retorn. La reserva d’espai es fa actualitzant el registre sp. 3. La generació de codi del cos del procediment.

Page 171: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

167

PRO 2.25 Crida a un procediment o funció. Resolt

Quan es crida un procediment o una funció, la generació de codi ha d’incloure: 1. La generació de codi corresponent a DARa, DARs i DARd DARa 1. Crear un nou frame

calcular i guardar cadena estètica guardar cadena dinàmica (salvar fp actual) guardar l’adreça de retorn

2. Actualitzar el registre fp ($fp <-- $sp) 3. Empilar els paràmetres. Considerar la forma de pas.

DARs 1. Saltar a l’etiqueta del procediment cridat. DARd

1. Recuperar el resultat de la funció 2. S’ha de considerar que hem de guardar els registres que hem utilitzat ja que quan cridem una funció els valors es ponen perdre. Si guardem registres desprès hem de recuperar-los. Hem de decidir qui fa aquesta tasca, pot ser el que crida o el cridat. En el primer cas guardarà els registres abans de saltar i els recuperarà en tornar. En el segon cas, guardarà els registres a l’entrada i els restaurarà abans de tornar.

PRO 2.26 Retorn d’un procediment o funció. Resolt

En el retorn d’un procediment o funció, la generació de codi ha d’incloure el codi corresponent a DATs. És a dir,

- guardar el valor de retorn - alliberar el frame - restaurar el fp - saltar al procediment que l’ha cridat. Això vol dir que hem d’utilitzar l’adreça de

retorn que havíem guardat en el frame

CAPITOL 3: OPTIMITZACIÓ DE CODI

PRO 3.1

Traduïu el fragment de programa donat en MIR. var A: vector [1..20,2..10] de sencer; ...... A[i+3,j+2] := i+(j-1)

Page 172: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

168

PRO 3.2

Doneu com es traduiria el fragment següent en MIR. s:=0; Per i:=x+2 fins n fer Inici t:= i + 2; s:= s+t: fi

PRO 3.3 Resolt

Traduïu el següent fragment de codi a MIR: A[i+3] := ((x * 7) + 5) / y

Solució:

t1 addr A t2 i* ts t3 t1 + t2 t4 li* ts t5 t3 – t4 t6 x * 7 t7 t6 + 5 t8 t7 / y *t5 t8

PRO 3.4 Resolt

Traduïu el següent fragment de codi a MIR: si x+2 > i llavors x:= x + 5 sino x:= 0 fsi Solució:

t1 x+2 t2 t1 > i If ! t2 goto L1 x x + 5 goto L2

L1: x:= 0 L2:

Page 173: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

169

PRO 3.5 Resolt

Traduïu el següent fragment de codi a MIR: mentre x> i fer i:= i +1

Solució:

t1 x > i L1: if !t1 goto L2 i i + 1 goto L1 L2:

PRO 3.6

Doneu com es traduiria la instrucció repetir. s:=0;i:= 1; Repetir t:= i + 2; s:= s+t: i := i + 1 fins i = 20;

PRO 3.7

Doneu la traducció del següent fragment de programa en MIR. var

b:vector[0..n] de sencer Inici b[5] := 10; b[2] := 8; b[3] := 7; b[4] := 2; b[1] := 100; index:=1;sum:=0; mentre index<=t fer inici sum:=sum+b[index]; index:=index+1 fi; fi.

Page 174: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

170

PRO 3.8 Problema resolt

Doneu la traducció del següent fragment de programa en MIR. i:= 2; Mentre i <= 5 fer Inici x:= a[i] ; a[0] := x ; j := i –1 ; Mentre x < a[j] fer Inici a[j+1] := a[j]; j := j –1: fi; a[j+1] := x; i := i +1: fi;

Page 175: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

171

3.8 a) Codi MIR

1 i 2 2 E1: if i > 5 goto E2 3 t1 addr A 4 t2 i * ts 5 t3 t1 + t2 6 t4 0* ts 7 t5 t3 – t4 8 x *t5 9 t6 addr A

10 t7 0 * ts 11 t8 t6 + t7 12 t9 0 * ts 13 t10 t8 - t9 14 *t10 x 15 j i-1 16 E3: t11 addr A 17 t12 j * ts 18 t13 t11 + t12 19 t14 0 * ts 20 t15 t13 - t14 21 t16 *t15 22 if x >= t16 goto E4 23 t17 j + 1 24 t18 addr A 25 t19 t17 * ts 26 t20 t18 + t19 27 t21 0 * ts 28 t22 t20 - t21 29 t23 addr A 30 t24 j * ts 31 t25 t23 + t24 32 t26 0 * ts 33 t27 t25 - t26 34 t28 *t27 35 *t22 t28 36 j j – 1 37 . goto E3 38 E4: t29 j + 1 39 t30 addr A 40 t31 t29 * ts 41 t32 t30 + t31 42 t33 0 * ts 43 t34 t32 - t33 44 *t34 x 45 i i + 1 46 goto E1 47 E2:

Page 176: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

172

3.8 b) Identificació de blocs bàsics. Graf de flux de control

3.8 c) Avaluació d’expressions constants. Propagació de constants

En l’exemple anterior ja hem substituït la constant li per 0. La constant ts no la substituïm ja que representa el nombre de bytes que ocupa un sencer en memòria. Aquesta constant depèn de la màquina per a la qual generarem codi.

Page 177: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

173

Simplificacions algebraiques i reassociació

En simplificar les expressions 6,10,12,19,27,32 i 42, els temporals corresponents són ara constants. Per tant, podem tornar a aplicar propagació de constants i simplificacions algebraiques. Les instruccions t4 0, t7 0,… es consideraran codi mort en pròximes optimitzacions. Les instruccions t5 t3, t8 t6,… es consideraran com còpies en pròximes optimitzacions. 1 i 2 2 E1: if i > 5 goto E2 3 t1 addr A 4 t2 i * ts 5 t3 t1 + t2 6 t4 0* ts t4 0 7 t5 t3 – t4 t5 t3 – 0 t5 t3 8 x *t5 9 t6 addr A 10 t7 0 * ts t7 0 11 t8 t6 + t7 t8 t6 + 0 t8 t6 12 t9 0 * ts t9 0 13 t10 t8 - t9 t10 t8 – 0 t10 t8 14 *t10 x 15 j i-1 16 E3: t11 addr A 17 t12 j * ts 18 t13 t11 + t12 19 t14 0 * ts t14 0 20 t15 t13 – t14 t15 t13 – 0 t15 t13 21 t16 *t15 22 if x >= t16 goto E4 23 t17 j + 1 24 t18 addr A 25 t19 t17 * ts 26 t20 t18 + t19 27 t21 0 * ts t21 0 28 t22 t20 - t21 t22 t20 – 0 t22 t20 29 t23 addr A 30 t24 j * ts 31 t25 t23 + t24

32 t26 0 * ts t26

0

33 t27 t25 - t26 t27 t25 – 0 t27 t25 34 t28 *t27 35 *t22 t28 36 j j – 1 37 . goto E3 38 E4: t29 j + 1 39 t30 addr A 40 t31 t29 * ts 41 t32 t30 + t31 42 t33 0 * ts t33 0 43 t34 t32 - t33 t34 t32 – 0 t34 t32

Page 178: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

174

44 *t34 x 45 i i + 1 46 goto E1 47 E2:

3.8 d) Eliminació de subexpressions comunes

1 i 2 2 E1: if i > 5 goto E2 3 t1 addr A t11 addr A, t1 t11 4 t2 i * ts 5 t3 t1 + t2 6 t4 0 7 t5 t3 8 x *t5 9 t6 addr A t6 t11 10 t7 0 11 t8 t6 12 t9 0 13 t10 t8 14 *t10 x 15 j i-1 16 E3: t11 addr A E3: t11 t11 17 t12 j * ts t121 j * ts, t12 t121 18 t13 t11 + t12 19 t14 0 20 t15 t13 21 t16 *t15 22 if x >= t16 goto E4 23 t17 j + 1 24 t18 addr A t18 t11 25 t19 t17 * ts 26 t20 t18 + t19 27 t21 0 28 t22 t20 29 t23 addr A t23 t11 30 t24 j * ts t24 t121 31 t25 t23 + t24 32 t26 0 33 t27 t25 34 t28 *t27 35 *t22 t28 36 j j – 1 37 . goto E3 38 E4: t29 j + 1 39 t30 addr A t30 t11 40 t31 t29 * ts 41 t32 t30 + t31 42 t33 0 43 t34 t32 44 *t34 x 45 i i + 1 46 goto E1 47 E2:

Page 179: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

175

3.8 e) Propagació de còpia (genera subexpressions comunes)

1 i 2 2 E1: if i > 5 goto E2 3 t11 addr A 3’ t1 t11 4 t2 i * ts 5 t3 t1 + t2 t3 t11 + t2 6 t4 0 7 t5 t3 8 x *t5 x *t3 9 t6 t11 10 t7 0 11 t8 t6 t8 t11 12 t9 0 13 t10 t8 t10 t11 14 *t10 x * t11 x 15 j i-1 16 E3: t11 t11 17 17’

t121 j * ts t12 t121

18 18’

t13 t11 + t12 t13 t11 +t121 t131 t11 +t121

t13 t131

19 t14 0 20 t15 t13 t15 t131 21 t16 *t15 t16 *t13 t16 *t131 22 if x >= t16 goto E4 23 t17 j + 1 24 t18 t11 25 t19 t17 * ts 26 t20 t18 + t19 t20 t11 + t19 27 t21 0 28 t22 t20 29 t23 t11 30 t24 t121 31 t25 t23 + t24 t25 t11 + t121 t25 t131 32 t26 0 33 t27 t25 t27 t131 34 t28 *t27 t28 *t25 t28 *t131 35 *t22 t28 *t20 t28 36 J j – 1 37 . goto E3 38 E4: t29 j + 1 39 t30 t11 40 t31 t29 * ts 41 t32 t30 + t31 t32 t11 + t31 42 t33 0 43 t34 t32 44 *t34 x *t32 x 45 i i + 1 46 goto E1 47 E2:

Page 180: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

176

1 i 2 2 E1: if i > 5 goto E2 3 t11 addr A t1 t11

4 t2 i * ts 5 t3 t11 + t2 6 t4 0 7 t5 t3 8 x *t3 9 t6 t11 10 t7 0 11 t8 t11 12 t9 0 13 t10 t11 14 * t11 x 15 j i-1 16 E3: t11 t11

17 t121 j * ts t12 t121

18 t131 t11 +t121

t13 t131

19 t14 0 20 t15 t131

21 t16 *t131 t161 *t131

t16 t161

22 if x >= t16 goto E4 if x >= t161 goto E4 23 t17 j + 1 24 t18 t11 25 t19 t17 * ts 26 t20 t11 + t19 27 t21 0 28 t22 t20 29 t23 t11 30 t24 t131 31 t25 t131 32 t26 0 33 t27 t 131

34 t28 *t131 t28

t161

35 *t20 t28 *t20 t161 36 j j – 1 37 . goto E3 38 E4: t29 j + 1 39 t30 t11 40 t31 t29 * ts 41 t32 t11 + t31 42 t33 0 43 t34 t32 44 *t32 x 45 i i + 1 46 goto E1 47 E2:

Page 181: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

177

3.8 f) Eliminació de codi mort

1 i 2 2 E1: if i > 5 goto E2 3 t11 addr A t1 t11 Eliminar

4 t2 i * ts 5 t3 t11 + t2 6 t4 0 Eliminar 7 t5 t3 Eliminar 8 x *t3 9 t6 t11 Eliminar 10 t7 0 Eliminar 11 t8 t11 Eliminar 12 t9 0 Eliminar 13 t10 t11 Eliminar 14 * t11 x 15 j i-1 16 E3: t11 t11 Eliminar

17 t121 j * ts t12 t121

Eliminar

18 t131 t11 +t121

t13 t131 Eliminar

19 t14 0 Eliminar 20 t15 t131 Eliminar

21

t161 *t131

t16 t161 Eliminar

22 if x >= t161 goto E4 23 t17 j + 1 24 t18 t11 Eliminar 25 t19 t17 * ts 26 t20 t11 + t19 27 t21 0 Eliminar 28 t22 t20 Eliminar 29 t23 t11 Eliminar 30 t24 t131 Eliminar 31 t25 t131 Eliminar 32 t26 0 Eliminar 33 t27 t131 Eliminar 34 t28 t161 Eliminar 35 *t20 t161 36 j j – 1 37 . goto E3 38 E4: t29 j + 1 39 t30 t11 Eliminar 40 t31 t29 * ts 41 t32 t11 + t31 42 t33 0 Eliminar 43 t34 t32 Eliminar 44 *t32 x 45 i i + 1 46 goto E1 47 E2:

Page 182: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

178

Abans de les optimitzacions de llaços

1 i 2 2 E1: if i > 5 goto E2 3 t11 addr A

4 t2 i * ts 5 t3 t11 + t2 6 7 8 x *t3 9 10 11 12 13 14 * t11 x 15 j i-1 16 E3: 17 t121 j * ts 18 t131 t11 +t121 19 20 21 t161 *t131 22 if x >= t161 goto E4 23 t17 j + 1 24 25 t19 t17 * ts 26 t20 t11 + t19 27 28 29 30 31 32 33 34 35 *t20 t161 36 j j – 1 37 . goto E3 38 E4: t29 j + 1 39 40 t31 t29 * ts 41 t32 t11 + t31 42 43 44 *t32 x 45 i i + 1 46 goto E1 47 E2:

Page 183: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

179

3.8 g) Moviment de codi invariant

3.8 h) Identificació de variables d’inducció (bàsiques i dependents)

Identifiquem dues variables d’inducció bàsiques. Cada variable d’inducció genera una classe. - classe i de la variable d’inducció bàsica i amb equació i i + 1 (d=1) - classe j de la variable d’inducció bàsica j amb equació j j - 1 (d= -1) Les variables d’inducció dependents de cada classe amb les seves equacions són:

Page 184: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

180

Classe i : t2 amb equació t2 ts * i (b= ts i c= 0) t3 amb equació t3 t11 + t2 t3 t11 + ts * i t3 ts * i + t11 (b=ts i c= t11) j amb equació j i -1 (b=1 i c=-1) Classe j : t121 amb equació t121 ts * j (b= ts i c= 0) t131 amb equació t131 t11 + t121

t131 ts*j + t11 (b=ts i c= t11) t17 amb equació t17 j + 1 (b= 1 i c= 1) t19 amb equació t19 t17*ts t19 ts *j + ts (b=ts i c=ts) t20 amb equació t20 t11 + t19 t20 ts *j + ts + t11 (b=ts i c=ts + t11) t29 amb equació t29 j + 1 (b= 1 i c= 1) t31 amb equació t31 t29*ts t31 ts *j + ts (b=ts i c=ts) t32 amb equació t32 t11 + t31 t32 ts *j + ts + t11 (b=ts i c=ts + t11) Per il·lustrar l’algorisme començarem per tractar la variable t2 de la classe i. Recordeu que la finalitat de l’algorisme és reduir força en les operacions (canviar per exemple productes per sumes). 1. La variable t2 té equació: t2 ts * i (b= ts i c= 0) 2. Sigui t2’ un nou temporal. Substituir la línia 4. per t2 t2’ 3. Inserir després de cada assignació a la variable d’inducció bàsica i (i i + 1, d=1) la instrucció: t2’ t2’ + d * b és a dir, incloure la línia 451. t2’ t2’ + ts 4. Inicialitzar la variable t2’ fora del llaç amb la instrucció t2’ b * i, és a dir, incloure la línia 21 t2’ ts*i 5. Substituir l’ús de t2 dintre del llaç per t2’. La instrucció de la línia 5 canviar a t3 t11 + t2’ 6. Afegir t2’ a la classe de i amb equació: t2’ ts*i Fixeu-vos-hi que s’ha generat codi mort. (línia 4) Ara tractarem la variable j en el bloc B3 ja que busquem eliminar variables d’inducció bàsiques. Aquesta variable en aquest bloc depèn de i. Fixeu-vos-hi com s’ha fet en la següent taula. No hem propagat còpia ja que no compleix els requisits.

Page 185: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

181

1 i 2

2

t11 addr A 21 t2’ ts*i

22 j’ i-1

3 E1: if i > 5 goto E2

4 t2 i * ts t2 t2’ Eliminar 5 t3 t11 + t2 t3 t11 + t2’ 6 7 8 x *t3 9 10 11 12 13 14 * t11 x 15 j i-1 j j’ 16 E3: 17 t121 j * ts 18 t131 t11 +t121 19 20 21 t161 *t131 22 if x >= t161 goto E4 23 t17 j + 1 24 25 t19 t17 * ts 26 t20 t11 + t19 27 28 29 30 31 32 33 34 35 *t20 t161 36 j j – 1 37 . goto E3 38 E4: t29 j + 1 39 40 t31 t29 * ts 41 t32 t11 + t31 42 43 44 *t32 x

45

i i + 1

451. t2’ t2’ + ts

452 . j’ j’ + 1

46 goto E1 47 E2:

Page 186: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

182

3.8 i) Eliminació de variables d’inducció

Ara la variable i només s’utilitza en la condició del llaç. Aplicant l’algorisme corresponent podem, en un primer pas, canviar la condició del llaç utilitzant una variable dependent d’i i, en un segon pas, eliminar l’increment a i ja que es torna codi mort. La condició if i > 5 goto E2 es modifica per: Escollim t2’ (una variable de la classe d’i) amb equació t2’ ts * i Sigui t2’’ un nou temporal (que substituirà el 5 de la condició)

1. inicialitzar t2’’ ts * 5 2. substituir la condició i > 5 per t2’ > t2’’

1 i 2

2

t11 addr A 21 t2’ ts*i 22 j’ i-1 23 t2’’ ts*i

21 t2’ ts*2 22 j’ 1 23 t2’’ ts*5

3 E1: if t2>t2’’ goto E2 4 5 t3 t11 + t2’ 6 7 8 x *t3 9 10 11 12 13 14 * t11 x 15 j j’ 16 E3: 17 t121 j * ts 18 t131 t11 +t121 19 20 21 t161 *t131 22 if x >= t161 goto E4 23 t17 j + 1 24 25 t19 t17 * ts 26 t20 t11 + t19 27 28 29 30 31 32 33 34 35 *t20 t161 36 j j – 1

Page 187: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

183

37 . goto E3 38 E4: t29 j + 1 39 40 t31 t29 * ts 41 t32 t11 + t31 42 43 44 *t32 x

45

i i + 1 451. t2’ t2’ + ts 452 . j’ j’ + 1

46 goto E1 47 E2:

Podeu continuar amb la resta de l’exercici.

3.8 j) Comptant operacions

Com un petit exercici contarem les operacions abans d’optimitzar i després de les optimitzacions fetes fins el pas i). Abans de cap optimització: bloc nombre de

vegades Assignacions sumes/restes productes/divisions

B1 1 1 B2 5 B3 4 52 (4x13) 20 (4x5) 16 (4x4) B4 14 84 (14x6) 28 (14x2) 28 (14x2) B5 13 182 (13x14) 78 (13x6) 52 (13x4) B6 4 32 (4x8) 16 (4x4) 8 (4x2) ....total 351 142 104 Desprès del pas i): bloc nombre de

vegades Assignacions sumes/restes productes/divisions

B1 1 4 2 B2 5 B3 4 16 (4x4) 4 (4x1) 0 B4 14 52 (14x3) 14 (14x1) 14 (14x1) B5 13 65 (13x5) 39 (13x3) 13 (13x1) B6 4 28 (4x7) 20 (4x5) 4 (4x1) ....total 165 77 33

Page 188: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

184

Page 189: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

185

Bibliografia

LLIBRES

Compilers. Principles, Techniques and Tools Aho, Afred V.; Sethi, Ravi; Ullman, Jefrey D. Addison-Wesley Publishing Company 1985 [Aho1985]

Advanced Compiler Design and Implementation Muchnick, Steven S. Morgan Kaufmann Publishers 1997 [Muchnick1997]

Assemblers, Linkers and the SPIM Simulator Larus, R. James Morgan Kaufmann Publishers Computer Science Departament, University of Wisconsin-Madison, 1998 [Larus1998]

Page 190: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

186

Page 191: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

187

Glossari

Back end Fase d’un compilador independent del codi font i dependent de la màquina per a la qual es compila.

Cadena estàtica Punter del context actual, que apunta un context en la pila que correspon al context que estàticament engloba el context actual. La cadena estàtica serveix per a l’accés a variables no locals. La cadena estàtica és anomenada, per alguns autors, textual link.

Cadena dinàmica Punter del context actual que apunta el context que l’ha cridat. La cadena dinàmica s’utilitza per poder restaurar el FP (frame pointer) quan es torna d’una crida.

Constant folding Optimització que pot ser realitzada en qualsevol moment i consisteix en l’avaluació d’expressions constants.

DDS Una definició dirigida per sintaxi (DDS) és una extensió del concepte de gramàtica incontextual. Una DDS és una gramàtica incontextual en què cada no terminal de la gramàtica té un conjunt d’atributs associats. Un atribut pot contenir informació diversa. Cada atribut es pot calcular en funció d’altres atributs i gairebé sempre són expressions

Frame, Context Conjunt d’informació que es guarda en la pila d’execució per cada context que es genera durant l’execució d’un programa. Un context es crea quan es crida una funció o procediment i s’allibera quan és retorn. La informació que es guarda és: cadena estàtica, cadena dinàmica, adreça de retorn, variables locals, paràmetres i valor de retorn.

FP, Frame pointer Punter utilitzat durant l’execució d’un programa que apunta la base del context actual. S’utilitza principalment per a l’accés a les variables locals.

Gramàtica incontextual Formalisme per expressar la sintaxi d’un llenguatge. Una gramàtica incontextual anomenada també lliure de context, té els següents components: un conjunt de terminals (tokens), un conjunt de no terminals, un conjunt de produccions (regles sintàctiques) i un no terminal especial anomenat símbol axioma. Les produccions són de la següent forma: A --> w, en què A és un no terminal i w és una cadena de terminals i no terminals.

Page 192: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

188

Gramàtica d’atributs Una gramàtica d’atributs és un cas particular de DDS ja que se li demana que les accions semàntiques no tinguin efectes col·laterals. Cada no terminal de la gramàtica pot ser vist com un registre, així els atributs es poden veure com camps. És per això que la notació utilitzada per als atributs és la notació de punt com en el cas dels camps d’un registre.

GP, Global pointer Punter utilitzat durant l’execució d’un programa que apunta la base del context en què són les variables globals. S’utilitza per a l’accés a aquestes variables.

HIR High Intermediate Representation. Representacions intermèdies d’alt nivell que s’utilitzen en les primeres etapes del compilador o en preprocessadors.

LL Les gramàtiques LL (Left-Left) són un subconjunt de les gramàtiques lliures de context. A tota gramàtica LL li podem construir un parser descendent predictiu. La primera L vol dir que l’entrada a analitzar es llegeix d’esquerra a dreta i la segona L vol dir que durant l’anàlisi sintàctica les produccions són aplicades d’esquerra a dreta. Els parsers construïts a partir de gramàtiques LL s’anomenen parsers LL.

Leader, Cap de bloc Un leader és la primera instrucció d’un bloc bàsic. La primera instrucció d’un bloc bàsic pot ser: el punt d’entrada de la rutina, una instrucció amb una etiqueta i una instrucció que estigui després d’un salt o d’un retornar.

LIR Low Intermediate Representation és un exemple de llenguatge intermedi de baix nivell. Els llenguatges intermedis de baix nivell són molt semblants als llenguatges assembladors i hi ha, en la majoria dels casos, una correspondència un a un entre les instruccions. Normalment són dependents de la màquina i utilitzats en les últimes fases per optimitzar al màxim. Aquests llenguatges utilitzen registres i adreçaments de tipus simple.

LR, canònics LR Les gramàtiques a les quals li podem construir un parser ascendent canònic són anomenades gramàtiques LR. La primera L vol dir que l’entrada es llegeix d’esquerra (Left) a dreta i la R vol dir que es produeix una derivació més a la dreta (Right)

MIR Medium Intermediate Representation és un exemple de llenguatge intermedi de nivell mitjà. Els llenguatges intermedis de nivell mitjà són dissenyats per poder representar les característiques de la majoria dels llenguatges de programació però de manera independent de la màquina. Una altra característica que han de tenir és la de permetre generar codi eficient per a diferents arquitectures. Permeten representar variables, temporals i redueixen les estructures de control complexes a salts condicionals o incondicionals.

Page 193: Creative Commons License Deed - La Salle · SESSIÓ 7: Expressions ... 3.9.2 Simplificacions algebraiques i reassociació ... Cada instrucció té una semàntica que s'ha de verificar

189

MIPS Llenguatge assemblador per a arquitectures RISC. L’arquitectura dels ordinadors MIPS és simple i fàcil d’entendre. El processador té 32 registres de propòsit general i 32 registres per aritmètica de punt flotant. Cada registre és de 32 bits. El conjunt d’instruccions permet la generació de codi molt fàcilment.

Parser ascendent, Parser bottom up , Parser shift-reduce Els parsers ascendents són analitzadors sintàctics que fan una anàlisi bottom up, és a dir, construeixen l’arbre de parser començant en les fulles i acabant en l’arrel. Els parsers LR que estudiarem són parsers shift-reduce ja que l’anàlisi sintàctica es fa amb dues operacions: shift i reduce.

Parser descendent, Parser top down Els parsers descendents són analitzadors sintàctics que fan una anàlisi top down, és a dir, construeixen l’arbre de parser començant en l’arrel (etiquetada amb el símbol axioma) i acabant en les fulles (terminals de la gramàtica). Les produccions de la gramàtica són aplicades d’esquerra a dreta, és a dir, expandint el no-terminal de la part esquerra per la part dreta corresponent.

Parser descendent predictiu Un parser descendent és predictiu (sense backtracking) si en cada pas de l’anàlisi sintàctica, sap seleccionar la pròxima producció examinant els primers k símbols de l’entrada.

Parser, Analitzador sintàctic Un analitzador sintàctic o parser és un algorisme capaç de reconèixer la sintaxi de qualsevol entrada corresponent al llenguatge de programació implementat. Dit d’una altra manera, és l’autòmat que reconeix el llenguatge que una gramàtica defineix.

SLR, simples SLR Les gramàtiques a les quals li podem construir un parser ascendent simple són anomenades gramàtiques SLR. La construcció d’un parser SLR consisteix a, primer, construir la col·lecció de conjunts d’ítems LR(0) i després a construir la corresponent taula.

SP, Stack pointer Punter utilitzat durant l’execució d’un programa que apunta la primera adreça disponible de la pila d’execució.

SPIM És un simulador per executar programes escrits en llenguatge MIPS.

Token Elements bàsics del llenguatge. Aquests elements bàsics són els terminals de la gramàtica incontextual que defineixen el llenguatge que volem compilar. Per determinar els tokens que ha de reconèixer l’analitzador hem d’estudiar el llenguatge i determinar tots els aspectes regulars. És imprescindible conèixer el vocabulari sobre el qual està definit el llenguatge.