aboutsummaryrefslogtreecommitdiffstats
path: root/backend/Duplicateaux.ml
diff options
context:
space:
mode:
authorCyril SIX <cyril.six@kalray.eu>2020-12-08 14:44:21 +0100
committerCyril SIX <cyril.six@kalray.eu>2020-12-08 14:44:21 +0100
commit569084f1ed8d55b6d694f8a659872c011ce49ae4 (patch)
treeec7fbacbf66e9bd6523f94650b824f5453282887 /backend/Duplicateaux.ml
parent714b2b0aacdd7d9348173c08c96c673f1b33be15 (diff)
downloadcompcert-kvx-569084f1ed8d55b6d694f8a659872c011ce49ae4.tar.gz
compcert-kvx-569084f1ed8d55b6d694f8a659872c011ce49ae4.zip
Fixing get_loop_info : part 2
Loops with multiple CBs were only partially predicted for some cases (the header CB would get predicted, but not the CBs inside) This would happen in the case of breaks leading to another loop, such as: ```c void lift_check_level() { int i; int middle = lift_one_level >> 2; if ( lift_cntValid ) { for ( lift_level = 1; lift_level < 14; ++lift_level ) { if ( lift_cnt < lift_levelPos[lift_level] - middle ) break; /* This break */ } } else lift_level = 0; for ( i = 0; i < 14; ++i ) lift_ctrl_io_led[i] = ( i == lift_level - 1 ); } ```
Diffstat (limited to 'backend/Duplicateaux.ml')
-rw-r--r--backend/Duplicateaux.ml36
1 files changed, 28 insertions, 8 deletions
diff --git a/backend/Duplicateaux.ml b/backend/Duplicateaux.ml
index 65d9547f..217ba1b2 100644
--- a/backend/Duplicateaux.ml
+++ b/backend/Duplicateaux.ml
@@ -206,6 +206,7 @@ let get_loop_info is_loop_header bfs_order code =
debug "==================================\n";
let loop_info = ref (PTree.map (fun n i -> None) code) in
let mark_path n =
+ let cb_info = ref PTree.empty in
let visited = ref (PTree.map (fun n i -> false) code) in
(* Returns true if there is a path from src to dest (not involving jumptables) *)
(* Mark nodes as visited along the way *)
@@ -213,11 +214,23 @@ let get_loop_info is_loop_header bfs_order code =
if src == dest then true
else if (get_some @@ PTree.get src !visited) then false
else begin
+ let inst = get_some @@ PTree.get src code in
visited := PTree.set src true !visited;
- match rtl_successors @@ get_some @@ PTree.get src code with
+ match rtl_successors inst with
| [] -> false
| [s] -> explore s dest
- | [s1; s2] -> (explore s1 dest) || (explore s2 dest)
+ | [s1; s2] -> begin
+ (* Remembering that we tried the ifso node *)
+ cb_info := PTree.set src true !cb_info;
+ match explore s1 dest with
+ | true -> true
+ | false -> begin
+ cb_info := PTree.set src false !cb_info;
+ match explore s2 dest with
+ | true -> true
+ | false -> (cb_info := PTree.remove src !cb_info; false)
+ end
+ end
| _ -> false
end
(* Goes forward until a CB is encountered
@@ -246,12 +259,19 @@ let get_loop_info is_loop_header bfs_order code =
let b2 = explore n2 n in
if (b1 && b2) then
debug "\tBoth paths lead back to the head: NONE\n"
- else if b1 then begin
- debug "\tTrue path leads to the head: TRUE\n";
- loop_info := PTree.set s (Some true) !loop_info
- end else if b2 then begin
- debug "\tFalse path leads to the head: FALSE\n";
- loop_info := PTree.set s (Some false) !loop_info
+ else if (b1 || b2) then begin
+ if b1 then begin
+ debug "\tTrue path leads to the head: TRUE\n";
+ loop_info := PTree.set s (Some true) !loop_info;
+ end else if b2 then begin
+ debug "\tFalse path leads to the head: FALSE\n";
+ loop_info := PTree.set s (Some false) !loop_info
+ end;
+ debug "\tSetting other CBs encountered..\n";
+ List.iter (fun (cb, dir) ->
+ debug "\t\t%d is %B\n" (P.to_int cb) dir;
+ loop_info := PTree.set cb (Some dir) !loop_info
+ ) (PTree.elements !cb_info)
end else
debug "\tNo path leads back to the head: NONE\n"
)