@@ -535,14 +535,25 @@ type queue_elt =
535
535
; deps : Code.Var.Set .t
536
536
}
537
537
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
543
554
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
546
557
(prop, c, Option. value ~default: loc' loc), queue
547
558
548
559
let should_flush (cond , _ ) prop = cond <> fst const_p && cond + prop > = fst flush_p
@@ -585,7 +596,7 @@ module Expr_builder : sig
585
596
586
597
val return : 'a -> 'a t
587
598
588
- val access : Var .t -> J .expression t
599
+ val access : ctx : Ctx . t -> Var .t -> J .expression t
589
600
590
601
val access' : ctx :Ctx .t -> prim_arg -> J .expression t
591
602
@@ -627,8 +638,8 @@ end = struct
627
638
let info ?(need_loc = false ) prop st =
628
639
() , { st with prop = or_p st.prop prop; need_loc = need_loc || st.need_loc }
629
640
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
632
643
( c
633
644
, { st with
634
645
prop = or_p st.prop prop
@@ -646,7 +657,7 @@ end = struct
646
657
assert (List. is_empty instrs);
647
658
(* We only have simple constants here *)
648
659
fun st -> js, st
649
- | Pv x -> access x
660
+ | Pv x -> access ~ctx x
650
661
651
662
let statement_loc loc st =
652
663
( (match st.loc with
@@ -859,7 +870,7 @@ let visit_all params args =
859
870
in
860
871
l
861
872
862
- let parallel_renaming loc back_edge params args continuation queue =
873
+ let parallel_renaming ctx loc back_edge params args continuation queue =
863
874
if
864
875
back_edge && Config.Flag. es6 ()
865
876
(* This is likely slower than using explicit temp variable
@@ -877,7 +888,7 @@ let parallel_renaming loc back_edge params args continuation queue =
877
888
loc
878
889
(List. fold_left args ~init: (return [] ) ~f: (fun acc a ->
879
890
let * acc = acc in
880
- let * cx = access a in
891
+ let * cx = access ~ctx a in
881
892
return (cx :: acc)))
882
893
in
883
894
let never, code = continuation queue in
@@ -900,7 +911,7 @@ let parallel_renaming loc back_edge params args continuation queue =
900
911
l
901
912
~init: (queue, [] , [] , Code.Var.Set. empty)
902
913
~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
904
915
let seen' = Code.Var.Set. add y seen in
905
916
if not Code.Var.Set. (is_empty (inter seen deps_x))
906
917
then
@@ -1326,14 +1337,14 @@ let rec translate_expr ctx loc x e level : (_ * J.statement_list) Expr_builder.t
1326
1337
let args = remove_unused_tail_args ctx exact trampolined args in
1327
1338
let * () = info ~need_loc: true mutator_p in
1328
1339
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
1331
1342
return (apply_fun ctx f args exact trampolined in_cps loc, [] )
1332
1343
| Block (tag , a , array_or_not , _mut ) ->
1333
1344
let * contents =
1334
1345
list_map
1335
1346
(fun x ->
1336
- let * cx = access x in
1347
+ let * cx = access ~ctx x in
1337
1348
let cx =
1338
1349
match cx with
1339
1350
| J. EVar (J. V v ) ->
@@ -1352,7 +1363,7 @@ let rec translate_expr ctx loc x e level : (_ * J.statement_list) Expr_builder.t
1352
1363
in
1353
1364
return (x, [] )
1354
1365
| Field (x , n , _ ) ->
1355
- let * cx = access x in
1366
+ let * cx = access ~ctx x in
1356
1367
let * () = info mutable_p in
1357
1368
return (Mlvalue.Block. field cx n, [] )
1358
1369
| 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
1450
1461
in
1451
1462
return (J. ENew (cc, (if List. is_empty args then None else Some args), loc))
1452
1463
| 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
1454
1465
let * () = info mutable_p in
1455
1466
return (J. dot co f)
1456
1467
| Extern " caml_js_set" , [ Pv o; Pc (NativeString (Utf f)); v ] when J. is_ident' f
1457
1468
->
1458
- let * co = access o in
1469
+ let * co = access ~ctx o in
1459
1470
let * cv = access' ~ctx v in
1460
1471
let * () = info mutator_p in
1461
1472
return (J. EBin (J. Eq , J. dot co f, cv))
1462
1473
| Extern " caml_js_delete" , [ Pv o; Pc (NativeString (Utf f)) ] when J. is_ident' f
1463
1474
->
1464
- let * co = access o in
1475
+ let * co = access ~ctx o in
1465
1476
let * () = info mutator_p in
1466
1477
return (J. EUn (J. Delete , J. dot co f))
1467
1478
(*
@@ -1584,7 +1595,7 @@ and translate_instr ctx expr_queue loc instr =
1584
1595
flush_queue
1585
1596
expr_queue
1586
1597
loc
1587
- (let * cy = access y in
1598
+ (let * cy = access ~ctx y in
1588
1599
let * () = info mutator_p in
1589
1600
let * loc = statement_loc loc in
1590
1601
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 =
1625
1636
flush_queue
1626
1637
expr_queue
1627
1638
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
1630
1641
let * () = info mutator_p in
1631
1642
let * loc = statement_loc loc in
1632
1643
return
@@ -1636,7 +1647,7 @@ and translate_instr ctx expr_queue loc instr =
1636
1647
flush_queue
1637
1648
expr_queue
1638
1649
loc
1639
- (let * cx = access x in
1650
+ (let * cx = access ~ctx x in
1640
1651
let expr = Mlvalue.Block. field cx 0 in
1641
1652
let expr' =
1642
1653
match n with
@@ -1652,9 +1663,9 @@ and translate_instr ctx expr_queue loc instr =
1652
1663
flush_queue
1653
1664
expr_queue
1654
1665
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
1658
1669
let * () = info mutator_p in
1659
1670
let * loc = statement_loc loc in
1660
1671
return
@@ -1718,7 +1729,7 @@ and translate_instrs_rev (ctx : Ctx.t) loc expr_queue instrs acc_rev muts_map =
1718
1729
Code.Var.Set. fold
1719
1730
(fun v (expr_queue , vars , lets ) ->
1720
1731
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
1722
1733
let flushed = Code.Var.Set. (equal (snd px) (singleton v)) in
1723
1734
match
1724
1735
( flushed
@@ -1760,7 +1771,9 @@ and translate_instrs_rev (ctx : Ctx.t) loc expr_queue instrs acc_rev muts_map =
1760
1771
match l with
1761
1772
| [ i ] -> mut_rec, i :: st_rev, expr_queue
1762
1773
| [] ->
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
1764
1777
( mut_rec
1765
1778
, (J. variable_declaration [ J. V x', (cx, locx) ], locx) :: st_rev
1766
1779
, expr_queue )
@@ -1982,12 +1995,13 @@ and compile_conditional st queue ~fall_through loc last scope_stack : _ * _ =
1982
1995
| Stop -> Format. eprintf " stop;@;"
1983
1996
| Cond (x , _ , _ ) -> Format. eprintf " @[<hv 2>cond(%a){@;" Code.Var. print x
1984
1997
| Switch (x , _ ) -> Format. eprintf " @[<hv 2>switch(%a){@;" Code.Var. print x);
1998
+ let ctx = st.ctx in
1985
1999
let res =
1986
2000
match last with
1987
2001
| Return x ->
1988
2002
let open Expr_builder in
1989
2003
let instrs =
1990
- let * cx = access x in
2004
+ let * cx = access ~ctx x in
1991
2005
let return_expr =
1992
2006
if Var. equal st.ctx.deadcode_sentinal x then None else Some cx
1993
2007
in
@@ -2008,7 +2022,7 @@ and compile_conditional st queue ~fall_through loc last scope_stack : _ * _ =
2008
2022
| Raise (x , k ) ->
2009
2023
let open Expr_builder in
2010
2024
let instrs =
2011
- let * cx = access x in
2025
+ let * cx = access ~ctx x in
2012
2026
let * loc = statement_loc loc in
2013
2027
return (throw_statement st.ctx cx k loc)
2014
2028
in
@@ -2063,7 +2077,9 @@ and compile_conditional st queue ~fall_through loc last scope_stack : _ * _ =
2063
2077
let never, code = compile_branch st J. N [] cont scope_stack ~fall_through in
2064
2078
never, flush_all queue loc code
2065
2079
| 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
2067
2083
(* We keep track of the location [loc_before] before the
2068
2084
expression is evaluated and of the location after [loc]. *)
2069
2085
let never, b =
@@ -2079,7 +2095,9 @@ and compile_conditional st queue ~fall_through loc last scope_stack : _ * _ =
2079
2095
in
2080
2096
never, flush_all queue loc_before b
2081
2097
| 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
2083
2101
(* We keep track of the location [loc_before] before the
2084
2102
expression is evaluated and of the location after [loc]. *)
2085
2103
let never, code =
@@ -2107,7 +2125,7 @@ and compile_argument_passing ctx loc queue (pc, args) back_edge continuation =
2107
2125
then continuation queue
2108
2126
else
2109
2127
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
2111
2129
2112
2130
and compile_branch st loc queue ((pc , _ ) as cont ) scope_stack ~fall_through : bool * _ =
2113
2131
let scope = List. assoc_opt pc scope_stack in
0 commit comments