@@ -100,6 +100,7 @@ type state =
100
100
; applied_functions : (Var .t * Var .t , unit ) Hashtbl .t
101
101
(* Functions that have been already considered at a call site.
102
102
This is to avoid repeated computations *)
103
+ ; fast : bool
103
104
}
104
105
105
106
let add_var st x = Var.ISet. add st.vars x
@@ -126,7 +127,8 @@ let add_assign_def st x y =
126
127
let add_param_def st x =
127
128
add_var st x;
128
129
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 }
130
132
131
133
let rec arg_deps st ?ignore params args =
132
134
match params, args with
@@ -155,6 +157,12 @@ let expr_deps blocks st x e =
155
157
(* The analysis knowns about these primitives, and will compute
156
158
an approximation of the value they return based on an
157
159
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 );
158
166
List. iter
159
167
~f: (fun a ->
160
168
match a with
@@ -207,7 +215,7 @@ let expr_deps blocks st x e =
207
215
match st.defs.(Var. idx f) with
208
216
| Expr (Closure (params , _ )) when List. length args = List. length params ->
209
217
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;
211
219
Var.Set. iter (fun y -> add_dep st x y) (Var.Map. find f st.return_values)
212
220
| _ -> () )
213
221
| Closure (l , cont ) ->
@@ -243,17 +251,19 @@ let program_deps st { blocks; _ } =
243
251
~f: (fun i (pc , _ ) ->
244
252
Hashtbl. replace h pc (i :: (try Hashtbl. find h pc with Not_found -> [] )))
245
253
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
257
267
| Pushtrap (cont , x , cont_h , _ ) ->
258
268
add_var st x;
259
269
st.defs.(Var. idx x) < - Phi { known = Var.Set. empty; others = true };
@@ -406,31 +416,34 @@ let propagate st ~update approx x =
406
416
| Top -> Top )
407
417
| Prim (Extern "caml_check_bound" , [ Pv y ; _ ]) -> Var.Tbl. get approx y
408
418
| 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 )
434
447
| Prim (Array_get, _ ) -> assert false
435
448
| Prim ((Vectlength | Not | IsInt | Eq | Neq | Lt | Le | Ult ), _ ) ->
436
449
(* The result of these primitive is neither a function nor a
@@ -457,12 +470,14 @@ let propagate st ~update approx x =
457
470
if not (Hashtbl. mem st.applied_functions (x, g))
458
471
then (
459
472
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;
466
481
Var.Set. iter
467
482
(fun y -> add_dep st x y)
468
483
(Var.Map. find g st.return_values));
@@ -550,6 +565,7 @@ let f p =
550
565
; possibly_mutable
551
566
; known_cases = Hashtbl. create 16
552
567
; applied_functions = Hashtbl. create 16
568
+ ; fast = not (Config.Flag. effects () )
553
569
}
554
570
in
555
571
program_deps st p;
0 commit comments