aboutsummaryrefslogtreecommitdiffstats
path: root/backend/Duplicateaux.ml
diff options
context:
space:
mode:
Diffstat (limited to 'backend/Duplicateaux.ml')
-rw-r--r--backend/Duplicateaux.ml164
1 files changed, 36 insertions, 128 deletions
diff --git a/backend/Duplicateaux.ml b/backend/Duplicateaux.ml
index ac960945..324acd99 100644
--- a/backend/Duplicateaux.ml
+++ b/backend/Duplicateaux.ml
@@ -99,39 +99,27 @@ let rtl_successors = LICMaux.rtl_successors
* Excludes any node given in excluded function *)
let bfs_until code entrypoint (predicate: node->bool) (excluded: node->bool) = begin
debug "bfs\n";
- let module E = struct
- exception Done
- end in
-
- let num_nodes = ref 0 in
- let num_visited = ref 0 in
- let visited = ref (PTree.map (fun n i -> num_nodes := !num_nodes + 1; false) code)
+ let visited = ref (PTree.map (fun n i -> false) code)
and bfs_list = ref []
and to_visit = Queue.create ()
and node = ref entrypoint
in begin
Queue.add entrypoint to_visit;
- try
- while not (Queue.is_empty to_visit) do
- node := Queue.pop to_visit;
- if (not (get_some @@ PTree.get !node !visited)) then begin
- visited := PTree.set !node true !visited;
- num_visited := !num_visited + 1;
- if not (excluded !node) then begin
- match PTree.get !node code with
- | None -> failwith "No such node"
- | Some i ->
- bfs_list := !node :: !bfs_list;
- if !num_visited = !num_nodes then raise_notrace E.Done
- else begin
- if not (predicate !node) then
- let succ = rtl_successors i in List.iter (fun n -> Queue.add n to_visit) succ
- end
- end
+ while not (Queue.is_empty to_visit) do
+ node := Queue.pop to_visit;
+ if (not (get_some @@ PTree.get !node !visited)) then begin
+ visited := PTree.set !node true !visited;
+ if not (excluded !node) then begin
+ match PTree.get !node code with
+ | None -> failwith "No such node"
+ | Some i ->
+ bfs_list := !node :: !bfs_list;
+ if not (predicate !node) then
+ let succ = rtl_successors i in List.iter (fun n -> Queue.add n to_visit) succ
end
- done;
- List.rev !bfs_list
- with E.Done -> List.rev !bfs_list
+ end
+ done;
+ List.rev !bfs_list
end
end
@@ -312,9 +300,7 @@ let rec find_last_node_before_loop code node trace is_loop_header =
(* The computation of sb_final requires to already have branch prediction *)
let get_inner_loops f code is_loop_header =
let fake_f = { fn_sig = f.fn_sig; fn_params = f.fn_params;
- fn_stacksize = f.fn_stacksize; fn_code = code; fn_entrypoint = f.fn_entrypoint;
- fn_untrusted_analysis = { answer_to_life_the_universe_and_everything = None;
- staged_header_dup = None } } in
+ fn_stacksize = f.fn_stacksize; fn_code = code; fn_entrypoint = f.fn_entrypoint } in
let (_, predmap, loopmap) = LICMaux.inner_loops fake_f in
begin
debug "PREDMAP: "; print_ptree print_intlist predmap;
@@ -942,21 +928,6 @@ let clone code revmap ln = begin
(!code', revmap', ln', fwmap)
end
-let clone_only_new code next_pc ln = begin
- assert (List.length ln > 0);
- let len = List.length ln in
- let ln' = List.init len (fun n -> n + next_pc) in
- let fwmap = generate_fwmap ln ln' PTree.empty in
- let revmap' = generate_revmap ln (List.map P.of_int ln') PTree.empty in
- let code' = ref PTree.empty in
- List.iter (fun n ->
- let instr = get_some @@ PTree.get n code in
- let instr' = change_nexts fwmap instr in
- code' := PTree.set (apply_map fwmap n) instr' !code'
- ) ln;
- (!code', revmap', ln', fwmap, next_pc + len)
-end
-
let rec count_ignore_nops code = function
| [] -> 0
| n::ln ->
@@ -1063,45 +1034,31 @@ let extract_upto_icond f code head =
let rec extract h =
let inst = get_some @@ PTree.get h code in
match inst with
- | Icond _ -> Some [h]
+ | Icond _ -> [h]
| _ -> ( match rtl_successors inst with
- | [n] -> begin
- (* testing if we reached the starting point
- * (this could happen in the case of an unconditional infinite loop in the source code)
- *)
- if n = head then None
- else match extract n with
- | Some l -> Some (h :: l)
- | None -> None
- end
+ | [n] -> h :: (extract n)
| _ -> failwith "Found a node with more than one successor??"
)
- in
- match extract head with
- | None -> None
- | Some(res) -> Some (List.rev res)
+ in List.rev @@ extract head
let rotate_inner_loop f code revmap iloop =
- let header_opt = extract_upto_icond f code iloop.head in
- match header_opt with
- | None -> (code, revmap)
- | Some header ->
- let limit = !Clflags.option_flooprotate in
- let nb_duplicated = count_ignore_nops code header in
- if nb_duplicated > limit then begin
- debug "Loop Rotate: too many nodes to duplicate (%d > %d)" (List.length header) limit;
- (code, revmap)
- end else if nb_duplicated == count_ignore_nops code iloop.body then begin
- debug "The conditional branch is already at the end! No need to rotate.";
- (code, revmap)
- end else
- let (code2, revmap2, dupheader, fwmap) = clone code revmap header in
- let code' = ref code2 in
- let head' = apply_map fwmap iloop.head in
- begin
- code' := change_pointers !code' iloop.head head' iloop.preds;
- (!code', revmap2)
- end
+ let header = extract_upto_icond f code iloop.head in
+ let limit = !Clflags.option_flooprotate in
+ let nb_duplicated = count_ignore_nops code header in
+ if nb_duplicated > limit then begin
+ debug "Loop Rotate: too many nodes to duplicate (%d > %d)" (List.length header) limit;
+ (code, revmap)
+ end else if nb_duplicated == count_ignore_nops code iloop.body then begin
+ debug "The conditional branch is already at the end! No need to rotate.";
+ (code, revmap)
+ end else
+ let (code2, revmap2, dupheader, fwmap) = clone code revmap header in
+ let code' = ref code2 in
+ let head' = apply_map fwmap iloop.head in
+ begin
+ code' := change_pointers !code' iloop.head head' iloop.preds;
+ (!code', revmap2)
+ end
let rotate_inner_loops f code revmap =
let is_loop_header = get_loop_headers code (f.fn_entrypoint) in
@@ -1178,52 +1135,3 @@ let tail_duplicate f =
superblockify_traces code preds is_loop_header traces revmap
else (code, revmap) in
((code, entrypoint), revmap)
-
-(* TODO: copied here to avoid cyclic dependency... *)
-let my_merge_no_overwrite m1 m2 =
- PTree.combine (fun x y -> match (x, y) with
- | None, None -> None
- | Some x, None
- | None, Some x -> Some x
- | Some _, Some _ -> failwith "Merge conflict."
- ) m1 m2
-
-let my_merge_overwrite m1 m2 =
- PTree.combine (fun x y -> match (x, y) with
- | None, None -> None
- | Some x, None
- | None, Some x -> Some x
- | Some _, Some y -> Some y
- ) m1 m2
-
-let lift_if f =
- (* do nothing for now *)
- let entrypoint = f.fn_entrypoint in
- let code = f.fn_code in
- let revmap = make_identity_ptree code in
- (* TODO predicate this transformation on a compiler flag *)
- let (code', revmap') =
- if !Clflags.option_fliftif > 0 then (
- Clflags.option_fcse3_only_conditions := true;
- (* lift_if_inner_loops f code revmap *)
- match f.fn_untrusted_analysis.staged_header_dup with
- | None -> (code, revmap)
- | Some(staged_revmap, staged_dupcode) ->
- let code = my_merge_overwrite code staged_dupcode in
- let revmap = my_merge_no_overwrite revmap staged_revmap in
- (code, revmap) )
- else
- (code, revmap)
- in
-
- let old_debug_flag = !debug_flag in
- debug_flag := false;
- debug "Old entrypoint = %d, new entrypoint = %d\n" (P.to_int entrypoint) (P.to_int @@ get_some @@ PTree.get entrypoint revmap');
- debug "Code before if-lifting:\n"; flush_all ();
- print_code code; flush_all ();
- debug "Code after if-lifting:\n"; flush_all ();
- print_code code'; flush_all ();
- debug_flag := old_debug_flag;
-
- (* TODO: may the entrypoint change? *)
- ((code', entrypoint), revmap') \ No newline at end of file