diff options
author | Justus Fasse <justus.fasse@etu.univ-grenoble-alpes.fr> | 2021-07-21 16:50:37 +0200 |
---|---|---|
committer | Justus Fasse <justus.fasse@etu.univ-grenoble-alpes.fr> | 2021-07-21 16:50:37 +0200 |
commit | 9a0345ab9783b93fb785508945bbc433106c1fa0 (patch) | |
tree | a49b50792386148b6b6e7339450a25fcc449db2d | |
parent | 69af426c3abc7be5b8caf94f1472ce6372afbd09 (diff) | |
download | compcert-kvx-9a0345ab9783b93fb785508945bbc433106c1fa0.tar.gz compcert-kvx-9a0345ab9783b93fb785508945bbc433106c1fa0.zip |
Don't attempt to schedule instrcution beyond an Icond if it is the last
instruction of the superblock.
-rw-r--r-- | scheduling/MyRTLpathScheduleraux.ml | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/scheduling/MyRTLpathScheduleraux.ml b/scheduling/MyRTLpathScheduleraux.ml index 40b1e5eb..1beab9f2 100644 --- a/scheduling/MyRTLpathScheduleraux.ml +++ b/scheduling/MyRTLpathScheduleraux.ml @@ -434,11 +434,11 @@ let update_liveins liveins live_renames = let replace_iconds_by_ocmps sb code ~next_free_reg = let module P = Camlcoq.P in - (* Don't modify the arguments *) - (* XXX: not necessary since instructions is never modified, only code *) - let instructions = Array.copy sb.instructions in + (* We won't replace an Icond if it is the last instruction of the superblock, then it + * cannot be moved. *) + let last_pc = sb.instructions.(Array.length sb.instructions - 1) in let (code, _previous_icond, next_free_reg) = - ArrayLabels.fold_left instructions + ArrayLabels.fold_left sb.instructions ~init:(code, None, next_free_reg) ~f:(fun (code, previous_icond_proxy_reg, next_free_reg) pc -> let inst = get_some @@ PTree.get pc code in @@ -451,25 +451,29 @@ let replace_iconds_by_ocmps sb code ~next_free_reg = let code' = PTree.set pc istore' code in (code', previous_icond_proxy_reg, next_free_reg) ) | Icond(cond, args, ifso, ifnot, prediction) -> - (match prediction with - | None -> - (* Case only happens at the very end of the path; no transformation necessary *) - assert(sb.instructions.(Array.length sb.instructions - 1) = pc); + (* Don't transform the last Icond of a superblock *) + if pc = last_pc then (code, None, next_free_reg) - | Some true -> ( - let ocmp = match previous_icond_proxy_reg with - | None -> Iop((Op.Ocmp cond), args, next_free_reg, ifso) - | Some r -> Iop((Op.Ocmp cond), r::args, next_free_reg, ifso) - in - let code' = PTree.set pc ocmp code in - (code', Some next_free_reg, P.succ next_free_reg) ) - | Some false -> ( - let ocmp = match previous_icond_proxy_reg with - | None -> Iop((Op.Ocmp cond), args, next_free_reg, ifnot) - | Some r -> Iop((Op.Ocmp cond), r::args, next_free_reg, ifnot) - in - let code' = PTree.set pc ocmp code in - (code', Some next_free_reg, P.succ next_free_reg) )) + else + (match prediction with + | None -> + (* Case only happens at the very end of the path; no transformation necessary *) + assert(sb.instructions.(Array.length sb.instructions - 1) = pc); + (code, None, next_free_reg) + | Some true -> ( + let ocmp = match previous_icond_proxy_reg with + | None -> Iop((Op.Ocmp cond), args, next_free_reg, ifso) + | Some r -> Iop((Op.Ocmp cond), r::args, next_free_reg, ifso) + in + let code' = PTree.set pc ocmp code in + (code', Some next_free_reg, P.succ next_free_reg) ) + | Some false -> ( + let ocmp = match previous_icond_proxy_reg with + | None -> Iop((Op.Ocmp cond), args, next_free_reg, ifnot) + | Some r -> Iop((Op.Ocmp cond), r::args, next_free_reg, ifnot) + in + let code' = PTree.set pc ocmp code in + (code', Some next_free_reg, P.succ next_free_reg) )) | Iload(trap, chunk, addr, args, dest, succ) -> ( if !Machine.config.Machine.has_non_trapping_loads then (code, previous_icond_proxy_reg, next_free_reg) @@ -483,8 +487,7 @@ let replace_iconds_by_ocmps sb code ~next_free_reg = | _ -> (code, previous_icond_proxy_reg, next_free_reg) ) in - let sb' = {sb with instructions = instructions} in - (sb', code, next_free_reg) + (code, next_free_reg) let is_store = function | Istore _ -> true @@ -494,9 +497,9 @@ let is_store = function * Iconds into Ocmps for the purpose of dependency calculations. *) let ideal_schedule' sb code ~next_free_reg = let old_debug_flag = !debug_flag in - let (fake_sb, fake_code, _next_free_reg) = replace_iconds_by_ocmps sb code ~next_free_reg in + let (fake_code, _next_free_reg) = replace_iconds_by_ocmps sb code ~next_free_reg in (* Does PTree.empty work or do I need to map the entries to Regset.empty *) - let fake_sb = { fake_sb with liveins = PTree.empty } in + let fake_sb = { sb with liveins = PTree.empty } in (* Copied from RTLpathScheduleraux.schedule_superblock *) let nr_instr_sb = Array.length sb.instructions in assert (nr_instr_sb = Array.length fake_sb.instructions); |