@@ -100,6 +100,7 @@ type state =
100100 ; applied_functions : (Var .t * Var .t , unit ) Hashtbl .t
101101 (* Functions that have been already considered at a call site.
102102 This is to avoid repeated computations *)
103+ ; fast : bool
103104 }
104105
105106let add_var st x = Var.ISet. add st.vars x
@@ -126,7 +127,8 @@ let add_assign_def st x y =
126127let add_param_def st x =
127128 add_var st x;
128129 let idx = Var. idx x in
129- assert (is_undefined st.defs.(idx))
130+ assert (is_undefined st.defs.(idx));
131+ if st.fast then st.defs.(idx) < - Phi { known = Var.Set. empty; others = true }
130132
131133let rec arg_deps st ?ignore params args =
132134 match params, args with
@@ -155,6 +157,12 @@ let expr_deps blocks st x e =
155157 (* The analysis knowns about these primitives, and will compute
156158 an approximation of the value they return based on an
157159 approximation of their arguments *)
160+ (if st.fast
161+ then
162+ match l with
163+ | Pv x :: _ -> do_escape st Escape x
164+ | Pc _ :: _ -> ()
165+ | [] -> assert false );
158166 List. iter
159167 ~f: (fun a ->
160168 match a with
@@ -204,12 +212,15 @@ let expr_deps blocks st x e =
204212 (* If [f] is obviously a function, we can add appropriate
205213 dependencies right now. This speeds up the analysis
206214 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- | _ -> () )
215+ if false
216+ then
217+ match st.defs.(Var. idx f) with
218+ | Expr (Closure (params , _ )) when List. length args = List. length params ->
219+ Hashtbl. add st.applied_functions (x, f) () ;
220+ if not st.fast
221+ 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 st.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 st.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 st.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));
@@ -550,6 +568,7 @@ let f p =
550568 ; possibly_mutable
551569 ; known_cases = Hashtbl. create 16
552570 ; applied_functions = Hashtbl. create 16
571+ ; fast = not (Config.Flag. effects () )
553572 }
554573 in
555574 program_deps st p;
0 commit comments