Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Generaciondecodigo
Generaciondecodigo
1.! 2.! 3.! 4.! 5.! 6.! Introduccin Tipos de Cdigo Intermedio Declaraciones Expresiones y Asignacin Estructuras de Control Procedimientos y Funciones
Lecturas: Scott, captulo 9 Muchnick, captulos 4, 6 Aho, captulo 8 Fischer, captulos 10, 11 , 12 , 13, 14 Holub, captulo 6 Bennett, captulo 4, 10
12048 - J. Neira 1
1/6. Introduccin
! Cdigo intermedio: interfaz entre front-ends y back-ends ! Se busca:
! transportabilidad ! posibilidades de optimizacin
! Debe ser:
! abstracto ! sencillo
! No se tiene en cuenta:
! modos de direccionamiento ! tamaos de datos ! existencia de registros ! eficiencia de cada operacin
Cdigo Intermedio
! Ventajas:
! Permite abstraer la mquina, separar operaciones de alto nivel de su implementacin a bajo nivel. ! Permite la reutilizacin de los front-ends y backends. ! Permite optimizaciones generales.
! Desventajas:
! Implica una pasada ms para el compilador (no se puede utilizar el modelo de una pasada, conceptualmente simple). ! Dificulta llevar a cabo optimizaciones especficas de la arquitectura destino. ! Suele ser ortogonal a la mquina destino, la traduccin a una arquitectura especfica ser ms larga e ineficiente.
3
12048 - J. Neira -
! Desventaja:
! espacio para almacenamiento
AST:
E + id(B) T * id(C)
4
id(A) id(B)
12048 - J. Neira -
ASTs
program gcd(input, output); var i,j : integer; begin read(i,j); while i <> j do if i > j then i := i j else j := j i; writeln(i); end.
12048 - J. Neira -
rbol sintctico:
E
DAG:
E +
T id(B) * id(C)
T id(B) * id(C)
id(B) * id(C)
! Las operaciones ms complejas requieren varias instrucciones: ! Este desenrollado facilita la optimizacin y generacin de cdigo final.
(a + b) x (c (d / e))
TAC
! Ensamblador general y simplificado para una mquina virtual: incluye etiquetas, instrucciones de flujo de control ! Incluye referencias explcitas a las direcciones de los resultados intermedios (se les da nombre). ! La utilizacin de nombres permite la reorganizacin (hasta cierto punto). ! Algunos compiladores generan este cdigo como cdigo final; se puede interpretar fcilmente (UCSD PCODE, Java). ! Operadores:
CI muchos pocos corto largo generacin optimizacin compleja sencilla compleja sencilla
12048 - J. Neira -
1. Asignacin: x := y op z x := op y x := y x[i] := y x := y[i] x := &y x := *y *x := y 2. Saltos: goto L if x oprel y goto L 3. Procedimientos: param x1 ... param xn call p, n
9
Representaciones de TAC
Fuente: a := b * c + b * d; ! Cudruplas: el destino suele ser una temporal. (*, b, c, t1) (*, b, d, t2) (+, t1, t2, a) ! Tripletas: slo se representan los operandos (1) (2) (3) (4) (*, b, c) (*, b, d) (+, (1), (2)) (:=, (3), a) ! Supuesta ventaja: es ms concisa. Falso: estadsticamente se requieren ms instrucciones.
! Desventaja: el cdigo generado es dependiente de la posicin. Cierto: la dependencia posicional dificulta la optimizacin.
10
12048 - J. Neira -
Representaciones de TAC
! Tripletas Indirectas: + vector que indica el orden de ejecucin de las instrucciones.
a := (b * c + b * d) * b * c; 1 2 3 4 5 6 b * c b * d b * c (1) + (2) (4) * (3) a := (5); 2 1 3 4 5 6 b * d b * c b * c (1) + (2) (4) * (3) a := (5); 1 2 3 4 5 b * c b * d (1) + (2) (3) * (1) a := (4);
Reorganizar es eficiente
12048 - J. Neira -
12048 - J. Neira -
12
Notacin posfija
! Polaca inversa, cdigo de cero direcciones:
! notacin matemtica libre de parntesis ! los operadores aparecen despus de los operandos
Notacin Postfija
! Ventajas:
! Cdigo generado conciso. ! No hacen falta temporales. ! Algunas optimizaciones sencillas. ! Mantiene la estructura a sintctica.
! Desventajas:
! Cdigo dependiente de la posicin. ! solo efectiva si el target es de pila.
:= b * c + b * c
(a + b) * c a b add c mult 14
a b c mult add
E T *id(C)
+ id(B) id(A)
! Declaracin de variables:
int sig, nivel = 0; void abrir_bloque() { ... sig = INICIAL; ++nivel; } void cerrar_bloque() { ... nivel--; } void crear_var (char *nom, int tipo) { ..... simbolo->dir = sig; switch (tipo) { case ENTERO : sig += 2; break; case REAL : sig += 4; break; .... } } Al final, sig indica el tamao del bloque de activacin. 16
Ejemplo
Programa p; entero i, j, m; 3 4 5 accion dato (ref entero d); Principio 3 Fin 3 4 5 accion mcd(Val entero a, b; ref entero m); entero r; 6 Principio Fin Principio Fin
12048 - J. Neira 17
Declaracin de Variables
! Y si se permite mezclar declaraciones de variables y procedimientos? ! C: este problema no existe. ! Pascal: muchos compiladores lo prohben. Posible solucin:
int sig[MAXANID], nivel = 0; void abrir_bloque () {... sig[++nivel] = INICIAL;} void cerrar_bloque () { ... nivel--;} void crear_var (char *nom, int tipo) { .... simbolo->dir = sig[nivel]; ... } 18
procedure P; i.dir = 0 var i,j,k : integer;j.dir = 2 procedure Q; var l,m : integer; begin .... end; var n : integer;
n.dir = 4 (igual que k!)
Inicializadores, C:
! extern y static:
! Valor inicial por defecto: 0. ! Admiten slo valores constantes. ! El inicializador se ejecuta una sola vez. #include <stdio.h> /* legal? */ int i = 1, /* legal? */ j = i + 1, /* legal? */ m = 34 + 1, f(), /* legal? */ k = f(), /* legal? */ l; /* legal? */ extern int n = 0;
12048 - J. Neira -
! auto y struct:
! Valor inicial por defecto: ninguno. ! Admiten valores no constantes. ! Se ejecutan c/vez que se activa el bloque. int f() { /* legal? int i = 1, /* legal? j = i + 1, g(), /* legal? k = g(i), /* legal? n = f(), l; */ */ */ */
12048 - J. Neira -
! Instrucciones generadas
! Acceso a datos ! Variables simples ! Registros ! Vectores ! Manipulacin de datos ! Conversiones ! Operaciones ! Flujo de control ! Validacin de subrangos ! Operadores complejos
22
! De los operadores:
! Respetar su precedencia ! Respetar su asociatividad ! Respetar orden de evaluacin (si definido) ! Determinar interpretacin correcta (si sobrecargado)
12048 - J. Neira -
Algunas dificultades
! Orden de evaluacin de los operandos:
push(pop() - pop()); Implementa correctamente SBT? Es relevante en el caso de PLUS?
a[i] = i++;
el valor del subndice es el anterior o actual valor de i? push (pop() && pop()); Implementa AND correctamente en C?
FRAMES[pop()] = pop();
Corresponde a ASG o ASGI? En C, ni la suma ni la asignacin tienen predefinido un orden de evaluacin.
12048 - J. Neira -
En C, el operador && se evala por corto circuito y por lo tanto de izquierda a derecha.
23
1);
0);
$1);
$1); ;
TIDENT { generar (SRF, ?, ?); generar (DRF); /* parametro? */ } | TIDENT { generar (SRF, ?, ?); /* parametro? */ } '[' expresion ']' { /* ?tamano? */ generar (DRF); } | TIDENT '(' args ')' { generar (OSF, ?, ?, ?); } .....
24
TIDENT { $$.cod = code (SRF,?,?); emit (&($$.cod), DRF); (STC, 1); /* parametro? */ } | TIDENT '[' expresion ']' { $$.cod = code (SRF, ?, ?); (STC, 0); /* parametro? */ concatenar (&($$.cod), $3.cod); /* ?tamano? */ (STC, $1); emit (&($$), (DRF); } | TIDENT '(' args ')' { $$.cod = $3; (STC, $1); emit (&($$.cod),OSF,?,?,?); } ..... ;
25
Vectores
! Componentes almacenadas de forma contigua
V[1] V[2] V[3] V[4] V[5]
12048 - J. Neira -
26
Procesamiento de Vectores
! Dada var v : array[4..8] of integer;
v[<expresin1>] := <expresin2>; ; n y o dependen de la declaracin SRF n o ; cdigo para expresin1 ... ; lmite inferior STC 4 SBT ; tamao (en este caso sobra) STC 1 TMS PLUS ; cdigo para expresin2 ... ASG
12048 - J. Neira -
27
Procesamiento de Vectores
! Dada var v : array[-3..5] of boolean;
if v[<expresin>] then ...; ; n y o dependen de la declaracin SRF n o ; cdigo para expresin ... ?? qu hacer aqu? ?? STC -3 GTE JMF ... ; procedimiento de error STC 5 LTE JMF ... ; procedimiento de error ; lmite inferior STC -3 SBT ; tamao STC 1 TMS PLUS DRF JMF ... 12048 - J. Neira -
28
0 159 4 5 8
12048 - J. Neira -
40 8 1
52
Formulacin alternativa, v2
entero v[2..5,3..7,1..8]; .... v[2,3,1] := ...; v[5,7,8] := ...; direccin? v[3,4,5] := ...; 2 13 105 0 5 32 264 159 3 19 157 52
30
105
4 5 8
12048 - J. Neira -
cn
dn addr
; }
12048 - J. Neira -
31
ci-1 si ci = ci-1 si + ei
;
12048 - J. Neira -
32
y porqu no...?
{% int i; %} %% lista_indices: expresion e1 { c1 = e1 i = 1; } | lista_indices ',' ci-1 { int s_i, i; i = i + 1; s_i = ..., generar (STC, s_i); si generar (TMS); ci-1 si } expresion e i { ci = ci-1 si + ei generar (PLUS); } ; entero v[1..10], w[1..3, 1..4, 1..5, 1..6]; .... w[v[1], v[2], v[3], v[4]] := ...;
12048 - J. Neira 33
Ejemplo: para
; v ; e_1 ; m_1 ; e_2 ; m_2 ; e_3 ; m_3 ; fin ; c SRF n o v1 STC 3 STC 40 TMS PLUS STC 4 STC 8 TMS PLUS STC 5 STC 1 TMS PLUS de los indices STC 105 SBT
v[3,4,5]
SRF n o v2 STC 3 STC 5 TMS STC 4 PLUS STC 8 TMS STC 5 PLUS de los indices STC 105 SBT PLUS
cul es ms eficiente?
34
12048 - J. Neira -
Operadores
! Algoritmo recursivo: comenzando en la raz del rbol sintctico:
a*b + c*d - e*f + 10
+ + * 10
1.! Generar cdigo para evaluar los operandos 1..n, almacenando los resultados en localizaciones temporales-
2.! Generar cdigo para eva* e f * luar el operador, utilizando los operandos almacenaa b c d dos en las n localizaciones temporales y almacenando a b * c d * + e f * - 10 + el resultado en otra localizacin temporal.
12048 - J. Neira 35
36
12048 - J. Neira -
38
Siguiente problema....
! qu hacer con los resultados intermedios?
a*1b +1 c*2d - e*3f +2 10 + + * a b c * e d * f 10
! Mquinas de pila:
;variable A SRF 0 3 DRF ;variable B SRF 0 4 DRF ;*1: A * B TMS ;variable C SRF 0 5 DRF ;variable D SRF 0 6 DRF ;*2:C * D TMS ;+1:(A*B)+(C*D) PLUS ;variable E SRF 0 7 DRF ;variable F SRF 0 8 DRF ;*3:E * F TMS ;-:((A*B)+(C*D))-(E*F) SBT STC 10 ;+2:(((A*B)+(C*D))-(E*F))+10 PLUS 39
t0 t1 t2 t3 t4 t5
:= := := := := :=
register allocation problem ! Al traducir este cdigo intermedio para una arquitectura destino, se utilizarn registros en lo posible, de lo contrario posiciones de memoria.
12048 - J. Neira 40
! Las expresiones tienen como atributo el nombre de la variable en la que quedan almacenadas.
%{ extern char *newtemp(); %} %union {...char *place;...} %type <place> TIDENT expresion %type <place> expresion_simple termino factor
12048 - J. Neira 41
Reutilizacin de temporales
! Una vez que una variable temporal aparece como operando, deja de utilizarse. t0 t1 t2 t3 t4 t5 t0 t1 t0 t1 t0 t0 := := := := := := := := := := := := A * B; C * D; t0 + t1; E * F; t2 - t3; t4 + 10; A * B; C * D; t0 + t1; E * F; t0 - t1; t0 + 10; ! Al traducir el cdigo intermedio, en lo posible se utilizarn registros (habr una cantidad limitada); de lo contrario, posiciones de memoria. ! Reduccin de temporales requeridas: 1.! c = 0 0 1 2 1 2 1 1 2.! Para generar un nuevo nombre temporal, utilizar tc, e incrementar c en 1. 3.! Cuando aparezca un nombre temporal como operando, decrementar c en 1. 43
12048 - J. Neira -
repetir: tREPETIR { $<instr>$ = nueva_etiqueta(); etiqueta ($<instr>$); } lista_instrucciones tHASTA_QUE expresion { generar (JMF, $<instr>2); } ;
12048 - J. Neira 44
Seleccin (sec)
si <exp> ent <instr1> si_no <instr2> fsi seleccion: tSI expresion { $<sino>$ = nueva_etiqueta(); generar (JMF, $<sino>$); } tENT lista_instrucciones { $<fin>$ = nueva_etiqueta(); generar (JMP,$<fin>$); etiqueta ($<sino>3); } resto_seleccion tFSI { etiqueta($<fin>6); } ; resto_seleccion: | tSI_NO lista_instrucciones ;
45
Optimalidad
! La generacin de cdigo puede no ser ptima:
; exp SRF n o DRF STC 1 EQ JMF L0 ; l1 SRF n o SRF n o DRF STC 1 PLUS ASG JMP L1 L0: L1:
46
si i = 1 ent i := i + 1; fsi
12048 - J. Neira -
Seleccin (AST)
; <exp> JMF SINO ; <instr1> JMP FIN SINO: ; <instr2> FIN:
seleccion: tSI expresion tENT lista_instrucciones resto_seleccion tFSI { char *lsino = newlabel(), *lfin = newlabel(); $$ = $2.cod; emit (&($$), JMF, lsino); concatenar (&($$), $4); if (longitud_lista($5)) { emit (&($$), JMP, lfin); label (&($$), lsino); concatenar (&($$), $5); label (&($$), lfin); } else label (&($$), lsino);
12048 - J. Neira -
Seleccin mltiple
; caso ; exp ; exp1 EQ JMF EXP2 ; instr1 JMP FIN EXP2: ... EXPn: ; expn EQ JMF DLC ; instrn JMP FIN DLC: ; dlc ; instr FIN:
48
caso <exp> <exp1> : <instr1> ; ... <expn> : <instrn> ; dlc <instr> fcaso problemas?
12048 - J. Neira -
Seleccin mltiple
; caso ; exp DUP ; exp1 EQ JMF EXP2 ; instr1 JMP FIN EXP2: ... EXPn: DUP ; expn EQ JMF DLC ; instrn JMP FIN DLC: ; dlc ; instr FIN: POP
49
equivale a: si <exp> = <exp1> ent <instr1> si_no si <exp> = <exp2> ent <instr2> .... si_no si <exp> = <expn> ent <instrn> si_no <instr> fsi ... fsi
12048 - J. Neira -
mientras_que: tMQ { $<exp>$ = nueva_etiqueta(); etiqueta ($<exp>$); } expresion { $<fin>$ = nueva_etiqueta(); generar (JMF, $<fin>$); } instr tFMQ { generar (JMP, $<exp>2); etiqueta($<fin>4); } ; 12048 - J. Neira
50
mientras_que: tMQ expresion bloque tFMQ { char *lcond = newlabel(), *lbloque = newlabel(); $$ = code (JMP, lcond); label (&($$), lbloque); concatenar( &($$), $3); label (&($$), lcond); concatenar (&($$), $2); emit (&($$), JMT, lbloque);
51
12048 - J. Neira -
Argumentos
! Los argumentos se transmiten a travs del stack
accion p(val entero i; ref booleano k; val caracter c); .......... p (a,b,d); ; recuperar C ; recuperar K ; recuperar I JMP P ... P: ; accion P ... CSF 53
; ; ; ;
Invocacin de Procedimientos
p (n+1, b, entacar(c+1)); ! Cuando se evalan las expresiones correspondientes a los argumentos, stos van almacenndose en la pila. ! Al crear el BA del procedimiento, debe respetarse el tamao del bloque actual ! El cambio de nivel es la diferencia entre el nivel actual y el invocado. ! La direccin del procedimiento o funcin se determina al introducir el smbolo en la tabla.
54
SRF nn on DRF STC 1 PLUS SRF nb ob DRF SRF nc oc DRF STC 1 PLUS OSF s l a
12048 - J. Neira -
Invocacin de Procedimientos
! Los parmetros ref requieren la direccin de la varia-ble referenciada; expresion genera cdigo para obtener el valor de la variable. SRF nn on n+1 DRF STC 1 PLUS SRF nb ob b DRF SRF nc oc entacar(c+1) DRF STC 1 PLUS OSF s l a
12048 - J. Neira -
! Para los parmetros ref elimino la ltima instruccin de cdigo generado por expresion
SRF nn on DRF STC 1 PLUS SRF nb ob SRF nc oc DRF STC 1 PLUS OSF s l a
55
Declaracin de procedimientos
! Evitar el posible cdigo de procedimientos y funciones locales
accion q (...); accion r (...); principio ... fin principio ... fin ; accion Q ; recuperar JMP Q ; accion R ; recuperar JMP R R: ; codigo de CSF Q: ; cdigo de CSF ; accion R ; recuperar R: ; codigo de CSF ; accion Q ; recuperar Q: ; cdigo de CSF args Q args R R Q
args R R args Q Q
56
12048 - J. Neira -
! Los argumentos de tipo vector pueden requerir que todas las componentes sean almacenadas en la pila y luego recuperadas.
57
Utilizacin de parmetros
1.! valor de un parmetro por referencia accion q(ref entero m); 2.! direccin de un parmetro principio por referencia escribir (m); 1 3.! valor de un parmetro por m := 0 2 fin valor y otro por referencia accion r(val entero k; 4.! parmetro por valor utilizaref entero l); do como argumento a principio parmetro por referencia escribir (k, l); 3 l := 0; 5.! parmetro por referencia 4 q (k); utilizado como argumento q (l); 5 a parmetro por referencia fin 6.! variables utilizadas como principio parmetros por valor y rer (i, j); 6 fin ferencia respectivamente programa p; entero i, j;
12048 - J. Neira 58
3 ;rec. M 3 ; M 3 ; M
1 2 ;
4 ;rec. L 3 ;rec. K 3 ; K
SRF DRF 3 DRF WRT SRF DRF STC ASG SRF 4 OSF SRF DRF 5 OSF CSF ; ppal P L0: SRF DRF 6 SRF OSF LVP
0 1 0 0 0 5 0 5 0 0 5
4 ; L 4 ; L 3 ; K 1 1 ; Q 4 ; L 1 1 ; Q
3 ; I 4 ; J 0 13 ; R
59
Y para funciones.....
! Versin C:
funcion mcd( val entero a,b) dev entero; entero r; principio r := a mod b; mq r <> 0 a := b; b := r; r := a mod b fmq; dev (b); fin
12048 - J. Neira -
; recuperar parametros SRF 0 4 ; B ASGI SRF 0 3 ; A ASGI JMP MCD ; codigo de mcd MCD: ... ... ; dejar resultado en ; la pila SRF 0 4 DRF CSF CSF
60
Y para funciones.....
! Versin Pascal:
funcion mcd( val entero a, b) dev entero; entero r; principio r := a mod b; mq r <> 0 a := b; b := r; r := a mod b fmq; mcd := b; fin
12048 - J. Neira -
; recuperar parmetros SRF 0 5 ; B ASGI SRF 0 4 ; A ASGI JMP MCD ; cdigo de mcd MCD: ... ... SRF 0 3 ; MCD SRF 0 5 ; B DRF ASG ; dejar resultado en ; la pila SRF 0 3 ; MCD DRF CSF
61