diff --git a/Sujet.pdf b/Sujet.pdf index df4388a9daf5586b91e8c03d357f754cb55c51a6..3325560c37f3688b60d6c296eec867d6c4c418e3 100644 Binary files a/Sujet.pdf and b/Sujet.pdf differ diff --git a/src/cfg_nop_elim.ml b/src/cfg_nop_elim.ml index 8b32dfdf39b32b615b17132e6ac87604081b0d0e..9de89ece4322c73f0282b39c0d55b1c74242b98d 100644 --- a/src/cfg_nop_elim.ml +++ b/src/cfg_nop_elim.ml @@ -4,64 +4,71 @@ open Prog open Utils open Cfg -(* [nop_transitions cfg] gives the list of NOP transitions in the CFG. +(* Élimination des NOPs. *) - If node n is [Cnop s], then [(n,s)] should be in the result list. +(* [nop_transitions cfg] donne la liste des transitions NOP dans un CFG. + + Si le nœud [n] contient [Cnop s], alors [(n,s)] devrait être dans le résultat. *) let nop_transitions (cfgfunbody: (int, cfg_node) Hashtbl.t) : (int * int) list = (* TODO *) [] -(* [follow n l visited] gives the first non-nop successor of [n], according to - the successor relation encoded in list [l]. [(x,y)] in [l] means there is a - NOP-transition from node [x] to node [y]. +(* [follow n l visited] donne le premier successeur à partir de [n] qui ne soit + pas un NOP. Pour connaître le successeur d'un nœud NOP, on utilisara la liste + [l] telle que produite précédemment. Pour rappel [(x,y)] dans [l] signifie + qu'il y a un transition depuis un nœud [x] qui contient une instruction [Cnop + y]. - The set [visited] is used to make sure we don't fall into an infinite loop. -*) + L'ensemble [visited] est utilisé pour éviter les boucles. + *) let rec follow (n: int) (l: (int * int) list) (visited: int Set.t) : int = (* TODO *) n -(* [nop_transitions_closed] contains the list [(n,s)] of nodes [n] such that the - instruction at node [n] is the beginning of a NOP-chain ending in node [s]. *) +(* [nop_transitions_closed] contient la liste [(n,s)] telle que l'instruction au + nœud [n] est le début d'une chaîne de NOPs qui termine au nœud [s]. Les + enseignants du cours de compiilation sont heureux de vous offrir cette + fonction. *) let nop_transitions_closed cfgfunbody = List.map (fun (node_id, node) -> (node_id, follow node_id (nop_transitions cfgfunbody) Set.empty)) (nop_transitions cfgfunbody) +(* Nous allons maintenant réécrire notre programme pour remplacer les + successeurs [s] de chaque nœud du CFG de la manière suivante : si [s] est le + début d'une chaîne de NOPs, on remplace [s] par la fin de cette chaîne, en + éliminant ainsi les nœuds NOPs. *) - -(* [preds n] gives the list of predecessors of a node [n]. *) -let preds cfgfunbody n = - Hashtbl.fold (fun m m' acc -> - match m' with - | Cfg.Cassign (_, _, s) - | Cfg.Cprint (_, s) - | Cfg.Cnop s -> if s = n then Set.add m acc else acc - | Cfg.Creturn _ -> acc - | Cfg.Ccmp (_, s1, s2) -> if s1 = n || s2 = n then Set.add m acc else acc - ) cfgfunbody Set.empty - -(* [replace_succ nop_succs s] gives the new name for node [s], after applying - nop-transitions. *) +(* [replace_succ nop_succs s] donne le nouveau nom du nœud [s], en utilisant la + liste [nop_succs] (telle que renvoyée par [nop_transitions_closed]). *) let replace_succ nop_succs s = - match List.assoc_opt s nop_succs with - None -> s - | Some t -> t + s -(* [replace_succs nop_succs n] replaces the old CFG node names in node [n] - with the new ones, according to [nop_succs]. *) +(* [replace_succs nop_succs n] remplace le nœud [n] par un nœud équivalent où on + a remplacé les successeurs, en utilisant la liste [nop_succs]. *) let replace_succs nop_succs (n: cfg_node) = (* TODO *) n -(* [nop_elim_fun f] transforms CFG function [f] by eliminating NOP instructions *) +(* [nop_elim_fun f] applique la fonction [replace_succs] à chaque nœud du CFG. *) let nop_elim_fun ({ cfgfunargs; cfgfunbody; cfgentry } as f: cfg_fun) = let nop_transf = nop_transitions_closed cfgfunbody in + (* On utilise la fonction [Hashtbl.filter_map f h] qui permet d'appliquer une + fonction à chaque nœud de [h] et d'éliminer ceux pour lesquels [f] renvoie + [None]. + + On souhaite éliminer les nœuds qui n'ont pas de prédécesseurs + (inaccessibles), et appliquer la fonction [replace_succs] aux nœuds qui + resteront. + *) let cfgfunbody = Hashtbl.filter_map (fun n node -> + (* TODO *) Some node ) cfgfunbody in + (* La fonction renvoyée est composée du nouveau [cfgfunbody] que l'on vient de + calculer, et le point d'entrée est transformé en conséquence. *) {f with cfgfunbody; cfgentry = replace_succ nop_transf cfgentry } let nop_elim_gdef gd =