Skip to content

Commit b609f96

Browse files
committed
Squash of 'instantiate' into upstream/main
Tip of 'instantiate' (#1905) as of commit 5afb940. This cherry-pick effectively merges #1872, #1873, #1726, and #1905 onto the 5.1.1minus-18 release (previous cherry-picks already added #1841 and #1846).
1 parent 319449b commit b609f96

File tree

139 files changed

+4401
-535
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

139 files changed

+4401
-535
lines changed

backend/amd64/proc.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ let extension_regs (type a) ?prefix (ext : a Language_extension.t) () =
174174
| Small_numbers -> hard_float32_reg ()
175175
| Mode | Unique | Include_functor | Comprehensions
176176
| Polymorphic_parameters | Immutable_arrays
177-
| Module_strengthening | Layouts | Labeled_tuples -> [||]
177+
| Module_strengthening | Layouts | Labeled_tuples | Instances -> [||]
178178
in match prefix with
179179
| None -> regs
180180
| Some p -> Array.sub regs 0 (Int.min p (Array.length regs))

backend/asminstantiator.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
let read_unit_info file : Instantiator.unit_info =
2+
let unit_info, _crc = Compilenv.read_unit_info file in
3+
let { Cmx_format.ui_unit; ui_arg_descr; ui_format; _ } = unit_info in
4+
{ Instantiator.ui_unit; ui_arg_descr; ui_format; }
5+
6+
let instantiate unix ~src ~args targetcmx ~flambda2 =
7+
Instantiator.instantiate ~src ~args targetcmx
8+
~expected_extension:".cmx"
9+
~read_unit_info
10+
~compile:(Optcompile.instance unix ~flambda2 ~keep_symbol_tables:false)

backend/asminstantiator.mli

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
val instantiate
2+
: (module Compiler_owee.Unix_intf.S)
3+
-> src:string
4+
-> args:string list
5+
-> string
6+
-> flambda2:(
7+
ppf_dump:Format.formatter ->
8+
prefixname:string ->
9+
filename:string ->
10+
keep_symbol_tables:bool ->
11+
Lambda.program ->
12+
Cmm.phrase list)
13+
-> unit

backend/asmpackager.ml

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,18 @@ let make_package_object unix ~ppf_dump members targetobj targetname coercion
128128
~style:transl_style
129129
in
130130
let code = Simplif.simplify_lambda code in
131+
let module_block_format : Lambda.module_block_format =
132+
Mb_record { mb_size = main_module_block_size }
133+
in
134+
let arg_block_field =
135+
(* Packs not supported as argument modules *)
136+
None
137+
in
131138
let program =
132139
{ Lambda.
133140
code;
134-
main_module_block_size;
141+
module_block_format;
142+
arg_block_field;
135143
compilation_unit;
136144
required_globals;
137145
}
@@ -152,12 +160,13 @@ let make_package_object unix ~ppf_dump members targetobj targetname coercion
152160
Ccomp.call_linker Ccomp.Partial targetobj (objtemp :: objfiles) ""
153161
in
154162
remove_file objtemp;
155-
if not (exitcode = 0) then raise(Error Linking_error)
163+
if not (exitcode = 0) then raise(Error Linking_error);
164+
main_module_block_size
156165
)
157166

158167
(* Make the .cmx file for the package *)
159168

