aboutsummaryrefslogtreecommitdiffstats
path: root/backend/Duplicateaux.ml
diff options
context:
space:
mode:
Diffstat (limited to 'backend/Duplicateaux.ml')
-rw-r--r--backend/Duplicateaux.ml148
1 files changed, 44 insertions, 104 deletions
diff --git a/backend/Duplicateaux.ml b/backend/Duplicateaux.ml
index d0b7129e..209527b9 100644
--- a/backend/Duplicateaux.ml
+++ b/backend/Duplicateaux.ml
@@ -95,52 +95,6 @@ let print_intset s =
Printf.printf "}"
end
-(* FIXME - dominators not working well because the order of dataflow update isn't right *)
- (*
-let get_dominators code entrypoint =
- let bfs_order = bfs code entrypoint
- and predecessors = get_predecessors_rtl code
- in let doms = ref (PTree.map (fun n i -> PSet.of_list bfs_order) code)
- in begin
- Printf.printf "BFS: ";
- print_intlist bfs_order;
- Printf.printf "\n";
- 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 begin
- Printf.printf "----------------------------------------\n";
- Printf.printf "n = %d\n" (P.to_int n);
- Printf.printf "set_p = "; print_intset set_p; Printf.printf "\n";
- Printf.printf "set_lp = ["; List.iter (fun s -> print_intset s; Printf.printf ", ") set_lp; Printf.printf "]\n";
- Printf.printf "=> inter = "; print_intset inter; Printf.printf "\n";
- Printf.printf "=> union = "; print_intset union; Printf.printf "\n";
- doms := PTree.set n union !doms
- end
- ) bfs_order;
- !doms
- end
-*)
-
-let print_dominators dominators =
- let domlist = PTree.elements dominators
- in begin
- Printf.printf "{\n";
- List.iter (fun (n, doms) ->
- Printf.printf "\t";
- Printf.printf "%d:" (P.to_int n);
- print_intset doms;
- Printf.printf "\n"
- ) domlist
- end
-
type vstate = Unvisited | Processed | Visited
(** Getting loop branches with a DFS visit :
@@ -206,78 +160,62 @@ let rec look_ahead code node is_loop_header predicate =
else look_ahead code n is_loop_header predicate
)
-exception HeuristicSucceeded
-
-let do_call_heuristic code ifso ifnot is_loop_header preferred =
+let do_call_heuristic code cond ifso ifnot is_loop_header =
let predicate n = (function
| Icall _ -> true
| _ -> false) @@ get_some @@ PTree.get n code
- in if (look_ahead code ifso is_loop_header predicate) then
- (preferred := false; raise HeuristicSucceeded)
- else if (look_ahead code ifnot is_loop_header predicate) then
- (preferred := true; raise HeuristicSucceeded)
- else ()
+ in if (look_ahead code ifso is_loop_header predicate) then Some false
+ else if (look_ahead code ifnot is_loop_header predicate) then Some true
+ else None
-let do_opcode_heuristic code cond ifso ifnot preferred = DuplicateOpcodeHeuristic.opcode_heuristic code cond ifso ifnot preferred
+let do_opcode_heuristic code cond ifso ifnot is_loop_header = DuplicateOpcodeHeuristic.opcode_heuristic code cond ifso ifnot is_loop_header
-let do_return_heuristic code ifso ifnot is_loop_header preferred =
+let do_return_heuristic code cond ifso ifnot is_loop_header =
let predicate n = (function
| Ireturn _ -> true
| _ -> false) @@ get_some @@ PTree.get n code
- in if (look_ahead code ifso is_loop_header predicate) then
- (preferred := false; raise HeuristicSucceeded)
- else if (look_ahead code ifnot is_loop_header predicate) then
- (preferred := true; raise HeuristicSucceeded)
- else ()
+ in if (look_ahead code ifso is_loop_header predicate) then Some false
+ else if (look_ahead code ifnot is_loop_header predicate) then Some true
+ else None
-let do_store_heuristic code ifso ifnot is_loop_header preferred =
+let do_store_heuristic code cond ifso ifnot is_loop_header =
let predicate n = (function
| Istore _ -> true
| _ -> false) @@ get_some @@ PTree.get n code
- in if (look_ahead code ifso is_loop_header predicate) then
- (preferred := false; raise HeuristicSucceeded)
- else if (look_ahead code ifnot is_loop_header predicate) then
- (preferred := true; raise HeuristicSucceeded)
- else ()
+ in if (look_ahead code ifso is_loop_header predicate) then Some false
+ else if (look_ahead code ifnot is_loop_header predicate) then Some true
+ else None
-let do_loop_heuristic code ifso ifnot is_loop_header preferred =
+let do_loop_heuristic code cond ifso ifnot is_loop_header =
let predicate n = get_some @@ PTree.get n is_loop_header
- in if (look_ahead code ifso is_loop_header predicate) then
- (preferred := true; raise HeuristicSucceeded)
- else if (look_ahead code ifnot is_loop_header predicate) then
- (preferred := false; raise HeuristicSucceeded)
- else ()
+ in if (look_ahead code ifso is_loop_header predicate) then Some true
+ else if (look_ahead code ifnot is_loop_header predicate) then Some false
+ else None
let get_directions code entrypoint =
let bfs_order = bfs code entrypoint
and is_loop_header = get_loop_headers code entrypoint
and directions = ref (PTree.map (fun n i -> false) code) (* false <=> fallthru *)
in begin
- Printf.printf "Loop headers: ";
- ptree_printbool is_loop_header;
- Printf.printf "\n";
+ (* Printf.printf "Loop headers: "; *)
+ (* ptree_printbool is_loop_header; *)
+ (* Printf.printf "\n"; *)
List.iter (fun n ->
match (get_some @@ PTree.get n code) with
| Icond (cond, lr, ifso, ifnot) ->
- Printf.printf "Analyzing %d.." (P.to_int n);
- let preferred = ref false
- in (try
- Printf.printf " call..";
- do_call_heuristic code ifso ifnot is_loop_header preferred;
- Printf.printf " opcode..";
- do_opcode_heuristic code cond ifso ifnot preferred;
- Printf.printf " return..";
- do_return_heuristic code ifso ifnot is_loop_header preferred;
- Printf.printf " store..";
- do_store_heuristic code ifso ifnot is_loop_header preferred;
- Printf.printf " loop..";
- do_loop_heuristic code ifso ifnot is_loop_header preferred;
- Printf.printf "Random choice for %d\n" (P.to_int n);
- preferred := Random.bool ()
- with HeuristicSucceeded | DuplicateOpcodeHeuristic.HeuristicSucceeded
- -> Printf.printf " %s\n" (match !preferred with true -> "BRANCH"
- | false -> "FALLTHROUGH")
- ); directions := PTree.set n !preferred !directions
+ (* Printf.printf "Analyzing %d.." (P.to_int n); *)
+ let heuristics = [ do_call_heuristic; do_opcode_heuristic;
+ do_return_heuristic; do_store_heuristic; do_loop_heuristic ] in
+ let preferred = ref None in
+ begin
+ List.iter (fun do_heur ->
+ match !preferred with
+ | None -> preferred := do_heur code cond ifso ifnot is_loop_header
+ | Some _ -> ()
+ ) heuristics;
+ (match !preferred with None -> preferred := Some (Random.bool ()) | Some _ -> ());
+ directions := PTree.set n (get_some !preferred) !directions
+ end
| _ -> ()
) bfs_order;
!directions
@@ -306,9 +244,9 @@ let rec to_ttl_code_rec directions = function
let to_ttl_code code entrypoint =
let directions = get_directions code entrypoint
in begin
- Printf.printf "Ifso directions: ";
+ (* Printf.printf "Ifso directions: ";
ptree_printbool directions;
- Printf.printf "\n";
+ Printf.printf "\n"; *)
Random.init(0); (* using same seed to make it deterministic *)
to_ttl_code_rec directions (PTree.elements code)
end
@@ -423,7 +361,7 @@ let select_traces code entrypoint =
end
end
done;
- Printf.printf "DFS: \t"; print_intlist order; Printf.printf "\n";
+ (* Printf.printf "DFS: \t"; print_intlist order; Printf.printf "\n"; *)
!traces
end
@@ -471,7 +409,7 @@ let rec change_pointers code n n' = function
* n': the integer which should contain the duplicate of n
* returns: new code, new ptree *)
let duplicate code ptree parent n preds n' =
- Printf.printf "Duplicating node %d into %d..\n" (P.to_int n) (P.to_int n');
+ (* Printf.printf "Duplicating node %d into %d..\n" (P.to_int n) (P.to_int n'); *)
match PTree.get n' code with
| Some _ -> failwith "The PTree already has a node n'"
| None ->
@@ -529,7 +467,7 @@ let tail_duplicate code preds ptree trace =
in (new_code, new_ptree, !nb_duplicated)
let superblockify_traces code preds traces =
- let max_nb_duplicated = 1 (* FIXME - should be architecture dependent *)
+ let max_nb_duplicated = !Clflags.option_fduplicate (* FIXME - should be architecture dependent *)
in let ptree = make_identity_ptree code
in let rec f code ptree = function
| [] -> (code, ptree, 0)
@@ -548,7 +486,7 @@ let rec invert_iconds_trace code = function
| Icond (c, lr, ifso, ifnot) ->
assert (n' == ifso || n' == ifnot);
if (n' == ifso) then (
- Printf.printf "Reversing ifso/ifnot for node %d\n" (P.to_int n);
+ (* Printf.printf "Reversing ifso/ifnot for node %d\n" (P.to_int n); *)
PTree.set n (Icond (Op.negate_condition c, lr, ifnot, ifso)) code )
else code
| _ -> code
@@ -561,12 +499,14 @@ let rec invert_iconds code = function
else code
in invert_iconds code' ts
-(* For now, identity function *)
let duplicate_aux f =
let entrypoint = f.fn_entrypoint in
let code = f.fn_code in
let traces = select_traces (to_ttl_code code entrypoint) entrypoint in
let icond_code = invert_iconds code traces in
let preds = get_predecessors_rtl icond_code in
- let (new_code, pTreeId) = (print_traces traces; superblockify_traces icond_code preds traces) in
- ((new_code, f.fn_entrypoint), pTreeId)
+ if !Clflags.option_fduplicate >= 1 then
+ let (new_code, pTreeId) = ((* print_traces traces; *) superblockify_traces icond_code preds traces) in
+ ((new_code, f.fn_entrypoint), pTreeId)
+ else
+ ((icond_code, entrypoint), make_identity_ptree code)