@@ -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
@@ -207,7 +215,7 @@ let expr_deps blocks st x e =
207215 match st.defs.(Var. idx f) with
208216 | Expr (Closure (params , _ )) when List. length args = List. length params ->
209217 Hashtbl. add st.applied_functions (x, f) () ;
210- List. iter2 ~f: (fun p a -> add_assign_def st p a) params args;
218+ if not st.fast then List. iter2 ~f: (fun p a -> add_assign_def st p a) params args;
211219 Var.Set. iter (fun y -> add_dep st x y) (Var.Map. find f st.return_values)
212220 | _ -> () )
213221 | Closure (l , cont ) ->
@@ -243,17 +251,19 @@ let program_deps st { blocks; _ } =
243251 ~f: (fun i (pc , _ ) ->
244252 Hashtbl. replace h pc (i :: (try Hashtbl. find h pc with Not_found -> [] )))
245253 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
254+ if not st.fast
255+ then
256+ Hashtbl. iter
257+ (fun pc tags ->
258+ let block = Addr.Map. find pc blocks in
259+ List. iter
260+ ~f: (fun i ->
261+ match i with
262+ | Let (y , Field (x' , _ )) when Var. equal x x' ->
263+ Hashtbl. add st.known_cases y tags
264+ | _ -> () )
265+ block.body)
266+ h
257267 | Pushtrap (cont , x , cont_h , _ ) ->
258268 add_var st x;
259269 st.defs.(Var. idx x) < - Phi { known = Var.Set. empty; others = true };
@@ -406,31 +416,34 @@ let propagate st ~update approx x =
406416 | Top -> Top )
407417 | Prim (Extern "caml_check_bound" , [ Pv y ; _ ]) -> Var.Tbl. get approx y
408418 | 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 )
419+ if st.fast
420+ then Domain. others
421+ else
422+ match Var.Tbl. get approx y with
423+ | Values { known; others } ->
424+ Domain. join_set
425+ ~update
426+ ~st
427+ ~approx
428+ ~others
429+ (fun z ->
430+ match st.defs.(Var. idx z) with
431+ | Expr (Block (_ , lst , _ )) ->
432+ Array. iter ~f: (fun t -> add_dep st x t) lst;
433+ let a =
434+ Array. fold_left
435+ ~f: (fun acc t ->
436+ Domain. join ~update ~st ~approx (Var.Tbl. get approx t) acc)
437+ ~init: Domain. bot
438+ lst
439+ in
440+ if st.possibly_mutable.(Var. idx z)
441+ then Domain. join ~update ~st ~approx Domain. others a
442+ else a
443+ | Expr (Closure _ ) -> Domain. bot
444+ | Phi _ | Expr _ -> assert false )
445+ known
446+ | Top -> Top )
434447 | Prim (Array_get, _ ) -> assert false
435448 | Prim ((Vectlength | Not | IsInt | Eq | Neq | Lt | Le | Ult ), _ ) ->
436449 (* The result of these primitive is neither a function nor a
@@ -457,12 +470,14 @@ let propagate st ~update approx x =
457470 if not (Hashtbl. mem st.applied_functions (x, g))
458471 then (
459472 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;
473+ if not st.fast
474+ then
475+ List. iter2
476+ ~f: (fun p a ->
477+ add_assign_def st p a;
478+ update ~children: false p)
479+ params
480+ args;
466481 Var.Set. iter
467482 (fun y -> add_dep st x y)
468483 (Var.Map. find g st.return_values));
@@ -550,6 +565,7 @@ let f p =
550565 ; possibly_mutable
551566 ; known_cases = Hashtbl. create 16
552567 ; applied_functions = Hashtbl. create 16
568+ ; fast = not (Config.Flag. effects () )
553569 }
554570 in
555571 program_deps st p;
0 commit comments