@@ -535,14 +535,25 @@ type queue_elt =
535535 ; deps : Code.Var.Set .t
536536 }
537537
538- let access_queue queue x =
539- try
540- let elt = List. assoc x queue in
541- ((elt.prop, elt.deps), elt.ce, elt.loc), List. remove_assoc x queue
542- with Not_found -> ((fst const_p, Code.Var.Set. singleton x), var x, None ), queue
538+ let access_queue ~live queue x =
539+ let idx = Var. idx x in
540+ if idx < Array. length live && Array. unsafe_get live idx = 1
541+ then
542+ match
543+ List. find_map queue ~f: (fun (x' , elt ) ->
544+ if Code.Var. equal x x' then Some elt else None )
545+ with
546+ | Some elt ->
547+ let [@ tail_mod_cons] rec clean x = function
548+ | [] -> []
549+ | ((v , _ ) as hd ) :: rem -> if Code.Var. equal v x then rem else hd :: clean x rem
550+ in
551+ ((elt.prop, elt.deps), elt.ce, elt.loc), clean x queue
552+ | None -> ((fst const_p, Code.Var.Set. singleton x), var x, None ), queue
553+ else ((fst const_p, Code.Var.Set. singleton x), var x, None ), queue
543554
544- let access_queue_loc queue loc' x =
545- let (prop, c, loc), queue = access_queue queue x in
555+ let access_queue_loc ~ ctx queue loc' x =
556+ let (prop, c, loc), queue = access_queue ~live: ctx. Ctx. live queue x in
546557 (prop, c, Option. value ~default: loc' loc), queue
547558
548559let should_flush (cond , _ ) prop = cond <> fst const_p && cond + prop > = fst flush_p
@@ -585,7 +596,7 @@ module Expr_builder : sig
585596
586597 val return : 'a -> 'a t
587598
588- val access : Var .t -> J .expression t
599+ val access : ctx : Ctx . t -> Var .t -> J .expression t
589600
590601 val access' : ctx :Ctx .t -> prim_arg -> J .expression t
591602
@@ -627,8 +638,8 @@ end = struct
627638 let info ?(need_loc = false ) prop st =
628639 () , { st with prop = or_p st.prop prop; need_loc = need_loc || st.need_loc }
629640
630- let access x st =
631- let (prop, c, loc), queue = access_queue st.queue x in
641+ let access ~ ctx x st =
642+ let (prop, c, loc), queue = access_queue ~live: ctx. Ctx. live st.queue x in
632643 ( c
633644 , { st with
634645 prop = or_p st.prop prop
@@ -646,7 +657,7 @@ end = struct
646657 assert (List. is_empty instrs);
647658 (* We only have simple constants here *)
648659 fun st -> js, st
649- | Pv x -> access x
660+ | Pv x -> access ~ctx x
650661
651662 let statement_loc loc st =
652663 ( (match st.loc with
@@ -859,7 +870,7 @@ let visit_all params args =
859870 in
860871 l
861872
862- let parallel_renaming loc back_edge params args continuation queue =
873+ let parallel_renaming ctx loc back_edge params args continuation queue =
863874 if
864875 back_edge && Config.Flag. es6 ()
865876 (* This is likely slower than using explicit temp variable
@@ -877,7 +888,7 @@ let parallel_renaming loc back_edge params args continuation queue =
877888 loc
878889 (List. fold_left args ~init: (return [] ) ~f: (fun acc a ->
879890 let * acc = acc in
880- let * cx = access a in
891+ let * cx = access ~ctx a in
881892 return (cx :: acc)))
882893 in
883894 let never, code = continuation queue in
@@ -900,7 +911,7 @@ let parallel_renaming loc back_edge params args continuation queue =
900911 l
901912 ~init: (queue, [] , [] , Code.Var.Set. empty)
902913 ~f: (fun (queue , before , renaming , seen ) (y , x ) ->
903- let ((_, deps_x), cx, locx), queue = access_queue_loc queue loc x in
914+ let ((_, deps_x), cx, locx), queue = access_queue_loc ~ctx queue loc x in
904915 let seen' = Code.Var.Set. add y seen in
905916 if not Code.Var.Set. (is_empty (inter seen deps_x))
906917 then
@@ -1326,14 +1337,14 @@ let rec translate_expr ctx loc x e level : (_ * J.statement_list) Expr_builder.t
13261337 let args = remove_unused_tail_args ctx exact trampolined args in
13271338 let * () = info ~need_loc: true mutator_p in
13281339 let in_cps = Var.Set. mem x ctx.Ctx. in_cps in
1329- let * args = list_map access args in
1330- let * f = access f in
1340+ let * args = list_map ( access ~ctx ) args in
1341+ let * f = access ~ctx f in
13311342 return (apply_fun ctx f args exact trampolined in_cps loc, [] )
13321343 | Block (tag , a , array_or_not , _mut ) ->
13331344 let * contents =
13341345 list_map
13351346 (fun x ->
1336- let * cx = access x in
1347+ let * cx = access ~ctx x in
13371348 let cx =
13381349 match cx with
13391350 | J. EVar (J. V v ) ->
@@ -1352,7 +1363,7 @@ let rec translate_expr ctx loc x e level : (_ * J.statement_list) Expr_builder.t
13521363 in
13531364 return (x, [] )
13541365 | Field (x , n , _ ) ->
1355- let * cx = access x in
1366+ let * cx = access ~ctx x in
13561367 let * () = info mutable_p in
13571368 return (Mlvalue.Block. field cx n, [] )
13581369 | Closure (args , ((pc , _ ) as cont ), cloc ) ->
@@ -1450,18 +1461,18 @@ let rec translate_expr ctx loc x e level : (_ * J.statement_list) Expr_builder.t
14501461 in
14511462 return (J. ENew (cc, (if List. is_empty args then None else Some args), loc))
14521463 | Extern "caml_js_get" , [ Pv o; Pc (NativeString (Utf f)) ] when J. is_ident' f ->
1453- let * co = access o in
1464+ let * co = access ~ctx o in
14541465 let * () = info mutable_p in
14551466 return (J. dot co f)
14561467 | Extern " caml_js_set" , [ Pv o; Pc (NativeString (Utf f)); v ] when J. is_ident' f
14571468 ->
1458- let * co = access o in
1469+ let * co = access ~ctx o in
14591470 let * cv = access' ~ctx v in
14601471 let * () = info mutator_p in
14611472 return (J. EBin (J. Eq , J. dot co f, cv))
14621473 | Extern " caml_js_delete" , [ Pv o; Pc (NativeString (Utf f)) ] when J. is_ident' f
14631474 ->
1464- let * co = access o in
1475+ let * co = access ~ctx o in
14651476 let * () = info mutator_p in
14661477 return (J. EUn (J. Delete , J. dot co f))
14671478 (*
@@ -1584,7 +1595,7 @@ and translate_instr ctx expr_queue loc instr =
15841595 flush_queue
15851596 expr_queue
15861597 loc
1587- (let * cy = access y in
1598+ (let * cy = access ~ctx y in
15881599 let * () = info mutator_p in
15891600 let * loc = statement_loc loc in
15901601 return [ J. Expression_statement (J. EBin (J. Eq , J. EVar (J. V x), cy)), loc ])
@@ -1625,8 +1636,8 @@ and translate_instr ctx expr_queue loc instr =
16251636 flush_queue
16261637 expr_queue
16271638 loc
1628- (let * cx = access x in
1629- let * cy = access y in
1639+ (let * cx = access ~ctx x in
1640+ let * cy = access ~ctx y in
16301641 let * () = info mutator_p in
16311642 let * loc = statement_loc loc in
16321643 return
@@ -1636,7 +1647,7 @@ and translate_instr ctx expr_queue loc instr =
16361647 flush_queue
16371648 expr_queue
16381649 loc
1639- (let * cx = access x in
1650+ (let * cx = access ~ctx x in
16401651 let expr = Mlvalue.Block. field cx 0 in
16411652 let expr' =
16421653 match n with
@@ -1652,9 +1663,9 @@ and translate_instr ctx expr_queue loc instr =
16521663 flush_queue
16531664 expr_queue
16541665 loc
1655- (let * cx = access x in
1656- let * cy = access y in
1657- let * cz = access z in
1666+ (let * cx = access ~ctx x in
1667+ let * cy = access ~ctx y in
1668+ let * cz = access ~ctx z in
16581669 let * () = info mutator_p in
16591670 let * loc = statement_loc loc in
16601671 return
@@ -1718,7 +1729,7 @@ and translate_instrs_rev (ctx : Ctx.t) loc expr_queue instrs acc_rev muts_map =
17181729 Code.Var.Set. fold
17191730 (fun v (expr_queue , vars , lets ) ->
17201731 assert (not (Code.Var.Set. mem v names));
1721- let (px, cx, locx), expr_queue = access_queue_loc expr_queue loc v in
1732+ let (px, cx, locx), expr_queue = access_queue_loc ~ctx expr_queue loc v in
17221733 let flushed = Code.Var.Set. (equal (snd px) (singleton v)) in
17231734 match
17241735 ( flushed
@@ -1760,7 +1771,9 @@ and translate_instrs_rev (ctx : Ctx.t) loc expr_queue instrs acc_rev muts_map =
17601771 match l with
17611772 | [ i ] -> mut_rec, i :: st_rev, expr_queue
17621773 | [] ->
1763- let (_px, cx, locx), expr_queue = access_queue_loc expr_queue loc x' in
1774+ let (_px, cx, locx), expr_queue =
1775+ access_queue_loc ~ctx expr_queue loc x'
1776+ in
17641777 ( mut_rec
17651778 , (J. variable_declaration [ J. V x', (cx, locx) ], locx) :: st_rev
17661779 , expr_queue )
@@ -1982,12 +1995,13 @@ and compile_conditional st queue ~fall_through loc last scope_stack : _ * _ =
19821995 | Stop -> Format. eprintf " stop;@;"
19831996 | Cond (x , _ , _ ) -> Format. eprintf " @[<hv 2>cond(%a){@;" Code.Var. print x
19841997 | Switch (x , _ ) -> Format. eprintf " @[<hv 2>switch(%a){@;" Code.Var. print x);
1998+ let ctx = st.ctx in
19851999 let res =
19862000 match last with
19872001 | Return x ->
19882002 let open Expr_builder in
19892003 let instrs =
1990- let * cx = access x in
2004+ let * cx = access ~ctx x in
19912005 let return_expr =
19922006 if Var. equal st.ctx.deadcode_sentinal x then None else Some cx
19932007 in
@@ -2008,7 +2022,7 @@ and compile_conditional st queue ~fall_through loc last scope_stack : _ * _ =
20082022 | Raise (x , k ) ->
20092023 let open Expr_builder in
20102024 let instrs =
2011- let * cx = access x in
2025+ let * cx = access ~ctx x in
20122026 let * loc = statement_loc loc in
20132027 return (throw_statement st.ctx cx k loc)
20142028 in
@@ -2063,7 +2077,9 @@ and compile_conditional st queue ~fall_through loc last scope_stack : _ * _ =
20632077 let never, code = compile_branch st J. N [] cont scope_stack ~fall_through in
20642078 never, flush_all queue loc code
20652079 | Cond (x , c1 , c2 ) ->
2066- let cx, loc_before, queue = Expr_builder. get queue loc (Expr_builder. access x) in
2080+ let cx, loc_before, queue =
2081+ Expr_builder. get queue loc (Expr_builder. access ~ctx x)
2082+ in
20672083 (* We keep track of the location [loc_before] before the
20682084 expression is evaluated and of the location after [loc]. *)
20692085 let never, b =
@@ -2079,7 +2095,9 @@ and compile_conditional st queue ~fall_through loc last scope_stack : _ * _ =
20792095 in
20802096 never, flush_all queue loc_before b
20812097 | Switch (x , a1 ) ->
2082- let cx, loc_before, queue = Expr_builder. get queue loc (Expr_builder. access x) in
2098+ let cx, loc_before, queue =
2099+ Expr_builder. get queue loc (Expr_builder. access ~ctx x)
2100+ in
20832101 (* We keep track of the location [loc_before] before the
20842102 expression is evaluated and of the location after [loc]. *)
20852103 let never, code =
@@ -2107,7 +2125,7 @@ and compile_argument_passing ctx loc queue (pc, args) back_edge continuation =
21072125 then continuation queue
21082126 else
21092127 let block = Addr.Map. find pc ctx.Ctx. blocks in
2110- parallel_renaming loc back_edge block.params args continuation queue
2128+ parallel_renaming ctx loc back_edge block.params args continuation queue
21112129
21122130and compile_branch st loc queue ((pc , _ ) as cont ) scope_stack ~fall_through : bool * _ =
21132131 let scope = List. assoc_opt pc scope_stack in
0 commit comments