aboutsummaryrefslogtreecommitdiffstats
path: root/backend/Duplicateaux.ml
diff options
context:
space:
mode:
authorCyril SIX <cyril.six@kalray.eu>2020-10-16 14:34:21 +0200
committerCyril SIX <cyril.six@kalray.eu>2020-10-16 14:39:44 +0200
commit0881f48aec682f14ea396420f8244b7281b848f0 (patch)
treef1cd8065ae101ef9aed3bae57f6d9c77535bfab2 /backend/Duplicateaux.ml
parentea96ae80041cc376f0ec3dce127b414a0a1514a0 (diff)
downloadcompcert-kvx-0881f48aec682f14ea396420f8244b7281b848f0.tar.gz
compcert-kvx-0881f48aec682f14ea396420f8244b7281b848f0.zip
Loop body unrolling
Diffstat (limited to 'backend/Duplicateaux.ml')
-rw-r--r--backend/Duplicateaux.ml40
1 files changed, 39 insertions, 1 deletions
diff --git a/backend/Duplicateaux.ml b/backend/Duplicateaux.ml
index ec7a4d02..84dc92ac 100644
--- a/backend/Duplicateaux.ml
+++ b/backend/Duplicateaux.ml
@@ -783,7 +783,6 @@ let unroll_inner_loop_single code revmap iloop =
debug "IHEAD: %d\n" (P.to_int iloop.head);
code' := change_pointers !code' (iloop.head) head' (iloop.preds);
code' := change_pointers !code' head' (iloop.head) [final'];
- (* code' := PTree.set last_n' (change_single_next first_n @@ ptree_get_some last_n' !code') !code' *)
(!code', revmap2)
end
@@ -801,6 +800,41 @@ let unroll_inner_loops_single f code revmap =
(!code', !revmap')
end
+(* 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 into the first of body'
+ * 3) Links the last instruction of body' into the first of body
+ *)
+let unroll_inner_loop_body code revmap iloop =
+ let body = HashedSet.PSet.elements (iloop.body) in
+ if count_ignore_nops code body > 1000 then begin (* FIXME *)
+ debug "Too many nodes in the loop body (%d > %d)" (List.length body) 1000;
+ (code, revmap)
+ end else
+ let (code2, revmap2, dupbody, fwmap) = clone code revmap body in
+ let code' = ref code2 in
+ let head' = apply_map fwmap (iloop.head) in
+ let final' = apply_map fwmap (iloop.final) in
+ begin
+ code' := change_pointers !code' iloop.head head' [iloop.final];
+ code' := change_pointers !code' head' iloop.head [final'];
+ (!code', revmap2)
+ end
+
+let unroll_inner_loops_body f code revmap =
+ let is_loop_header = get_loop_headers code (f.fn_entrypoint) in
+ let inner_loops = get_inner_loops f code is_loop_header in
+ let code' = ref code in
+ let revmap' = ref revmap in
+ begin
+ print_inner_loops inner_loops;
+ List.iter (fun iloop ->
+ let (new_code, new_revmap) = unroll_inner_loop_body !code' !revmap' iloop in
+ code' := new_code; revmap' := new_revmap
+ ) inner_loops;
+ (!code', !revmap')
+ end
+
let duplicate_aux f =
(* initializing *)
let entrypoint = f.fn_entrypoint in
@@ -819,6 +853,10 @@ let duplicate_aux f =
unroll_inner_loops_single f code revmap
else (code, revmap) in
+ (* unroll body *)
+ let (code, revmap) =
+ unroll_inner_loops_body f code revmap in
+
(* static prediction bis *)
let code =
if !Clflags.option_fpredict then