160-
let build_package_cmx members cmxfile =
169+
let build_package_cmx members cmxfile ~main_module_block_size =
161170
let unit_names =
162171
List.map (fun m -> m.pm_name) members in
163172
let filter lst =
@@ -184,17 +193,23 @@ let build_package_cmx members cmxfile =
184193
List.iter (fun info -> Zero_alloc_info.merge info.ui_zero_alloc_info
185194
~into:ui_zero_alloc_info) units;
186195
let modname = Compilation_unit.name ui.ui_unit in
196+
let format : Lambda.module_block_format =
197+
(* Open modules not supported with packs, so always just a record *)
198+
Mb_record { mb_size = main_module_block_size }
199+
in
187200
let pkg_infos =
188201
{ ui_unit = ui.ui_unit;
189202
ui_defines =
190203
List.flatten (List.map (fun info -> info.ui_defines) units) @
191204
[ui.ui_unit];
205+
ui_arg_descr = None;
192206
ui_imports_cmi =
193207
(Import_info.create modname
194208
~crc_with_unit:(Some (ui.ui_unit, Env.crc_of_unit modname))) ::
195209
filter (Asmlink.extract_crc_interfaces ());
196210
ui_imports_cmx =
197211
filter(Asmlink.extract_crc_implementations());
212+
ui_format = format;
198213
ui_generic_fns =
199214
{ curry_fun =
200215
union(List.map (fun info -> info.ui_generic_fns.curry_fun) units);
@@ -221,9 +236,11 @@ let package_object_files unix ~ppf_dump files targetcmx
221236
in
222237
let members = map_left_right (read_member_info pack_path) files in
223238
check_units members;
224-
make_package_object unix ~ppf_dump members targetobj targetname coercion
225-
~flambda2;
226-
build_package_cmx members targetcmx
239+
let main_module_block_size =
240+
make_package_object unix ~ppf_dump members targetobj targetname coercion
241+
~flambda2
242+
in
243+
build_package_cmx members targetcmx ~main_module_block_size
227244

228245
(* The entry point *)
229246

driver/optcompile.ml

Lines changed: 116 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,36 +23,55 @@ let tool_name = "ocamlopt"
2323
let with_info = Compile_common.with_info ~native:true ~tool_name
2424

2525
let interface ~source_file ~output_prefix =
26-
with_info ~source_file ~output_prefix ~dump_ext:"cmi" @@ fun info ->
26+
with_info ~source_file ~output_prefix ~dump_ext:"cmi"
27+
~compilation_unit:Inferred_from_output_prefix
28+
@@ fun info ->
2729
Compile_common.interface
2830
~hook_parse_tree:(Compiler_hooks.execute Compiler_hooks.Parse_tree_intf)
2931
~hook_typed_tree:(Compiler_hooks.execute Compiler_hooks.Typed_tree_intf)
3032
info
3133

3234
(** Native compilation backend for .ml files. *)
3335

34-
let compile i typed ~transl_style ~unix ~pipeline =
35-
typed
36-
|> Profile.(record transl)
37-
(Translmod.transl_implementation i.module_name ~style:transl_style)
36+
let make_arg_descr ~param ~arg_block_field : Lambda.arg_descr option =
37+
match param, arg_block_field with
38+
| Some arg_param, Some arg_block_field -> Some { arg_param; arg_block_field }
39+
| None, None -> None
40+
| Some _, None -> Misc.fatal_error "No argument field"
41+
| None, Some _ -> Misc.fatal_error "Unexpected argument field"
42+
43+
let compile_from_raw_lambda i raw_lambda ~unix ~pipeline ~as_arg_for =
44+
raw_lambda
3845
|> print_if i.ppf_dump Clflags.dump_rawlambda Printlambda.program
3946
|> Compiler_hooks.execute_and_pipe Compiler_hooks.Raw_lambda
4047
|> Profile.(record generate)
41-
(fun program ->
48+
(fun (program : Lambda.program) ->
4249
Builtin_attributes.warn_unused ();
4350
let code = Simplif.simplify_lambda program.Lambda.code in
4451
{ program with Lambda.code }
4552
|> print_if i.ppf_dump Clflags.dump_lambda Printlambda.program
4653
|> Compiler_hooks.execute_and_pipe Compiler_hooks.Lambda
47-
|> (fun program ->
54+
|> (fun (program : Lambda.program) ->
4855
Asmgen.compile_implementation
4956
unix
5057
~pipeline
5158
~filename:i.source_file
5259
~prefixname:i.output_prefix
5360
~ppf_dump:i.ppf_dump
5461
program);
55-
Compilenv.save_unit_info (cmx i))
62+
let arg_descr =
63+
make_arg_descr ~param:as_arg_for
64+
~arg_block_field:program.arg_block_field
65+
in
66+
Compilenv.save_unit_info (cmx i)
67+
~module_block_format:program.module_block_format
68+
~arg_descr)
69+
70+
let compile_from_typed i typed ~transl_style ~unix ~pipeline ~as_arg_for =
71+
typed
72+
|> Profile.(record transl)
73+
(Translmod.transl_implementation i.module_name ~style:transl_style)
74+
|> compile_from_raw_lambda i ~unix ~pipeline ~as_arg_for
5675

5776
type flambda2 =
5877
ppf_dump:Format.formatter ->
@@ -68,31 +87,106 @@ let emit unix i =
6887
Asmgen.compile_implementation_linear unix
6988
i.output_prefix ~progname:i.source_file
7089

71-
let implementation unix ~(flambda2 : flambda2) ~start_from ~source_file
72-
~output_prefix ~keep_symbol_tables =
73-
let backend info ({ structure; coercion; _ } : Typedtree.implementation) =
90+
type starting_point =
91+
| Parsing
92+
| Emit
93+
| Instantiation of {
94+
runtime_args : Translmod.runtime_arg list;
95+
main_module_block_size : int;
96+
arg_descr : Lambda.arg_descr option;
97+
}
98+
99+
let starting_point_of_compiler_pass start_from =
100+
match (start_from:Clflags.Compiler_pass.t) with
101+
| Parsing -> Parsing
102+
| Emit -> Emit
103+
| _ -> Misc.fatal_errorf "Cannot start from %s"
104+
(Clflags.Compiler_pass.to_string start_from)
105+
106+
let implementation0 unix ~(flambda2 : flambda2) ~start_from
107+
~source_file ~output_prefix ~keep_symbol_tables
108+
~(compilation_unit : Compile_common.compilation_unit_or_inferred) =
109+
let transl_style : Translmod.compilation_unit_style =
110+
if Config.flambda || Config.flambda2 then Plain_block
111+
else Set_individual_fields
112+
in
113+
let pipeline : Asmgen.pipeline =
114+
Direct_to_cmm (flambda2 ~keep_symbol_tables)
115+
in
116+
let backend info ({ structure; coercion; argument_interface; _ }
117+
: Typedtree.implementation) =
74118
Compilenv.reset info.module_name;
75-
let typed = structure, coercion in
76-
let transl_style : Translmod.compilation_unit_style =
77-
if Config.flambda || Config.flambda2 then Plain_block
78-
else Set_individual_fields
119+
let argument_coercion =
120+
match argument_interface with
121+
| Some { ai_coercion_from_primary; ai_signature = _ } ->
122+
Some ai_coercion_from_primary
123+
| None -> None
79124
in
80-
let pipeline : Asmgen.pipeline =
81-
Direct_to_cmm (flambda2 ~keep_symbol_tables)
125+
let typed = structure, coercion, argument_coercion in
126+
let as_arg_for =
127+
!Clflags.as_argument_for
128+
|> Option.map (fun param ->
129+
(* Currently, parameters don't have parameters, so we assume the argument
130+
list is empty *)
131+
Global_module.Name.create_exn param [])
82132
in
83133
if not (Config.flambda || Config.flambda2) then Clflags.set_oclassic ();
84-
compile info typed ~unix ~transl_style ~pipeline
134+
compile_from_typed info typed ~unix ~transl_style ~pipeline ~as_arg_for
85135
in
86-
with_info ~source_file ~output_prefix ~dump_ext:"cmx" @@ fun info ->
136+
with_info ~source_file ~output_prefix ~dump_ext:"cmx" ~compilation_unit
137+
@@ fun info ->
87138
if !Flambda_backend_flags.internal_assembler then
88139
Emitaux.binary_backend_available := true;
89-
match (start_from:Clflags.Compiler_pass.t) with
140+
match start_from with
90141
| Parsing ->
91142
Compile_common.implementation
92143
~hook_parse_tree:(Compiler_hooks.execute Compiler_hooks.Parse_tree_impl)
93144
~hook_typed_tree:(fun (impl : Typedtree.implementation) ->
94145
Compiler_hooks.execute Compiler_hooks.Typed_tree_impl impl)
95146
info ~backend
96147
| Emit -> emit unix info ~ppf_dump:info.ppf_dump
97-
| _ -> Misc.fatal_errorf "Cannot start from %s"
98-
(Clflags.Compiler_pass.to_string start_from)
148+
| Instantiation { runtime_args; main_module_block_size; arg_descr } ->
149+
Compilenv.reset info.module_name;
150+
(* FIXME delete {[
151+
let global_name =
152+
Compilation_unit.to_global_name_exn info.module_name
153+
in
154+
(* Consider the names of arguments to be parameters for the purposes of the
155+
subset rule - that is, a module we import can refer to our arguments as
156+
parameters. *)
157+
List.iter
158+
(fun (param, _value) ->
159+
let import = Compilation_unit.Name.of_head_of_global_name param in
160+
Env.register_parameter_import import)
161+
global_name.args;
162+
]} *)
163+
let as_arg_for, arg_block_field =
164+
match (arg_descr : Lambda.arg_descr option) with
165+
| Some { arg_param; arg_block_field } ->
166+
Some arg_param, Some arg_block_field
167+
| None -> None, None
168+
in
169+
let impl =
170+
Translmod.transl_instance info.module_name ~runtime_args
171+
~main_module_block_size ~arg_block_field
172+
~style:transl_style
173+
in
174+
if not (Config.flambda || Config.flambda2) then Clflags.set_oclassic ();
175+
compile_from_raw_lambda info impl ~unix ~pipeline ~as_arg_for
176+
177+
let implementation unix ~flambda2 ~start_from ~source_file
178+
~output_prefix ~keep_symbol_tables =
179+
let start_from = start_from |> starting_point_of_compiler_pass in
180+
implementation0 unix ~flambda2 ~start_from ~source_file
181+
~output_prefix ~keep_symbol_tables
182+
~compilation_unit:Inferred_from_output_prefix
183+
184+
let instance unix ~flambda2 ~source_file
185+
~output_prefix ~compilation_unit ~runtime_args ~main_module_block_size
186+
~arg_descr ~keep_symbol_tables =
187+
let start_from =
188+
Instantiation { runtime_args; main_module_block_size; arg_descr }
189+
in
190+
implementation0 unix ~flambda2 ~start_from ~source_file
191+
~output_prefix ~keep_symbol_tables
192+
~compilation_unit:(Exactly compilation_unit)

driver/optcompile.mli

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,20 @@ val implementation
2929
-> start_from:Clflags.Compiler_pass.t
3030
-> source_file:string -> output_prefix:string -> keep_symbol_tables:bool
3131
-> unit
32+
33+
val instance
34+
: (module Compiler_owee.Unix_intf.S)
35+
-> flambda2:(
36+
ppf_dump:Format.formatter ->
37+
prefixname:string ->
38+
filename:string ->
39+
keep_symbol_tables:bool ->
40+
Lambda.program ->
41+
Cmm.phrase list)
42+
-> source_file:string -> output_prefix:string
43+
-> compilation_unit:Compilation_unit.t
44+
-> runtime_args:Translmod.runtime_arg list
45+
-> main_module_block_size:int
46+
-> arg_descr:Lambda.arg_descr option
47+
-> keep_symbol_tables:bool
48+
-> unit

driver/optmaindriver.ml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,21 @@ let main unix argv ppf ~flambda2 =
8181
Compenv.readenv ppf Before_link;
8282
if
8383
List.length (List.filter (fun x -> !x)
84-
[make_package; make_archive; shared;
84+
[make_package; make_archive; shared; instantiate;
8585
Compenv.stop_early; output_c_object]) > 1
8686
then
8787
begin
8888
let module P = Clflags.Compiler_pass in
8989
match !stop_after with
9090
| None ->
9191
Compenv.fatal "Please specify at most one of -pack, -a, -shared, -c, \
92-
-output-obj";
92+
-output-obj, -instantiate";
9393
| Some ((P.Parsing | P.Typing | P.Lambda | P.Middle_end | P.Scheduling
9494
| P.Simplify_cfg | P.Emit | P.Selection) as p) ->
9595
assert (P.is_compilation_pass p);
9696
Printf.ksprintf Compenv.fatal
9797
"Options -i and -stop-after (%s) \
98-
are incompatible with -pack, -a, -shared, -output-obj"
98+
are incompatible with -pack, -a, -shared, -output-obj, -instantiate"
9999
(String.concat "|"
100100
(P.available_pass_names ~filter:(fun _ -> true) ~native:true))
101101
end;
@@ -116,6 +116,23 @@ let main unix argv ppf ~flambda2 =
116116
~flambda2);
117117
Warnings.check_fatal ();
118118
end
119+
else if !instantiate then begin
120+
Compmisc.init_path ();
121+
(* Requiring [-o] isn't really necessary, but we don't intend for humans
122+
to be invoking [-instantiate] by hand, and computing the correct value
123+
here would be awkward *)
124+
let target = Compenv.extract_output !output_name in
125+
let src, args =
126+
match Compenv.get_objfiles ~with_ocamlparam:false with
127+
| [] | [_] ->
128+
Printf.ksprintf Compenv.fatal
129+
"Must specify at least two .cmx files with -instantiate"
130+
| src :: args ->
131+
src, args
132+
in
133+
Asminstantiator.instantiate unix ~src ~args target ~flambda2;
134+
Warnings.check_fatal ();
135+
end
119136
else if !shared then begin
120137
Compmisc.init_path ();
121138
let target = Compenv.extract_output !output_name in

dune

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
afl_instrument
8787
arch
8888
asmgen
89+
asminstantiator
8990
asmlibrarian
9091
asmlink
9192
asmpackager

0 commit comments

Comments
 (0)