@@ -36,6 +36,7 @@ module Generate (Target : Target_sig.S) = struct
3636 { live : int array
3737 ; in_cps : Effects .in_cps
3838 ; deadcode_sentinal : Var .t
39+ ; global_flow_info : Global_flow .info
3940 ; types : Typing .typ Var.Tbl .t
4041 ; blocks : block Addr.Map .t
4142 ; closures : Closure_conversion .closure Var.Map .t
@@ -784,44 +785,53 @@ module Generate (Target : Target_sig.S) = struct
784785
785786 let rec translate_expr ctx context x e =
786787 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
808810 environment. In case of partial application, we
809811 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 ]))
825835 | Block (tag , a , _ , _ ) ->
826836 Memory. allocate
827837 ~deadcode_sentinal: ctx.deadcode_sentinal
@@ -1390,6 +1400,7 @@ module Generate (Target : Target_sig.S) = struct
13901400 ~warn_on_unhandled_effect
13911401*)
13921402 ~deadcode_sentinal
1403+ ~global_flow_info
13931404 ~types =
13941405 global_context.unit_name < - unit_name;
13951406 let p, closures = Closure_conversion. f p in
@@ -1400,6 +1411,7 @@ module Generate (Target : Target_sig.S) = struct
14001411 { live = live_vars
14011412 ; in_cps
14021413 ; deadcode_sentinal
1414+ ; global_flow_info
14031415 ; types
14041416 ; blocks = p.blocks
14051417 ; closures
@@ -1512,7 +1524,17 @@ let f ~context ~unit_name p ~live_vars ~in_cps ~deadcode_sentinal ~global_flow_d
15121524 let types = Typing. f ~state ~info ~deadcode_sentinal p in
15131525 let t = Timer. make () in
15141526 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
15161538 if times () then Format. eprintf " code gen.: %a@." Timer. print t;
15171539 res
15181540
0 commit comments