Você está na página 1de 13

2012

UNIVERSIDAD NACIONAL DE TRUJILLO

GENERACIN DE CDIGO INTERMEDIO

INTEGRANTES Snchez Muoz Jean Carlos Novoa Ruiz Pedro Luis

Ingeniera informtica VII |

GENERACIN DE CDIGO INTERMEDIO 1. Introduccin El proceso de la compilacin se desglosa en dos partes: la parte que depende solo del lenguaje fuente (etapa inicial o front-end) y la parte que depende solo del lenguaje objeto (etapa final o back-end). La etapa inicial traduce un programa fuente a una representacin intermedia a partir de la cual la etapa final genera el cdigo objeto. De esta forma, los detalles que tienen que ver con las caractersticas del lenguaje objeto (cdigo ensamblador, cdigo maquina absoluto o relocalizable, etc.), la arquitectura de la maquina (nmero de registros, modos de direccionamiento, tamao de los tipos de datos, memoria cache, etc.), el entorno de ejecucin (estructura de registros y memoria de la mquina donde se va a ejecutar el programa) y el sistema operativo se engloban en la etapa final y se aslan del resto. El cdigo intermedio es un cdigo abstracto independiente de la mquina para la que se generar el cdigo objeto. El cdigo intermedio ha de cumplir dos requisitos importantes: ser fcil de producir a partir del anlisis sintctico, y ser fcil de traducir al lenguaje objeto. Con una representacin intermedia bien definida, un compilador para el lenguaje I y la maquina J puede ser construido combinando el front-end para el lenguaje I con el back-end de la maquina J. De esta manera se pueden construir m*n compiladores escribiendo nicamente m front-ends y n back-ends. 2. Lenguajes Intermedios Un lenguaje intermedio es el lenguaje de una mquina abstracta diseada para ayudar en el anlisis de los programas de computadora. El trmino viene de su uso en los compiladores, donde un compilador primero traduce el cdigo fuente de un programa, en una forma ms apropiada para las transformaciones de mejora del cdigo (forma usualmente llamada bytecode), como un paso intermedio antes de generar el archivo objeto o el cdigo mquina para una mquina especfica. 2.1. Caractersticas Su principal ventaja es la portabilidad, pues el mismo cdigo puede ser ejecutado en diferentes plataformas y arquitecturas. Esta ventaja la tiene tambin los lenguajes interpretados, aunque generalmente con mejor rendimiento. Por esto, muchos lenguajes interpretados se compilan a bytecode y despus son ejecutados por un intrprete de bytecode. 2.2. Cdigo intermedio en las fases de un Compilador

El siguiente grfico muestra las dos etapas y como se relacionan entre s a travs de la representacin intermedia.

3. Tipos de Lenguajes Intermedios Hay tres tipos de lenguaje intermedio los cuales son: 3.1. Tipo 1 Es una representacin ms abstracta y uniforme que un lenguaje mquina concreto. Su misin es descomponer las expresiones complejas en binarias y las sentencias complejas en sentencias simples. a) Ventajas Permite una fase de anlisis (anlisis semntico) independiente de la mquina. Se pueden realizar optimizaciones sobre el cdigo intermedio (Las complejas rutinas de optimizacin son independientes de la mquina. b) Desventajas Perdida de eficiencia (no permite una compilacin de una sola pasada). Introduce en el compilador una nueva fase de traduccin.

