1. Optimisation des comparaisons dont le second membre est une
constante
On rajoute au fichier de fonctions de service mips1.ml une
nouvelle fonction d'écriture d'un branchement conditionnel :
let ecrire_rel_n fichier rel etiq_sortie spr n =
let mnem = match rel with
| Eg -> "beq" | Ineg -> "bne"
| Sup -> "bgt" | Supeg -> "bge"
| Inf -> "blt" | Infeg -> "ble"
in begin etiqueter fichier marge;
printf__fprintf fichier "%s $%u, $%d, %s \n"
mnem spr c etiq_sortie
end
;;
On modifie ensuite le cas Comparaison de la fonction
comp_bool du fichier gencode.ml :
| Comparaison(rel, (e1,e2))
(match e1 with
| Cte 0 -> idem ...
| Const ch -> idem ...
| _
(match e2 with
| Cte n ->
begin comp_ar fichier etiq_inst spr e1;
if n=0 then ecrire_rel_0 fichier rel etiq_sortie spr
else ecrire_rel_n fichier rel etiq_sortie spr n
end
| Cste ch ->
begin comp_ar fichier etiq_inst spr e1;
(match val_const ch with
0 -> ecrire_rel_0 fichier rel etiq_sortie spr
| n -> ecrire_rel_n fichier rel etiq_sortie spr n
end
| idem ..
En résolvant le cas délicat dit "du 0 = 0" par double
filtrage :
| Comparaison(rel, (e1,e2))
(match e1, e2 with
Cte n, _ ->
begin comp_ar fichier etiq_inst spr e2;
if n = 0 then
ecrire_rel_0 fichier (op_bool_sym rel) etiq_sortie spr
else
ecrire_rel_n fichier (op_bool_sym rel) etiq_sortie spr n
end
| Cste ch, _ ->
begin comp_ar fichier etiq_inst spr e2;
let n = val_const ch in
if n = 0 then
ecrire_rel_0 fichier (op_bool_sym rel) etiq_sortie spr
else
ecrire_rel_n fichier (op_bool_sym rel) etiq_sortie spr n
end
| _, Cte n ->
begin comp_ar fichier etiq_inst spr e1;
if n = 0 then
ecrire_rel_0 fichier rel etiq_sortie spr
else
ecrire_rel_n fichier rel etiq_sortie spr n
end
| _, Cste ch ->
begin comp_ar fichier etiq_inst spr e1;
let n = val_const ch in
if n = 0 then
ecrire_rel_0 fichier rel etiq_sortie spr
else
ecrire_rel_n fichier rel etiq_sortie spr n
end
| _, (Bin _) -> etc ...
2. Une autre syntaxe pour MIL-2
a) Dans la règle unique du fichier lex_mil.mll on
supprime les cas
|"FINSI" {Finsi}
|"FINTQ" {Fintq}
et on rajoute les cas
|"DEBUT" {Debut}
|"FIN" {Fin}
b) On suppose le lexeur de MIL-2 mis àjour. Dans le fichier
d'analyse syntaxique mil2/ansynt/synt_mil.mly on procède aux
modifications suivantes :
- Déclaration des unités lexicales Debut et Fin et
suppression des Finsi, Fintq et Finpr.
- Ajout de la règle qui crée un bloc avec déclarations
éventuellement vides pour les instructions composées :
INSTCOMP : Debut DECL SEQINST Fin
{ begin sortip_bloc $2 (taille_listes $2) $3;
Bloc($3, $2)
end} ;
- Ajout du cas INSTCOMP àla règle INST et
modification des règles COND, BCL et SUITEPOUR
pour supprimer les marqueurs de fin et remplacer SEQINST par
INST (qui peut être composée).
Pour ce qui est de la génération de code :
Mauvaise solution !
on modifie les fonctions de service ecrire_decr_sp et
ecrire_incr_sp du fichier mips2.ml :
let ecrire_decr_sp fichier etiq k =
if k <> 0 then
begin idem ... end
;;
let ecrire_incr_sp fichier etiq k =
if k <> 0 then
begin idem ... end
;;
Bonne solution ?
on modifie le cas Bloc de la fonction comp_inst du
fichier gencode.ml :
| Bloc(corps, list) ->
let table = cons_tab_symb listes
in let taille = taille_mem table
in if taille = 0 then
comp_inst fichier etiq spr corps
else
begin
idem ...
end
c) On amende les règles DECL et INSCOMP en testant la
valeur des listes de déclarations :
DECL : LDECCONST LDECVAR LDECVECT LDECMAT
{ let listes = ($1, $2, $3, $4) in
begin
(if listes <> [], [], [], [] then entrep_bloc listes);
listes
end} ;
...
INSTCOMP : Debut DECL SEQINST Fin
{ match $2 with
[],[],[],[] -> $3
|_ ->
begin sortip_bloc $2 (taille_listes $2) $3;
Bloc($3, $2)
end} ;
This document was translated from LATEX by HEVEA.