diff options
Diffstat (limited to 'backend/Duplicateaux.ml')
-rw-r--r-- | backend/Duplicateaux.ml | 36 |
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" ) |