let make_ssa f max_register_number variable_attribute =
    let temp_id_map = Array.create max_register_number [] in
    let variable_counter = ref 0 in
    let new_temp_id() =
        let n = !variable_counter in
        incr variable_counter;
        n
    in
    let refer environment n = environment.(n) in
    let assign environment n =
        let m = new_temp_id() in
        environment.(n) <- m;
        temp_id_map.(n) <- m::temp_id_map.(n);
        m
    in
    let update_phi_function environment l =
        let update( n, t, a ) = assign environment n, t, a in
        List.map update l
    in
    let update_insn environment l =
        let refer r = refer environment r in
        let assign r = assign environment r in
        let rec continue = function
            [] -> []
          | insn::l ->
              let insn = map_il assign refer insn in
              insn::continue l
        in
        continue l
    in
    let modify_phi_function i environment =
        let visit j =
            let which = which i f.(j).predecessor in
            let update( n1, t, a ) =
                let n2 = refer environment a.(which) in
                if n2 != -1 then
                    a.(which) <- n2;
            in
            List.iter update f.(j).phi_function
        in
        List.iter visit f.(i).successor
    in
    let root, dominance_tree = make_dominance_tree f in
    let rec search environment i =
(*        print_string ("^(string_of_int i)^"); *)
        let environment = Array.copy environment in
        f.(i).phi_function <- update_phi_function environment f.(i).phi_function;
        f.(i).code <- update_insn environment f.(i).code;
        modify_phi_function i environment;
        List.iter (search environment) dominance_tree.(i)
    in
    print_dominance_tree root dominance_tree;
    let environment = Array.create max_register_number (-1) in
    List.iter (search environment) root;
    let variable_environment = Array.create (!variable_counter) null_variable_attribute in
    for i = 0 to max_register_number - 1 do
        let transfer j = variable_environment.(j) <- variable_attribute.(i) in
        List.iter transfer temp_id_map.(i)
    done;
    f, !variable_counter, variable_environment