2010-06-15 10:49:03 +02:00
|
|
|
(**************************************************************************)
|
|
|
|
(* *)
|
|
|
|
(* Heptagon *)
|
|
|
|
(* *)
|
|
|
|
(* Author : Marc Pouzet *)
|
|
|
|
(* Organization : Demons, LRI, University of Paris-Sud, Orsay *)
|
|
|
|
(* *)
|
|
|
|
(**************************************************************************)
|
|
|
|
|
|
|
|
(* control optimisation *)
|
|
|
|
|
|
|
|
|
|
|
|
open Minils
|
2010-07-23 19:45:19 +02:00
|
|
|
open Idents
|
2010-06-15 10:49:03 +02:00
|
|
|
open Misc
|
2010-07-08 17:17:00 +02:00
|
|
|
open Obc
|
2010-07-23 22:06:06 +02:00
|
|
|
open Clocks
|
2010-06-15 10:49:03 +02:00
|
|
|
|
|
|
|
let var_from_name map x =
|
|
|
|
begin try
|
2010-06-26 16:53:25 +02:00
|
|
|
Env.find x map
|
2010-06-15 10:49:03 +02:00
|
|
|
with
|
|
|
|
_ -> assert false
|
|
|
|
end
|
|
|
|
|
2010-07-22 09:36:22 +02:00
|
|
|
let fuse_blocks b1 b2 =
|
|
|
|
{ b1 with b_locals = b1.b_locals @ b2.b_locals;
|
|
|
|
b_body = b1.b_body @ b2.b_body }
|
|
|
|
|
2010-06-15 10:49:03 +02:00
|
|
|
let rec find c = function
|
|
|
|
| [] -> raise Not_found
|
|
|
|
| (c1, s1) :: h ->
|
|
|
|
if c = c1 then s1, h else let s, h = find c h in s, (c1, s1) :: h
|
|
|
|
|
|
|
|
let rec control map ck s =
|
|
|
|
match ck with
|
|
|
|
| Cbase | Cvar { contents = Cindex _ } -> s
|
|
|
|
| Cvar { contents = Clink ck } -> control map ck s
|
|
|
|
| Con(ck, c, n) ->
|
2010-07-08 17:17:00 +02:00
|
|
|
let x = var_from_name map n in
|
2010-07-22 09:36:22 +02:00
|
|
|
control map ck (Acase(mk_exp (Elhs x), [(c, mk_block [s])]))
|
2010-06-15 10:49:03 +02:00
|
|
|
|
2010-07-08 17:17:00 +02:00
|
|
|
let is_deadcode = function
|
|
|
|
| Aassgn (lhs, e) ->
|
|
|
|
(match e.e_desc with
|
|
|
|
| Elhs l -> l = lhs
|
|
|
|
| _ -> false
|
2010-06-26 16:53:25 +02:00
|
|
|
)
|
2010-09-14 09:39:02 +02:00
|
|
|
| Acase (_, []) -> true
|
2010-07-22 09:36:22 +02:00
|
|
|
| Afor(_, _, _, { b_body = [] }) -> true
|
2010-07-08 17:17:00 +02:00
|
|
|
| _ -> false
|
2010-06-15 10:49:03 +02:00
|
|
|
|
2010-07-08 17:17:00 +02:00
|
|
|
let rec joinlist l =
|
|
|
|
let l = List.filter (fun a -> not (is_deadcode a)) l in
|
|
|
|
match l with
|
|
|
|
| [] -> []
|
|
|
|
| [s1] -> [s1]
|
|
|
|
| s1::s2::l ->
|
|
|
|
match s1, s2 with
|
|
|
|
| Acase(e1, h1),
|
|
|
|
Acase(e2, h2) when e1.e_desc = e2.e_desc ->
|
|
|
|
joinlist ((Acase(e1, joinhandlers h1 h2))::l)
|
|
|
|
| s1, s2 -> s1::(joinlist (s2::l))
|
2010-06-15 10:49:03 +02:00
|
|
|
|
2010-07-22 09:36:22 +02:00
|
|
|
and join_block b =
|
|
|
|
{ b with b_body = joinlist b.b_body }
|
|
|
|
|
2010-06-15 10:49:03 +02:00
|
|
|
and joinhandlers h1 h2 =
|
|
|
|
match h1 with
|
|
|
|
| [] -> h2
|
|
|
|
| (c1, s1) :: h1' ->
|
|
|
|
let s1', h2' =
|
2010-07-22 09:36:22 +02:00
|
|
|
try let s2, h2'' = find c1 h2 in fuse_blocks s1 s2, h2''
|
2010-07-08 17:17:00 +02:00
|
|
|
with Not_found -> s1, h2 in
|
2010-07-22 09:36:22 +02:00
|
|
|
(c1, join_block s1') :: joinhandlers h1' h2'
|