aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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"
)