Skip to content

Commit a3ba737

Browse files
authored
flambda-backend: Enable Stdlib.Effect + add Flambda 2 support (#2205)
1 parent 6006ee3 commit a3ba737

File tree

15 files changed

+266
-243
lines changed

15 files changed

+266
-243
lines changed

asmcomp/cmmgen.ml

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -955,17 +955,15 @@ and transl_prim_1 env p arg dbg =
955955
| Pget_header m ->
956956
box_int dbg Pnativeint m (get_header (transl env arg) dbg)
957957
| Pperform ->
958-
Misc.fatal_error "Effects-related primitives not yet supported"
959-
(* CR mshinwell: use [Runtimetags] once available
960958
let cont =
961-
make_alloc dbg cont_tag [int_const dbg 0] ~mode:Lambda.alloc_heap
959+
make_alloc dbg Runtimetags.cont_tag [int_const dbg 0]
960+
~mode:Lambda.alloc_heap
962961
in
963-
(* CR mshinwell: Rc_normal may be wrong, but this code is unlikely
964-
to be in production by then *)
965-
Cop(Capply (typ_val, Rc_normal),
962+
(* Rc_normal means "allow tailcalls". Preventing them here by using
963+
Rc_nontail improves backtraces of paused fibers. *)
964+
Cop(Capply (typ_val, Rc_nontail),
966965
[Cconst_symbol ("caml_perform", dbg); transl env arg; cont],
967966
dbg)
968-
*)
969967
| Pdls_get ->
970968
Cop(Cdls_get, [transl env arg], dbg)
971969
| Patomic_load {immediate_or_pointer = Immediate} ->
@@ -1264,35 +1262,28 @@ and transl_prim_3 env p arg1 arg2 arg3 dbg =
12641262

12651263
(* Effects *)
12661264
| Presume ->
1267-
Misc.fatal_error "Effects-related primitives not yet supported"
1268-
(*
1269-
(* CR mshinwell: Rc_normal may be wrong, but this code is unlikely
1270-
to be in production by then *)
1265+
(* Rc_normal is required here, because there are some usages of effects
1266+
with repeated resumes, and these should consume O(1) stack space by
1267+
tail-calling caml_resume. *)
12711268
Cop (Capply (typ_val, Rc_normal),
12721269
[Cconst_symbol ("caml_resume", dbg);
12731270
transl env arg1; transl env arg2; transl env arg3],
12741271
dbg)
1275-
*)
12761272
| Prunstack ->
1277-
Misc.fatal_error "Effects-related primitives not yet supported"
1278-
(*
1279-
(* CR mshinwell: Rc_normal may be wrong, but this code is unlikely
1280-
to be in production by then *)
1281-
Cop (Capply (typ_val, Rc_normal),
1273+
(* Rc_normal is fine here but unlikely to ever be a tail call (usages
1274+
of this primitive shouldn't be generated in tail position), so
1275+
we use Rc_nontail for clarity. *)
1276+
Cop (Capply (typ_val, Rc_nontail),
12821277
[Cconst_symbol ("caml_runstack", dbg);
12831278
transl env arg1; transl env arg2; transl env arg3],
12841279
dbg)
1285-
*)
12861280
| Preperform ->
1287-
Misc.fatal_error "Effects-related primitives not yet supported"
1288-
(*
1289-
(* CR mshinwell: Rc_normal may be wrong, but this code is unlikely
1290-
to be in production by then *)
1281+
(* Rc_normal is required here, this is used in tail position and should
1282+
tail call. *)
12911283
Cop (Capply (typ_val, Rc_normal),
12921284
[Cconst_symbol ("caml_reperform", dbg);
12931285
transl env arg1; transl env arg2; transl env arg3],
12941286
dbg)
1295-
*)
12961287

12971288
| Pperform | Pdls_get
12981289
| Patomic_exchange | Patomic_fetch_add | Patomic_load _

bytecomp/emitcode.ml

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,10 @@ and emit_branch_comp = function
205205
| Clt -> out opBLTINT | Cle -> out opBLEINT
206206
| Cgt -> out opBGTINT | Cge -> out opBGEINT
207207

208+
let runtime5_only () =
209+
if not Config.runtime5 then
210+
Misc.fatal_error "Effect primitives are only supported on runtime5"
211+
208212
let emit_instr = function
209213
Klabel lbl -> define_label lbl
210214
| Kacc n ->
@@ -311,17 +315,11 @@ let emit_instr = function
311315
| Kgetpubmet tag -> out opGETPUBMET; out_int tag; out_int 0
312316
| Kgetdynmet -> out opGETDYNMET
313317
| Kevent ev -> record_event ev
314-
(* CR mshinwell: enable for effects support
315-
| Kperform -> out opPERFORM
316-
| Kresume -> out opRESUME
317-
| Kresumeterm n -> out opRESUMETERM; out_int n
318-
| Kreperformterm n -> out opREPERFORMTERM; out_int n
319-
| Kstop -> out opSTOP *)
320-
| Kperform
321-
| Kresume
322-
| Kresumeterm _
323-
| Kreperformterm _
324-
| Kstop -> Misc.fatal_error "No effects support provided yet"
318+
| Kperform -> runtime5_only (); out opPERFORM
319+
| Kresume -> runtime5_only (); out opRESUME
320+
| Kresumeterm n -> runtime5_only (); out opRESUMETERM; out_int n
321+
| Kreperformterm n -> runtime5_only (); out opREPERFORMTERM; out_int n
322+
| Kstop -> out opSTOP
325323

326324
(* Emission of a list of instructions. Include some peephole optimization. *)
327325

lambda/lambda.ml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,8 @@ let primitive_may_allocate : primitive -> alloc_mode option = function
17851785
| Punbox_float _ | Punbox_int _ -> None
17861786
| Pbox_float (_, m) | Pbox_int (_, m) -> Some m
17871787
| Prunstack | Presume | Pperform | Preperform ->
1788-
Misc.fatal_error "Effects-related primitives are not yet supported"
1788+
(* CR mshinwell: check *)
1789+
Some alloc_heap
17891790
| Patomic_load _
17901791
| Patomic_exchange
17911792
| Patomic_cas
@@ -1960,9 +1961,7 @@ let primitive_result_layout (p : primitive) =
19601961
layout_any_value
19611962
| (Parray_to_iarray | Parray_of_iarray) -> layout_any_value
19621963
| Pget_header _ -> layout_boxedint Pnativeint
1963-
| Prunstack | Presume | Pperform | Preperform ->
1964-
(* CR mshinwell/ncourant: to be thought about later *)
1965-
Misc.fatal_error "Effects-related primitives are not yet supported"
1964+
| Prunstack | Presume | Pperform | Preperform -> layout_any_value
19661965
| Patomic_load { immediate_or_pointer = Immediate } -> layout_int
19671966
| Patomic_load { immediate_or_pointer = Pointer } -> layout_any_value
19681967
| Patomic_exchange

lambda/translprim.ml

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ type prim =
9494
| Identity
9595
| Apply of Lambda.region_close * Lambda.layout
9696
| Revapply of Lambda.region_close * Lambda.layout
97+
| Unsupported of Lambda.primitive
9798

9899
let units_with_used_primitives = Hashtbl.create 7
99100
let add_used_primitive loc env path =
@@ -180,6 +181,7 @@ let to_lambda_prim prim ~poly_sort =
180181
~is_layout_poly:prim.prim_is_layout_poly
181182

182183
let lookup_primitive loc ~poly_mode ~poly_sort pos p =
184+
let runtime5 = Config.runtime5 in
183185
let mode = to_locality ~poly:poly_mode p.prim_native_repr_res in
184186
let arg_modes =
185187
List.map (to_modify_mode ~poly:poly_mode) p.prim_native_repr_args
@@ -710,10 +712,14 @@ let lookup_primitive loc ~poly_mode ~poly_sort pos p =
710712
| "%atomic_exchange" -> Primitive (Patomic_exchange, 2)
711713
| "%atomic_cas" -> Primitive (Patomic_cas, 3)
712714
| "%atomic_fetch_add" -> Primitive (Patomic_fetch_add, 2)
713-
| "%runstack" -> Primitive (Prunstack, 3)
714-
| "%reperform" -> Primitive (Preperform, 3)
715-
| "%perform" -> Primitive (Pperform, 1)
716-
| "%resume" -> Primitive (Presume, 3)
715+
| "%runstack" ->
716+
if runtime5 then Primitive (Prunstack, 3) else Unsupported Prunstack
717+
| "%reperform" ->
718+
if runtime5 then Primitive (Preperform, 3) else Unsupported Preperform
719+
| "%perform" ->
720+
if runtime5 then Primitive (Pperform, 1) else Unsupported Pperform
721+
| "%resume" ->
722+
if runtime5 then Primitive (Presume, 3) else Unsupported Presume
717723
| "%dls_get" -> Primitive (Pdls_get, 1)
718724
| "%unbox_nativeint" -> Primitive(Punbox_int Pnativeint, 1)
719725
| "%box_nativeint" -> Primitive(Pbox_int (Pnativeint, mode), 1)
@@ -1268,6 +1274,21 @@ let lambda_of_prim prim_name prim loc args arg_exps =
12681274
ap_region_close = pos;
12691275
ap_mode = alloc_heap;
12701276
}
1277+
| Unsupported prim, _ ->
1278+
let exn =
1279+
transl_extension_path loc (Lazy.force Env.initial)
1280+
Predef.path_invalid_argument
1281+
in
1282+
let msg =
1283+
Format.asprintf "Unsupported primitive %a" Printlambda.primitive prim
1284+
in
1285+
Lprim (
1286+
Praise Raise_regular,
1287+
[Lprim (
1288+
Pmakeblock (0, Immutable, None, alloc_heap),
1289+
[exn; Lconst (Const_immstring msg)],
1290+
loc)],
1291+
loc)
12711292
| (Raise _ | Raise_with_backtrace
12721293
| Lazy_force _ | Loc _ | Primitive _ | Sys_argv | Comparison _
12731294
| Send _ | Send_self _ | Send_cache _ | Frame_pointers | Identity
@@ -1305,6 +1326,7 @@ let check_primitive_arity loc p =
13051326
| Frame_pointers -> p.prim_arity = 0
13061327
| Identity -> p.prim_arity = 1
13071328
| Apply _ | Revapply _ -> p.prim_arity = 2
1329+
| Unsupported _ -> true
13081330
in
13091331
if not ok then raise(Error(loc, Wrong_arity_builtin_primitive p.prim_name))
13101332

@@ -1488,7 +1510,8 @@ let primitive_needs_event_after = function
14881510
lambda_primitive_needs_event_after (comparison_primitive comp knd)
14891511
| Lazy_force _ | Send _ | Send_self _ | Send_cache _
14901512
| Apply _ | Revapply _ -> true
1491-
| Raise _ | Raise_with_backtrace | Loc _ | Frame_pointers | Identity -> false
1513+
| Raise _ | Raise_with_backtrace | Loc _ | Frame_pointers | Identity
1514+
| Unsupported _ -> false
14921515

14931516
let transl_primitive_application loc p env ty ~poly_mode ~poly_sort
14941517
path exp args arg_exps pos =

middle_end/clambda_primitives.ml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,7 @@ let result_layout (p : primitive) =
323323
Lambda.layout_any_value
324324
| Pget_header _ -> Lambda.layout_boxedint Pnativeint
325325
| Prunstack | Presume | Pperform | Preperform ->
326-
(* CR mshinwell/ncourant: to be thought about later *)
327-
Misc.fatal_error "Effects-related primitives are not yet supported"
326+
Lambda.layout_any_value
328327
| Patomic_load { immediate_or_pointer = Immediate } -> Lambda.layout_int
329328
| Patomic_load { immediate_or_pointer = Pointer } -> Lambda.layout_any_value
330329
| Patomic_exchange

runtime4/caml/instruct.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ enum instructions {
6161
EVENT, BREAK,
6262
RERAISE, RAISE_NOTRACE,
6363
GETSTRINGCHAR,
64+
PERFORM, RESUME, RESUMETERM, REPERFORMTERM,
6465
MAKE_FAUX_MIXEDBLOCK,
6566
FIRST_UNIMPLEMENTED_OP};
6667

runtime4/interp.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,6 +1223,12 @@ value caml_interprete(code_t prog, asize_t prog_size)
12231223
Restore_after_debugger;
12241224
Restart_curr_instr;
12251225

1226+
Instruct(PERFORM):
1227+
Instruct(RESUME):
1228+
Instruct(RESUMETERM):
1229+
Instruct(REPERFORMTERM):
1230+
caml_fatal_error("Effect primitives not supported on runtime4");
1231+
12261232
#ifndef THREADED_CODE
12271233
default:
12281234
#if _MSC_VER >= 1200

runtime4/misc.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,3 +273,25 @@ CAMLprim value caml_atomic_fetch_add(value ref, value incr)
273273
*p = Val_long(Long_val(ret) + Long_val(incr));
274274
return ret;
275275
}
276+
277+
// Dummy implementations so effect.ml can compile
278+
279+
CAMLprim value caml_continuation_use_noexc(void)
280+
{
281+
caml_fatal_error("Effects not implemented in runtime4");
282+
}
283+
284+
CAMLprim value caml_alloc_stack(void)
285+
{
286+
caml_fatal_error("Effects not implemented in runtime4");
287+
}
288+
289+
CAMLprim value caml_get_continuation_callstack(void)
290+
{
291+
caml_fatal_error("Effects not implemented in runtime4");
292+
}
293+
294+
CAMLprim value caml_continuation_use_and_update_handler_noexc(void)
295+
{
296+
caml_fatal_error("Effects not implemented in runtime4");
297+
}

stdlib/effect.ml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# 1 "effect.ml"
12
(**************************************************************************)
23
(* *)
34
(* OCaml *)
@@ -12,10 +13,6 @@
1213
(* *)
1314
(**************************************************************************)
1415

15-
(* CR mshinwell: To be re-enabled in due course *)
16-
17-
(*
18-
1916
type 'a t = ..
2017
external perform : 'a t -> 'a = "%perform"
2118

@@ -163,5 +160,3 @@ module Shallow = struct
163160
('a,'b) continuation -> int -> Printexc.raw_backtrace =
164161
"caml_get_continuation_callstack"
165162
end
166-
167-
*)

stdlib/effect.mli

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# 1 "effect.mli"
12
(**************************************************************************)
23
(* *)
34
(* OCaml *)
@@ -12,10 +13,6 @@
1213
(* *)
1314
(**************************************************************************)
1415

15-
(* CR mshinwell: To be re-enabled in due course *)
16-
17-
(*
18-
1916
[@@@alert unstable
2017
"The Effect interface may change in incompatible ways in the future."
2118
]
@@ -149,5 +146,3 @@ module Shallow : sig
149146
(** [get_callstack c n] returns a description of the top of the call stack on
150147
the continuation [c], with at most [n] entries. *)
151148
end
152-
153-
*)

stdlib/stdlib.ml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -608,10 +608,7 @@ module Complex = Complex
608608
module Condition = Condition
609609
module Digest = Digest
610610
module Domain = Domain
611-
(* CR ocaml 5 effects:
612-
BACKPORT
613611
module Effect = Effect
614-
*)
615612
module Either = Either
616613
module Ephemeron = Ephemeron
617614
module Filename = Filename

stdlib/stdlib.mli

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,14 +1410,10 @@ module Domain = Domain
14101410
[@@alert unstable
14111411
"The Domain interface may change in incompatible ways in the future."
14121412
]
1413-
(* CR ocaml 5 effects:
1414-
BACKPORT
14151413
module Effect = Effect
1416-
[@@alert "-unstable"]
14171414
[@@alert unstable
14181415
"The Effect interface may change in incompatible ways in the future."
14191416
]
1420-
*)
14211417
module Either = Either
14221418
module Ephemeron = Ephemeron
14231419
module Filename = Filename

0 commit comments

Comments
 (0)