|
@@ -626,6 +626,33 @@ module Fusion = struct
|
|
end
|
|
end
|
|
| {eexpr = TVar(v1,Some e1)} :: el when config.optimize && config.local_dce && state#get_reads v1 = 0 && state#get_writes v1 = 0 ->
|
|
| {eexpr = TVar(v1,Some e1)} :: el when config.optimize && config.local_dce && state#get_reads v1 = 0 && state#get_writes v1 = 0 ->
|
|
fuse acc (e1 :: el)
|
|
fuse acc (e1 :: el)
|
|
|
|
+ | ({eexpr = TVar(v1,None)} as ev) :: el when not v1.v_capture ->
|
|
|
|
+ let found = ref false in
|
|
|
|
+ let rec replace deep e = match e.eexpr with
|
|
|
|
+ | TBinop(OpAssign,{eexpr = TLocal v2},e2) when v1 == v2 ->
|
|
|
|
+ if deep then raise Exit;
|
|
|
|
+ found := true;
|
|
|
|
+ {ev with eexpr = TVar(v1,Some e2)}
|
|
|
|
+ | TLocal v2 when v1 == v2 -> raise Exit
|
|
|
|
+ | _ -> Type.map_expr (replace true) e
|
|
|
|
+ in
|
|
|
|
+ begin try
|
|
|
|
+ let rec loop acc el = match el with
|
|
|
|
+ | e :: el ->
|
|
|
|
+ let e = replace false e in
|
|
|
|
+ if !found then (List.rev (e :: acc)) @ el
|
|
|
|
+ else loop (e :: acc) el
|
|
|
|
+ | [] ->
|
|
|
|
+ List.rev acc
|
|
|
|
+ in
|
|
|
|
+ let el = loop [] el in
|
|
|
|
+ if not !found then raise Exit;
|
|
|
|
+ state#changed;
|
|
|
|
+ state#dec_writes v1;
|
|
|
|
+ fuse acc el
|
|
|
|
+ with Exit ->
|
|
|
|
+ fuse (ev :: acc) el
|
|
|
|
+ end
|
|
| ({eexpr = TVar(v1,Some e1)} as ev) :: el when can_be_fused v1 e1 ->
|
|
| ({eexpr = TVar(v1,Some e1)} as ev) :: el when can_be_fused v1 e1 ->
|
|
let found = ref false in
|
|
let found = ref false in
|
|
let blocked = ref false in
|
|
let blocked = ref false in
|
|
@@ -808,7 +835,30 @@ module Fusion = struct
|
|
fuse acc el
|
|
fuse acc el
|
|
with Exit ->
|
|
with Exit ->
|
|
if config.fusion_debug then print_endline (Printf.sprintf "NO: %s" (Printexc.get_backtrace()));
|
|
if config.fusion_debug then print_endline (Printf.sprintf "NO: %s" (Printexc.get_backtrace()));
|
|
- fuse (ev :: acc) el
|
|
|
|
|
|
+ begin match el with
|
|
|
|
+ | ({eexpr = TUnop((Increment | Decrement) as op,Prefix,{eexpr = TLocal v1})} as e2) :: el ->
|
|
|
|
+ let found = ref false in
|
|
|
|
+ let rec replace e = match e.eexpr with
|
|
|
|
+ | TLocal v2 when v1 == v2 ->
|
|
|
|
+ if !found then raise Exit;
|
|
|
|
+ found := true;
|
|
|
|
+ {e with eexpr = TUnop(op,Postfix,e)}
|
|
|
|
+ | TIf _ | TSwitch _ | TTry _ | TWhile _ | TFor _ ->
|
|
|
|
+ raise Exit
|
|
|
|
+ | _ ->
|
|
|
|
+ Type.map_expr replace e
|
|
|
|
+ in
|
|
|
|
+ begin try
|
|
|
|
+ let ev = replace ev in
|
|
|
|
+ if not !found then raise Exit;
|
|
|
|
+ state#changed;
|
|
|
|
+ fuse acc (ev :: el)
|
|
|
|
+ with Exit ->
|
|
|
|
+ fuse (ev :: acc) (e2 :: el)
|
|
|
|
+ end
|
|
|
|
+ | _ ->
|
|
|
|
+ fuse (ev :: acc) el
|
|
|
|
+ end
|
|
end
|
|
end
|
|
| {eexpr = TUnop((Increment | Decrement as op,Prefix,({eexpr = TLocal v} as ev)))} as e1 :: e2 :: el ->
|
|
| {eexpr = TUnop((Increment | Decrement as op,Prefix,({eexpr = TLocal v} as ev)))} as e1 :: e2 :: el ->
|
|
begin try
|
|
begin try
|