aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCyril SIX <cyril.six@kalray.eu>2020-12-16 17:07:00 +0100
committerCyril SIX <cyril.six@kalray.eu>2020-12-16 17:07:21 +0100
commit54f781cd0a32d2a3636eed03a67524199b700115 (patch)
treecee0b2a610c6eb22649f9f43f7aea47fbb896ab7
parent0f0f7d4829001ee01dbcc67acd6b8a55789dc50b (diff)
downloadcompcert-kvx-54f781cd0a32d2a3636eed03a67524199b700115.tar.gz
compcert-kvx-54f781cd0a32d2a3636eed03a67524199b700115.zip
Partially fixing turning loads into non trap
There are now too many loads turned into non trap. To be investigated
-rw-r--r--scheduling/RTLpathScheduleraux.ml78
1 files changed, 56 insertions, 22 deletions
diff --git a/scheduling/RTLpathScheduleraux.ml b/scheduling/RTLpathScheduleraux.ml
index e57ac3f1..22ac47c9 100644
--- a/scheduling/RTLpathScheduleraux.ml
+++ b/scheduling/RTLpathScheduleraux.ml
@@ -6,7 +6,7 @@ open Registers
open Camlcoq
open Machine
-let has_non_trapping_loads = !(Machine.config).has_non_trapping_loads
+let config = Machine.config
type superblock = {
instructions: P.t array; (* pointers to code instructions *)
@@ -225,10 +225,22 @@ let sinst_to_rinst = function
let is_a_cb = function Icond _ -> true | _ -> false
let is_a_load = function Iload _ -> true | _ -> false
+let find_array arr n =
+ let index = ref None in
+ begin
+ Array.iteri (fun i n' ->
+ if n = n' then
+ match !index with
+ | Some _ -> failwith "More than one element present"
+ | None -> index := Some i
+ ) arr;
+ !index
+ end
+
let apply_schedule code sb new_order =
let tc = ref code in
let old_order = sb.instructions in
- let count_cbs order =
+ let count_cbs order code =
let current_cbs = ref HashedSet.PSet.empty in
let cbs_above = ref PTree.empty in
Array.iter (fun n ->
@@ -237,9 +249,12 @@ let apply_schedule code sb new_order =
else if is_a_load inst then cbs_above := PTree.set n !current_cbs !cbs_above
) order;
!cbs_above
+ in let fmap n =
+ let index = get_some @@ find_array new_order n in
+ old_order.(index)
in begin
check_order code old_order new_order;
- (* First pass - modify the successors, nothing else *)
+ (* First pass - modify the positions, nothing else *)
Array.iteri (fun i n' ->
let inst' = get_some @@ PTree.get n' code in
let iend = Array.length old_order - 1 in
@@ -262,31 +277,50 @@ let apply_schedule code sb new_order =
@@ rinst_to_sinst inst'
in tc := PTree.set (Array.get old_order i) new_inst !tc
) new_order;
- (* Second pass - turn the loads into non-trapping when needed, if the architecture supports it *)
- if has_non_trapping_loads then begin
- (* 1) We remember which CBs are "above" a given load *)
- let cbs_above = count_cbs old_order in
- (* 2) We do the same for new_order *)
- let cbs_above' = count_cbs new_order in
- (* 3) We examine each load, turn it into non-trapping if cbs_above is not included in cbs_above' *)
- Array.iter (fun n ->
- let inst = get_some @@ PTree.get n !tc in
- match inst with
- | Iload (t,a,b,c,d,s) ->
- let pset = get_some @@ PTree.get n cbs_above in
- let pset' = get_some @@ PTree.get n cbs_above' in
- if not @@ HashedSet.PSet.is_subset pset pset' then tc := PTree.set n (Iload (AST.NOTRAP,a,b,c,d,s)) !tc
- | _ -> ()
- ) old_order
- end;
+ (* Second pass - turn the loads back into trapping when it was not needed *)
+ (* 1) We remember which CBs are "above" a given load *)
+ let cbs_above = count_cbs old_order code in
+ (* 2) We do the same for new_order *)
+ let cbs_above' = count_cbs new_order !tc in
+ (* 3) We examine each load, turn it back into trapping if cbs_above is included in cbs_above' *)
+ Array.iter (fun n ->
+ let n' = fmap n in
+ let inst' = get_some @@ PTree.get n' !tc in
+ match inst' with
+ | Iload (t,a,b,c,d,s) -> dprintf "Examining load number %d\n" (P.to_int n');
+ let pset = get_some @@ PTree.get n cbs_above in
+ let pset' = get_some @@ PTree.get n' cbs_above' in
+ if HashedSet.PSet.is_subset pset pset' then tc := PTree.set n' (Iload (AST.TRAP,a,b,c,d,s)) !tc
+ else assert !config.has_non_trapping_loads
+ | _ -> ()
+ ) old_order;
!tc
end
+let turn_all_loads_nontrap sb code =
+ if not !config.has_non_trapping_loads then code
+ else begin
+ let code' = ref code in
+ Array.iter (fun n ->
+ let inst = get_some @@ PTree.get n code in
+ match inst with
+ | Iload (t,a,b,c,d,s) -> code' := PTree.set n (Iload (AST.NOTRAP,a,b,c,d,s)) !code'
+ | _ -> ()
+ ) sb.instructions;
+ !code'
+ end
+
let rec do_schedule code = function
| [] -> code
| sb :: lsb ->
- let schedule = schedule_superblock sb code in
- let new_code = apply_schedule code sb schedule in
+ (* Trick: instead of turning loads into non trap as needed..
+ * First, we turn them all into non-trap.
+ * Then, we turn back those who didn't need to be turned, into TRAP again
+ * This is because the scheduler (rightfully) refuses to schedule ahead of a branch
+ * operations that might trap *)
+ let code' = turn_all_loads_nontrap sb code in
+ let schedule = schedule_superblock sb code' in
+ let new_code = apply_schedule code' sb schedule in
begin
(* debug_flag := true; *)
dprintf "Old Code: "; print_code code;