Commit ab96f24f authored by Wilke Pierre's avatar Wilke Pierre
Browse files

Sujet TP - CFG - Vivacité - Élimination de code mort

parent a9b39aaf
No preview for this file type
......@@ -3,21 +3,32 @@ open Cfg
open Prog
open Utils
open Cfg_liveness
(* Dead Assign Elimination *)
(* [dead_assign_elimination_fun f] performs DAE on function [f]. *)
(* Dead Assign Elimination -- Élimination des affectations mortes *)
(* [dead_assign_elimination_fun f] élimine les affectations mortes dans la
function [f]. Cette fonction renvoie un couple [(f',c)] oú [f'] est la
nouvelle fonction, et [c] est un booléen qui indique si du progrès a été
fait. *)
let dead_assign_elimination_fun ({ cfgfunargs; cfgfunbody; cfgentry } as f: cfg_fun) =
let changed = ref false in
let cfgfunbody =
Hashtbl.map (fun (n: int) (m: cfg_node) ->
match m with
(* TODO *)
| _ -> m
) cfgfunbody in
{ f with cfgfunbody }
({ f with cfgfunbody }, !changed )
(* Applique l'élimination de code mort autant de fois que nécessaire. Testez
notamment sur le fichier de test [basic/useless_assigns.e]. *)
let rec iter_dead_assign_elimination_fun f =
let f, c = dead_assign_elimination_fun f in
(* TODO *)
f
let dead_assign_elimination_gdef = function
Gfun f -> Gfun (dead_assign_elimination_fun f)
Gfun f -> Gfun (iter_dead_assign_elimination_fun f)
let dead_assign_elimination p =
assoc_map dead_assign_elimination_gdef p
......@@ -3,48 +3,42 @@ open Cfg
open Prog
open Utils
(* Liveness analysis *)
(* Analyse de vivacité *)
(* [vars_in_expr e] returns the set of variables appearing in [e]. *)
(* [vars_in_expr e] renvoie l'ensemble des variables qui apparaissent dans [e]. *)
let rec vars_in_expr (e: expr) =
(* TODO *)
Set.empty
(* [live_cfg_node node live_after] gives the set of variables live before the
node [node], given the set [live_after] of variables live after this node. *)
(* [live_cfg_node node live_after] renvoie l'ensemble des variables vivantes
avant un nœud [node], étant donné l'ensemble [live_after] des variables
vivantes après ce nœud. *)
let live_cfg_node (node: cfg_node) (live_after: string Set.t) =
(* TODO *)
live_after
(* Computes the set of live variables after a node [n] in a CFG [cfg].
[lives] is a mapping from CFG node identifier to the set of variables that
are live before this node.
*)
(* [live_after_node cfg n] renvoie l'ensemble des variables vivantes après le
nœud [n] dans un CFG [cfg]. [lives] est l'état courant de l'analyse,
c'est-à-dire une table dont les clés sont des identifiants de nœuds du CFG et
les valeurs sont les ensembles de variables vivantes avant chaque nœud. *)
let live_after_node cfg n (lives: (int, string Set.t) Hashtbl.t) : string Set.t =
(* TODO *)
Set.empty
(* [live_cfg_nodes cfg lives] makes one iteration of the fixpoint computation.
(* [live_cfg_nodes cfg lives] effectue une itération du calcul de point fixe.
This returns a boolean that is true if some progress has been made in this
iteration (the set of variables live at at least one node has changed), false
otherwise. *)
Cette fonction met à jour l'état de l'analyse [lives] et renvoie un booléen
qui indique si le calcul a progressé durant cette itération (i.e. s'il existe
au moins un nœud n pour lequel l'ensemble des variables vivantes avant ce
nœud a changé). *)
let live_cfg_nodes cfg (lives : (int, string Set.t) Hashtbl.t) =
(* TODO *)
false
(* [live_cfg_fun f] computes the set of live variables at each point by
iterating [live_cfg_nodes] as long as progress is made. *)
let live_cfg_fun ({ cfgfunargs; cfgfunbody; cfgentry }: cfg_fun) =
let lives : (int, string Set.t) Hashtbl.t = Hashtbl.create 17 in
let rec aux () =
if live_cfg_nodes cfgfunbody lives
then aux ()
else () in
aux ();
lives
let live_cfg_fun ({ cfgfunargs; cfgfunbody; cfgentry }: cfg_fun) =
fixpoint (fun cfg lives n ->
match Hashtbl.find_option cfg n with
| Some cn -> live_cfg_node cn (live_after_node cfg n lives)
| None -> failwith "Unknown node"
)
(fun cfg n cn -> Set.empty)
cfgfunbody
(* [live_cfg_fun f] calcule l'ensemble des variables vivantes avant chaque nœud
du CFG en itérant [live_cfg_nodes] jusqu'à ce qu'un point fixe soit atteint.
*)
let live_cfg_fun (f: cfg_fun) : (int, string Set.t) Hashtbl.t =
let lives = Hashtbl.create 17 in
(* TODO *)
lives
......@@ -59,10 +59,10 @@ let alphabet = char_list_of_string (lowercase_letters ^ uppercase_letters ^ digi
let letter_regexp = char_range (char_list_of_string (uppercase_letters ^ lowercase_letters))
let digit_regexp = char_range (char_list_of_string digits)
let identifier_material = char_range (char_list_of_string (uppercase_letters ^ lowercase_letters ^ digits ^ "_"))
let keyword_regexp s = str_regexp (char_list_of_string s)
(* La liste des expressions régulières permettant d'identifier les tokens du langage E *)
let list_regexp =
let keyword_regexp s = str_regexp (char_list_of_string s) in
[
(keyword_regexp "while", fun s -> Some (SYM_WHILE));
(keyword_regexp "int", fun s -> Some (SYM_INT));
......
......@@ -5,19 +5,13 @@ open Utils
open Symbols
let () =
let lowercase_letters = "abcdefghijklmnopqrstuvwxyz" in
let uppercase_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" in
let digits = "0123456789" in
let other_characters = "?!=<>_ ;,{}()[]-+*/%\n\t" in
let alphabet = char_list_of_string (lowercase_letters ^ uppercase_letters ^ digits ^ other_characters) in
let letter_regexp = char_range (char_list_of_string (uppercase_letters ^ lowercase_letters)) in
let digit_regexp = char_range (char_list_of_string digits) in
let keyword_regexp s = str_regexp (char_list_of_string s) in
let regexp_list = [
(keyword_regexp "while", fun s -> Some (SYM_WHILE));
(keyword_regexp "if", fun s -> Some (SYM_IF));
] in
(* Décommentez la ligne suivante pour tester sur la vraie liste d'expressions
régulières. *)
(* let regexp_list = list_regexp in *)
List.iteri
(fun i (rg, _) -> Printf.printf "%d: %s\n" i (string_of_regexp rg))
regexp_list;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment