Skip to content

Commit 9842eeb

Browse files
committed
Merge pull request ocaml#422 from chambart/flambda_prereq-preallocated_blocks
GPR#422: Change the interface of Cmmgen to accept preallocated blocks and constants as argument
2 parents adfa454 + 0000ac5 commit 9842eeb

File tree

7 files changed

+109
-37
lines changed

7 files changed

+109
-37
lines changed

asmcomp/asmgen.ml

+10-1
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,19 @@ let compile_unit ~source_provenance asm_filename keep_asm obj_filename gen =
125125
raise exn
126126

127127
let gen_implementation ?toplevel ~source_provenance ppf (size, lam) =
128+
let main_module_block =
129+
{
130+
Clambda.symbol = Compilenv.make_symbol None;
131+
exported = true;
132+
tag = 0;
133+
size;
134+
}
135+
in
128136
Emit.begin_assembly ();
129137
Timings.(time (Clambda source_provenance)) (Closure.intro size) lam
130138
++ clambda_dump_if ppf
131-
++ Timings.(time (Cmm source_provenance)) (Cmmgen.compunit size)
139+
++ Timings.(time (Cmm source_provenance))
140+
(fun clam -> Cmmgen.compunit (clam, [main_module_block], []))
132141
++ Timings.(time (Compile_phrases source_provenance))
133142
(List.iter (compile_phrase ppf))
134143
++ (fun () -> ());

asmcomp/clambda.ml

+15
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,21 @@ type value_approximation =
8989
| Value_const of uconstant
9090
| Value_global_field of string * int
9191

