Skip to content
Snippets Groups Projects
Commit 2d18417c authored by Wilke Pierre's avatar Wilke Pierre
Browse files

Sujet TP4 - Bonus - Élimination des NOPs

parent ab96f24f
No related branches found
No related tags found
No related merge requests found
No preview for this file type
......@@ -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 =
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment