Skip to content

Commit ed87247

Browse files
mshinwellpoechsel
authored andcommitted
flambda-backend: Preallocation of blocks in Translmod for value let rec w/ flambda2 (#59)
1 parent a4b04d5 commit ed87247

File tree

1 file changed

+56
-4
lines changed

1 file changed

+56
-4
lines changed

lambda/translmod.ml

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,34 @@ let record_primitive = function
212212
primitive_declarations := p :: !primitive_declarations
213213
| _ -> ()
214214

215+
(* Helper for compiling value "let rec". This is only used for Flambda 2
216+
at present, which uses the new [Dissect_letrec] module, planned to be
217+
upstreamed. At that point this helper can move into that module. *)
218+
219+
let preallocate_letrec ~bindings ~body =
220+
assert Config.flambda2;
221+
let caml_update_dummy_prim =
222+
Primitive.simple ~name:"caml_update_dummy" ~arity:2 ~alloc:true
223+
in
224+
let update_dummy var expr =
225+
Lprim (Pccall caml_update_dummy_prim, [Lvar var; expr], Loc_unknown)
226+
in
227+
let bindings = List.rev bindings in
228+
let body_with_initialization =
229+
List.fold_left
230+
(fun body (id, def, _size) -> Lsequence (update_dummy id def, body))
231+
body bindings
232+
in
233+
List.fold_left
234+
(fun body (id, _def, size) ->
235+
let desc =
236+
Primitive.simple ~name:"caml_alloc_dummy" ~arity:1 ~alloc:true
237+
in
238+
let size : lambda = Lconst (Const_base (Const_int size)) in
239+
Llet (Strict, Pgenval, id,
240+
Lprim (Pccall desc, [size], Loc_unknown), body))
241+
body_with_initialization bindings
242+
215243
(* Utilities for compiling "module rec" definitions *)
216244

217245
let mod_prim = Lambda.transl_prim "CamlinternalMod"
@@ -419,12 +447,14 @@ let compile_recmodule ~scopes compile_rhs bindings cont =
419447

420448
(* Code to translate class entries in a structure *)
421449

450+
let class_block_size = 4
451+
422452
let transl_class_bindings ~scopes cl_list =
423453
let ids = List.map (fun (ci, _) -> ci.ci_id_class) cl_list in
424454
(ids,
425455
List.map
426456
(fun ({ci_id_class=id; ci_expr=cl; ci_virt=vf}, meths) ->
427-
(id, transl_class ~scopes ids id meths cl vf))
457+
(id, transl_class ~scopes ids id meths cl vf, class_block_size))
428458
cl_list)
429459

430460
(* Compile one or more functors, merging curried functors to produce
@@ -709,7 +739,13 @@ and transl_structure ~scopes loc fields cc rootpath final_env = function
709739
transl_structure ~scopes loc (List.rev_append ids fields)
710740
cc rootpath final_env rem
711741
in
712-
Lletrec(class_bindings, body), size
742+
if Config.flambda2 then
743+
preallocate_letrec ~bindings:class_bindings ~body, size
744+
else
745+
let class_bindings =
746+
List.map (fun (id, lam, _) -> id, lam) class_bindings
747+
in
748+
Lletrec(class_bindings, body), size
713749
| Tstr_include incl ->
714750
let ids = bound_value_identifiers incl.incl_type in
715751
let modl = incl.incl_mod in
@@ -1155,8 +1191,17 @@ let transl_store_structure ~scopes glob map prims aliases str =
11551191
(add_idents true ids subst) cont rem))
11561192
| Tstr_class cl_list ->
11571193
let (ids, class_bindings) = transl_class_bindings ~scopes cl_list in
1194+
let body = store_idents Loc_unknown ids in
11581195
let lam =
1159-
Lletrec(class_bindings, store_idents Loc_unknown ids)
1196+
if Config.flambda2 then
1197+
preallocate_letrec
1198+
~bindings:class_bindings
1199+
~body
1200+
else
1201+
let class_bindings =
1202+
List.map (fun (id, lam, _) -> id, lam) class_bindings
1203+
in
1204+
Lletrec(class_bindings, body)
11601205
in
11611206
Lsequence(Lambda.subst no_env_update subst lam,
11621207
transl_store ~scopes rootpath (add_idents false ids subst)
@@ -1524,7 +1569,14 @@ let transl_toplevel_item ~scopes item =
15241569
be a value named identically *)
15251570
let (ids, class_bindings) = transl_class_bindings ~scopes cl_list in
15261571
List.iter set_toplevel_unique_name ids;
1527-
Lletrec(class_bindings, make_sequence toploop_setvalue_id ids)
1572+
let body = make_sequence toploop_setvalue_id ids in
1573+
if Config.flambda2 then
1574+
preallocate_letrec ~bindings:class_bindings ~body
1575+
else
1576+
let class_bindings =
1577+
List.map (fun (id, lam, _) -> id, lam) class_bindings
1578+
in
1579+
Lletrec(class_bindings, body)
15281580
| Tstr_include incl ->
15291581
let ids = bound_value_identifiers incl.incl_type in
15301582
let modl = incl.incl_mod in

0 commit comments

Comments
 (0)