Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Apuntes T9 PDF
Apuntes T9 PDF
Apuntes T9 PDF
Tabla de contenido:
!"#$%&'()*++,-% """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""".!
/"#01(2*34#564,+(4#7#8'9:(4#)3#:1*;(""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""<!
."#=>&,?,@9+,(%34#1(+9134"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""A!
"#$#!%&'()*+&,'-.+(/)!'01/2&'.-')############################################################################################################################# 3!
"#4#!%&'()*+&,'-.+(/)!56/!7&/)/&8'(!0'!/)9&6-96&'########################################################################################### :!
!"#"$"%&'()*+,--./'%01%0'21.3.3%+4%51,6*%+4%+0(*3 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""7!
!"#"#"%819,'03%()0'35*):0-.*'43%;,4%<)434)=0'%10%43(),-(,)0"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" $#!
!"#"!"%>)05*3%+.).9.+*3%0-?-1.-*3@%>A83"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" $!!
!"#"B"%C4-*'3(),--./'%+41%-/+.9*%.'(4):4+.*%0%<0)(.)%+4%,'%>A8""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" $D!
B"#=>&,?,@9+,(%34#81(59134 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" !C!
;#$#!<79.,.='-.>(!?/!)'09+) ######################################################################################################################################### $:!
;#4#!@/9/--.>(!?/!26-0/) ############################################################################################################################################### $:!
;#"#!AB9&'--.>(!?/!->?.1+!.(8'&.'(9/####################################################################################################################### 44!
;#;#!C/?6--.>(!?/!.(9/().?'?!/(!8'&.'20/)!?/!.(?6--.>( ############################################################################### 4D!
;#D#!A0.,.('-.>(!?/!8'&.'20/)!?/!.(?6--.>(########################################################################################################## "4!
U nidad t emtica 9:
V. 10
Cualquier sugerencia o error detectado puede ser enviado a la direccin de correo vgisbert@dsic.upv.es
E(1*+,(%34#)3#1(4#3;3'+,+,(4#4313++,(%9)(4" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""B.!
0,51,(8'9:F9" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" AG!
1. Introduccin
En general el cdigo intermedio generado por un compilador suele ser bastante ineficiente.
Basta observar el cdigo generado para la evaluacin de una expresin para darse cuenta de este
hecho.
Ejemplo 3.1:
Cdigo fuente !
a := x^2 + y
Cdigo intermedio: ! t1 := 2
t2 := x^t1
t3 := t2 + y
a := t3
Cdigo mejorado: ! t1 := x * x
a := t1 + y
Programa fuente.
Optimizaciones cuyos efectos podran obtenerse con una implementacin ms
apropiada del programa fuente. El programador puede: perfilar el programa, cambiar
el algoritmo, mejorar bucles por ejemplo podra substituir if TRUE then A else
B por A
Cdigo intermedio.
Hay mejoras que no son posibles en el programa fuente, Ej. El cdigo generado para
acceder a los elementos de una matriz dentro de un bucle, calcular varias veces la
misma funcin de acceso. Ejemplos de estas transformaciones son:
En el Ejemplo 3.1 observamos dos tipos de mejoras: talla del cdigo, el nmero de
instrucciones se reduce a la mitad, y eficiencia en la ejecucin, hay dos asignaciones menos y
una operacin de menor coste.
Subexpresiones comunes
Transformaciones algebraicas.
Copias de variables
Cdigo inactivo
Bucles
Cdigo objeto.
En este nivel el uso adecuado de los registros, as como de las instrucciones propias
de la mquina destino pueden suponer beneficios importantes respecto de la eficiencia
del programa objeto. Ej. Aprovechar una instruccin de la mquina destino que ya
proporciona una suma y un salto condicional en funcin del resultado.
Ejemplo 3.2:
Cdigo fuente !
2.
Un bloque bsico lo forma un lder y todas las instrucciones que le siguen hasta el siguiente
lder (sin incluir a ste ltimo).
Ejemplo 3.3:
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
(11)
(12)
(13)
(14)
(15)
(16)
(17)
(18)
(19)
i
:= m - 1
j
:= n
t1 := 4 * n
v
:= a[t1]
if i < j goto (7)
goto (29)
i
:= i + 1
t2 := 4 * i
t3 := a[t2]
if t3 >= v goto (12)
goto (7)
j
:= j - 1
t4 := 4 * j
t5 := a[t4]
if t5 <= v goto (17)
goto (12)
if i >= j goto (19)
goto (20)
goto (28)
(20)
(21)
(22)
(23)
(24)
(25)
(26)
(27)
(28)
(29)
(30)
(31)
(32)
(33)
(34)
(35)
(36)
t6 := 4 * i
x
:= a[t6]
t7 := 4 * i
t8 := 4 * j
t9 := a[t8]
a[t7] := t9
t10 := 4 * j
a[t10] := x
goto (5)
t11 := 4 * i
x
:= a[t11]
t12 := 4 * i
t13 := 4 * n
t14 := a[t13]
a[t12] := t14
t15 := 4 * n
a[t15] := x
El conjunto de lderes de este cdigo son las instrucciones: (1), (5), (6), (7), (11), (12), (16), (17),
(18), (19), (20), (28) y (29). Los bloques bsicos estaran formados por:
B1: (1) a (4)
B2: (5)
B3: (6)
B5: (11)
B7: (16)
B8: (17)
B9: (18)
B10: (19)
B12: (28)
Grafo de flujo
Calcular lderes
1.1 La primera instruccin del programa es un lder.
1.2 Cualquier instruccin destino de un salto condicional o incondicional o de una
llamada a procedimiento es un lder.
1.3 Cualquier instruccin inmediatamente a continuacin de un salto condicional o
incondicional o de una llamada a procedimiento es un lder.
Grafo dirigido que representa el flujo de control de un programa. Cada bloque bsico ser un
nodo del grafo. El nodo inicial es el bloque bsico que contiene la primera instruccin del
programa. Habr una arista dirigida del nodo BX al BY, (BX ! BY) si BY puede ir
inmediatamente despus de BX en alguna secuencia de ejecucin del programa. Es decir:
a) Hay un salto condicional o incondicional desde la ltima instruccin de BX a la primera de
BY,
Operador " 1 distributivo respecto a " 2: # "1 ($ "2 %) = (# "1 $) "2 (# "1 %)
Operador unario autoinverso: " " # = #
B1
not not x = x
Ejemplo 3.4:
La aplicacin sucesiva de algunas de las propiedades anteriores nos permite realizar la
siguiente transformacin:
B4
B5
A*(B*C)+(B*A)*D+A*E = A*(B*(C+D)+E)
B6
B13
B7
B8
2. Reduccin de intensidad.
B9
B10
La mejora de cdigo consiste en sustituir una operacin por otra equivalente pero menos
costosa, por ejemplo, la sustitucin de ciertos productos por sumas o de potencias por
productos,
B11
y := x ^2 ! y := x * x; y := x * 2 ! y := x + x;
B12
3. Clculo previo de constantes.
En el cdigo objeto a menudo aparecen operaciones que se pueden realizar en tiempo de
compilacin, puesto que sus operandos son conocidos en ese momento. Por ejemplo:
3. Optimizaciones locales
PI := 3.1415
x := 3 * PI
La instruccin anterior puede ser sustituida por x := 6.2830 en el momento de la
compilacin.
Esta tcnica tambin se conoce como plegado (holding).
Ejemplo 3.5
En este ejemplo muestra una utilizacin de las transformaciones algebraicas:
y := 3
1. Simplificaciones algebraicas:
Expresiones de identidad: identidad " # = #
7
t1 := 2 + y
t2 := t1 + z
x := t2 + 5
Por aplicacin de las reglas: conmutativa, asociativa y propagacin de constantes
obtendramos.
x := 10 + z
Una variable est activa en un arco del grafo de flujo si existe un camino dirigido desde ese arco
a un uso de la variable que no pasa por ninguna definicin de la variable. En el siguiente ejemplo
las variables activas en cada arco son: (I)! {y, z, b} ;(II) ! {x, b, z}; (III) ! {a, x, b, z}
Los nmeros en coma flotante no cumplen siempre todas las propiedades algebraicas. El
siguiente ejemplo demuestra que la suma no es asociativa. Esto es una consecuencia del
truncamiento y del redondeo al representar un nmero real en memoria. (El programa ha sido
compilado y ejecutado en un compilador comercial)
program precision;
var x,y,z:real;
{ clculo de nmeros reales por Emulacin}
begin
x := 11111111111.0; y := 2.45; z := 0.055; {probar: 2.46; 0.055 y 2.46; 0.054}
writeln(( x + y ) + z ); { 1.1111111114E+10 }
writeln( x + ( y + z )); { 1.1111111113E+10 }
end.
Ejemplo 3.6:
(1) x :=
(I)
(2) x := y + z
(II)
(3) a := x + b
(III)
(4) y := a + x
(5) if x < 5 goto 2
(6) b := x
Una variable x est activa a la entrada de un nodo n (x & ent[n]) si est activa en cualquiera de
los arcos de entrada del nodo. De igual forma, una variable x est activa a la salida de un nodo n
(x & sal[n]) si est activa en cualquiera de los arcos de salida del nodo.
En el Ejemplo 3.6:
ent[n]
(1)
(2)
(3)
(4)
(5)
(6)
y, z, b
x, b, z
a, x, b, z
x, y, z, b
x
sal[n]
y, z, b
x, b, z
a, x, b, z
x, y, z, b
x, y, z, b
Supondremos, como caso excepcional, que la ltima instruccin del bloque bsico puede ser un
salto condicional a la primera instruccin del bloque bsico. Las funciones def[] y usa[] calculan
las variables definidas o usadas en cada instruccin de un bloque bsico.
def[i] = Variable que se define en la instruccin de asignacin i.
usa[i] = Conjunto de variables que se usan en la parte derecha de la instruccin i.
Las siguientes definiciones se pueden aplicar sobre nodos que representan bloques bsicos, y
tambin sobre nodos que representen instrucciones individuales. En cada caso los arcos del grafo
de flujo indican los posibles caminos que puede seguir el control del flujo del programa.
Las ecuaciones siguientes establecen la relacin que existe entre las funciones ent[], sal[],def[] y
usa[].
10
Con el fin de establecer las variables activas en cada punto de un bloque bsico perfilaremos la
definicin de bloque bsico. Un bloque bsico estar formado por un tupla de tres elementos: (I,
E, S): I el conjunto de instrucciones que forman el bloque bsico, E el conjunto de variables
activas a la entrada del bloque bsico, y S el conjunto de variables activas a la salida del bloque.
En el caso de que la ltima instruccin del bloque bsico sea un salto condicional a la primera
instruccin del bloque bsico, entonces S ser el conjunto de variables activas en el arco que va a
la instruccin que sigue a la instruccin condicional.
Observar que la instruccin (1) y la (3) no calculan las mismas expresiones. En cambio, a d
es una subexpresin comn a las instrucciones (2) y (4).
, E, S).
(2)
(3)
(4)
(5)
x
a
y
1 iteracin
ent[]
sal[]
y, z, b
x, b
x, b
a, x
a, x
x
x
x
a := b + c
b := a d
c := b + c
d .= b
Aunque en un principio parece que el cdigo no mejore, nos facilitar la posible eliminacin
posterior de asignaciones a i (ver eliminacin de cdigo inactivo)
sal[i] :=
(1)x := t3
(2) t9 := t5
(3)a[t2] := t9
(4)a[t4] := x
Ejemplo 3.7: Consideremos el bloque bsico ({2,3,4,5}, {y, z, b}, {x}) del Ejemplo 3.6. si
aplicamos el algoritmo para el clculo de ent[] y sal[] obtendremos:
usa
y, z
x, b
a, x
x
a := b + c
b := a - d
c := b + c
d := a - d
def
(1)
(2)
(3)
(4)
2 iteracin
ent[]
sal[]
y, z, b
x, b, z
x, b, z
a, x, z, b
a, x, z, b x, y, z, b
x, y, z, b x, y, z, b
3 iteracin
ent[]
sal[]
y, z, b
x, b, z
x, b, z
a, x, z, b
a, x, z, b x, y, z, b
x, y, z, b x, y, z, b
(1)x := t3
(2)t9 := t5
(3)a[t2] := t5
(4)a[t4] := t3
Ahora si la variable t9 no esta activa a la salida del bloque entonces la instruccin (2) puede
eliminarse. Esto ocurre a menudo con las variables temporales que introduce el generador de
cdigo intermedio.
3. Eliminacin de cdigo inactivo
Llamamos cdigo inactivo a la secuencia de instrucciones que calculan valores que nunca llegan
a utilizarse o realizan acciones que nunca llegan a ejecutarse. Este cdigo puede aparecer como
consecuencia de alguna de las transformaciones anteriores.
Dado un bloque bsico (I, E, S) la aplicacin reiterativa, hasta que el bloque bsico no sufra
ninguna modificacin, de las siguientes reglas permite eliminar las instrucciones inactivas del
bloque bsico.
Algoritmo 3.3: Eliminacin de instrucciones inactivas
Para toda i & I si la instruccin i define la variable a y a ( sal[i] entonces I := I {insi }
11
12
a := x
En el ejemplo podemos observar que los nodos del grafo estn ocupados por variables
(posiblemente constantes) cuyo valor se supone conocido a la entrada al bloque o por
operadores. Junto al valor del nodo aparecen los nombres de las variables que contienen, al final
del bloque, el valor de la expresin asociada al subgrafo correspondiente a ese nodo. Observar
tambin que si una variable se define varias veces en el bloque, slo aparecer en el GDA su
ltima definicin. Por ltimo, hay que distinguir entre las variables que ocupan un nodo, en el
ejemplo 3.11, a y b y las variables que se definen en el bloque, las distinguiremos utilizando
el subndice 0 para las que ocupan un nodo.
Ejemplo 3.9:
Dado el bloque bsico
B = ({ f := a + a; g := f * c; f := a + b; g := a * b}, {a, b, c}, {f, g})
la aplicacin de estas reglas produce:
B = ({ f := a + a; f := a + b; g := a * b}, {a, b, c}, {f, g})
B = ({ f := a + b; g := a * b}, {a, b}, {f, g})
4. Renombrar variables temporales
Siempre se puede transformar un bloque bsico en otro equivalente en el que cada instruccin
que define una variable temporal, emplea una variable nueva. En este caso se dice que el bloque
bsico est en forma normal. Esta modificacin permite una mejor utilizacin de los registros en
el momento de generar cdigo objeto.
Ejemplo 3.10:
si u es una variable temporal nueva entonces
t := b + c !
u := b + c
y, adems, se cambian todos los usos posteriores de t por u.
etiq:
der, izq:
lista_var:
end;
Dos instrucciones,
t1 := b + c
t2 := x + y
/* Funcin que devuelve el ltimo nodo que contiene, como etiqueta o en su lista_var, a la
variable var*/
METODO
Un bloque bsico en forma normal permite todos los intercambios de instrucciones posibles.
Si Si &{x := y op z; x := y[ z ]} hacer
si ult_nodo(y)=NIL ent ult_nodo(y) := Crear_nodo(y)
si ult_nodo(z)=NIL ent ult_nodo(z) := Crear_nodo(z)
si ) (nodo.etiq & {op, [ ]} * nodo.izq = ult_nodo(y) *
"
nodo.der = ult_nodo(z) )
13
14
si ult_nodo(x) + NIL
ent ult_nodo(x).lista_vbles := ult_nodo(x).lista_vbles {x}
nodo.lista_vbles := nodo.lista_vbles + {x}
ult_nodo(x) := nodo
Si Si = {x := op y} hacer
si ult_nodo(y)=NIL ent ult_nodo(y) := Crear_nodo(y)
El GDA quedara:
si ) (nodo.etiq = op * nodo.der = ult_nodo(y))
ent nodo := CrearNodo(op)
nodo.der := ult_nodo(y)
si ult_nodo(x) + NIL
ent ult_nodo(x).lista_vbles := ult_nodo(x).lista_vbles {x}
nodo.lista_vbles := nodo.lista_vbles + {x}
ult_nodo(x) := nodo
Si Si = {x := y} hacer
si ult_nodo(y)=NIL ent ult_nodo(y) := Crear_nodo(y)
3. El orden de reconstruccin debe ser un orden topolgico, es decir, slo se generar cdigo
para un operador y sus hijos cuando se haya generado el cdigo necesario para evaluar los
subgrafos correspondientes a sus hijos.
nodo := ult_nodo(y)
si ult_nodo(x) + NIL
ent ult_nodo(x).lista_vbles := ult_nodo(x).lista_vbles {x}
nodo.lista_vbles := nodo.lista_vbles + {x}
ult_nodo(x) := nodo
3.2.4. Reconstruccin del cdigo intermedio a partir de un GDA
El proceso de reconstruccin es una tarea no determinista en la que la obtencin de un bloque
bsico equivalente exige el respeto de ciertas reglas:
1. Si un nodo sin ascendientes no tiene en el campo lista_vbles ninguna variable activa a la
salida del bloque, eliminar el nodo. Repetir este paso hasta que no se elimine ningn nodo.
2. Plegado de constantes. Si un nodo tiene como descendientes directos dos hojas cuyas
etiquetas son constantes, sustituir el nodo por una hoja cuya etiqueta sea el resultado del
clculo con las constantes y cuya lista_vbles sea la misma que la del nodo. Las hojas del
nodo en cuestin no se eliminan, slo se suprimen los arcos de este nodo a estas hojas.
15
16
7. En los casos en que haya que seguir un determinado orden, ste deber hacerse constar en
el GDA. Por ejemplo, las instrucciones de control siempre ocupan la ltima posicin en un
bloque bsico, la asignacin a un elemento de un array si posteriormente se usa el array en el
bloque,
"
f := a + a
g := f * c
f := a + b
g := a * b
Las dos siguientes secuencias respetan el orden topolgico:
x := a c
z := a d
y := a z
(1)
z := a - d
x := a c
y := a - z
(2)
f := a + b
g := a * b
Si dado un bloque bsico se construye su GDA y luego se reconstruye el cdigo respetando
las reglas anteriores, el cdigo obtenido no tiene subexpresiones comunes, no hay
instrucciones de copia eliminables localmente, no tiene cdigo intil y permite obtener todos
los ordenes de instrucciones vlidos posibles.
Si la etiqueta es una variable y no se modifica dentro del bloque, se considerar sta junto
a su lista de variables y se aplicar el mismo criterio.
Las secuencias anteriores (1) y (2) cumplen esta regla, en cambio la secuencia (3) no.
5. Si un nodo no contiene ninguna variable en el campo lista_vbles y se necesita almacenar
temporalmente su valor, se crear una nueva variable temporal.
6. No se generar cdigo para definir una variable X (que aparece en lista_vbles de algn nodo)
que tambin aparezca como etiqueta de un nodo hoja (X0) hasta haber generado el cdigo
que corresponde a todos los usos del valor representado por el nodo hoja de esa variable (X0).
Ejemplo 3.12:
Cdigo fuente:
z := a[i] + b[i]
La siguiente secuencia, obtenida a partir del anterior GDA, incumple esta regla:
c := a d
x := a c
y := a c
z := c
Cdigo reconstruido:
t1 := 4 * i
t2 := a[t1]
t4 := b[t1]
(3)
17
18
z := t2 + t4
4. Optimizaciones globales
4.1. Optimizacin de saltos
El generador de cdigo intermedio produce en muchas ocasiones instrucciones de salto que
son fcilmente mejorables, veamos a continuacin algunos casos. Observar que las
modificaciones propuestas nunca prescinden de la etiquetas, aunque puedan parecer superfluas,
es posible que sean destino de otros saltos del programa.
a)
b)
c)
d)
e)
GOTO L1
..
L1: GOTO L2
"
GOTO L2
..
L1: GOTO L2
IF a < b GOTO L1
..
L1: GOTO L2
"
IF a < b GOTO L2
..
L1: GOTO L2
"
L1: ..
"
IF a ! b GOTO L2
L1:
..
GOTO L1
L1: ..
IF a < b GOTO L1
GOTO L2
L1: ..
Bucles naturales
Una aplicacin de la informacin sobre dominadores es facilitar la deteccin de los bucles de
un grafo de flujo objeto de mejora. Por bucles entendemos aquellas estructuras que en algn
sentido vuelven a comenzar en el mismo punto y que tienen un nico punto de entrada desde
fuera de la estructura. Una definicin que recoge esta idea de una forma ms precisa es la de
bucle natural.
Un conjunto de nodos de un grafo de flujo forman un bucle natural si cumplen las siguientes
dos propiedades:
1. El bucle debe tener un solo punto de entrada (encabezamiento). Este punto de entrada
domina todos los nodos dentro del bucle, o no sera la nica entrada al bucle.
2. Debe haber al menos una forma de iterar el bucle, es decir, desde cualquier nodo del bucle
debe haber al menos un camino de regreso al encabezamiento.
Podemos detectar los bucles si encontramos las aristas de retroceso: Aristas cuyas cabezas
dominen a sus colas. Diremos que n ! d es una arista de retroceso si el nodo d (cabeza)
domina al n (cola).
Dada una arista de retroceso n ! d, llamamos bucle natural de la arista, a d
(encabezamiento del bucle ) ms el conjunto de nodos que pueden alcanzar n sin pasar a travs
de d.
Algoritmo 3.5: Construccin del bucle natural asociado a una arista de retroceso.
19
20
Pre-encabezamiento
Salida: Conjunto de todos los nodos que constituyen el bucle natural asociado a n --> d.
Aadimos un nuevo bloque vaco inicialmente, llamado pre-encabezamiento, que solo tiene
como sucesor al encabezamiento del bucle, de forma que todas las aristas que entraban al
encabezamiento desde fuera del bucle ahora entran al pre-encabezamiento. Las aristas que llegan
al encabezamiento pero tienen su origen dentro del bucle, no se modifican.
Mtodo:
procedure inserta(m);
Invariante: clculos cuyo valor no cambia mientras el control permanece dentro del bucle.
/* programa principal */
OBJETIVO: Sacar del bucle las expresiones invariantes (tomarn el mismo valor
independientemente del nmero de veces que se ejecute el bucle).
pila := vaca;
bucle:= { d };
inserta( n );
Repetir
Marcar las instrucciones cuyos operandos sean constantes, no se definan dentro del bucle,
o tengan una sola definicin dentro del bucle y sta ya est marcada como invariante. Las
instrucciones se numerarn respecto del orden de deteccin.
m := pop ;
Ejemplo 3.15
(1) a:= 5 + N
(2) i := i +1
(3) b := a * 4
(4) arr[i] := b
(5) if a < N goto (1)
(6) x:= t
Ejemplo 3.14: Aristas de retroceso y bucles naturales del grafo del Ejemplo 3.13.
Arista de retroceso
7!4
{ 4,5,6,7,8,10 }
10 ! 7
{ 7,8,10 }
9!1
{ 1,2,3,4,5,6,7,8,9,10 }
El bucle natural 10 !7 consta de los nodos 7, 8 y 10 (alcanzan 10 sin pasar por 7). El bucle
natural 9 !1 consta de todos los nodos. (ver camino 10!7!8!9) Aunque pueda parecerlo el
conjunto {4, 5, 6, 7 } no constituyen un bucle natural puesto que el nodo 4 no sera el nico
punto de entrada.
Obsrvese que en el siguiente grafo de flujo no hay ninguna arista de retroceso en
consecuencia no hay ningn bucle natural. Aunque exista iteracin entre los nodos 2 y 3.
21
(1) a:= 5
(2) if b > 2 goto (4)
(3) a := 4
(4) b := 2 * b
(5) if b < N goto (2)
(6) x := a
En este bucle la instruccin (3) es invariante pero no puede ser extrada del bucle sin que el
comportamiento del cdigo cambie. Si sacramos la instruccin (3) fuera del bucle, al preencabezamiento, para los valores N = 2 y b = 3, x terminara valiendo 4, en cambio, con el orden
inicial x valdra 5.
22
Est en un bloque que domina todas las salidas del bucle, (o x no est activa a
la salida del bucle).
En los siguientes ejemplos se muestra la necesidad de imponer las restricciones i) a iii) del
algoritmo de extraccin de cdigo.
No cumple la condicin i)
No cumple la condicin iii)
23
24
Ejemplo 3.17:
(0) i := i + 3
(1) t1 := 2 * i
(2) j := t1 + 5
(3) t2 := 3 * j
(4) k := t2 + 6
(5) m := a[j]
(6) a[k] := m
(7) if i < N goto (0)
En este ejemplo la variable bsica de induccin es i, mientras que t1, representada por (i,2,0); j
por (i,2,5); t2 por (i,6,15); y k por (i,6,21) son variables de induccin de la Familia(i). Donde j =
2i + 5 y k = 6i + 21. La variable de induccin bsica i lleva asociado el triple (i,1,0).
En el ejemplo vemos que si una variable j pertenece a la Familia(i), y hay otra variable k
cuya definicin en el bucle es de la forma k := d*j + e, entonces k tambin pertenece a la
Famila(i) ya que k := c*d*i + d*b + e.
Algoritmo3.8:
Entrada
Salida
Mtodo
1) Encontrar todas las variables bsicas de induccin i.
Asociar a cada una el triple (i, 1, 0).
2) Buscar las variables k con una sola definicin dentro del bucle de la forma:
k := j*b,
k := b*j,
k := j/b,
k := jb,
k := bj
donde b es una cte. (o invariable dentro del bucle) y j una variable de induccin.
Si j es variable de induccin bsica
entonces k est en la familia de j
asociar a k la terna (j, b, 0) [(j, 1/b, 0), (j, 1, b)]
sino /* j pertenece a familia(i) */
si ( ) definicin de i entre la definicin de j y la de k)
25
26
Ejemplo 3.19: La aplicacin del algoritmo de reduccin de intensidad sobre las variables de
induccin del cdigo del Ejemplo 3.17 producir:
s1 := 2 * i
s2 := 2 * i
s2 := s2 + 5
s3 := 6 * i
s3 := s3 + 15
s4 := 6 * i
s4 := s4 + 21
(0)
(1)
(2)
(3)
(4)
(5)
(6)
(7)
i := i + 3
s4 := s4 + 18
s3 := s3 + 18
s2 := s2 + 6
s1 := s1 + 6
t1 := s1
j := s2
t2 := s3
k := s4
m := a[j]
a[k] := m
if i < N goto (0)
/* terna (i, c, d) */
/* si c es 1 poner s := i */
s := s + d
/* omitir si d es 0 */
27
28
Ejemplo 3.20:
i := m-1
j := n
t1 := 4*n
v
:=
a[t1]
B1
En el bucle B2-B3, B4, B5 las variables de induccin bsica son i y j teniendo que t2, t6 &
Familia(i) y t4, t8 & Familia(j).
Si aplicamos el algoritmo de reduccin de intensidad a los bucles B2 y B3 obtendremos:
i := i+1
t2 := 4*i
t3 := a[t2]
if t3<v goto
B2
B2
j := j-1
t4 := 4*j
t5 := a[t4]
if t5>v goto
B3
if i>=j goto B6
B3
B4
t6 := 4*i
x := a[t6]
t8 := 4*j
t9 := a[t8]
a[t6] := t9
a[t8] := x
goto B2
B5
t11 := 4*i
x := a[t11]
t13 := 4*n
t14 := a[t13]
a[t11] := t14
a[t13] := x
B6
29
30
s1 := 4 *
i
Preencabezamiento 1
Despus de la reduccin de intensidad, a menudo se observa que algunas variables de
induccin solo se usan en su propia definicin o que se usan a lo sumo para realizar algn test.
En estos casos se puede/n suprimir alguna/s variable/s de induccin.
B2
i := i + 1
s1 := s1 + 4
t2 := s1
t3 := a[t2]
if t3<v goto
B2
s2 := 4 *
j
B3
j := j 1
s2 := s2 - 4
t4 := s2
t5 := a[t4]
if t5>v goto
B3
0) Si i es una variable de induccin no activa a la salida del bucle y cuyo nico uso dentro del bucle es
su propia definicin o si ni esta activa a la salida del bucle ni se usa en el bucle y se define en la
instruccin de copia entonces Elimnese su definicin.
Preencabezamiento
Elimnense tambin las instrucciones correspondientes a estas variables que se hayan podido aadir al
pre-encabezamiento.
Repetir 0) mientras quede alguna variable de induccin que cumpla esa condicin.
B2
1) Para toda variable bsica de induccin i que se usa slo para calcular variables de induccin en su
familia y/o saltos condicionales.
hacer
Elegir una j & Familia(i)
/* con triple (i, c, d) lo ms simple */
modificar cada comprobacin en que aparezca i para utilizar j
B3
/* r := x si c es 1 */
r := r + d
if j oprel r goto B
t6 := s6
x := a[t6]
t8 := s8
t9 := a[t8]
a[t6] := t9
a[t8] := x
goto B2
t11 := 4*i
x := a[t11]
t13 := 4*n
t14 := a[t13]
a[t11] := t14
a[t13] := x
/* se omite si d es 0 */
/* r temporal */
31
32
para toda variable de induccin cuyo nico uso sea su propia definicin
hacer borrar todas su definicin.
finpara
Aplicar otra vez el paso 0)
2) Para toda variable de induccin j para la que el algoritmo de reduccin de intensidad introdujo una
proposicin j := s
s2 := 2 * i
s2 := s2 + 5
s4 := 6 * i
s4 := s4 + 21
t := 2 * N
t := t + 5
hacer
a) Comprobar que no se define s entre j := s y cualquier uso de j
(0) s4 := s4 + 18
s2 := s2 + 6
(2) m := a[s2]
(6) a[s4] := m
(7) if s2 < t goto (0)
(0) i := i + 3
s4 := s4 + 18
s2 := s2 + 6
(2) j := s2
(3) k := s4
(5) m := a[j]
(6) a[k] := m
(7) if i < N goto (0)
i := i + 1
s1 := s1 + 4
t3 := a[s1]
if t3<v goto B2
B3
s2 := 4 * j
B3
j := j 1
s2 := s2 - 4
t5 := a[s2]
if t5>v goto B3
Ntese que las variables de induccin bsicas no pueden ser eliminadas de los bucles B2 ni B3,
puesto que a la salida de estos bucles ambas variables estn activas. Por otro lado si aplicamos
33
34
los algoritmos anteriores al bucle B2, B2, B3, B3, B4 y B5 las nicas variables de induccin
son la i y la j. En cambio, ni s1, ni s2 son variables de induccin puesto que estn definidas en el
bucle dos veces cada una de ellas.
Ejemplo 3.21:
Cdigo fuente !
Suponemos que las variables k y i, y el array a[] se usan despus de esta instruccin.
Tambin suponemos, por simplicidad, que para el array su posicin relativa en memoria se ha
obtenido incluyendo la parte constante de la funcin de acceso.
Cdigo intermedio: !
100 t1:= i * 10
101 t2 := t1 + k
102 t3 := t2 * 2
103 t4 := a[t3]
104 t5 := M
105 if t4 < t5 goto 107
106 goto 111
107 t6 := 1
108 t7 := k t6
109 k := t7
110 goto 100
111
Cdigo intermedio: !
100 t1:= i * 10
101 t2 := t1 + k
102 t3 := t2 * 2
103 t4 := a[t3]
104 if t4 < M goto 106
105 goto 108
106 k := k 1
107 goto 100
108
Un anlisis de los saltos correspondientes a las instrucciones 104 y 105 permiten una mejora
de cdigo de acuerdo al caso 4.1 d). Despus de esta modificacin tendremos:
100 t1:= i * 10
101 t2 := t1 + k
102 t3 := t2 * 2
103 t4 := a[t3]
104 if t4 ! M goto 107
105 k := k 1
106 goto 100
107
Los nuevos bloques bsicos de este cdigo son:
B1: 100 104
B2: 105 106
B3: 107
Las optimizaciones locales, construccin del GDA y reconstruccin del cdigo, aplicadas a
los bloques B1 y B3 producirn:
35
36
107 t3 := s3
108 t4 := a[t3]
109 if t4 ! M goto 114
110 k := k 1
111 s3 := s3 2
112 s2 := s2 - 1
113 goto 106
114
Eliminacin de variables de induccin.
Paso 0) del algoritmo: la variable t2 no est activa a la salida del bucle, por lo tanto se puede
eliminar la instruccin 106. Lo mismo es aplicable a s2 := s2 - 1. La variable k no se puede
eliminar puesto que est activa a la salida del bucle. As mismo, eliminamos del preencabezamiento las instrucciones 101 y 102. El paso 1) no es aplicable en este ejemplo puesto
que no hay otros usos de la variable k en el bucle. El paso 2) del algoritmo eliminar la
instruccin 107 y modificar la 108, quedando:
Comprese este cdigo con el inicial: dentro del bucle hay 3 instrucciones de copia menos y
2 productos menos. Inicialmente en cada iteracin se ejecutaban 10 instrucciones y en el cdigo
mejorado se han reducido a 5 instrucciones.
101 t1:= i * 10
102 s3 := 2 * k
103 t10 := 2 * t1
104 s3 := s3 + t10
105 t4 := a[s3]
106 if t4 ! M goto 110
107 k := k - 1
108 s3 := s3 - 2
109 goto 105
110
t1:= i * 10
s2 := k
s2 := s2 + t1
s3 := 2 * k
t10 := 2 * t1
s3 := s3 + t10
t2 := s2
37
38
Ejercicios.
*
total := 0
i := 1
t3 := i
t4 := t3 * 2
t5 := B[t4]
t6 := i
t7 := t6 * 4
t8 := A[t7]
t9 := t5 + t8
t10 := t9 + total
total := t10
t11 := i
t12 := t11 + 1
i := t12
if i <> 11 goto 12
b) Tras localizar los bloques bsicos que forman el bucle, indica las variables de induccin y
sus familias de variables de induccin (con las ternas asociadas).
a) Determina los bloques bsicos, el grafo de flujo y construye los GDAs de cada uno de los
bloques bsicos. Reconstruye el cdigo optimizado a partir de los GDAs.
...
var a: array [1..20, 1..10] of integer;
...
while a[i, k] < M do k := k 1;
3.- A partir del cdigo fuente Pascal que se muestra a continuacin, un compilador ha generado
cdigo intermedio que se muestra en el cuadro.
t1:= i * 10
t2 := t1 + k
t3 := t2 * 2
t4 := a[t3]
t5 := M ;
if t4 < t5 goto 107
goto 110
t6 := k - 1
k := t6
goto 100
39
for j := 0 to 9 do
for k := 0 to 9 do b[5, k ] := b[5, k] + a[5, j, k] ;
*5. Dado el siguiente bloque bsico, aplicad las optimizaciones locales mediante la construccin
de su GDA y la reconstruccin del cdigo intermedio. Suponed que, a la salida del bloque
bsico, solo estn activas las variables a, b, d, e y f .
t1 := a
t2 := 5
a := t1 + t2
t3 := 5
t4 := b ! t3
b := t4
t5 := t3 *1
t6 := t3 * t5
d := t6
e := a + t2
t7 := 1
t8 := b ! t7
f := e ! d
*6. Dado el siguiente fragmento de cdigo intermedio, y suponiendo que todas las variables
estn activas en el resto de programa, construid el grafo de flujo, localizad los bucles y, para
cada uno de ellos, extraed el cdigo invariante y calculad los triples de sus variables de
induccin.
09
10
11
12
13
14
15
16
17
18
19
20
22
22
23
24
25
8.- Optimizar el cdigo intermedio del siguiente bloque. Construir el GDA correspondiente y a
partir de l, reescribir el cdigo.
(BB, {a, b, x}, {j, a, y})
BB = { x := a + b
j := 5 * a
j := x + j
y := a + b
a := x
j := j + a}
...
k := 10 ! d
c := k ! 5
a := c + 2
j := c ! 2
if c > 5 goto 19
e := e + c
a := a + 1
if a < 20 goto 14
goto 22
j := j + 2
f := f + j
if j < 30 goto 14
c := c + k
if c < 10 goto 12
z := k ! c
b) Realiza las mismas operaciones pero sustituyendo la ltima lnea por la instruccin
j := a + b.
9.- Dado el siguiente fragmento de ETDS (solo se muestra la parte de generacin de cdigo
intermedio):
, repeat
S1 until B
, id
RS
S.aux := SI;
CompletaLans(B.lf, S.aux); CompletaLans(B.lv, SI);
RS.ident := ident;
RS
RS
, := E
, [ E1 ]:= E2
, E1 oprel E2
E
E
E
, id
RE
, cte
, E1 op E2
RE.ident := ident;
E.pos := RE.pos;
E.pos:=CreaVarTemp; Emite(E.pos := num);
E.pos:= CreaVarTemp; Emite (E.pos := E1.pos op E2.pos);
RE
, [E]
RE
, -
a) Considerando que los ndices de los arrays estn definidos entre [0..N] y que la talla de cada
uno de sus elementos es una constante k. Obtn el cdigo intermedio que producir el ETDS
anterior para el siguiente fragmento de programa:
i := 0 ;
repeat A[i] := A[i+1] * i;
i:= i + 2;
43
44
c) rbol de dominacin:
Arista de retroceso B3 , B2
Bucle Natural: B2, B3
La instruccin t6 := x * y es invariante dentro del bucle y rene las condiciones para ser
extrada fuera del bucle. La extraccin de cdigo invariante junto con la reduccin de intensidad
de las variables de induccin - variable de induccin bsica i (i, 1, 0) y la nica otra variable de
la familia(i) es t2 (i, k, 0)- permitira obtener:
45
46
2.- a)
47
48
rbol de dominacin:
b)
GDA B1
GDA B3
Al reconstruir el cdigo a partir de los dos GDA, se puede observar que se ha realizado una
propagacin de copia.
Aplicando el algoritmo de reduccin de intensidad sobre las variables t2 y t3, para las que se
crean las variables temporales s2 y s3 respectivamente:
c) Arista de retroceso: B3 ! B1
49
50
3.- a)
BB1:
total := 0
i := 1
La variable s2 no estaba activa a la salida del bucle y no se usaba mas que en su propia
definicin, por lo que se ha suprimido s2 := s2-1. Lo mismo ha ocurrido con la variable k.
BB2:
t3 := i
t4 := t3 * 2
t5 := B[t4]
t6 := i
t7 := t6 * 4
t8 := A[t7]
t9 := t5 + t8
t10 := t9 + total
total := t10
t11 := i
t12 := t11 + 1
i := t12
if i <> 11 goto 12
Grafo de flujo
Teniendo en cuenta que la variable s2 no esta activa a la salida del bucle, se podra eliminar
BB
1
BB2
GDA de BB1:
(0) {total}
(1) {i}
GDA de BB2:
51
52
Preencabezamiento
BB2
Preencabezamiento
BB2
s4 := i * 2
s7 := i * 4
t13 := 11 * 2
( t13 := 22)
t5 := B[s4]
t8 := A[s7]
t9 := t5 + t8
total := t9 + total
s7 := s7 + 4
s4 := s4 + 2
if s4 <> t13 goto BB2
s4 := i * 2
s7 := i * 4
t4 := s4
t5 := B[t4]
t7 := s7
t8 := A[t7]
t9 := t5 + t8
total := t9 + total
i := i + 1
s7 := s7 + 4
s4 := s4 + 2
53
54
L4:
j := j + 1
goto L1
c) rbol de dominacin:
L3:
b)Bloques bsicos y grafo de flujo
Aristas de retroceso B6 , B2 y B5 , B4
Bucle natural interno: { B4, B5 }
Bucle natural externo: { B2, B3, B4, B5, B6 }
d) Los GDAs de los bloques bsicos B1, B3 y B6 son muy simples, igual que la
reconstruccin del cdigo correspondiente. El GDA asociado al bloque B5 sera:
55
56
La variable de induccin bsica del bucle interno es k (k, 1, 0) y las otras variables de la
familia(k) son t7 (k, 1, 50), t8 (k, 2, 100), t14 (k, 1, t13) y t15 (k, 2, 2*t13). t14 es una variable
de induccin porque t13 es un invariante de este bucle interno, t15 lo es, por serlo t14.
Las instrucciones t12 := 50 + j , t13 := t12 * 10 son invariantes dentro del bucle interno y
renen las condiciones para ser extradas fuera de este bucle (ni t2 ni t3 estn activas a la salida
del bucle) lo que genera el cdigo siguiente:
57
58
Construyendo el GDA del nuevo bloque bsico formado por B3 y el pre-encabezamiento del
bucle interno y reconstruyendo el cdigo a partir de este GDA obtendramos:
59
60
Ahora volvemos a aplicar las optimizaciones globales sobre el bucle externo (B2, B3, B4, B5 y
B6).
Marcamos como invariantes las instrucciones s8:=100 y t22:=118, pero solo podemos extraer la
segunda, porque la variable s8 se define tambin en el bloque B5, incumpliendo la segunda de las
condiciones que debe cumplir una instruccin invariante para poder extraerse.
La variable de induccin bsica del bucle externo es j (j,1,0), y el resto de variables de su familia
son t12 (j, 1, 50), y t13(j,10,500). Se puede observar que la variable s15 no es variable de induccin
del bucle externo porque tiene ms de una definicin en ste (s15:=2*t13 y s15:=s15+2).
61
62
63
64
65
66
6.
7.a)
B1
B2
k := 10 * d
c := k - 5
a := c + 2
j := c - 2
IF c > 5 GOTO
B6
B3
B4
i (i, 1,0)
t1 (i, 1, -12)
t2 (i, k, -12k)
j (j, 1, 0)
t4 (j, 2, 0)
t5 (j, 2, -4)
Preencab.
B6
e := e + c
a := a + 1
IF a< 20 GOTO B3
j := j + 2
f := f + j
IF j < 30 GOTO B3
s1 := i 12
s2 := i * k
t20 := -12 * k
s2 := s2 + t20
s4 := 2 * j
s5 := 2 * j
s5 := s5 4
B5
B1 i := i + 1
s2 := s2 + k
s1 := s1 + 1
t1 := s1
t2 := s2
t3 := b[t2]
t4 := s4
t5 := s5
a [t5] := t3
if j> 20 goto B3
GOTO 23
c := c + k
IF c < 10 GOTO B2
B7
B8
z := k * c
B2
Arista de retroceso
B4 -> B3
B6 -> B3
B7 -> B2
Blucle
B3, B4
B3, B6
B2, B3, B4, B5, B6, B7
Vbles. induccin
e (e, 1, 0) ; a (a,1,0)
j (j,1,0)
c (c,1,0)
j := j + 1
s5 := s5 + 2
s4 := s4 + 2
goto B1
B3
Nota:
Ni a ni j son variables de induccin del bucle B7->B2 porque hay ms de una definicin de
cada una de ellas dentro del bucle.
67
68
b)
Bibliografa.
Preencab.
s2 := i * k
t20 := -12 * k
s2 := s2 + t20
s5 := 2 * j
s5 := s5 4
Este tema ha sido desarrollado tomando como base el captulo 10 del [Aho, Sethi y Ullman
1990], complementndolo con el captulo 12 del [Tremblay y Soenson 1985], con el captulo 11
del [Aho y Ullman 1973 - Vol. 2] y con [A. W. Appel, M. Ginsburg.1998, Modern compiler
implementation in C].
B1 s2 := s2 + k
t3 := b[s2]
a [s5] := t3
if s5> 36 goto
B3
B2
s5 := s5 + 2
goto B1
B3
69
70
APNDICE
ENTRADA Un bloque bsico $ = (I, E, S)
SALIDA GDA
USA
N=record
etiq:
der, izq:
lista_var:
end;
Busca_Subrbol: etiqueta1 x etiqueta2 x etiqueta3 ! ptro_a_nodo
/* Funcin que busca un subrbol con
hijo izquierdo = etiqueta1 , hijo derecho = etiqueta3 y nodo = etiqueta3
y en el caso de que no exista, total o parcialmente, crea el nodo o nodos necesarios */
METODO
para toda variable x & usa[$] ' def[$] hacer ult_nodo(x) :=NIL
para toda instruccin Si & I hacer
/*Desde i=0 hasta NumeroInstrucciones($) */
Si Si &{x := y op z; x := y[ z ]} hacer
nodo := Busca_Subrbol(y, op, z)
actualiza_lista_var(x, nodo)
Si Si = {x := op y} hacer
nodo := Busca_Subrbol(y, op)
actualiza_lista_var(x, nodo)
Si Si = {x := y} hacer
nodo := Busca_Subrbol(y)
actualiza_lista_var(x, nodo)
71