Skip to content

Commit 456af07

Browse files
committed
WIP: experiment with a faster analysis
1 parent 9822fc7 commit 456af07

File tree

2 files changed

+72
-49
lines changed

2 files changed

+72
-49
lines changed

compiler/lib/global_flow.ml

Lines changed: 67 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ let times = Debug.find "times"
3131

3232
open Code
3333

34+
let fast = true
35+
3436
(****)
3537

3638
(* Compute the list of variables containing the return values of each
@@ -126,7 +128,8 @@ let add_assign_def st x y =
126128
let add_param_def st x =
127129
add_var st x;
128130
let idx = Var.idx x in
129-
assert (is_undefined st.defs.(idx))
131+
assert (is_undefined st.defs.(idx));
132+
if fast then st.defs.(idx) <- Phi { known = Var.Set.empty; others = true }
130133

131134
let rec arg_deps st ?ignore params args =
132135
match params, args with
@@ -155,6 +158,12 @@ let expr_deps blocks st x e =
155158
(* The analysis knowns about these primitives, and will compute
156159
an approximation of the value they return based on an
157160
approximation of their arguments *)
161+
(if fast
162+
then
163+
match l with
164+
| Pv x :: _ -> do_escape st Escape x
165+
| Pc _ :: _ -> ()
166+
| [] -> assert false);
158167
List.iter
159168
~f:(fun a ->
160169
match a with
@@ -204,12 +213,14 @@ let expr_deps blocks st x e =
204213
(* If [f] is obviously a function, we can add appropriate
205214
dependencies right now. This speeds up the analysis
206215
significantly. *)
207-
match st.defs.(Var.idx f) with
208-
| Expr (Closure (params, _)) when List.length args = List.length params ->
209-
Hashtbl.add st.applied_functions (x, f) ();
210-
List.iter2 ~f:(fun p a -> add_assign_def st p a) params args;
211-
Var.Set.iter (fun y -> add_dep st x y) (Var.Map.find f st.return_values)
212-
| _ -> ())
216+
if false
217+
then
218+
match st.defs.(Var.idx f) with
219+
| Expr (Closure (params, _)) when List.length args = List.length params ->
220+
Hashtbl.add st.applied_functions (x, f) ();
221+
if not fast then List.iter2 ~f:(fun p a -> add_assign_def st p a) params args;
222+
Var.Set.iter (fun y -> add_dep st x y) (Var.Map.find f st.return_values)
223+
| _ -> ())
213224
| Closure (l, cont) ->
214225
List.iter l ~f:(fun x -> add_param_def st x);
215226
cont_deps blocks st cont
@@ -243,17 +254,19 @@ let program_deps st { blocks; _ } =
243254
~f:(fun i (pc, _) ->
244255
Hashtbl.replace h pc (i :: (try Hashtbl.find h pc with Not_found -> [])))
245256
a2;
246-
Hashtbl.iter
247-
(fun pc tags ->
248-
let block = Addr.Map.find pc blocks in
249-
List.iter
250-
~f:(fun i ->
251-
match i with
252-
| Let (y, Field (x', _)) when Var.equal x x' ->
253-
Hashtbl.add st.known_cases y tags
254-
| _ -> ())
255-
block.body)
256-
h
257+
if not fast
258+
then
259+
Hashtbl.iter
260+
(fun pc tags ->
261+
let block = Addr.Map.find pc blocks in
262+
List.iter
263+
~f:(fun i ->
264+
match i with
265+
| Let (y, Field (x', _)) when Var.equal x x' ->
266+
Hashtbl.add st.known_cases y tags
267+
| _ -> ())
268+
block.body)
269+
h
257270
| Pushtrap (cont, x, cont_h, _) ->
258271
add_var st x;
259272
st.defs.(Var.idx x) <- Phi { known = Var.Set.empty; others = true };
@@ -406,31 +419,34 @@ let propagate st ~update approx x =
406419
| Top -> Top)
407420
| Prim (Extern "caml_check_bound", [ Pv y; _ ]) -> Var.Tbl.get approx y
408421
| Prim ((Array_get | Extern "caml_array_unsafe_get"), [ Pv y; _ ]) -> (
409-
match Var.Tbl.get approx y with
410-
| Values { known; others } ->
411-
Domain.join_set
412-
~update
413-
~st
414-
~approx
415-
~others
416-
(fun z ->
417-
match st.defs.(Var.idx z) with
418-
| Expr (Block (_, lst, _)) ->
419-
Array.iter ~f:(fun t -> add_dep st x t) lst;
420-
let a =
421-
Array.fold_left
422-
~f:(fun acc t ->
423-
Domain.join ~update ~st ~approx (Var.Tbl.get approx t) acc)
424-
~init:Domain.bot
425-
lst
426-
in
427-
if st.possibly_mutable.(Var.idx z)
428-
then Domain.join ~update ~st ~approx Domain.others a
429-
else a
430-
| Expr (Closure _) -> Domain.bot
431-
| Phi _ | Expr _ -> assert false)
432-
known
433-
| Top -> Top)
422+
if fast
423+
then Domain.others
424+
else
425+
match Var.Tbl.get approx y with
426+
| Values { known; others } ->
427+
Domain.join_set
428+
~update
429+
~st
430+
~approx
431+
~others
432+
(fun z ->
433+
match st.defs.(Var.idx z) with
434+
| Expr (Block (_, lst, _)) ->
435+
Array.iter ~f:(fun t -> add_dep st x t) lst;
436+
let a =
437+
Array.fold_left
438+
~f:(fun acc t ->
439+
Domain.join ~update ~st ~approx (Var.Tbl.get approx t) acc)
440+
~init:Domain.bot
441+
lst
442+
in
443+
if st.possibly_mutable.(Var.idx z)
444+
then Domain.join ~update ~st ~approx Domain.others a
445+
else a
446+
| Expr (Closure _) -> Domain.bot
447+
| Phi _ | Expr _ -> assert false)
448+
known
449+
| Top -> Top)
434450
| Prim (Array_get, _) -> assert false
435451
| Prim ((Vectlength | Not | IsInt | Eq | Neq | Lt | Le | Ult), _) ->
436452
(* The result of these primitive is neither a function nor a
@@ -457,12 +473,14 @@ let propagate st ~update approx x =
457473
if not (Hashtbl.mem st.applied_functions (x, g))
458474
then (
459475
Hashtbl.add st.applied_functions (x, g) ();
460-
List.iter2
461-
~f:(fun p a ->
462-
add_assign_def st p a;
463-
update ~children:false p)
464-
params
465-
args;
476+
if not fast
477+
then
478+
List.iter2
479+
~f:(fun p a ->
480+
add_assign_def st p a;
481+
update ~children:false p)
482+
params
483+
args;
466484
Var.Set.iter
467485
(fun y -> add_dep st x y)
468486
(Var.Map.find g st.return_values));

compiler/lib/specialize.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,16 @@ let function_arity info x =
4949
in
5050
arity info x []
5151

52+
let count = ref 0
53+
5254
let specialize_instr function_arity (acc, free_pc, extra) i =
5355
match i with
5456
| Let (x, Apply { f; args; exact }) when (not exact) && Config.Flag.optcall () -> (
5557
let n' = List.length args in
5658
match function_arity f with
5759
| None -> i :: acc, free_pc, extra
5860
| Some n when n = n' ->
61+
incr count;
5962
Let (x, Apply { f; args; exact = true }) :: acc, free_pc, extra
6063
| Some n when n < n' ->
6164
let v = Code.Var.fresh () in
@@ -84,6 +87,7 @@ let specialize_instr function_arity (acc, free_pc, extra) i =
8487
| _ -> i :: acc, free_pc, extra
8588

8689
let specialize_instrs ~function_arity p =
90+
count := 0;
8791
let blocks, free_pc =
8892
Addr.Map.fold
8993
(fun pc block (blocks, free_pc) ->
@@ -99,6 +103,7 @@ let specialize_instrs ~function_arity p =
99103
p.blocks
100104
(Addr.Map.empty, p.free_pc)
101105
in
106+
Format.eprintf "EXACT: %d@." !count;
102107
{ p with blocks; free_pc }
103108

104109
let f = specialize_instrs

0 commit comments

Comments
 (0)