diff options
author | Cyril SIX <cyril.six@kalray.eu> | 2020-10-02 14:56:55 +0200 |
---|---|---|
committer | Cyril SIX <cyril.six@kalray.eu> | 2020-10-02 14:57:18 +0200 |
commit | a805c02949d16ae5794c2661f8a3157105a1982b (patch) | |
tree | 04e82c16c737aad0f79afbfdfc33a5014916c453 /backend/LICMaux.ml | |
parent | 043a6caa766bf1f3508b389cd3c7ae69d596eded (diff) | |
download | compcert-kvx-a805c02949d16ae5794c2661f8a3157105a1982b.tar.gz compcert-kvx-a805c02949d16ae5794c2661f8a3157105a1982b.zip |
Moving some code from Duplicateaux to LICMaux to prevent cyclic deps
Diffstat (limited to 'backend/LICMaux.ml')
-rw-r--r-- | backend/LICMaux.ml | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/backend/LICMaux.ml b/backend/LICMaux.ml index c3907809..0ca4418b 100644 --- a/backend/LICMaux.ml +++ b/backend/LICMaux.ml @@ -19,6 +19,62 @@ open Inject;; type reg = P.t;; +(** get_loop_headers moved from Duplicateaux.ml to LICMaux.ml to prevent cycle dependencies *) +let debug_flag = ref false + +let debug fmt = + if !debug_flag then Printf.eprintf fmt + else Printf.ifprintf stderr fmt + +type vstate = Unvisited | Processed | Visited + +let get_some = function +| None -> failwith "Did not get some" +| Some thing -> thing + +let rtl_successors = function +| Itailcall _ | Ireturn _ -> [] +| Icall(_,_,_,_,n) | Ibuiltin(_,_,_,n) | Inop n | Iop (_,_,_,n) +| Iload (_,_,_,_,_,n) | Istore (_,_,_,_,n) -> [n] +| Icond (_,_,n1,n2,_) -> [n1; n2] +| Ijumptable (_,ln) -> ln + +(** Getting loop branches with a DFS visit : + * Each node is either Unvisited, Visited, or Processed + * pre-order: node becomes Processed + * post-order: node becomes Visited + * + * If we come accross an edge to a Processed node, it's a loop! + *) +let get_loop_headers code entrypoint = begin + debug "get_loop_headers\n"; + let visited = ref (PTree.map (fun n i -> Unvisited) code) + and is_loop_header = ref (PTree.map (fun n i -> false) code) + in let rec dfs_visit code = function + | [] -> () + | node :: ln -> + match (get_some @@ PTree.get node !visited) with + | Visited -> () + | Processed -> begin + debug "Node %d is a loop header\n" (P.to_int node); + is_loop_header := PTree.set node true !is_loop_header; + visited := PTree.set node Visited !visited + end + | Unvisited -> begin + visited := PTree.set node Processed !visited; + match PTree.get node code with + | None -> failwith "No such node" + | Some i -> let next_visits = rtl_successors i in dfs_visit code next_visits; + visited := PTree.set node Visited !visited; + dfs_visit code ln + end + in begin + dfs_visit code [entrypoint]; + !is_loop_header + end +end + + module Dominator = struct type t = Unreachable | Dominated of int | Multiple @@ -57,7 +113,7 @@ let apply_dominator (is_marked : node -> bool) (pc : node) let dominated_parts1 (f : coq_function) : (bool PTree.t) * (Dominator.t PMap.t option) = - let headers = Duplicateaux.get_loop_headers f.fn_code f.fn_entrypoint in + let headers = get_loop_headers f.fn_code f.fn_entrypoint in let dominated = Dominator_Solver.fixpoint f.fn_code RTL.successors_instr (apply_dominator (fun pc -> match PTree.get pc headers with | Some x -> x @@ -248,7 +304,7 @@ let print_dominated_parts1 oc f = (PTree.elements f.fn_code);; let loop_headers (f : coq_function) : RTL.node list = - List.map fst (List.filter snd (PTree.elements (Duplicateaux.get_loop_headers f.fn_code f.fn_entrypoint)));; + List.map fst (List.filter snd (PTree.elements (get_loop_headers f.fn_code f.fn_entrypoint)));; let print_loop_headers f = print_endline "Loop headers"; |