3.2. Tipo 2 Tipo de lenguajes intermedios: rbol sintctico. rbol sintctico abstracto (todos los nodos del rbol representan smbolos terminales, los nodos hijos son operandos y los nodos internos son operadores). Grafo dirigido a cclico (GDA). Notacin posfija. 3.3. Tipo 3 Tripletas Cuartetos 4. Generadores de Cdigo Se describen a continuacin: 4.1. Caractersticas La generacin de cdigo es un proceso que toma un cdigo fuente y genera un cdigo objeto de igual semntica (generalmente en un nivel de abstraccin menor). En la estructura general de un compilador, este proceso acostumbra a aparecer en dos contextos. o Generacin de Cdigo Intermedio (front-end). o Generacin de Cdigo Destino (back-end). El cdigo intermedio de un compilador suele ser cdigo del lenguaje de una mquina abstracta. Puede ser interna (gcc) o externa al compilador (Java). o La representacin externa ms utilizada est basada en mquina de pila (JVM, LLVM, CLI). o Es en la representacin interna donde ms aparece la representacin basada en cdigo de tres direcciones. 4.2. Tareas de un generador de Cdigo Cualquier proceso de generacin de cdigo, debe resolver los siguientes problemas: Seleccin de instrucciones

Encontrar la secuencia de instrucciones del lenguaje destino con igual semntica que las construcciones del lenguaje de entrada. Seleccin de direcciones de almacenamiento En funcin del cdigo destino, deber identificarse para cada smbolo. o Un modo de almacenamiento (dinmico o esttico). o Una direccin de memoria (absoluta o relativa). o Un esquema de traduccin de estructuras de alto nivel a su traduccin a bajo nivel. Asignacin de registros Si el cdigo destino est basado en un lenguaje que utiliza (un nmero limitado de) registros, se deber encontrar un modo de distribuir stos. 5. Cdigo de Tres Direcciones 5.1. Caractersticas Son las siguientes: Se compone de instrucciones que contienen tres (o menos) direcciones, dos para los operandos y una para el resultado. Los operandos y el resultado pueden ser nombres, o variables temporales generadas por el compilador. Los operandos pueden tambin ser constantes. Las instrucciones pueden estar marcadas por etiquetas simblicas (representan un ndice dentro del conjunto de instrucciones). Tiene instrucciones de control de flujo.

5.2. Casos Comunes 5.2.1. Instrucciones de Asignacin (op es un operador binario, aritmtico o lgico). (op es un operador unario, menos conversin).

a) Asignaciones indexadas

b) Apuntadores (asigna la direccin de y). (y es un apuntador). (x es apuntador). 5.2.2. Saltos a) Incondicional goto L b) Condicional if x rel-op y goto L 5.2.3. Llamada a procedimientos y retorno param x1 param x2 ... param xn call p n return y 6. Implementaciones de Cdigos de Tres Direcciones Una proposicin de tres direcciones es una forma abstracta de cdigo intermedio. En un compilador estas proposiciones se pueden implementar como registros con campos para el operador y los operandos. Las implementaciones pueden ser: 6.1. Tripletas Para evitar tener que introducir nombres temporales en la tabla de smbolos, se hace referencia a un valor temporal segn la posicin de la proposicin que lo calcula. Las propias instrucciones representan el valor del nombre temporal. La implementacin se hace mediante registros de solo tres campos (op, arg1, arg2). operador (0) (1) * + arg1 2 (0) arg2 X 10

op: operador arg1: argumento 1 operando 1. arg2: argumento 2 operando 2.

En la notacin de tripletes se necesita menor espacio y el compilador no necesita generar los nombres temporales. Sin embargo, en esta notacin, trasladar una proposicin que defina un valor temporal exige que se modifiquen todas las referencias a esa proposicin. Lo cual supone un inconveniente a la hora de optimizar el cdigo, pues a menudo es necesario cambiar proposiciones de lugar. Una forma de solucionar esto consiste en listar las posiciones a las tripletas en lugar de listar las tripletas mismas. De esta manera, un optimizador podra mover una instruccin reordenando la lista, sin tener que mover las tripletas en s. 6.2. Cudruplas Una cudrupla es una estructura tipo registro con cuatro campos que se llaman (op, result, arg1, arg2). op (0) (1) * + arg1 2 T1 arg 2 X 10 result T1 T2

