let rec local_opt_base_block base_block =
let opt_instr2 x y =
match (x, y) with
| Unspill(_, v1), Mov_i(v1', _)
| Mov_i(v1, _), Mov_i(v1', _) when get_var_reg v1' = get_var_reg v1 -> None
| Spill(_, _, vd), Spill(_, _, vd') when vd.vd_ident = vd'.vd_ident -> None
| _ -> Some x
in
let opt_instr = function
| Add_i(v1, v2, v3) when get_var_value v3 = Some (Int 0) -> None
| Div_i(v1, v2, v3) when get_var_value v3 = Some (Int 1) -> None
| Div_i(v1, v2, v3) when get_var_value v2 = Some (Int 0) -> None
| Mult_i(v1, v2, v3) when get_var_value v3 = Some (Int 0) ->
set_var_reg v1 (get_var_reg v2);
Some (Mov_i(v1, new_const_int_var 0 (-1)))
| Sub_i(v1, v2, v3) when get_var_value v3 = Some (Int 0) -> None
| x -> Some x
in
let rec opt_instrs = function
| x :: y :: t ->
(
match opt_instr2 x y with
| None -> opt_instrs (y :: t)
| Some x' when x' == x ->
(
match opt_instr x with
| Some x' when x' == x -> x :: (opt_instrs (y :: t))
| Some x' -> opt_instrs (x' :: y :: t)
| None -> opt_instrs (y :: t)
)
| Some x' -> opt_instrs (x' :: y :: t)
)
| [x] ->
(
match opt_instr x with
| Some x' -> [x']
| None -> []
)
| [] -> []
in
(
match base_block.bb_link with
| If(_, b1, b2, b3) ->
local_opt_base_block b1;
local_opt_base_block b2;
local_opt_base_block b3
| While(_, be, b1, b2) ->
local_opt_base_block be;
local_opt_base_block b1;
local_opt_base_block b2
| End -> ()
);
base_block.bb_block <- opt_instrs base_block.bb_block