diff options
author | Cyril SIX <cyril.six@kalray.eu> | 2019-12-09 17:33:31 +0100 |
---|---|---|
committer | Cyril SIX <cyril.six@kalray.eu> | 2019-12-09 17:33:31 +0100 |
commit | 5382048e0eef1a726119172067a4d6afdf7881fb (patch) | |
tree | f53545b03d56c437352de9e70fe008da7c70507a /backend/Duplicateaux.ml | |
parent | 1cc98a193dcf83aff89fe22a3b23d4881b7123f9 (diff) | |
download | compcert-kvx-5382048e0eef1a726119172067a4d6afdf7881fb.tar.gz compcert-kvx-5382048e0eef1a726119172067a4d6afdf7881fb.zip |
Rajout du calcul de dominateurs - pas testé
Diffstat (limited to 'backend/Duplicateaux.ml')
-rw-r--r-- | backend/Duplicateaux.ml | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/backend/Duplicateaux.ml b/backend/Duplicateaux.ml index a655e76b..069741de 100644 --- a/backend/Duplicateaux.ml +++ b/backend/Duplicateaux.ml @@ -111,6 +111,49 @@ let bfs code entrypoint = let ptree_get_some n ptree = get_some @@ PTree.get n ptree +let get_predecessors code = + let preds = ref (PTree.map (fun n i -> []) code) in + let process_inst (node, ti) = match ti with + | Tleaf _ -> () + | Tnext (_, i) -> let succ = match i with + | Inop n | Iop (_,_,_,n) | Iload (_, _,_,_,_,n) | Istore (_,_,_,_,n) + | Icall (_,_,_,_,n) | Ibuiltin (_, _, _, n) -> [n] + | Icond (_,_,n1,n2) -> [n1;n2] + | Ijumptable (_,ln) -> ln + | _ -> [] + in List.iter (fun s -> preds := PTree.set s (node::(get_some @@ PTree.get s !preds)) !preds) succ + in begin + List.iter process_inst (PTree.elements code); + !preds + end + +module PInt = struct + type t = P.t + let compare x y = compare (P.to_int x) (P.to_int y) +end + +module PSet = Set.Make(PInt) + +let dominators code entrypoint = + let bfs_order = bfs code entrypoint + and predecessors = get_predecessors code + in let doms = ref (PTree.map (fun n i -> PSet.of_list bfs_order) code) + in begin + List.iter (fun n -> + let preds = get_some @@ PTree.get n predecessors + and single = PSet.singleton n + in match preds with + | [] -> doms := PTree.set n single !doms + | p::lp -> + let set_p = get_some @@ PTree.get p !doms + and set_lp = List.map (fun p -> get_some @@ PTree.get p !doms) lp + in let inter = List.fold_left PSet.inter set_p set_lp + in let union = PSet.union inter single + in doms := PTree.set n union !doms + ) bfs_order; + !doms + end + let rec select_unvisited_node is_visited = function | [] -> failwith "Empty list" | n :: ln -> if not (ptree_get_some n is_visited) then n else select_unvisited_node is_visited ln @@ -129,22 +172,6 @@ let best_predecessor_of node predecessors order is_visited = | Some lp -> try Some (List.find (fun n -> (List.mem n lp) && (not (ptree_get_some n is_visited))) order) with Not_found -> None -let get_predecessors code = - let preds = ref (PTree.map (fun n i -> []) code) in - let process_inst (node, ti) = match ti with - | Tleaf _ -> () - | Tnext (_, i) -> let succ = match i with - | Inop n | Iop (_,_,_,n) | Iload (_, _,_,_,_,n) | Istore (_,_,_,_,n) - | Icall (_,_,_,_,n) | Ibuiltin (_, _, _, n) -> [n] - | Icond (_,_,n1,n2) -> [n1;n2] - | Ijumptable (_,ln) -> ln - | _ -> [] - in List.iter (fun s -> preds := PTree.set s (node::(get_some @@ PTree.get s !preds)) !preds) succ - in begin - List.iter process_inst (PTree.elements code); - !preds - end - (* for debugging *) let print_intlist l = let rec f = function |