From 0881f48aec682f14ea396420f8244b7281b848f0 Mon Sep 17 00:00:00 2001 From: Cyril SIX Date: Fri, 16 Oct 2020 14:34:21 +0200 Subject: Loop body unrolling --- backend/Duplicateaux.ml | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'backend/Duplicateaux.ml') 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 -- cgit