let eliminate_redundant_move f max_variable_number =
    let basic_block_size = Array.length f in
    let variable_link = Array.create max_variable_number None in
    let check = function
        ILstmtAssign( n, _, ILexpIdent m ) -> variable_link.(n) <- Some m
      |        _ -> ()
    in
    for i = 0 to basic_block_size - 1 do
        List.iter check f.(i).code
    done;
    let rec get_final_variable n =
        match variable_link.(n) with
            None -> n
          | Some m ->
              let l = get_final_variable m in
              if l != m then
                  variable_link.(m) <- Some l;
              l
    in
    for i = 0 to max_variable_number - 1 do
        match variable_link.(i) with
            None -> ()
          | Some j -> variable_link.(i) <- Some (get_final_variable i)
    done;
    let rename n =
        match variable_link.(n) with
            None -> n
          | Some m -> m
    in
    let rename_phi_function( n, t, a ) = n, t, Array.map rename a in
    let rename_code insn = map_il (function n -> n) rename insn in
    for i = 0 to basic_block_size - 1 do
        f.(i).phi_function <- List.map rename_phi_function f.(i).phi_function;
        f.(i).code <- List.map rename_code f.(i).code
    done