Op: operador arg1: argumento 1 operando 1. arg2: argumento 2 operando 2. result: resultado de la operacin. Por ejemplo, la proposicin de tres direcciones x = y + z se podra representar mediante la cudrupla: ( ) Los contenidos de los campos Argumento1, Argumento2 y Resultado son generalmente punteros a la Tabla de Smbolos. Las proposiciones con operadores unarios no usan el arg2. Los campos que no se usan se dejan vacos o un valor NULL. Como se necesitan cuatro campos se le llama representacin mediante cudruplas.

7. Cdigo intermedio como un atributo sintetizado El cdigo intermedio puede ser considerado como un atributo sintetizado. El cdigo intermedio es visto como una cadena de caracteres y se puede disear un esquema de traduccin dirigido por la sintaxis (ETDS) que genere dicho cdigo al recorrer el rbol de anlisis sintctico en orden postfijo. Consideremos como ejemplo la siguiente gramtica simplificada que genera expresiones aritmticas. Dada la expresin se calcula el valor del no-terminal en un nombre temporal. Por el momento, se crea un nuevo

nombre cada vez que se necesita. Ms tarde veremos un sencillo mtodo para reutilizar los nombres temporales. Cada no-terminal tiene dos atributos: , nombre temporal que contendr el valor ( ). , serie de todas las proposiciones de cdigo de 3-direcciones que calculan .

Ambos atributos sintetizados. La funcin de () genera nombres distintos cada vez que es llamada. Las llaves indican una instruccin de 3-direcciones. El smbolo // representa la concatenacin de los trozos de cdigo. Ejemplo:

Expresin:

7.1. Reutilizacin de los nombres temporales Hasta ahora se ha supuesto que la funcin () genera un nombre temporal cada vez que se necesita un temporal. Sin embargo, los nombres temporales utilizados para guardar valores intermedios de los clculos de expresiones tienen que ser introducidos en la tabla de smbolos para guardar sus valores con el consiguiente aumento de espacio. Los nombres temporales se pueden reutilizar mediante un sencillo mtodo que consiste en llevar una cuenta q, iniciada a cero, de variables temporales. Cuando se utilice un nombre temporal como operando hay que decrementar el valor de es 1. Siempre que se genere un nuevo nombre temporal se usa el valor del contador ( ) y se incrementa el valor de en 1. Consideremos el siguiente ejemplo

8. OPTIMIZACIN DE CDIGO INTERMEDIO La optimizacin de cdigo intermedio se puede realizar: nivel local: slo utilizan la informacin de un bloque bsico para realizar la optimizacin. nivel global: que usan informacin de varios bloques bsicos.

El termino optimizacin de cdigo es inadecuado ya que no se garantiza el obtener, en

el sentido matemtico, el mejor cdigo posible atendiendo a maximizar o minimizar una funcin objetivo (tiempo de ejecucin y espacio). El termino de mejora de cdigo sera ms apropiado que el de optimizacin. Nos concentraremos bsicamente en la optimizacin de cdigo de tres direcciones, puesto que son siempre transportables a cualquier etapa nal, son optimizaciones independientes de la mquina. La mayora de los programas emplean el 90% del tiempo de ejecucin en el 10% de su cdigo. Lo ms adecuado es identicar las partes del programa que se ejecutan ms frecuentemente y tratar de que se ejecuten lo ms ecientemente posible. En la prctica, son los lazos internos los mejores candidatos para realizar las transformaciones. Adems de la optimizacin a nivel de cdigo intermedio, se puede reducir el tiempo de ejecucin de un programa actuando a otros niveles: a nivel de cdigo fuente y a nivel de cdigo objeto.

