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.