aboutsummaryrefslogtreecommitdiffstats
path: root/backend/Duplicateaux.ml
diff options
context:
space:
mode:
authorCyril SIX <cyril.six@kalray.eu>2020-12-08 10:56:06 +0100
committerCyril SIX <cyril.six@kalray.eu>2020-12-08 10:56:06 +0100
commita62f28a4b10fa3d0cb28d7eef0ffb443a68ea215 (patch)
tree0505473b9ca98f3caae1e905b08f939eac8f4085 /backend/Duplicateaux.ml
parent5c426cf3b668d43b2f5294f70ab288654c316405 (diff)
downloadcompcert-kvx-a62f28a4b10fa3d0cb28d7eef0ffb443a68ea215.tar.gz
compcert-kvx-a62f28a4b10fa3d0cb28d7eef0ffb443a68ea215.zip
Do not duplicate nodes that don't need to when unrolling the body
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