Un bloque bsico es una unidad fundamental de cdigo. Es una secuencia de proposiciones donde el ujo de control entra en el principio del bloque y sale al nal del bloque. Los bloques bsicos pueden recibir el control desde ms de un punto en el programa (se puede llegar desde varios sitios a una etiqueta) y el control puede salir desde ms de una proposicin (se podra ir a una etiqueta o seguir con la siguiente instruccin). Cuando aplicamos optimizacin dentro de un bloque bsico slo nos tenemos que preocupar sobre los efectos de la optimizacin en los valores de las variables a la entrada del bloque y los valores que tienen a la salida del bloque, que han de ser los mismos que en el cdigo original sin transformar. El algoritmo para particionar un programa en bloques se describe a continuacin: 1 Encontrar todas las proposiciones que comienzan el principio de un bloque bsico: La primera sentencia del programa. Cualquier proposicin del programa que es el objetivo de un salto. Cualquier proposicin que sigue a una bifurcacin. 2 Para cualquier proposicin que comienza un bloque bsico, el bloque consiste de esa proposicin y de todas las siguientes hasta el principio del siguiente bloque o el final del programa.

Algunas deniciones previas: Dada una proposicin de 3-direcciones de la forma a = b op c decimos que la proposicin referencia b y c y que dene a. Se dice que un nombre en un bloque bsico vive al nal del bloque si su valor es referenciado en otro bloque bsico en el programa. Se dice que un nombre est muerto si no es referenciado en el resto del programa. Se presentan algunas de las transformaciones ms tiles para mejorar el cdigo. Son transformaciones locales, se pueden realizar observando slo las proposiciones de un bloque bsico. 8.1 ELIMINACIN DE SUBEXPRESIONES COMUNES Si una expresin se calcula ms de una vez, se puede remplazar el clculo de la segunda por el valor de la primera expresin. Consideremos el siguiente ejemplo del cdigo (a). Vemos que la expresin t3 * t1 se calcula dos veces, por tanto podemos escribir el cdigo de la gura (b):

t1 = 4 - 2 t2 = t1 / 2 t3 = a * t2 t4 = t3 * t1 t5 = t4 + b t6 = t3 * t1 t7 = t6 + b c = t5 * t7 (a)

t1 = 4 - 2 t2 = t1 / 2 t3 = a * t2 t4 = t3 * t1 t5 = t4 + b t6 = t4 t7 = t6 + b c = t5 * t5 (b)

Eliminacin de sub-expresiones comunes Esto slo es posible si los operandos que estn implicados en el clculo de la expresin no han modicado su valor en las proposiciones intermedias. 8.1 PROPAGACIN DE COPIAS La propagacin de copias considera las proposiciones de la forma a=b. Despus de esta sentencia sabemos que a y b tienen el mismo valor, por tanto, podemos remplazar cada vez que aparezca a por b con la esperanza de que podamos remplazar todas las ocurrencias de a hasta que se convierta en un nombre muerto y se pueda entonces eliminar la proposicin de copia. A partir del cdigo anterior podemos eliminar la proposicin de copia t6=t4. Sustituimos t6 por t4. Vase gura (a). Ahora se puede ver que hay de nuevo una subexpresin comn que puede ser eliminada, obteniendo el cdigo que se muestra en (b). Y nalmente realizando otra vez propagacin de copias, obtenemos (c):

t1 = 4 - 2 t2 = t1 / 2 t3 = a * t2 t4 = t3 * t1 t5 = t4 + b t6 = t4 t7 = t4 + b c = t5 * t7 (a)

t1 = 4 - 2 t2 = t1 / 2 t3 = a * t2 t4 = t3 * t1 t5 = t4 + b t6 = t4 t7 = t5 c = t5 * t5 (c) Propagacin de copias y eliminacin de subexpresiones comunes

t1 = 4 - 2 t2 = t1 / 2 t3 = a * t2 t4 = t3 * t1 t5 = t4 + b t6 = t4 t7 = t5 c = t5 * t7 (b)

