@@ -36,6 +36,7 @@ module Generate (Target : Target_sig.S) = struct
36
36
{ live : int array
37
37
; in_cps : Effects .in_cps
38
38
; deadcode_sentinal : Var .t
39
+ ; global_flow_info : Global_flow .info
39
40
; types : Typing .typ Var.Tbl .t
40
41
; blocks : block Addr.Map .t
41
42
; closures : Closure_conversion .closure Var.Map .t
@@ -784,44 +785,53 @@ module Generate (Target : Target_sig.S) = struct
784
785
785
786
let rec translate_expr ctx context x e =
786
787
match e with
787
- | Apply { f; args; exact }
788
- when exact || List. length args = if Var.Set. mem x ctx.in_cps then 2 else 1 ->
789
- let rec loop acc l =
790
- match l with
791
- | [] -> (
792
- let arity = List. length args in
793
- let funct = Var. fresh () in
794
- let * closure = tee funct (load f) in
795
- let * ty, funct =
796
- Memory. load_function_pointer
797
- ~cps: (Var.Set. mem x ctx.in_cps)
798
- ~arity
799
- (load funct)
800
- in
801
- let * b = is_closure f in
802
- if b
803
- then return (W. Call (f, List. rev (closure :: acc)))
804
- else
805
- match funct with
806
- | W. RefFunc g ->
807
- (* Functions with constant closures ignore their
788
+ | Apply { f; args; exact; _ } ->
789
+ if exact || List. length args = if Var.Set. mem x ctx.in_cps then 2 else 1
790
+ then
791
+ let rec loop acc l =
792
+ match l with
793
+ | [] -> (
794
+ let arity = List. length args in
795
+ let funct = Var. fresh () in
796
+ let * closure = tee funct (load f) in
797
+ let * ty, funct =
798
+ Memory. load_function_pointer
799
+ ~cps: (Var.Set. mem x ctx.in_cps)
800
+ ~arity
801
+ (load funct)
802
+ in
803
+ let * b = is_closure f in
804
+ if b
805
+ then return (W. Call (f, List. rev (closure :: acc)))
806
+ else
807
+ match funct with
808
+ | W. RefFunc g ->
809
+ (* Functions with constant closures ignore their
808
810
environment. In case of partial application, we
809
811
still need the closure. *)
810
- let * cl = if exact then Value. unit else return closure in
811
- return (W. Call (g, List. rev (cl :: acc)))
812
- | _ -> return (W. Call_ref (ty, funct, List. rev (closure :: acc))))
813
- | x :: r ->
814
- let * x = load_and_box ctx x in
815
- loop (x :: acc) r
816
- in
817
- loop [] args
818
- | Apply { f; args; _ } ->
819
- let * apply =
820
- need_apply_fun ~cps: (Var.Set. mem x ctx.in_cps) ~arity: (List. length args)
821
- in
822
- let * args = expression_list (fun x -> load_and_box ctx x) args in
823
- let * closure = load f in
824
- return (W. Call (apply, args @ [ closure ]))
812
+ let * cl = if exact then Value. unit else return closure in
813
+ return (W. Call (g, List. rev (cl :: acc)))
814
+ | _ -> (
815
+ match
816
+ if exact
817
+ then Global_flow. get_unique_closure ctx.global_flow_info f
818
+ else None
819
+ with
820
+ | Some g -> return (W. Call (g, List. rev (closure :: acc)))
821
+ | None -> return (W. Call_ref (ty, funct, List. rev (closure :: acc)))
822
+ ))
823
+ | x :: r ->
824
+ let * x = load_and_box ctx x in
825
+ loop (x :: acc) r
826
+ in
827
+ loop [] args
828
+ else
829
+ let * apply =
830
+ need_apply_fun ~cps: (Var.Set. mem x ctx.in_cps) ~arity: (List. length args)
831
+ in
832
+ let * args = expression_list (fun x -> load_and_box ctx x) args in
833
+ let * closure = load f in
834
+ return (W. Call (apply, args @ [ closure ]))
825
835
| Block (tag , a , _ , _ ) ->
826
836
Memory. allocate
827
837
~deadcode_sentinal: ctx.deadcode_sentinal
@@ -1390,6 +1400,7 @@ module Generate (Target : Target_sig.S) = struct
1390
1400
~warn_on_unhandled_effect
1391
1401
*)
1392
1402
~deadcode_sentinal
1403
+ ~global_flow_info
1393
1404
~types =
1394
1405
global_context.unit_name < - unit_name;
1395
1406
let p, closures = Closure_conversion. f p in
@@ -1400,6 +1411,7 @@ module Generate (Target : Target_sig.S) = struct
1400
1411
{ live = live_vars
1401
1412
; in_cps
1402
1413
; deadcode_sentinal
1414
+ ; global_flow_info
1403
1415
; types
1404
1416
; blocks = p.blocks
1405
1417
; closures
@@ -1512,7 +1524,17 @@ let f ~context ~unit_name p ~live_vars ~in_cps ~deadcode_sentinal ~global_flow_d
1512
1524
let types = Typing. f ~state ~info ~deadcode_sentinal p in
1513
1525
let t = Timer. make () in
1514
1526
let p = fix_switch_branches p in
1515
- let res = G. f ~context ~unit_name ~live_vars ~in_cps ~deadcode_sentinal ~types p in
1527
+ let res =
1528
+ G. f
1529
+ ~context
1530
+ ~unit_name
1531
+ ~live_vars
1532
+ ~in_cps
1533
+ ~deadcode_sentinal
1534
+ ~global_flow_info: info
1535
+ ~types
1536
+ p
1537
+ in
1516
1538
if times () then Format. eprintf " code gen.: %a@." Timer. print t;
1517
1539
res
1518
1540
0 commit comments