92+
(* Preallocated globals *)
93+
94+
type preallocated_block = {
95+
symbol : string;
96+
exported : bool;
97+
tag : int;
98+
size : int;
99+
}
100+
101+
type preallocated_constant = {
102+
symbol : string;
103+
exported : bool;
104+
definition : ustructured_constant;
105+
}
106+
92107
(* Comparison functions for constants. We must not use Pervasives.compare
93108
because it compares "0.0" and "-0.0" equal. (PR#6442) *)
94109

asmcomp/clambda.mli

+13
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,16 @@ val compare_structured_constants:
9595
ustructured_constant -> ustructured_constant -> int
9696
val compare_constants:
9797
uconstant -> uconstant -> int
98+
99+
type preallocated_block = {
100+
symbol : string;
101+
exported : bool;
102+
tag : int;
103+
size : int;
104+
}
105+
106+
type preallocated_constant = {
107+
symbol : string;
108+
exported : bool;
109+
definition : ustructured_constant;
110+
}

asmcomp/cmmgen.ml

+58-31
Original file line numberDiff line numberDiff line change
@@ -740,8 +740,10 @@ let transl_structured_constant cst =
740740

741741
(* Translate constant closures *)
742742

743+
type is_global = Global | Not_global
744+
743745
let constant_closures =
744-
ref ([] : (string * ufunction list * uconstant list) list)
746+
ref ([] : ((string * is_global) * ufunction list * uconstant list) list)
745747

746748
(* Boxed integers *)
747749

@@ -1423,7 +1425,7 @@ let rec transl env e =
14231425
transl_constant sc
14241426
| Uclosure(fundecls, []) ->
14251427
let lbl = Compilenv.new_const_symbol() in
1426-
constant_closures := (lbl, fundecls, []) :: !constant_closures;
1428+
constant_closures := ((lbl, Not_global), fundecls, []) :: !constant_closures;
14271429
List.iter (fun f -> Queue.add f functions) fundecls;
14281430
Cconst_symbol lbl
14291431
| Uclosure(fundecls, clos_vars) ->
@@ -2426,14 +2428,19 @@ let rec transl_all_functions already_translated cont =
24262428
with Queue.Empty ->
24272429
cont, already_translated
24282430

2431+
let cdefine_symbol (symb, global) =
2432+
match global with
2433+
| Global -> [Cglobal_symbol symb; Cdefine_symbol symb]
2434+
| Not_global -> [Cdefine_symbol symb]
2435+
24292436
(* Emit structured constants *)
24302437

24312438
let rec emit_structured_constant symb cst cont =
24322439
let emit_block white_header symb cont =
24332440
(* Headers for structured constants must be marked black in case we
24342441
are in no-naked-pointers mode. See [caml_darken]. *)
24352442
let black_header = Nativeint.logor white_header caml_black in
2436-
Cint black_header :: Cdefine_symbol symb :: cont
2443+
Cint black_header :: cdefine_symbol symb @ cont
24372444
in
24382445
match cst with
24392446
| Uconst_float s->
@@ -2457,7 +2464,8 @@ let rec emit_structured_constant symb cst cont =
24572464
emit_block (floatarray_header (List.length fields)) symb
24582465
(Misc.map_end (fun f -> Cdouble f) fields cont)
24592466
| Uconst_closure(fundecls, lbl, fv) ->
2460-
constant_closures := (lbl, fundecls, fv) :: !constant_closures;
2467+
assert(lbl = fst symb);
2468+
constant_closures := (symb, fundecls, fv) :: !constant_closures;
24612469
List.iter (fun f -> Queue.add f functions) fundecls;
24622470
cont
24632471

@@ -2518,7 +2526,7 @@ let emit_constant_closure symb fundecls clos_vars cont =
25182526
emit_others (pos + 4) rem in
25192527
Cint(black_closure_header (fundecls_size fundecls
25202528
+ List.length clos_vars)) ::
2521-
Cdefine_symbol symb ::
2529+
cdefine_symbol symb @
25222530
if f1.arity = 1 || f1.arity = 0 then
25232531
Csymbol_address f1.label ::
25242532
cint_const f1.arity ::
@@ -2531,24 +2539,26 @@ let emit_constant_closure symb fundecls clos_vars cont =
25312539

25322540
(* Emit all structured constants *)
25332541

2534-
let emit_all_constants cont =
2542+
let emit_constants cont (constants:Clambda.preallocated_constant list) =
25352543
let c = ref cont in
25362544
List.iter
2537-
(fun (lbl, global, cst) ->
2538-
let cst = emit_structured_constant lbl cst [] in
2539-
let cst = if global then
2540-
Cglobal_symbol lbl :: cst
2541-
else cst in
2545+
(fun { symbol = lbl; exported; definition = cst } ->
2546+
let global = if exported then Global else Not_global in
2547+
let cst = emit_structured_constant (lbl, global) cst [] in
25422548
c:= Cdata(cst):: !c)
2543-
(Compilenv.structured_constants());
2549+
constants;
25442550
List.iter
25452551
(fun (symb, fundecls, clos_vars) ->
25462552
c := Cdata(emit_constant_closure symb fundecls clos_vars []) :: !c)
25472553
!constant_closures;
25482554
constant_closures := [];
2549-
Compilenv.clear_structured_constants ();
25502555
!c
25512556

2557+
let emit_all_constants cont =
2558+
let constants = Compilenv.structured_constants () in
2559+
Compilenv.clear_structured_constants ();
2560+
emit_constants cont constants
2561+
25522562
let transl_all_functions_and_emit_all_constants cont =
25532563
let rec aux already_translated cont =
25542564
if Compilenv.structured_constants () = [] &&
@@ -2571,17 +2581,10 @@ let emit_module_roots_table ~symbols cont =
25712581
[Cint 0n])
25722582
:: cont
25732583

2574-
(* Translate a compilation unit *)
2584+
(* Build preallocated blocks (used for Flambda [Initialize_symbol]
2585+
constructs, and Clambda global module) *)
25752586

2576-
let compunit size ulam =
2577-
let glob = Compilenv.make_symbol None in
2578-
let init_code = transl empty_env ulam in
2579-
let c1 = [Cfunction {fun_name = Compilenv.make_symbol (Some "entry");
2580-
fun_args = [];
2581-
fun_body = init_code; fun_fast = false;
2582-
fun_dbg = Debuginfo.none }] in
2583-
let c2 = transl_all_functions_and_emit_all_constants c1 in
2584-
let c3 = emit_module_roots_table ~symbols:[glob] c2 in
2587+
let preallocate_block cont { Clambda.symbol; exported; tag; size } =
25852588
let space =
25862589
(* These words will be registered as roots and as such must contain
25872590
valid values, in case we are in no-naked-pointers mode. Likewise
@@ -2591,9 +2594,35 @@ let compunit size ulam =
25912594
(Array.init size (fun _index ->
25922595
Cint (Nativeint.of_int 1 (* Val_unit *))))
25932596
in
2594-
Cdata ([Cint(black_block_header 0 size);
2595-
Cglobal_symbol glob;
2596-
Cdefine_symbol glob] @ space) :: c3
2597+
let data =
2598+
Cint(black_block_header tag size) ::
2599+
if exported then
2600+
Cglobal_symbol symbol ::
2601+
Cdefine_symbol symbol :: space
2602+
else
2603+
Cdefine_symbol symbol :: space
2604+
in
2605+
Cdata data :: cont
2606+
2607+
let emit_preallocated_blocks preallocated_blocks cont =
2608+
let symbols =
2609+
List.map (fun ({ Clambda.symbol }:Clambda.preallocated_block) -> symbol)
2610+
preallocated_blocks
2611+
in
2612+
let c1 = emit_module_roots_table ~symbols cont in
2613+
List.fold_left preallocate_block c1 preallocated_blocks
2614+
2615+
(* Translate a compilation unit *)
2616+
2617+
let compunit (ulam, preallocated_blocks, constants) =
2618+
let init_code = transl empty_env ulam in
2619+
let c1 = [Cfunction {fun_name = Compilenv.make_symbol (Some "entry");
2620+
fun_args = [];
2621+
fun_body = init_code; fun_fast = false;
2622+
fun_dbg = Debuginfo.none }] in
2623+
let c2 = emit_constants c1 constants in
2624+
let c3 = transl_all_functions_and_emit_all_constants c2 in
2625+
emit_preallocated_blocks preallocated_blocks c3
25972626

25982627
(*
25992628
CAMLprim value caml_cache_public_method (value meths, value tag, value *cache)
@@ -2938,8 +2967,7 @@ let reference_symbols namelist =
29382967
Cdata(List.map mksym namelist)
29392968

29402969
let global_data name v =
2941-
Cdata(Cglobal_symbol name ::
2942-
emit_structured_constant name
2970+
Cdata(emit_structured_constant (name, Global)
29432971
(Uconst_string (Marshal.to_string v [])) [])
29442972

29452973
let globals_map v = global_data "caml_globals_map" v
@@ -2979,9 +3007,8 @@ let predef_exception i name =
29793007
let symname = "caml_exn_" ^ name in
29803008
let cst = Uconst_string name in
29813009
let label = Compilenv.new_const_symbol () in
2982-
let cont = emit_structured_constant label cst [] in
2983-
Cdata(Cglobal_symbol symname ::
2984-
emit_structured_constant symname
3010+
let cont = emit_structured_constant (label, Not_global) cst [] in
3011+
Cdata(emit_structured_constant (symname, Global)
29853012
(Uconst_block(Obj.object_tag,
29863013
[
29873014
Uconst_ref(label, Some cst);

asmcomp/cmmgen.mli

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212

1313
(* Translation from closed lambda to C-- *)
1414

15-
val compunit: int -> Clambda.ulambda -> Cmm.phrase list
15+
val compunit:
16+
Clambda.ulambda
17+
* Clambda.preallocated_block list
18+
* Clambda.preallocated_constant list
19+
-> Cmm.phrase list
1620

1721
val apply_function: int -> Cmm.phrase
1822
val send_function: int -> Cmm.phrase

asmcomp/compilenv.ml

+7-3
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,13 @@ let clear_structured_constants () =
294294

295295
let structured_constants () =
296296
List.map
297-
(fun (lbl, cst) ->
298-
(lbl, Hashtbl.mem exported_constants lbl, cst)
299-
) (!structured_constants).strcst_all
297+
(fun (symbol, definition) ->
298+
{
299+
Clambda.symbol;
300+
exported = Hashtbl.mem exported_constants symbol;
301+
definition;
302+
})
303+
(!structured_constants).strcst_all
300304

301305
(* Error report *)
302306

asmcomp/compilenv.mli

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ val new_structured_constant:
6565
shared:bool -> (* can be shared with another structually equal constant *)
6666
string
6767
val structured_constants:
68-
unit -> (string * bool * Clambda.ustructured_constant) list
68+
unit -> Clambda.preallocated_constant list
6969
val clear_structured_constants: unit -> unit
7070
val add_exported_constant: string -> unit
7171

0 commit comments

Comments
 (0)