Vemos que el haber hecho una optimizacin puede dar lugar a que sea posible aplicar nuevas optimizaciones. 8.1 ELIMINACIN DE CDIGO MUERTO Podemos tener proposiciones que denen un nombre que nunca ms es referenciado, est muerto. Estas proposiciones pueden entonces ser eliminadas. Dada la proposicin a= b op c, se dice que es cdigo muerto o inactivo si no es referenciada. En general, el cdigo muerto aparece como consecuencia de la propagacin de copias y es esto lo que hace que la tcnica de propagacin de copias sea tan til. Veamos cmo aplicar esta tcnica al ejemplo anterior en la gura (c). Vemos que t6 y t7 no tienen ninguna referencia a partir de su denicin, por tanto pueden ser eliminadas. Obtenemos el cdigo que aparece en la siguiente gura . Se ha supuesto que todas las variables no-temporales estn vivas, se hace referencia a ellas en el resto del programa. t1 = 4 - 2 t2 = t1 / 2 t3 = a * t2 t4 = t3 * t1 t5 = t4 + b c = t5 * t5 Eliminacin de cdigo muerto Aunque es poco probable que el programador introduzca cdigo muerto o inactivo, ste puede aparecer como resultado de transformaciones anteriores.

8.1 TRANSFORMACIONES ARITMTICAS Se pueden hacer uso de transformaciones algebraicas simples para reducir la cantidad de computacin transformando operaciones ms costosas por otras menos costosas. Existen tres tipos de transformaciones algebraicas bsicas.

8.5.1 Calculo previo de constantes Se trata de calcular a nivel de compilacin el valor previo de constantes en vez de hacerlo en tiempo de ejecucin que retardara la ejecucin de un programa. A esta optimizacin se le llama clculo previo de constantes (en ingls constant folding). El cdigo de la gura anterior puede ser mejorado dando lugar al cdigo de la gura 7.10 (a). Haciendo una propagacin de copias y eliminacin de cdigo muerto tenemos el cdigo de la gura 7.10 (b). Realizando de nuevo un clculo previo de constantes obtenemos 7.10(c). Y nalmente podemos hacer de nuevo la propagacin de copias y la eliminacin de cdigo muerto, obteniendo el cdigo de la gura 7.10 (d). t1 =2 t2 = t1 / 2 t3 = a * t2 t4 = t3 * t1 t5 = t4 + b c = t5 * t5 (a) t2 = 2 / 2 t3 = a * t2 t4 = t3 * 2 t5 = t4 + b c = t5 * t5 (b) t2 = 1 t3 = a * t2 t4 = t3 * 2 t5 = t4 + b c = t5 * t5 (c) t3 = a * 1 t4 = t3 * 2 t5 = t4 + b c = t5 * t5 (d)

Tabla 7.10: Clculo previo de constantes Hemos pasado de seis proposiciones a tener cuatro, eliminado una substraccin y una divisin en el proceso. 8.5.2 Transformaciones algebraicas Podemos hacer uso de identidades algebraicas para simplicar el cdigo. Las principales identidades son: Partiendo de la gura 7.10 (d) podemos obtener el cdigo de la gura 7.11(a). De nuevo si usamos propagacin de copias y eliminacin de cdigo muerto obtenemos el cdigo de la gura 7.11 (b): t3 = a t4 = a * 2 t4 = t3 * 2 t5 = t4 + b t5 = t4 + b c = t5 * t5 c = t5 * t5 (b) (a) Tabla 7.11: Identidades algebraicas 8.5.3 Reduccin de intensidad En la mayora de las mquinas las operaciones de multiplicacin y divisin son substancialmente ms costosas que las operaciones de suma y resta. Y a su vez, las potencias son ms costosas que las multiplicaciones y divisiones. Por tanto, siempre que sea posible es conveniente sustituir un operador ms costoso por otro menos costoso. A esto se le conoce como reduccin de la intensidad. Las identidades ms comunes son: En nuestro ejemplo de la gura 7.11 (b) podemos obtener el cdigo 7.12 Otra transformacin tpica es usar desplazamientos de bits cuando se divida o se multiplique por potencias de dos. t4 = a + a t5 = t4 + b c = t5 * t5 Tabla 7.12: Reduccin de intensidad

Você também pode gostar