Commit 1083a1bf authored by Armillon Damien's avatar Armillon Damien
Browse files

register allocation

parent a8c6dc3c
......@@ -80,9 +80,18 @@ let regalloc_on_stack_fun (f: linear_fun) : ((reg, loc) Hashtbl.t * int)=
*)
let add_interf (rig : (reg, reg Set.t) Hashtbl.t) (x: reg) (y: reg) : unit =
(* TODO *)
let linked_x = Hashtbl.find rig x in
let linked_y = Hashtbl.find rig y in
if not (Set.mem y linked_x) then Hashtbl.replace rig x (Set.add y linked_x );
if not (Set.mem x linked_y) then Hashtbl.replace rig y (Set.add x linked_y );
()
let rec add_interf_list rig reg_list : unit =
match reg_list with
| [] -> ()
| re::[] -> ();
| x::r -> List.iter (fun y -> add_interf rig x y) r; add_interf_list rig r;
()
(* [make_interf_live rig live] ajoute des arcs dans le graphe d'interférence
pour chaque paire de registres vivants en même temps à un point de programme.
......@@ -90,8 +99,11 @@ let add_interf (rig : (reg, reg Set.t) Hashtbl.t) (x: reg) (y: reg) : unit =
let make_interf_live
(rig: (reg, reg Set.t) Hashtbl.t)
(live : (int, reg Set.t) Hashtbl.t) : unit =
(* TODO *)
()
Hashtbl.iter (fun _ regis ->
let regis_list = Set.elements regis in
add_interf_list rig regis_list;
) live;
()
(* [build_interference_graph live_out] construit, en utilisant les fonctions que
vous avez écrites, le graphe d'interférence en fonction de la vivacité des
......@@ -122,7 +134,11 @@ let build_interference_graph (live_out : (int, reg Set.t) Hashtbl.t) code : (reg
(* [remove_from_rig rig v] supprime le sommet [v] du graphe d'interférences
[rig]. *)
let remove_from_rig (rig : (reg, reg Set.t) Hashtbl.t) (v: reg) : unit =
(* TODO *)
Hashtbl.remove rig v;
Hashtbl.iter (fun key reg_set ->
if Set.mem v reg_set
then Hashtbl.replace rig key (Set.remove v reg_set)
) rig;
()
......@@ -161,8 +177,11 @@ type regalloc_decision =
possédant strictement moins de [n] voisins. Retourne [None] si aucun sommet
ne satisfait cette condition. *)
let pick_node_with_fewer_than_n_neighbors (rig : (reg, reg Set.t) Hashtbl.t) (n: int) : reg option =
(* TODO *)
None
Hashtbl.fold (fun key reg_list acc ->
match acc with
| None -> if Set.cardinal reg_list < n then Some(key) else None
| _ -> acc
) rig None
(* Lorsque la fonction précédente échoue (i.e. aucun sommet n'a moins de [n]
voisins), on choisit un pseudo-registre à évincer.
......@@ -173,15 +192,28 @@ let pick_node_with_fewer_than_n_neighbors (rig : (reg, reg Set.t) Hashtbl.t) (n:
[pick_spilling_candidate rig] retourne donc le pseudo-registre [r] qui a le
plus de voisins dans [rig], ou [None] si [rig] est vide. *)
let pick_spilling_candidate (rig : (reg, reg Set.t) Hashtbl.t) : reg option =
(* TODO *)
None
let (max_neighbours_register,mmm) = Hashtbl.fold (fun key reg_list (reg_opt, neighbours) ->
let new_neighbours = Set.cardinal reg_list in
match reg_opt with
| Some(r) -> if new_neighbours > neighbours then (Some(key), new_neighbours) else (reg_opt, neighbours)
| _ -> (Some(key), neighbours)
) rig (None, 0) in
max_neighbours_register
(* [make_stack rig stack ncolors] construit la pile, selon l'algorithme vu en
cours (slides 60 à 63 du cours "Allocation de registres - Autres slides"
présent sur Edunao.) *)
let rec make_stack (rig : (reg, reg Set.t) Hashtbl.t) (stack : regalloc_decision list) (ncolors: int) : regalloc_decision list =
(* TODO *)
stack
match pick_node_with_fewer_than_n_neighbors rig ncolors with
| None -> (
match pick_spilling_candidate rig with
| None -> stack
| Some(r) -> remove_from_rig rig r; make_stack rig (Spill(r)::stack) ncolors
)
| Some(r) -> remove_from_rig rig r; make_stack rig (NoSpill(r)::stack) ncolors
(* Maintenant que nous avons une pile de [regalloc_decision], il est temps de
colorer notre graphe, i.e. associer une couleur (un numéro de registre
......@@ -220,8 +252,22 @@ let allocate (allocation: (reg, loc) Hashtbl.t) (rig: (reg, reg Set.t) Hashtbl.t
(all_colors: int Set.t)
(next_stack_slot: int) (decision: regalloc_decision)
: int =
(* TODO *)
next_stack_slot
match decision with
| Spill(r) ->
Hashtbl.replace allocation r (Stk next_stack_slot);
next_stack_slot - 1
| NoSpill(r) ->
let colors_copy = Set.union all_colors Set.empty in
let neighbours = Hashtbl.find rig r in
let non_color_neighbours = Set.fold ( fun neighbour acc ->
match Hashtbl.find_option allocation neighbour with
| None -> acc
| Some(Stk(location)) -> acc
| Some(Reg(location)) -> Set.remove location acc
) neighbours colors_copy in
Hashtbl.replace allocation r (Reg (Set.choose non_color_neighbours));
next_stack_slot
(* [regalloc_fun f live_out all_colors] effectue l'allocation de registres pour
la fonction [f].
......
Markdown is supported
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