Generacion De Codigo
Enviado por DianneLarissa • 2 de Febrero de 2015 • 1.974 Palabras (8 Páginas) • 336 Visitas
8. Generación de código
La fase final de un compilador es el generador de código. El programa destino debe preservar el significado semántico del programa fuente y ser de alta calidad, además el generados de código de código en si debe ejecutarse con eficiencia.
El problema de generar un programa destino óptimo para un programa fuente dado no se puede determinar, muchos de los subproblemas que surgen en la generación de código, son indecibles en sentido computacional.
Las fases de optimización y generación de código de un compilador, a las que con frecuencia se les conoce como l back-end, pueden realizar varias pasadas sobre la representación intermedia antes de generar el programa destino.
Un generador de código tiene tres tareas principales: selección de instrucciones, repartición y asignación de registros, y ordenamiento de instrucciones. La selección de instrucciones implica la selección de instrucciones apropiadas de la maquina destino para implementar las instrucciones de la representación intermedia. La repartición y asignación de registros implica decidir que valores mantener en que registros. El ordenamiento de instrucciones implica decidir en qué orden se va a programar su ejecución.
Muchos generadores de código particionan las instrucciones de representación intermedia en “bloques básicos”, en los cuales consisten en secuencias de instrucciones que siempre se ejecutan en conjunto.
8.1 Cuestiones sobre el diseño de un generador de código
El criterio más importante para un generador de código es que debe producir código correcto. Diseñar un generador de código de manera que pueda implementarse, probarse y mantenerse con facilidad es una meta primordial de diseño.
8.1.1 Entrada del generador de código
La entrada del generador de código es la representación intermedia del programa fuente producido por la interfaz de usuario, junto con la información en la tabla de símbolos.
Entre las diversas opciones para la representación intermedia se encuentran las representaciones de tres direcciones, como los cuádruplos, tripletas, tripletas indirectas; las representaciones lineales como la notación postfija; y las representaciones gráficas, como los arboles sintácticos y los GDAs.
8.1.2 El programa destino
La arquitectura del conjunto de instrucciones de la maquina destino tiene un impacto considerable en la dificultad de construir un buen generador de código que produzca código máquina de alta calidad. Las arquitecturas más comunes de las máquinas de destino son RISC, CISC y basadas en pilas.
Una maquina RISC tiene muchos registros, instrucciones de tres direcciones, modos de direccionamiento simple y una arquitectura del conjunto de instrucciones relativamente sencilla. Una maquina CISC, por lo general, tiene menos registros, instrucciones de dos direcciones, una variedad de modos de direccionamiento, varias clases de registros, instrucciones de longitud variable e instrucciones con efectos adicionales. En una maquina basada en pila, y después llevando a cabo las operaciones con los operandos en la parte superior de la pila. Para lograr un alto rendimiento, la parte superior de la pila se mantiene, por lo general, en los registros.
Producir un producir un programa en lenguaje maquina absoluto como salida tiene la ventaja de que puede colocarse en una ubicación fija en la memoria, y ejecutarse de inmediato, los programas pueden compilarse y ejecutarse con rapidez.
Para producir un programa en lenguaje maquina reubicable como salida permite que los subprogramas se compilen por separado. Un conjunto de módulos objeto reubicables pueden enlazarse y cargarse para que lo ejecute un cargador de enlace.
Si la maquina destino no maneja la reubicación de manera automática, el compilador debe proporcionar información de reubicación explicita al cargador para enlazar los módulos del programa.
Producir un programa en lenguaje ensamblador como salida facilita de alguna manera el proceso de la generación e código.
8.1.3 Selección de instrucciones
El generador de código debe asignar el programa de representación intermedia a una secuencia de código que la máquina de destino pueda ejecutar, su complejidad se determina mediante:
- El nivel de la representación intermedia
- La naturaleza de la arquitectura del conjunto de instrucciones
- La calidad deseada del código generado
Si la representación intermedia es el alto nivel, el generador de código puede traducir cada instrucción de este tipo en una secuencia de instrucciones de máquina, usando plantillas de código.
La velocidad delas instrucciones y las características específicas de la maquinas son factores importantes.
Para cada tipo de instrucción de tres direcciones, podemos diseñar un esqueleto de código que defina el código destino a generar para esa construcción. Por ejemplo, toda instrucción de tres direcciones de la form a x = y + z, en donde x, y, z se asignan en forma estática, puede traducirse en la siguiente secuencia de código:
Por lo general, la calidad del código generado se determina en base a su velocidad y tamaño, por lo general. En la mayoría de las maquinas se puede implementar un programa representación intermedia mediante muchas secuencias de código distintas, con diferencias considerables en cuanto al rendimiento de las distintas implementaciones.
Para decidir que secuencia de código maquina es mejor para una construcción de tres direcciones dada, tal vez también sea necesario tener conocimientos acerca del contexto en el que aparece esa construcción.
8.1.4 Asignación de registros
Un problema clave en la generación de código es decidir que valores guardar en que registros. Los registros son la unidad computacional más veloz en la maquina destino pero, por lo general no tenemos suficientes como para contenes todos los valores. Los valores que no se guardan en registros deben residir en la memoria.
A menudo, el uso de los registros se divide en dos subproblemas:
- Repartición de registros, durante la cual seleccionamos el conjunto de variables que residirán en los registros, en cada punto del programa.
- Asignación de registros, durante la cual elegimos el registro específico en el que residirá una variable.
Es difícil encontrar una asignación optima de registros a variables, incluso en las maquinas con un solo registro.
8.1.5 Orden de evaluación
El orden en el que se realizan los cálculos puede afectar la eficiencia del código destino. Ciertos órdenes de los cálculos requieren menos registros que otros para contener resultados inmediatos.
8.2 El lenguaje destino
...