@@ -404,10 +404,11 @@ module Inlining = struct
404
404
let callee = Apply. callee apply in
405
405
let region_inlined_into =
406
406
match Apply. call_kind apply with
407
- | Function { alloc_mode; _ } | Method { alloc_mode; _ } -> alloc_mode
408
- | C_call _ ->
407
+ | Function { alloc_mode; _ } -> alloc_mode
408
+ | Method _ | C_call _ | Effect _ ->
409
409
Misc. fatal_error
410
- " Trying to call [Closure_conversion.Inlining.inline] on a C call."
410
+ " Trying to call [Closure_conversion.Inlining.inline] on a non-OCaml \
411
+ function call."
411
412
in
412
413
let args = Apply. args apply in
413
414
let apply_return_continuation = Apply. continuation apply in
@@ -508,10 +509,7 @@ let close_c_call acc env ~loc ~let_bound_ids_with_kinds
508
509
in
509
510
let cost_metrics_of_body, free_names_of_body, acc, body =
510
511
Acc. measure_cost_metrics acc ~f: (fun acc ->
511
- k acc
512
- (List. map
513
- (fun var -> Named. create_simple (Simple. var var))
514
- let_bound_vars))
512
+ k acc (List. map Named. create_var let_bound_vars))
515
513
in
516
514
let alloc_mode =
517
515
match Lambda. alloc_mode_of_primitive_description prim_desc with
@@ -752,6 +750,82 @@ let close_raise acc env ~raise_kind ~arg ~dbg exn_continuation =
752
750
let acc, arg = find_simple acc env arg in
753
751
close_raise0 acc env ~raise_kind ~arg ~dbg exn_continuation
754
752
753
+ let close_effect_primitive acc env ~dbg exn_continuation
754
+ (prim : Lambda.primitive ) ~args ~let_bound_ids_with_kinds
755
+ (k : Acc.t -> Named.t list -> Expr_with_acc.t ) : Expr_with_acc.t =
756
+ if not Config. runtime5
757
+ then Misc. fatal_error " Effect primitives are only supported on runtime5" ;
758
+ (* CR mshinwell: share with close_c_call, above *)
759
+ let _env, let_bound_vars =
760
+ List. fold_left_map
761
+ (fun env (id , kind ) -> Env. add_var_like env id Not_user_visible kind)
762
+ env let_bound_ids_with_kinds
763
+ in
764
+ let let_bound_var =
765
+ match let_bound_vars with
766
+ | [let_bound_var] -> let_bound_var
767
+ | [] | _ :: _ :: _ ->
768
+ Misc. fatal_errorf
769
+ " close_effect_primitive: expected singleton return for primitive %a, \
770
+ but got: [%a]"
771
+ Printlambda. primitive prim
772
+ (Format. pp_print_list ~pp_sep: Format. pp_print_space Variable. print)
773
+ let_bound_vars
774
+ in
775
+ let continuation = Continuation. create () in
776
+ let return_kind = Flambda_kind.With_subkind. any_value in
777
+ let params =
778
+ [BP. create let_bound_var return_kind] |> Bound_parameters. create
779
+ in
780
+ let close call_kind =
781
+ let apply acc =
782
+ Apply_expr. create ~callee: None ~continuation: (Return continuation)
783
+ exn_continuation ~args: [] ~args_arity: Flambda_arity. nullary
784
+ ~return_arity:
785
+ (Flambda_arity. create_singletons
786
+ [Flambda_kind.With_subkind. any_value])
787
+ ~call_kind dbg ~inlined: Never_inlined
788
+ ~inlining_state: (Inlining_state. default ~round: 0 )
789
+ ~probe: None ~position: Normal
790
+ ~relative_history: Inlining_history.Relative. empty
791
+ |> Expr_with_acc. create_apply acc
792
+ in
793
+ Let_cont_with_acc. build_non_recursive acc continuation
794
+ ~handler_params: params
795
+ ~handler: (fun acc ->
796
+ let cost_metrics_of_body, free_names_of_body, acc, code_after_call =
797
+ Acc. measure_cost_metrics acc ~f: (fun acc ->
798
+ k acc (List. map Named. create_var let_bound_vars))
799
+ in
800
+ let acc =
801
+ Acc. with_cost_metrics
802
+ (Cost_metrics. ( + ) (Acc. cost_metrics acc) cost_metrics_of_body)
803
+ (Acc. with_free_names free_names_of_body acc)
804
+ in
805
+ acc, code_after_call)
806
+ ~body: apply ~is_exn_handler: false ~is_cold: false
807
+ in
808
+ let module C = Call_kind in
809
+ let module E = C. Effect in
810
+ match [@ ocaml.warning " -fragile-match" ] prim, args with
811
+ | Pperform , [[eff]] ->
812
+ let call_kind = C. effect (E. perform ~eff ) in
813
+ close call_kind
814
+ | Prunstack , [[stack]; [f]; [arg]] ->
815
+ let call_kind = C. effect (E. run_stack ~stack ~f ~arg ) in
816
+ close call_kind
817
+ | Presume , [[stack]; [f]; [arg]] ->
818
+ let call_kind = C. effect (E. resume ~stack ~f ~arg ) in
819
+ close call_kind
820
+ | Preperform , [[eff]; [cont]; [last_fiber]] ->
821
+ let call_kind = C. effect (E. reperform ~eff ~cont ~last_fiber ) in
822
+ close call_kind
823
+ | _ ->
824
+ Misc. fatal_errorf
825
+ " close_effect_primitive: Wrong primitive and/or number of arguments: %a \
826
+ (%d args)"
827
+ Printlambda. primitive prim (List. length args)
828
+
755
829
let close_primitive acc env ~let_bound_ids_with_kinds named
756
830
(prim : Lambda.primitive ) ~args loc
757
831
(exn_continuation : IR.exn_continuation option ) ~current_region
@@ -879,6 +953,17 @@ let close_primitive acc env ~let_bound_ids_with_kinds named
879
953
assert false
880
954
in
881
955
k acc [Named. create_simple (Simple. symbol sym)]
956
+ | (Pperform | Prunstack | Presume | Preperform ), args ->
957
+ let exn_continuation =
958
+ match exn_continuation with
959
+ | None ->
960
+ Misc. fatal_errorf
961
+ " Effect primitive is missing exception continuation: %a"
962
+ IR. print_named named
963
+ | Some exn_continuation -> exn_continuation
964
+ in
965
+ close_effect_primitive acc env ~dbg exn_continuation prim ~args
966
+ ~let_bound_ids_with_kinds k
882
967
| prim , args ->
883
968
Lambda_to_flambda_primitives. convert_and_bind acc exn_continuation
884
969
~big_endian: (Env. big_endian env) ~register_const0 prim ~args dbg
0 commit comments