aboutsummaryrefslogtreecommitdiffstats
path: root/backend/Duplicateaux.ml
diff options
context:
space:
mode:
Diffstat (limited to 'backend/Duplicateaux.ml')
-rw-r--r--backend/Duplicateaux.ml22
1 files changed, 18 insertions, 4 deletions
diff --git a/backend/Duplicateaux.ml b/backend/Duplicateaux.ml
index dc95d5b9..9c4304e3 100644
--- a/backend/Duplicateaux.ml
+++ b/backend/Duplicateaux.ml
@@ -895,6 +895,18 @@ let unroll_inner_loops_single f code revmap =
let is_some o = match o with Some _ -> true | None -> false
+let rec go_through_predicted code start final =
+ if start == final then
+ Some [start]
+ else
+ match rtl_successors_pref @@ get_some @@ PTree.get start code with
+ | [n] -> (
+ match go_through_predicted code n final with
+ | Some ln -> Some (start :: ln)
+ | None -> None
+ )
+ | _ -> None
+
(* Unrolls the body of the inner loop once - duplicating the exit condition as well
* 1) Clones body into body'
* 2) Links the last instruction of body (sb_final) into the first of body'
@@ -911,13 +923,15 @@ let unroll_inner_loop_body code revmap iloop =
debug "The loop body does not form a superblock OR we have predicted that we do not loop";
(code, revmap)
end else
- let (code2, revmap2, dupbody, fwmap) = clone code revmap body in
+ let sb_final = get_some @@ iloop.sb_final in
+ let sb_body = get_some @@ go_through_predicted code iloop.head sb_final in
+ let (code2, revmap2, dupbody, fwmap) = clone code revmap sb_body in
let code' = ref code2 in
let head' = apply_map fwmap (iloop.head) in
- let finals' = apply_map_list fwmap (iloop.finals) in
+ let sb_final' = apply_map fwmap sb_final in
begin
- code' := change_pointers !code' iloop.head head' [get_some @@ iloop.sb_final];
- code' := change_pointers !code' head' iloop.head finals';
+ code' := change_pointers !code' iloop.head head' [sb_final];
+ code' := change_pointers !code' head' iloop.head [sb_final'];
(!code', revmap2)
end