summaryrefslogtreecommitdiff
path: root/asmcomp/split.ml
diff options
context:
space:
mode:
Diffstat (limited to 'asmcomp/split.ml')
-rw-r--r--asmcomp/split.ml202
1 files changed, 0 insertions, 202 deletions
diff --git a/asmcomp/split.ml b/asmcomp/split.ml
deleted file mode 100644
index db797b0527..0000000000
--- a/asmcomp/split.ml
+++ /dev/null
@@ -1,202 +0,0 @@
-(* Renaming of registers at reload points to split live ranges. *)
-
-open Reg
-open Mach
-
-(********
-open Format
-let print_subst m =
- open_hovbox 1; print_string "{";
- let first = ref true in
- Reg.Map.iter
- (fun r1 r2 ->
- if !first then first := false else print_space();
- Printmach.reg r1; print_string "->"; Printmach.reg r2)
- m;
- print_string "}"; close_box()
-let print_subst_opt = function
- None -> print_string "None"
- | Some s -> print_subst s
-**********)
-
-(* Substitutions are represented by register maps *)
-
-type subst = Reg.t Reg.Map.t
-
-let subst_reg r sub =
- try
- Reg.Map.find r sub
- with Not_found ->
- r
-
-let subst_regs rv sub =
- match sub with
- None -> rv
- | Some s ->
- let n = Array.length rv in
- let nv = Array.new n Reg.dummy in
- for i = 0 to n-1 do nv.(i) <- subst_reg rv.(i) s done;
- nv
-
-(* We maintain equivalence classes of registers using a standard
- union-find algorithm *)
-
-let equiv_classes = ref (Reg.Map.empty : Reg.t Reg.Map.t)
-
-let rec repres_reg r =
- try
- repres_reg(Reg.Map.find r !equiv_classes)
- with Not_found ->
- r
-
-let repres_regs rv =
- let n = Array.length rv in
- for i = 0 to n-1 do rv.(i) <- repres_reg rv.(i) done
-
-(* Identify two registers.
- The second register is chosen as canonical representative. *)
-let identify r1 r2 =
- let repres1 = repres_reg r1 in
- let repres2 = repres_reg r2 in
- if repres1.stamp = repres2.stamp then () else begin
- equiv_classes := Reg.Map.add repres1 repres2 !equiv_classes
- end
-
-(* Identify the image of a register by two substitutions.
- Be careful to use the original register as canonical representative
- in case it does not belong to the domain of one of the substitutions. *)
-
-let identify_sub sub1 sub2 reg =
- try
- let r1 = Reg.Map.find reg sub1 in
- try
- let r2 = Reg.Map.find reg sub2 in
- identify r1 r2
- with Not_found ->
- identify r1 reg
- with Not_found ->
- try
- let r2 = Reg.Map.find reg sub2 in
- identify r2 reg
- with Not_found ->
- ()
-
-(* Identify registers so that the two substitutions agree on the
- registers live before the given instruction. *)
-let merge_substs sub1 sub2 i =
- match (sub1, sub2) with
- (None, None) -> None
- | (Some s1, None) -> sub1
- | (None, Some s2) -> sub2
- | (Some s1, Some s2) ->
- Reg.Set.iter (identify_sub s1 s2) (Reg.add_set_array i.live i.arg);
- sub1
-
-(* Same, for N substitutions *)
-let merge_subst_array subv instr =
- let rec find_one_subst i =
- if i >= Array.length subv then None else begin
- match subv.(i) with
- None -> find_one_subst (i+1)
- | Some si as sub ->
- for j = i+1 to Array.length subv - 1 do
- match subv.(j) with
- None -> ()
- | Some sj ->
- Reg.Set.iter (identify_sub si sj)
- (Reg.add_set_array instr.live instr.arg)
- done;
- sub
- end in
- find_one_subst 0
-
-(* First pass: rename registers at reload points *)
-
-let exit_subst = ref (None: subst option)
-
-let rec rename i sub =
- match i.desc with
- Iend ->
- (i, sub)
- | Ireturn | Iop(Itailcall_ind) | Iop(Itailcall_imm _) ->
- (instr_cons i.desc (subst_regs i.arg sub) [||] i.next,
- None)
- | Iop Ireload ->
- begin match sub with
- None -> rename i.next sub
- | Some s ->
- let oldr = i.res.(0) in
- let newr = Reg.clone i.res.(0) in
- let (new_next, sub_next) =
- rename i.next (Some(Reg.Map.add oldr newr s)) in
- (instr_cons i.desc i.arg [|newr|] new_next,
- sub_next)
- end
- | Iop _ ->
- let (new_next, sub_next) = rename i.next sub in
- (instr_cons i.desc (subst_regs i.arg sub) (subst_regs i.res sub)
- new_next,
- sub_next)
- | Iifthenelse(tst, ifso, ifnot) ->
- let (new_ifso, sub_ifso) = rename ifso sub in
- let (new_ifnot, sub_ifnot) = rename ifnot sub in
- let (new_next, sub_next) =
- rename i.next (merge_substs sub_ifso sub_ifnot i.next) in
- (instr_cons (Iifthenelse(tst, new_ifso, new_ifnot))
- (subst_regs i.arg sub) [||] new_next,
- sub_next)
- | Iswitch(index, cases) ->
- let new_sub_cases = Array.map (fun c -> rename c sub) cases in
- let sub_merge =
- merge_subst_array (Array.map (fun (n, s) -> s) new_sub_cases) i.next in
- let (new_next, sub_next) = rename i.next sub_merge in
- (instr_cons (Iswitch(index, Array.map (fun (n, s) -> n) new_sub_cases))
- (subst_regs i.arg sub) [||] new_next,
- sub_next)
- | Iloop(body) ->
- let (new_body, sub_body) = rename body sub in
- let (new_next, sub_next) = rename i.next (merge_substs sub sub_body i) in
- (instr_cons (Iloop(new_body)) [||] [||] new_next,
- sub_next)
- | Icatch(body, handler) ->
- let saved_exit_subst = !exit_subst in
- exit_subst := None;
- let (new_body, sub_body) = rename body sub in
- let sub_entry_handler = !exit_subst in
- exit_subst := saved_exit_subst;
- let (new_handler, sub_handler) = rename handler sub_entry_handler in
- let (new_next, sub_next) =
- rename i.next (merge_substs sub_body sub_handler i.next) in
- (instr_cons (Icatch(new_body, new_handler)) [||] [||] new_next,
- sub_next)
- | Iexit ->
- exit_subst := merge_substs !exit_subst sub i.next;
- (i, None)
- | Itrywith(body, handler) ->
- let (new_body, sub_body) = rename body sub in
- let (new_handler, sub_handler) = rename handler sub in
- let (new_next, sub_next) =
- rename i.next (merge_substs sub_body sub_handler i.next) in
- (instr_cons (Itrywith(new_body, new_handler)) [||] [||] new_next,
- sub_next)
- | Iraise ->
- (instr_cons Iraise (subst_regs i.arg sub) [||] i.next,
- None)
-
-(* Second pass: replace registers by their final representatives *)
-
-let set_repres i =
- instr_iter (fun i -> repres_regs i.arg; repres_regs i.res) i
-
-(* Entry point *)
-
-let fundecl f =
- equiv_classes := Reg.Map.empty;
- let new_args = Array.copy f.fun_args in
- let (new_body, sub_body) = rename f.fun_body (Some Reg.Map.empty) in
- repres_regs new_args;
- set_repres new_body;
- equiv_classes := Reg.Map.empty;
- { fun_name = f.fun_name;
- fun_args = new_args;
- fun_body = new_body }