1. Optimización Global
•
Grafo del flujo de ejecución
–
Antes de realizar una optimización global es necesario crear el grafo de
flujo de ejecución.
–
El grafo de flujo de ejecución representa todos los caminos posibles de
ejecución del programa.
–
La información contenida en el grafo es útil para
•
•
•
el programador y
el optimizador
La optimización global a partir del análisis del grafo del flujo de ejecución permite
–
–
Eliminación del código no utilizado
–
•
Una propagación de constantes fuera del bloque básico.
Una mejor asignación de los registros.
Problema: la optimización global es muy costosa en tiempo de compilación
Construcción del Grafo del Flujo de Ejecución
•
Tipos de grafo
–
–
•
Orientado a procedimiento/función
Grafo de llamadas
Ejemplo
int fact(int n) {
int r;
r=1;
i=1;
while (i<=n) {
r=r*i;
2. ++i;
}
return r;
}
Construcción del Grafo del Flujo de Ejecución
•
Pasos
–
Dividir el programa en bloques básicos
•
Se representa el programa en un código intermedio donde queden
explícitamente representados los saltos condicionales e
incondicionales.
•
Un bloque básico será cualquier trozo de código que no contenga
saltos ni etiquetas en su interior (es posible tener etiquetas al inicio
del bloque y saltos al final).
3. –
•
En el grafo, los vértices representan los bloques básicos y las aristas
representan los saltos de un bloque básico a otro.
Detección de código no utilizado
El código no utilizado son los bloques básicos donde no llega ninguna arista
Análisis del Grafo del Flujo de Ejecución
•
Hay que considerar como la información sobre las variables y expresiones se
propaga a través del grafo.
•
Problemas resueltos durante el análisis del grafo
–
–
Alcance de las definiciones
–
variables vivas
–
•
expresiones disponibles (al seguir la ejecución sigue siendo válido el
resultado obtenido)
expresiones muy utilizadas
Para la resolución de los problemas anteriores se utiliza la idea de punto entre
instrucciones o bloques básicos.
r=1
i=1
Puntos
while
(i<=n)
4. 7.1.3 Globales
•La optimización global se da con respecto a todo el código.
•Este tipo de optimización es más lenta pero mejora el desempeño general de todo
programa.
•Las optimizaciones globales pueden depender de laarquitectura de la máquina.
•En algunos casos es mejor mantener variables globales para agilizar los procesos (el
proceso de declarar variables y eliminarlas toma su tiempo) pero consume más memoria.
•Algunas optimizaciones incluyen utilizar como variables registros del CPU, utilizar
instrucciones en ensamblador.
De mirilla
•La optimización de mirilla trata de estructurar de manera eficiente el flujo del programa,
sobre todo en instrucciones de bifurcación como son las decisiones, ciclos y saltos de
rutinas.
•La idea es tener los saltos lo más cerca de las llamadas, siendo el salto lo más pequeño
posible
Optimización de tipo Mirilla (Peephole optimization) Aplicable en código intermedio o
código objeto.
Constituye una nueva fase aislada. Idea Básica Se recorre el código buscando
combinaciones de instrucciones que puedan ser reemplazadas por otras equivalentes más
eficientes. Se utiliza una ventana de instrucciones y un conjunto de patrones de
transformación (patrón, secuencias reemplaza.) Si las instrucciones de la ventana en cajan
con algún patrón se reemplazan por lo secuencia de reemplazmiento asociada. Las
nuevas instrucciones son reconsideradas para las futuras optimizaciones Ejemplos:
Eliminación de cargas innecesarias MOVRi,X MOVX,Rj →MOVRi,Rj Reducción de potencia
Eliminación de cadenas de saltos ifCgotoL1 L1: gotoL2 → ifCgotoL2 ifCgotoL1 gotoFIN L1:
FIN: ... ... ifnotCgotoFIN → L1: FIN: