From 669e7329e0689f412ce897ac7cc35c5950b01d82 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Sat, 14 Jan 2023 19:53:03 -0800 Subject: [PATCH 1/8] delay cmj optimizations --- jscomp/core/js_implementation.ml | 12 +- jscomp/core/lam_compile_main.ml | 210 +++++++++++++++---------------- jscomp/core/lam_compile_main.mli | 7 +- jscomp/test/ext_list_test.js | 3 +- jscomp/test/gpr_405_test.js | 2 +- jscomp/test/ocaml_proto_test.js | 1 - jscomp/test/sexp.js | 2 +- 7 files changed, 116 insertions(+), 121 deletions(-) diff --git a/jscomp/core/js_implementation.ml b/jscomp/core/js_implementation.ml index bc8e3e8f53..a83b00655f 100644 --- a/jscomp/core/js_implementation.ml +++ b/jscomp/core/js_implementation.ml @@ -180,16 +180,18 @@ let after_parsing_impl ppf fname (ast : Parsetree.structure) = let lambda = Translmod.transl_implementation modulename typedtree_coercion in - let js_program = - print_if_pipe ppf Clflags.dump_rawlambda Printlambda.lambda lambda.code - |> Lam_compile_main.compile outputprefix + let lambda_coercion = + print_if ppf Clflags.dump_rawlambda Printlambda.lambda lambda.code; + Lam_compile_main.compile_coercion ~output_prefix:outputprefix + lambda.code in if not !Js_config.cmj_only then (* XXX(anmonteiro): important that we get package_info after processing, as `[@@@config {flags = [| ... |]}]` could have added to package specs. *) let package_info = Js_packages_state.get_packages_info () in - Lam_compile_main.lambda_as_module ~package_info js_program outputprefix); + Lam_compile_main.lambda_as_module ~package_info + ~output_prefix:outputprefix lambda_coercion); process_with_gentype (outputprefix ^ ".cmt") let implementation ~parser ppf fname = @@ -215,8 +217,8 @@ let implementation_cmj _ppf fname = Res_compmisc.init_path (); let cmj = Js_cmj_format.from_file fname in Lam_compile_main.lambda_as_module ~package_info:cmj.package_spec + ~output_prefix:(Config_util.output_prefix fname) cmj.delayed_program - (Config_util.output_prefix fname) let make_structure_item ~ns cunit : Parsetree.structure_item = let open Ast_helper in diff --git a/jscomp/core/lam_compile_main.ml b/jscomp/core/lam_compile_main.ml index 2e1b5782cf..d54b1b8523 100644 --- a/jscomp/core/lam_compile_main.ml +++ b/jscomp/core/lam_compile_main.ml @@ -23,16 +23,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) - - - - - - -(* module E = Js_exp_make *) -(* module S = Js_stmt_make *) - - let compile_group (meta : Lam_stats.t) (x : Lam_group.t) : Js_output.t = match x with @@ -85,8 +75,7 @@ let no_side_effects (rest : Lam_group.t list) : string option = Ext_list.find_opt rest (fun x -> match x with | Single(kind,id,body) -> - begin - match kind with + begin match kind with | Strict | Variable -> if not @@ Lam_analysis.no_side_effects body then Some (Printf.sprintf "%s" (Ident.name id)) @@ -118,12 +107,9 @@ let _d = fun s lam -> let _j = Js_pass_debug.dump -(* Actually simplify_lets is kind of global optimization since it requires you to know whether - it's used or not -*) -let compile - (output_prefix : string) - (lam : Lambda.lambda) = +(* Actually simplify_lets is kind of global optimization since it requires you + to know whether it's used or not *) +let compile_coercion ~output_prefix (lam : Lambda.lambda) = let export_idents = Translmod.get_export_identifiers() in let export_ident_sets = Set_ident.of_list export_idents in (* To make toplevel happy - reentrant for js-demo *) @@ -134,8 +120,7 @@ let compile #endif Lam_compile_env.reset () ; in - let lam, may_required_modules = Lam_convert.convert export_ident_sets lam in - + let lam, maybe_required_modules = Lam_convert.convert export_ident_sets lam in let lam = _d "initial" lam in let lam = Lam_pass_deep_flatten.deep_flatten lam in @@ -148,7 +133,7 @@ let compile let lam = let lam = lam - |> _d "flattern1" + |> _d "flatten1" |> Lam_pass_exits.simplify_exits |> _d "simplyf_exits" |> (fun lam -> Lam_pass_collect.collect_info meta lam; @@ -206,93 +191,104 @@ let compile in #ifndef BS_RELEASE_BUILD -let () = - Ext_log.dwarn ~__POS__ "After coercion: %a@." Lam_stats.print meta ; - if Js_config.get_diagnose () then - let f = - Ext_filename.new_extension !Location.input_name ".lambda" in - Ext_fmt.with_file_as_pp f (fun fmt -> - Format.pp_print_list ~pp_sep:Format.pp_print_newline - Lam_group.pp_group fmt (coerced_input.groups)) -in + let () = + Ext_log.dwarn ~__POS__ "After coercion: %a@." Lam_stats.print meta ; + if Js_config.get_diagnose () then + let f = + Ext_filename.new_extension !Location.input_name ".lambda" in + Ext_fmt.with_file_as_pp f (fun fmt -> + Format.pp_print_list ~pp_sep:Format.pp_print_newline + Lam_group.pp_group fmt (coerced_input.groups)) + in #endif -let maybe_pure = no_side_effects groups in + + let maybe_pure = no_side_effects groups in + #ifndef BS_RELEASE_BUILD -let () = Ext_log.dwarn ~__POS__ "\n@[[TIME:]Pre-compile: %f@]@." (Sys.time () *. 1000.) in + let () = Ext_log.dwarn ~__POS__ "\n@[[TIME:]Pre-compile: %f@]@." (Sys.time () *. 1000.) in #endif -let body = - Ext_list.map groups (fun group -> compile_group meta group) - |> Js_output.concat - |> Js_output.output_as_block -in + + let body = + Ext_list.map groups (fun group -> compile_group meta group) + |> Js_output.concat + |> Js_output.output_as_block + in + #ifndef BS_RELEASE_BUILD -let () = Ext_log.dwarn ~__POS__ "\n@[[TIME:]Post-compile: %f@]@." (Sys.time () *. 1000.) in + let () = Ext_log.dwarn ~__POS__ "\n@[[TIME:]Post-compile: %f@]@." (Sys.time () *. 1000.) in #endif -(* The file is not big at all compared with [cmo] *) -(* Ext_marshal.to_file (Ext_path.chop_extension filename ^ ".mj") js; *) -let meta_exports = meta.exports in -let export_set = Set_ident.of_list meta_exports in -let js : J.program = - { - exports = meta_exports ; - export_set; - block = body} -in -js -|> _j "initial" -|> Js_pass_flatten.program -|> _j "flattern" -|> Js_pass_tailcall_inline.tailcall_inline -|> _j "inline_and_shake" -|> Js_pass_flatten_and_mark_dead.program -|> _j "flatten_and_mark_dead" -(* |> Js_inline_and_eliminate.inline_and_shake *) -(* |> _j "inline_and_shake" *) -|> (fun js -> ignore @@ Js_pass_scope.program js ; js ) -|> Js_shake.shake_program -|> _j "shake" -|> ( fun (program: J.program) -> - let external_module_ids : Lam_module_ident.t list = - if !Js_config.all_module_aliases then [] - else - let hard_deps = - Js_fold_basic.calculate_hard_dependencies program.block in - Lam_compile_env.populate_required_modules - may_required_modules hard_deps ; - Ext_list.sort_via_array (Lam_module_ident.Hash_set.to_list hard_deps) - (fun id1 id2 -> - Ext_string.compare (Lam_module_ident.name id1) (Lam_module_ident.name id2) - ) - in - Warnings.check_fatal(); - let effect = - Lam_stats_export.get_dependent_module_effect - maybe_pure external_module_ids in - let delayed_program = { - J.program = program ; - side_effect = effect ; - modules = external_module_ids - } - in - let case = - Js_packages_info.module_case - ~output_prefix - (Js_packages_state.get_packages_info ()) - in - let cmj : Js_cmj_format.t = - Lam_stats_export.export_to_cmj - ~case - ~delayed_program - meta - effect - coerced_input.export_map - in - (if not !Clflags.dont_write_files then - Js_cmj_format.to_file - ~check_exists:(not !Js_config.force_cmj) - (output_prefix ^ Literals.suffix_cmj) cmj); - delayed_program - ) + let external_module_ids : Lam_module_ident.t list = + if !Js_config.all_module_aliases then [] + else + let hard_deps = + Js_fold_basic.calculate_hard_dependencies body in + Lam_compile_env.populate_required_modules + maybe_required_modules hard_deps ; + Ext_list.sort_via_array (Lam_module_ident.Hash_set.to_list hard_deps) + (fun id1 id2 -> + Ext_string.compare (Lam_module_ident.name id1) (Lam_module_ident.name id2) + ) + in + + + (* The file is not big at all compared with [cmo] *) + (* Ext_marshal.to_file (Ext_path.chop_extension filename ^ ".mj") js; *) + let meta_exports = meta.exports in + let export_set = Set_ident.of_list meta_exports in + let js : J.program = + { + exports = meta_exports ; + export_set; + block = body} + in + let effect = + Lam_stats_export.get_dependent_module_effect + maybe_pure external_module_ids in + + let delayed_program = { + J.program = js ; + side_effect = effect ; + modules = external_module_ids + } + in + let case = + Js_packages_info.module_case + ~output_prefix + (Js_packages_state.get_packages_info ()) + in + let cmj : Js_cmj_format.t = + Lam_stats_export.export_to_cmj + ~case + ~delayed_program + meta + effect + coerced_input.export_map + in + (if not !Clflags.dont_write_files then + Js_cmj_format.to_file + ~check_exists:(not !Js_config.force_cmj) + (output_prefix ^ Literals.suffix_cmj) cmj); + + delayed_program + +let emit_program (deps_program : J.deps_program) = + deps_program.program + |> _j "initial" + |> Js_pass_flatten.program + |> _j "flatten" + |> Js_pass_tailcall_inline.tailcall_inline + |> _j "inline_and_shake" + |> Js_pass_flatten_and_mark_dead.program + |> _j "flatten_and_mark_dead" + (* |> Js_inline_and_eliminate.inline_and_shake *) + (* |> _j "inline_and_shake" *) + |> (fun js -> ignore @@ Js_pass_scope.program js ; js ) + |> Js_shake.shake_program + |> _j "shake" + |> ( fun (program: J.program) -> + Warnings.check_fatal(); + {deps_program with program } + ) ;; let (//) = Filename.concat @@ -302,15 +298,12 @@ let write_to_file ~package_info ~output_info ~output_prefix lambda_output file Js_dump_program.dump_deps_program ~package_info ~output_info ~output_prefix lambda_output chan) -let lambda_as_module - ~package_info - (lambda_output : J.deps_program) - (output_prefix : string) - : unit = +let lambda_as_module ~package_info ~output_prefix t : unit = let make_basename suffix = Ext_namespace.change_ext_ns_suffix (Filename.basename output_prefix) (Ext_js_suffix.to_string suffix) in + let lambda_output : J.deps_program = emit_program t in match (!Js_config.js_stdout, !Clflags.output_name) with | (true, None) -> Js_dump_program.dump_deps_program @@ -337,7 +330,6 @@ let lambda_as_module end) - (* We can use {!Env.current_unit = "Pervasives"} to tell if it is some specific module, We need handle some definitions in standard libraries in a special way, most are io specific, includes {!Pervasives.stdin, Pervasives.stdout, Pervasives.stderr} diff --git a/jscomp/core/lam_compile_main.mli b/jscomp/core/lam_compile_main.mli index 0e8c4f0cbf..197fe215c4 100644 --- a/jscomp/core/lam_compile_main.mli +++ b/jscomp/core/lam_compile_main.mli @@ -27,10 +27,13 @@ (** Compile and register the hook of function to compile a lambda to JS IR *) -val compile : string -> Lambda.lambda -> J.deps_program +val compile_coercion : output_prefix:string -> Lambda.lambda -> J.deps_program (** For toplevel, [filename] is [""] which is the same as {!Env.get_unit_name ()} *) val lambda_as_module : - package_info:Js_packages_info.t -> J.deps_program -> string -> unit + package_info:Js_packages_info.t -> + output_prefix:string -> + J.deps_program -> + unit diff --git a/jscomp/test/ext_list_test.js b/jscomp/test/ext_list_test.js index 00a8ea8e66..709f6fb4b5 100644 --- a/jscomp/test/ext_list_test.js +++ b/jscomp/test/ext_list_test.js @@ -5,7 +5,6 @@ var $$Array = require("melange/lib/js/array.js"); var Curry = require("melange/lib/js/curry.js"); var Caml_obj = require("melange/lib/js/caml_obj.js"); var Caml_option = require("melange/lib/js/caml_option.js"); -var Ext_string_test = require("./ext_string_test.js"); function filter_map(f, _xs) { while(true) { @@ -979,4 +978,4 @@ exports.sort_via_array = sort_via_array; exports.last = last; exports.assoc_by_string = assoc_by_string; exports.assoc_by_int = assoc_by_int; -/* Ext_string_test Not a pure module */ +/* No side effect */ diff --git a/jscomp/test/gpr_405_test.js b/jscomp/test/gpr_405_test.js index 02a725fd63..72681aaa52 100644 --- a/jscomp/test/gpr_405_test.js +++ b/jscomp/test/gpr_405_test.js @@ -121,4 +121,4 @@ function Make(funarg) { } exports.Make = Make; -/* Hashtbl Not a pure module */ +/* No side effect */ diff --git a/jscomp/test/ocaml_proto_test.js b/jscomp/test/ocaml_proto_test.js index bc35ce70f0..60ae8f2618 100644 --- a/jscomp/test/ocaml_proto_test.js +++ b/jscomp/test/ocaml_proto_test.js @@ -9,7 +9,6 @@ var Lexing = require("melange/lib/js/lexing.js"); var Printf = require("melange/lib/js/printf.js"); var Stdlib = require("melange/lib/js/stdlib.js"); var $$String = require("melange/lib/js/string.js"); -var Hashtbl = require("melange/lib/js/hashtbl.js"); var Parsing = require("melange/lib/js/parsing.js"); var Caml_obj = require("melange/lib/js/caml_obj.js"); var Filename = require("melange/lib/js/filename.js"); diff --git a/jscomp/test/sexp.js b/jscomp/test/sexp.js index abc4daaa99..22a45510d0 100644 --- a/jscomp/test/sexp.js +++ b/jscomp/test/sexp.js @@ -538,4 +538,4 @@ exports.of_variant = of_variant; exports.of_field = of_field; exports.of_record = of_record; exports.Traverse = Traverse; -/* Hashtbl Not a pure module */ +/* No side effect */ From 9c708b678cd0572e70d8f6a7d3992bca03cc3324 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Sat, 14 Jan 2023 20:46:00 -0800 Subject: [PATCH 2/8] revert jscomp/test --- jscomp/test/ext_list_test.js | 3 ++- jscomp/test/gpr_405_test.js | 2 +- jscomp/test/ocaml_proto_test.js | 1 + jscomp/test/sexp.js | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/jscomp/test/ext_list_test.js b/jscomp/test/ext_list_test.js index 709f6fb4b5..00a8ea8e66 100644 --- a/jscomp/test/ext_list_test.js +++ b/jscomp/test/ext_list_test.js @@ -5,6 +5,7 @@ var $$Array = require("melange/lib/js/array.js"); var Curry = require("melange/lib/js/curry.js"); var Caml_obj = require("melange/lib/js/caml_obj.js"); var Caml_option = require("melange/lib/js/caml_option.js"); +var Ext_string_test = require("./ext_string_test.js"); function filter_map(f, _xs) { while(true) { @@ -978,4 +979,4 @@ exports.sort_via_array = sort_via_array; exports.last = last; exports.assoc_by_string = assoc_by_string; exports.assoc_by_int = assoc_by_int; -/* No side effect */ +/* Ext_string_test Not a pure module */ diff --git a/jscomp/test/gpr_405_test.js b/jscomp/test/gpr_405_test.js index 72681aaa52..02a725fd63 100644 --- a/jscomp/test/gpr_405_test.js +++ b/jscomp/test/gpr_405_test.js @@ -121,4 +121,4 @@ function Make(funarg) { } exports.Make = Make; -/* No side effect */ +/* Hashtbl Not a pure module */ diff --git a/jscomp/test/ocaml_proto_test.js b/jscomp/test/ocaml_proto_test.js index 60ae8f2618..bc35ce70f0 100644 --- a/jscomp/test/ocaml_proto_test.js +++ b/jscomp/test/ocaml_proto_test.js @@ -9,6 +9,7 @@ var Lexing = require("melange/lib/js/lexing.js"); var Printf = require("melange/lib/js/printf.js"); var Stdlib = require("melange/lib/js/stdlib.js"); var $$String = require("melange/lib/js/string.js"); +var Hashtbl = require("melange/lib/js/hashtbl.js"); var Parsing = require("melange/lib/js/parsing.js"); var Caml_obj = require("melange/lib/js/caml_obj.js"); var Filename = require("melange/lib/js/filename.js"); diff --git a/jscomp/test/sexp.js b/jscomp/test/sexp.js index 22a45510d0..abc4daaa99 100644 --- a/jscomp/test/sexp.js +++ b/jscomp/test/sexp.js @@ -538,4 +538,4 @@ exports.of_variant = of_variant; exports.of_field = of_field; exports.of_record = of_record; exports.Traverse = Traverse; -/* No side effect */ +/* Hashtbl Not a pure module */ From f525215bfc1bce7b0bab03813a07b77c8d4e60df Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Sat, 14 Jan 2023 20:54:51 -0800 Subject: [PATCH 3/8] commit test cases --- jscomp/core/lam_compile_main.ml | 4 ++-- jscomp/test/demo_int_map.js | 2 ++ jscomp/test/flow_parser_reg_test.js | 1 + jscomp/test/map_find_test.js | 2 ++ jscomp/test/map_test.js | 2 ++ jscomp/test/ocaml_parsetree_test.js | 1 + jscomp/test/ocaml_proto_test.js | 1 + jscomp/test/ocaml_re_test.js | 1 + jscomp/test/ocaml_typedtree_test.js | 1 + jscomp/test/test_functor_dead_code.js | 4 ++++ jscomp/test/test_int_map_find.js | 3 +++ jscomp/test/test_non_export.js | 7 +++++++ jscomp/test/test_string_map.js | 2 ++ 13 files changed, 29 insertions(+), 2 deletions(-) diff --git a/jscomp/core/lam_compile_main.ml b/jscomp/core/lam_compile_main.ml index d54b1b8523..b37349aacf 100644 --- a/jscomp/core/lam_compile_main.ml +++ b/jscomp/core/lam_compile_main.ml @@ -230,7 +230,6 @@ let compile_coercion ~output_prefix (lam : Lambda.lambda) = ) in - (* The file is not big at all compared with [cmo] *) (* Ext_marshal.to_file (Ext_path.chop_extension filename ^ ".mj") js; *) let meta_exports = meta.exports in @@ -239,7 +238,8 @@ let compile_coercion ~output_prefix (lam : Lambda.lambda) = { exports = meta_exports ; export_set; - block = body} + block = body + } in let effect = Lam_stats_export.get_dependent_module_effect diff --git a/jscomp/test/demo_int_map.js b/jscomp/test/demo_int_map.js index d172d0031c..0874dff78d 100644 --- a/jscomp/test/demo_int_map.js +++ b/jscomp/test/demo_int_map.js @@ -1,7 +1,9 @@ 'use strict'; +var Seq = require("melange/lib/js/seq.js"); var Curry = require("melange/lib/js/curry.js"); var Stdlib = require("melange/lib/js/stdlib.js"); +var Caml_option = require("melange/lib/js/caml_option.js"); function compare(x, y) { return x - y | 0; diff --git a/jscomp/test/flow_parser_reg_test.js b/jscomp/test/flow_parser_reg_test.js index 0ca4100af3..f8ee809c82 100644 --- a/jscomp/test/flow_parser_reg_test.js +++ b/jscomp/test/flow_parser_reg_test.js @@ -2,6 +2,7 @@ var Mt = require("./mt.js"); var Fs = require("fs"); +var Seq = require("melange/lib/js/seq.js"); var Sys = require("melange/lib/js/sys.js"); var Caml = require("melange/lib/js/caml.js"); var Char = require("melange/lib/js/char.js"); diff --git a/jscomp/test/map_find_test.js b/jscomp/test/map_find_test.js index 3ca368ba5b..73b628ab6c 100644 --- a/jscomp/test/map_find_test.js +++ b/jscomp/test/map_find_test.js @@ -1,10 +1,12 @@ 'use strict'; var Mt = require("./mt.js"); +var Seq = require("melange/lib/js/seq.js"); var Caml = require("melange/lib/js/caml.js"); var List = require("melange/lib/js/list.js"); var Curry = require("melange/lib/js/curry.js"); var Stdlib = require("melange/lib/js/stdlib.js"); +var Caml_option = require("melange/lib/js/caml_option.js"); var compare = Caml.caml_int_compare; diff --git a/jscomp/test/map_test.js b/jscomp/test/map_test.js index 55e87d5cb3..0e60c38ce5 100644 --- a/jscomp/test/map_test.js +++ b/jscomp/test/map_test.js @@ -1,11 +1,13 @@ 'use strict'; var Mt = require("./mt.js"); +var Seq = require("melange/lib/js/seq.js"); var Caml = require("melange/lib/js/caml.js"); var List = require("melange/lib/js/list.js"); var Curry = require("melange/lib/js/curry.js"); var Stdlib = require("melange/lib/js/stdlib.js"); var $$String = require("melange/lib/js/string.js"); +var Caml_option = require("melange/lib/js/caml_option.js"); var compare = Caml.caml_int_compare; diff --git a/jscomp/test/ocaml_parsetree_test.js b/jscomp/test/ocaml_parsetree_test.js index 1da03db25a..91935d2b53 100644 --- a/jscomp/test/ocaml_parsetree_test.js +++ b/jscomp/test/ocaml_parsetree_test.js @@ -25,6 +25,7 @@ var Caml_sys = require("melange/lib/js/caml_sys.js"); var Filename = require("melange/lib/js/filename.js"); var Caml_array = require("melange/lib/js/caml_array.js"); var Caml_bytes = require("melange/lib/js/caml_bytes.js"); +var Caml_int32 = require("melange/lib/js/caml_int32.js"); var Caml_int64 = require("melange/lib/js/caml_int64.js"); var Caml_format = require("melange/lib/js/caml_format.js"); var Caml_option = require("melange/lib/js/caml_option.js"); diff --git a/jscomp/test/ocaml_proto_test.js b/jscomp/test/ocaml_proto_test.js index bc35ce70f0..53a34a2a04 100644 --- a/jscomp/test/ocaml_proto_test.js +++ b/jscomp/test/ocaml_proto_test.js @@ -1,6 +1,7 @@ 'use strict'; var Mt = require("./mt.js"); +var Seq = require("melange/lib/js/seq.js"); var Char = require("melange/lib/js/char.js"); var List = require("melange/lib/js/list.js"); var Bytes = require("melange/lib/js/bytes.js"); diff --git a/jscomp/test/ocaml_re_test.js b/jscomp/test/ocaml_re_test.js index 1461c36de7..b8f7d53a56 100644 --- a/jscomp/test/ocaml_re_test.js +++ b/jscomp/test/ocaml_re_test.js @@ -1,6 +1,7 @@ 'use strict'; var Mt = require("./mt.js"); +var Seq = require("melange/lib/js/seq.js"); var Caml = require("melange/lib/js/caml.js"); var Char = require("melange/lib/js/char.js"); var List = require("melange/lib/js/list.js"); diff --git a/jscomp/test/ocaml_typedtree_test.js b/jscomp/test/ocaml_typedtree_test.js index 58c2726eaa..1685bb5eda 100644 --- a/jscomp/test/ocaml_typedtree_test.js +++ b/jscomp/test/ocaml_typedtree_test.js @@ -31,6 +31,7 @@ var Filename = require("melange/lib/js/filename.js"); var Printexc = require("melange/lib/js/printexc.js"); var Caml_array = require("melange/lib/js/caml_array.js"); var Caml_bytes = require("melange/lib/js/caml_bytes.js"); +var Caml_int32 = require("melange/lib/js/caml_int32.js"); var Caml_int64 = require("melange/lib/js/caml_int64.js"); var Caml_format = require("melange/lib/js/caml_format.js"); var Caml_option = require("melange/lib/js/caml_option.js"); diff --git a/jscomp/test/test_functor_dead_code.js b/jscomp/test/test_functor_dead_code.js index 183e0e880b..8256ecae23 100644 --- a/jscomp/test/test_functor_dead_code.js +++ b/jscomp/test/test_functor_dead_code.js @@ -1,6 +1,10 @@ 'use strict'; +var Seq = require("melange/lib/js/seq.js"); var Curry = require("melange/lib/js/curry.js"); +var Stdlib = require("melange/lib/js/stdlib.js"); +var $$String = require("melange/lib/js/string.js"); +var Caml_option = require("melange/lib/js/caml_option.js"); function is_empty(param) { if (param) { diff --git a/jscomp/test/test_int_map_find.js b/jscomp/test/test_int_map_find.js index 6dcac9857a..df1afbf0fe 100644 --- a/jscomp/test/test_int_map_find.js +++ b/jscomp/test/test_int_map_find.js @@ -1,8 +1,11 @@ 'use strict'; +var Seq = require("melange/lib/js/seq.js"); var Caml = require("melange/lib/js/caml.js"); var List = require("melange/lib/js/list.js"); var Curry = require("melange/lib/js/curry.js"); +var Stdlib = require("melange/lib/js/stdlib.js"); +var Caml_option = require("melange/lib/js/caml_option.js"); var compare = Caml.caml_int_compare; diff --git a/jscomp/test/test_non_export.js b/jscomp/test/test_non_export.js index c0559c00d6..3f58e075d7 100644 --- a/jscomp/test/test_non_export.js +++ b/jscomp/test/test_non_export.js @@ -1,5 +1,12 @@ 'use strict'; +var Seq = require("melange/lib/js/seq.js"); +var List = require("melange/lib/js/list.js"); +var Curry = require("melange/lib/js/curry.js"); +var Stdlib = require("melange/lib/js/stdlib.js"); +var $$String = require("melange/lib/js/string.js"); +var Caml_obj = require("melange/lib/js/caml_obj.js"); +var Caml_option = require("melange/lib/js/caml_option.js"); /* Not a pure module */ diff --git a/jscomp/test/test_string_map.js b/jscomp/test/test_string_map.js index 12d92b2ff0..84f6ceca3a 100644 --- a/jscomp/test/test_string_map.js +++ b/jscomp/test/test_string_map.js @@ -1,8 +1,10 @@ 'use strict'; +var Seq = require("melange/lib/js/seq.js"); var Caml = require("melange/lib/js/caml.js"); var Curry = require("melange/lib/js/curry.js"); var Stdlib = require("melange/lib/js/stdlib.js"); +var Caml_option = require("melange/lib/js/caml_option.js"); var compare = Caml.caml_string_compare; From 402e7d001c5959af4777f5a1ab8c3c525797cdd6 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Mon, 16 Jan 2023 12:50:55 -0800 Subject: [PATCH 4/8] Update jscomp/core/lam_compile_main.ml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Javier Chávarri --- jscomp/core/lam_compile_main.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jscomp/core/lam_compile_main.ml b/jscomp/core/lam_compile_main.ml index b37349aacf..926032d12c 100644 --- a/jscomp/core/lam_compile_main.ml +++ b/jscomp/core/lam_compile_main.ml @@ -135,7 +135,7 @@ let compile_coercion ~output_prefix (lam : Lambda.lambda) = lam |> _d "flatten1" |> Lam_pass_exits.simplify_exits - |> _d "simplyf_exits" + |> _d "simplify_exits" |> (fun lam -> Lam_pass_collect.collect_info meta lam; #ifndef BS_RELEASE_BUILD let () = From 51b337e0e682f043589a7a887937383f159f155d Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Thu, 15 Feb 2024 14:14:44 -0800 Subject: [PATCH 5/8] fix: check for fatal warnings in the right place --- jscomp/core/lam_compile_main.cppo.ml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jscomp/core/lam_compile_main.cppo.ml b/jscomp/core/lam_compile_main.cppo.ml index 68f96befe6..3e2e441df0 100644 --- a/jscomp/core/lam_compile_main.cppo.ml +++ b/jscomp/core/lam_compile_main.cppo.ml @@ -280,6 +280,8 @@ in block = body} in + Warnings.check_fatal(); + let effect = Lam_stats_export.get_dependent_module_effect maybe_pure external_module_ids in @@ -321,7 +323,6 @@ let emit_program (deps_program: J.deps_program) = |> Js_shake.shake_program |> _j "shake" |> (fun (program: J.program) -> - Warnings.check_fatal(); {deps_program with program }) let optimize_program = emit_program From 3e3cad0ae62a2e50c5b3af05ad8fc0f335937f01 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Thu, 15 Feb 2024 14:15:13 -0800 Subject: [PATCH 6/8] chore: snapshot runtime tests --- jscomp/test/dist/jscomp/test/demo_int_map.js | 3 +++ jscomp/test/dist/jscomp/test/flow_parser_reg_test.js | 1 + jscomp/test/dist/jscomp/test/map_find_test.js | 2 ++ jscomp/test/dist/jscomp/test/map_test.js | 2 ++ jscomp/test/dist/jscomp/test/ocaml_parsetree_test.js | 1 + jscomp/test/dist/jscomp/test/ocaml_proto_test.js | 1 + jscomp/test/dist/jscomp/test/ocaml_re_test.js | 1 + jscomp/test/dist/jscomp/test/ocaml_typedtree_test.js | 1 + jscomp/test/dist/jscomp/test/test_functor_dead_code.js | 6 ++++++ jscomp/test/dist/jscomp/test/test_int_map_find.js | 3 +++ jscomp/test/dist/jscomp/test/test_non_export.js | 8 ++++++++ jscomp/test/dist/jscomp/test/test_string_map.js | 3 +++ 12 files changed, 32 insertions(+) diff --git a/jscomp/test/dist/jscomp/test/demo_int_map.js b/jscomp/test/dist/jscomp/test/demo_int_map.js index e8b13df55a..df458669f7 100644 --- a/jscomp/test/dist/jscomp/test/demo_int_map.js +++ b/jscomp/test/dist/jscomp/test/demo_int_map.js @@ -2,8 +2,11 @@ 'use strict'; let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); +let Caml_option = require("melange.js/caml_option.js"); let Curry = require("melange.js/curry.js"); let Stdlib = require("melange/stdlib.js"); +let Stdlib__List = require("melange/list.js"); +let Stdlib__Seq = require("melange/seq.js"); function compare(x, y) { return x - y | 0; diff --git a/jscomp/test/dist/jscomp/test/flow_parser_reg_test.js b/jscomp/test/dist/jscomp/test/flow_parser_reg_test.js index 282ff25b8b..c0e314920d 100644 --- a/jscomp/test/dist/jscomp/test/flow_parser_reg_test.js +++ b/jscomp/test/dist/jscomp/test/flow_parser_reg_test.js @@ -22,6 +22,7 @@ let Stdlib__Lexing = require("melange/lexing.js"); let Stdlib__List = require("melange/list.js"); let Stdlib__Printf = require("melange/printf.js"); let Stdlib__Queue = require("melange/queue.js"); +let Stdlib__Seq = require("melange/seq.js"); let Stdlib__String = require("melange/string.js"); let Stdlib__Sys = require("melange/sys.js"); let Fs = require("fs"); diff --git a/jscomp/test/dist/jscomp/test/map_find_test.js b/jscomp/test/dist/jscomp/test/map_find_test.js index e29b07154e..1941856b68 100644 --- a/jscomp/test/dist/jscomp/test/map_find_test.js +++ b/jscomp/test/dist/jscomp/test/map_find_test.js @@ -3,10 +3,12 @@ let Caml = require("melange.js/caml.js"); let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); +let Caml_option = require("melange.js/caml_option.js"); let Curry = require("melange.js/curry.js"); let Mt = require("./mt.js"); let Stdlib = require("melange/stdlib.js"); let Stdlib__List = require("melange/list.js"); +let Stdlib__Seq = require("melange/seq.js"); const compare = Caml.caml_int_compare; diff --git a/jscomp/test/dist/jscomp/test/map_test.js b/jscomp/test/dist/jscomp/test/map_test.js index 231202b208..3e90de9386 100644 --- a/jscomp/test/dist/jscomp/test/map_test.js +++ b/jscomp/test/dist/jscomp/test/map_test.js @@ -3,10 +3,12 @@ let Caml = require("melange.js/caml.js"); let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); +let Caml_option = require("melange.js/caml_option.js"); let Curry = require("melange.js/curry.js"); let Mt = require("./mt.js"); let Stdlib = require("melange/stdlib.js"); let Stdlib__List = require("melange/list.js"); +let Stdlib__Seq = require("melange/seq.js"); let Stdlib__String = require("melange/string.js"); const compare = Caml.caml_int_compare; diff --git a/jscomp/test/dist/jscomp/test/ocaml_parsetree_test.js b/jscomp/test/dist/jscomp/test/ocaml_parsetree_test.js index 52a340d0f6..f6e8d2404c 100644 --- a/jscomp/test/dist/jscomp/test/ocaml_parsetree_test.js +++ b/jscomp/test/dist/jscomp/test/ocaml_parsetree_test.js @@ -7,6 +7,7 @@ let Caml_bytes = require("melange.js/caml_bytes.js"); let Caml_exceptions = require("melange.js/caml_exceptions.js"); let Caml_external_polyfill = require("melange.js/caml_external_polyfill.js"); let Caml_format = require("melange.js/caml_format.js"); +let Caml_int32 = require("melange.js/caml_int32.js"); let Caml_int64 = require("melange.js/caml_int64.js"); let Caml_io = require("melange.js/caml_io.js"); let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); diff --git a/jscomp/test/dist/jscomp/test/ocaml_proto_test.js b/jscomp/test/dist/jscomp/test/ocaml_proto_test.js index 8b49c0b3be..394d66763b 100644 --- a/jscomp/test/dist/jscomp/test/ocaml_proto_test.js +++ b/jscomp/test/dist/jscomp/test/ocaml_proto_test.js @@ -20,6 +20,7 @@ let Stdlib__List = require("melange/list.js"); let Stdlib__Parsing = require("melange/parsing.js"); let Stdlib__Printexc = require("melange/printexc.js"); let Stdlib__Printf = require("melange/printf.js"); +let Stdlib__Seq = require("melange/seq.js"); let Stdlib__String = require("melange/string.js"); function field(optionsOpt, label, number, type_, name) { diff --git a/jscomp/test/dist/jscomp/test/ocaml_re_test.js b/jscomp/test/dist/jscomp/test/ocaml_re_test.js index aa113b4b26..d1306040b7 100644 --- a/jscomp/test/dist/jscomp/test/ocaml_re_test.js +++ b/jscomp/test/dist/jscomp/test/ocaml_re_test.js @@ -18,6 +18,7 @@ let Stdlib__Char = require("melange/char.js"); let Stdlib__Format = require("melange/format.js"); let Stdlib__Hashtbl = require("melange/hashtbl.js"); let Stdlib__List = require("melange/list.js"); +let Stdlib__Seq = require("melange/seq.js"); let Stdlib__String = require("melange/string.js"); const suites = { diff --git a/jscomp/test/dist/jscomp/test/ocaml_typedtree_test.js b/jscomp/test/dist/jscomp/test/ocaml_typedtree_test.js index 66e04cb1b5..3b95ad8f0f 100644 --- a/jscomp/test/dist/jscomp/test/ocaml_typedtree_test.js +++ b/jscomp/test/dist/jscomp/test/ocaml_typedtree_test.js @@ -7,6 +7,7 @@ let Caml_bytes = require("melange.js/caml_bytes.js"); let Caml_exceptions = require("melange.js/caml_exceptions.js"); let Caml_external_polyfill = require("melange.js/caml_external_polyfill.js"); let Caml_format = require("melange.js/caml_format.js"); +let Caml_int32 = require("melange.js/caml_int32.js"); let Caml_int64 = require("melange.js/caml_int64.js"); let Caml_io = require("melange.js/caml_io.js"); let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); diff --git a/jscomp/test/dist/jscomp/test/test_functor_dead_code.js b/jscomp/test/dist/jscomp/test/test_functor_dead_code.js index b6a6f3a751..4e1d25f80c 100644 --- a/jscomp/test/dist/jscomp/test/test_functor_dead_code.js +++ b/jscomp/test/dist/jscomp/test/test_functor_dead_code.js @@ -1,7 +1,13 @@ // Generated by Melange 'use strict'; +let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); +let Caml_option = require("melange.js/caml_option.js"); let Curry = require("melange.js/curry.js"); +let Stdlib = require("melange/stdlib.js"); +let Stdlib__List = require("melange/list.js"); +let Stdlib__Seq = require("melange/seq.js"); +let Stdlib__String = require("melange/string.js"); function is_empty(param) { if (param) { diff --git a/jscomp/test/dist/jscomp/test/test_int_map_find.js b/jscomp/test/dist/jscomp/test/test_int_map_find.js index 1c2eaf0f4f..59a793ef3a 100644 --- a/jscomp/test/dist/jscomp/test/test_int_map_find.js +++ b/jscomp/test/dist/jscomp/test/test_int_map_find.js @@ -3,8 +3,11 @@ let Caml = require("melange.js/caml.js"); let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); +let Caml_option = require("melange.js/caml_option.js"); let Curry = require("melange.js/curry.js"); +let Stdlib = require("melange/stdlib.js"); let Stdlib__List = require("melange/list.js"); +let Stdlib__Seq = require("melange/seq.js"); const compare = Caml.caml_int_compare; diff --git a/jscomp/test/dist/jscomp/test/test_non_export.js b/jscomp/test/dist/jscomp/test/test_non_export.js index 18d1b2691c..2c965ba93e 100644 --- a/jscomp/test/dist/jscomp/test/test_non_export.js +++ b/jscomp/test/dist/jscomp/test/test_non_export.js @@ -1,6 +1,14 @@ // Generated by Melange 'use strict'; +let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); +let Caml_obj = require("melange.js/caml_obj.js"); +let Caml_option = require("melange.js/caml_option.js"); +let Curry = require("melange.js/curry.js"); +let Stdlib = require("melange/stdlib.js"); +let Stdlib__List = require("melange/list.js"); +let Stdlib__Seq = require("melange/seq.js"); +let Stdlib__String = require("melange/string.js"); /* Not a pure module */ diff --git a/jscomp/test/dist/jscomp/test/test_string_map.js b/jscomp/test/dist/jscomp/test/test_string_map.js index 206cf8e8de..ea4740db6e 100644 --- a/jscomp/test/dist/jscomp/test/test_string_map.js +++ b/jscomp/test/dist/jscomp/test/test_string_map.js @@ -3,8 +3,11 @@ let Caml = require("melange.js/caml.js"); let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); +let Caml_option = require("melange.js/caml_option.js"); let Curry = require("melange.js/curry.js"); let Stdlib = require("melange/stdlib.js"); +let Stdlib__List = require("melange/list.js"); +let Stdlib__Seq = require("melange/seq.js"); const compare = Caml.caml_string_compare; From b10b762a2907a5df0c9baa8832bd3971f6247159 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Thu, 15 Feb 2024 17:44:34 -0800 Subject: [PATCH 7/8] Calculate dependencies again at JS emission time --- jscomp/core/js_cmj_format.ml | 6 +- jscomp/core/js_cmj_format.mli | 6 +- jscomp/core/js_implementation.ml | 13 +-- jscomp/core/lam_compile.ml | 3 +- jscomp/core/lam_compile_env.ml | 4 +- jscomp/core/lam_compile_main.cppo.ml | 147 +++++++++++++++++---------- jscomp/core/lam_compile_main.mli | 11 +- jscomp/core/lam_stats_export.ml | 19 ++-- jscomp/core/lam_stats_export.mli | 2 +- jscomp/core/lam_util.ml | 2 - jscomp/core/lam_util.mli | 1 - 11 files changed, 121 insertions(+), 93 deletions(-) diff --git a/jscomp/core/js_cmj_format.ml b/jscomp/core/js_cmj_format.ml index 6b39436974..637938ddea 100644 --- a/jscomp/core/js_cmj_format.ml +++ b/jscomp/core/js_cmj_format.ml @@ -33,8 +33,6 @@ type cmj_value = { (** Either constant or closed functor *) } -type effect = string option - let single_na = Single Lam_arity.na type keyed_cmj_value = { @@ -47,7 +45,7 @@ type keyed_cmj_values = keyed_cmj_value array type t = { values : keyed_cmj_values; - pure : bool; + effect : string option; package_spec : Js_packages_info.t; case : Js_packages_info.file_case; delayed_program : J.deps_program; @@ -63,7 +61,7 @@ let make ~(values : cmj_value String.Map.t) ~effect ~package_spec ~case arity = v.arity; persistent_closed_lambda = v.persistent_closed_lambda; }); - pure = effect = None; + effect; package_spec; case; delayed_program; diff --git a/jscomp/core/js_cmj_format.mli b/jscomp/core/js_cmj_format.mli index bc2acd1f16..e2157d8be6 100644 --- a/jscomp/core/js_cmj_format.mli +++ b/jscomp/core/js_cmj_format.mli @@ -54,8 +54,6 @@ type cmj_value = { (* Either constant or closed functor *) } -type effect = string option - type keyed_cmj_value = { name : string; arity : arity; @@ -64,7 +62,7 @@ type keyed_cmj_value = { type t = { values : keyed_cmj_value array; - pure : bool; + effect : string option; package_spec : Js_packages_info.t; case : Js_packages_info.file_case; delayed_program : J.deps_program; @@ -72,7 +70,7 @@ type t = { val make : values:cmj_value String.Map.t -> - effect:effect -> + effect:string option -> package_spec:Js_packages_info.t -> case:Js_packages_info.file_case -> delayed_program:J.deps_program -> diff --git a/jscomp/core/js_implementation.ml b/jscomp/core/js_implementation.ml index 8a3ab210ac..efb078eed6 100644 --- a/jscomp/core/js_implementation.ml +++ b/jscomp/core/js_implementation.ml @@ -167,7 +167,7 @@ let after_parsing_impl ppf fname (ast : Parsetree.structure) = let lambda = Translmod.transl_implementation modulename typedtree_coercion in - let lambda_coercion = + let cmj = print_if ppf Clflags.dump_rawlambda Printlambda.lambda lambda.code; Lam_compile_main.compile_coercion ~output_prefix:outputprefix lambda.code @@ -176,9 +176,11 @@ let after_parsing_impl ppf fname (ast : Parsetree.structure) = (* XXX(anmonteiro): important that we get package_info after processing, as `[@@@config {flags = [| ... |]}]` could have added to package specs. *) - let package_info = Js_packages_state.get_packages_info () in - Lam_compile_main.lambda_as_module ~package_info - ~output_prefix:outputprefix lambda_coercion + let cmj = + let package_spec = Js_packages_state.get_packages_info () in + { cmj with package_spec } + in + Lam_compile_main.lambda_as_module ~output_prefix:outputprefix cmj (* process_with_gentype (Artifact_extension.append_extension outputprefix Cmt) *) let implementation ~parser ppf fname = @@ -202,5 +204,4 @@ let implementation_cmj _ppf fname = let output_prefix = output_prefix ~f:Filename.chop_all_extensions_maybe fname in - Lam_compile_main.lambda_as_module ~package_info:cmj.package_spec - cmj.delayed_program ~output_prefix + Lam_compile_main.lambda_as_module cmj ~output_prefix diff --git a/jscomp/core/lam_compile.ml b/jscomp/core/lam_compile.ml index a1df320a1a..cc78a573c4 100644 --- a/jscomp/core/lam_compile.ml +++ b/jscomp/core/lam_compile.ml @@ -190,7 +190,8 @@ type initialization = J.block let rec compile_external_field (* Like [List.empty]*) (lamba_cxt : Lam_compile_context.t) (id : Ident.t) name : Js_output.t = match Lam_compile_env.query_external_id_info id name with - | { persistent_closed_lambda = Some lam; _ } when Lam_util.not_function lam -> + | { persistent_closed_lambda = Some lam; _ } + when not (Lam_util.is_function lam) -> compile_lambda lamba_cxt lam | _ -> Js_output.output_of_expression lamba_cxt.continuation diff --git a/jscomp/core/lam_compile_env.ml b/jscomp/core/lam_compile_env.ml index 8d1d385b95..2f9208610e 100644 --- a/jscomp/core/lam_compile_env.ml +++ b/jscomp/core/lam_compile_env.ml @@ -130,9 +130,9 @@ let is_pure_module (oid : Lam_module_ident.t) = match Js_cmj_format.load_unit (Lam_module_ident.name oid) with | cmj_load_info -> oid +> Ml cmj_load_info; - cmj_load_info.cmj_table.pure + cmj_load_info.cmj_table.effect = None | exception _ -> false) - | Some (Ml { cmj_table; _ }) -> cmj_table.pure + | Some (Ml { cmj_table; _ }) -> cmj_table.effect = None | Some External -> false) let populate_required_modules extras diff --git a/jscomp/core/lam_compile_main.cppo.ml b/jscomp/core/lam_compile_main.cppo.ml index 3e2e441df0..48c3a43f0b 100644 --- a/jscomp/core/lam_compile_main.cppo.ml +++ b/jscomp/core/lam_compile_main.cppo.ml @@ -228,7 +228,7 @@ let () = in #endif - let maybe_pure = no_side_effects groups in + let maybe_impure = no_side_effects groups in #ifndef BS_RELEASE_BUILD let () = @@ -248,11 +248,24 @@ let () = (Pp.textf "[TIME:]Post-compile: %f" (Sys.time () *. 1000.)) in #endif + let program : J.program = + let meta_exports = meta.exports in + let export_set = + Ident.Set.of_list meta_exports + in + { + exports = meta_exports ; + export_set; + block = body} + in + + Warnings.check_fatal(); + let external_module_ids : Lam_module_ident.t list = if !Js_config.all_module_aliases then [] else let hard_deps = - Js_fold_basic.calculate_hard_dependencies body + Js_fold_basic.calculate_hard_dependencies program.block in Lam_compile_env.populate_required_modules maybe_required_modules hard_deps; let module_ids = @@ -268,30 +281,19 @@ in in module_ids in + let effect = + Lam_stats_export.get_dependent_module_effect + maybe_impure external_module_ids in - let js : J.program = - let meta_exports = meta.exports in - let export_set = - Ident.Set.of_list meta_exports - in + let delayed_program: J.deps_program = { - exports = meta_exports ; - export_set; - block = body} + J.program; + side_effect = effect; + preamble = !Js_config.preamble; + modules = external_module_ids + } in - Warnings.check_fatal(); - - let effect = - Lam_stats_export.get_dependent_module_effect - maybe_pure external_module_ids in - let delayed_program = { - J.program = js ; - side_effect = effect ; - preamble = !Js_config.preamble; - modules = external_module_ids - } - in let case = Js_packages_info.module_case ~output_prefix @@ -302,51 +304,86 @@ in ~case ~delayed_program meta - effect + ~effect coerced_input.export_map in (if not !Clflags.dont_write_files then Js_cmj_format.to_file (Artifact_extension.append_extension output_prefix Cmj) cmj); - delayed_program + cmj ;; -let emit_program (deps_program: J.deps_program) = - deps_program.program - |> _j "initial" - |> Js_pass_flatten.program - |> _j "flatten" - |> Js_pass_tailcall_inline.tailcall_inline - |> _j "inline_and_shake" - |> Js_pass_flatten_and_mark_dead.program - |> _j "flatten_and_mark_dead" - |> Js_pass_scope.program - |> Js_shake.shake_program - |> _j "shake" - |> (fun (program: J.program) -> - {deps_program with program }) - -let optimize_program = emit_program - - -let write_to_file ~package_info ~output_info ~output_prefix lambda_output file = - let oc = open_out_bin file in - Fun.protect - ~finally:(fun () -> close_out oc) - (fun () -> - Js_dump_program.dump_deps_program - ~package_info - ~output_info - ~output_prefix - lambda_output - oc) +let optimize_program (cmj: Js_cmj_format.t) = + let deps_program = + let deps_program = cmj.delayed_program in + deps_program.program + |> _j "initial" + |> Js_pass_flatten.program + |> _j "flatten" + |> Js_pass_tailcall_inline.tailcall_inline + |> _j "inline_and_shake" + |> Js_pass_flatten_and_mark_dead.program + |> _j "flatten_and_mark_dead" + |> Js_pass_scope.program + |> Js_shake.shake_program + |> _j "shake" + |> (fun (program: J.program) -> + {deps_program with program }) + in + let program = deps_program.program in + let external_module_ids : Lam_module_ident.t list = + if !Js_config.all_module_aliases then [] + else + let hard_deps = + Js_fold_basic.calculate_hard_dependencies program.block + in + Lam_compile_env.populate_required_modules + (deps_program.modules |> Array.of_list |> Lam_module_ident.Hash_set.of_array) + hard_deps; + let module_ids = + let arr = + Lam_module_ident.Hash_set.to_list hard_deps + |> Array.of_list + in + Array.sort + ~cmp:(fun id1 id2 -> + String.compare (Lam_module_ident.name id1) (Lam_module_ident.name id2)) + arr; + Array.to_list arr + in + module_ids + in + let effect = + Lam_stats_export.get_dependent_module_effect + cmj.effect external_module_ids + in + let deps_program = { + deps_program with + side_effect = effect ; + modules = external_module_ids + } + in + deps_program let lambda_as_module = let (//) = Path.(//) in - fun ~package_info ~output_prefix t : unit -> + let write_to_file ~package_info ~output_info ~output_prefix lambda_output file = + let oc = open_out_bin file in + Fun.protect + ~finally:(fun () -> close_out oc) + (fun () -> + Js_dump_program.dump_deps_program + ~package_info + ~output_info + ~output_prefix + lambda_output + oc) + in + fun ~output_prefix (cmj : Js_cmj_format.t) -> let make_basename suffix = (Filename.basename output_prefix) ^ (Js_suffix.to_string suffix) in - let lambda_output : J.deps_program = emit_program t in + let package_info = cmj.package_spec in + let lambda_output : J.deps_program = optimize_program cmj in match (!Js_config.js_stdout, !Clflags.output_name) with | (true, None) -> Js_dump_program.dump_deps_program diff --git a/jscomp/core/lam_compile_main.mli b/jscomp/core/lam_compile_main.mli index 9769088bbf..9a40681195 100644 --- a/jscomp/core/lam_compile_main.mli +++ b/jscomp/core/lam_compile_main.mli @@ -28,14 +28,9 @@ open Import (** Compile and register the hook of function to compile a lambda to JS IR *) -val compile_coercion : output_prefix:string -> Lambda.lambda -> J.deps_program +val compile_coercion : output_prefix:string -> Lambda.lambda -> Js_cmj_format.t (** For toplevel, [filename] is [""] which is the same as {!Env.get_unit_name ()} *) -val optimize_program : J.deps_program -> J.deps_program - -val lambda_as_module : - package_info:Js_packages_info.t -> - output_prefix:string -> - J.deps_program -> - unit +val optimize_program : Js_cmj_format.t -> J.deps_program +val lambda_as_module : output_prefix:string -> Js_cmj_format.t -> unit diff --git a/jscomp/core/lam_stats_export.ml b/jscomp/core/lam_stats_export.ml index 723ff0da79..74fab1449e 100644 --- a/jscomp/core/lam_stats_export.ml +++ b/jscomp/core/lam_stats_export.ml @@ -117,14 +117,15 @@ let values_of_export (meta : Lam_stats.t) (export_map : Lam.t Ident.Map.t) : *) let get_dependent_module_effect (maybe_pure : string option) (external_ids : Lam_module_ident.t list) = - if maybe_pure = None then - let non_pure_module = - List.find_opt - ~f:(fun id -> not (Lam_compile_env.is_pure_module id)) - external_ids - in - Option.map (fun x -> Lam_module_ident.name x) non_pure_module - else maybe_pure + match maybe_pure with + | None -> + let non_pure_module = + List.find_opt + ~f:(fun id -> not (Lam_compile_env.is_pure_module id)) + external_ids + in + Option.map (fun x -> Lam_module_ident.name x) non_pure_module + | Some _ -> maybe_pure (* Note that [lambda_exports] is @@ -137,7 +138,7 @@ let get_dependent_module_effect (maybe_pure : string option) ]} TODO: check that we don't do this in browser environment *) -let export_to_cmj ~case meta effect export_map = +let export_to_cmj ~case meta ~effect export_map = let values = values_of_export meta export_map in Js_cmj_format.make ~values ~effect diff --git a/jscomp/core/lam_stats_export.mli b/jscomp/core/lam_stats_export.mli index fae0849009..cb04281f28 100644 --- a/jscomp/core/lam_stats_export.mli +++ b/jscomp/core/lam_stats_export.mli @@ -30,7 +30,7 @@ val get_dependent_module_effect : val export_to_cmj : case:Js_packages_info.file_case -> Lam_stats.t -> - Js_cmj_format.effect -> + effect:string option -> Lam.t Ident.Map.t -> (* FIXME: this is a leaky abstraction *) delayed_program:J.deps_program -> diff --git a/jscomp/core/lam_util.ml b/jscomp/core/lam_util.ml index 30af287439..46d139b273 100644 --- a/jscomp/core/lam_util.ml +++ b/jscomp/core/lam_util.ml @@ -198,8 +198,6 @@ let generate_label ?(name = "") () = let is_function (lam : Lam.t) = match lam with Lfunction _ -> true | _ -> false -let not_function (lam : Lam.t) = - match lam with Lfunction _ -> false | _ -> true (* let is_var (lam : Lam.t) id = match lam with diff --git a/jscomp/core/lam_util.mli b/jscomp/core/lam_util.mli index 5dbb4a1f74..402954ecdc 100644 --- a/jscomp/core/lam_util.mli +++ b/jscomp/core/lam_util.mli @@ -56,5 +56,4 @@ val alias_ident_or_global : val refine_let : kind:Lam_group.let_kind -> Ident.t -> Lam.t -> Lam.t -> Lam.t val generate_label : ?name:string -> unit -> J.label -val not_function : Lam.t -> bool val is_function : Lam.t -> bool From f8c1f19684e35dab003213e196108ee52c0e76c3 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Thu, 15 Feb 2024 17:45:42 -0800 Subject: [PATCH 8/8] chore: snapshot runtime tests, demonstrate we get optmiziation back --- jscomp/test/dist/jscomp/test/demo_int_map.js | 3 --- jscomp/test/dist/jscomp/test/flow_parser_reg_test.js | 1 - jscomp/test/dist/jscomp/test/map_find_test.js | 2 -- jscomp/test/dist/jscomp/test/map_test.js | 2 -- jscomp/test/dist/jscomp/test/ocaml_parsetree_test.js | 1 - jscomp/test/dist/jscomp/test/ocaml_proto_test.js | 1 - jscomp/test/dist/jscomp/test/ocaml_re_test.js | 1 - jscomp/test/dist/jscomp/test/ocaml_typedtree_test.js | 1 - jscomp/test/dist/jscomp/test/test_functor_dead_code.js | 6 ------ jscomp/test/dist/jscomp/test/test_int_map_find.js | 3 --- jscomp/test/dist/jscomp/test/test_non_export.js | 8 -------- jscomp/test/dist/jscomp/test/test_string_map.js | 3 --- 12 files changed, 32 deletions(-) diff --git a/jscomp/test/dist/jscomp/test/demo_int_map.js b/jscomp/test/dist/jscomp/test/demo_int_map.js index df458669f7..e8b13df55a 100644 --- a/jscomp/test/dist/jscomp/test/demo_int_map.js +++ b/jscomp/test/dist/jscomp/test/demo_int_map.js @@ -2,11 +2,8 @@ 'use strict'; let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); -let Caml_option = require("melange.js/caml_option.js"); let Curry = require("melange.js/curry.js"); let Stdlib = require("melange/stdlib.js"); -let Stdlib__List = require("melange/list.js"); -let Stdlib__Seq = require("melange/seq.js"); function compare(x, y) { return x - y | 0; diff --git a/jscomp/test/dist/jscomp/test/flow_parser_reg_test.js b/jscomp/test/dist/jscomp/test/flow_parser_reg_test.js index c0e314920d..282ff25b8b 100644 --- a/jscomp/test/dist/jscomp/test/flow_parser_reg_test.js +++ b/jscomp/test/dist/jscomp/test/flow_parser_reg_test.js @@ -22,7 +22,6 @@ let Stdlib__Lexing = require("melange/lexing.js"); let Stdlib__List = require("melange/list.js"); let Stdlib__Printf = require("melange/printf.js"); let Stdlib__Queue = require("melange/queue.js"); -let Stdlib__Seq = require("melange/seq.js"); let Stdlib__String = require("melange/string.js"); let Stdlib__Sys = require("melange/sys.js"); let Fs = require("fs"); diff --git a/jscomp/test/dist/jscomp/test/map_find_test.js b/jscomp/test/dist/jscomp/test/map_find_test.js index 1941856b68..e29b07154e 100644 --- a/jscomp/test/dist/jscomp/test/map_find_test.js +++ b/jscomp/test/dist/jscomp/test/map_find_test.js @@ -3,12 +3,10 @@ let Caml = require("melange.js/caml.js"); let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); -let Caml_option = require("melange.js/caml_option.js"); let Curry = require("melange.js/curry.js"); let Mt = require("./mt.js"); let Stdlib = require("melange/stdlib.js"); let Stdlib__List = require("melange/list.js"); -let Stdlib__Seq = require("melange/seq.js"); const compare = Caml.caml_int_compare; diff --git a/jscomp/test/dist/jscomp/test/map_test.js b/jscomp/test/dist/jscomp/test/map_test.js index 3e90de9386..231202b208 100644 --- a/jscomp/test/dist/jscomp/test/map_test.js +++ b/jscomp/test/dist/jscomp/test/map_test.js @@ -3,12 +3,10 @@ let Caml = require("melange.js/caml.js"); let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); -let Caml_option = require("melange.js/caml_option.js"); let Curry = require("melange.js/curry.js"); let Mt = require("./mt.js"); let Stdlib = require("melange/stdlib.js"); let Stdlib__List = require("melange/list.js"); -let Stdlib__Seq = require("melange/seq.js"); let Stdlib__String = require("melange/string.js"); const compare = Caml.caml_int_compare; diff --git a/jscomp/test/dist/jscomp/test/ocaml_parsetree_test.js b/jscomp/test/dist/jscomp/test/ocaml_parsetree_test.js index f6e8d2404c..52a340d0f6 100644 --- a/jscomp/test/dist/jscomp/test/ocaml_parsetree_test.js +++ b/jscomp/test/dist/jscomp/test/ocaml_parsetree_test.js @@ -7,7 +7,6 @@ let Caml_bytes = require("melange.js/caml_bytes.js"); let Caml_exceptions = require("melange.js/caml_exceptions.js"); let Caml_external_polyfill = require("melange.js/caml_external_polyfill.js"); let Caml_format = require("melange.js/caml_format.js"); -let Caml_int32 = require("melange.js/caml_int32.js"); let Caml_int64 = require("melange.js/caml_int64.js"); let Caml_io = require("melange.js/caml_io.js"); let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); diff --git a/jscomp/test/dist/jscomp/test/ocaml_proto_test.js b/jscomp/test/dist/jscomp/test/ocaml_proto_test.js index 394d66763b..8b49c0b3be 100644 --- a/jscomp/test/dist/jscomp/test/ocaml_proto_test.js +++ b/jscomp/test/dist/jscomp/test/ocaml_proto_test.js @@ -20,7 +20,6 @@ let Stdlib__List = require("melange/list.js"); let Stdlib__Parsing = require("melange/parsing.js"); let Stdlib__Printexc = require("melange/printexc.js"); let Stdlib__Printf = require("melange/printf.js"); -let Stdlib__Seq = require("melange/seq.js"); let Stdlib__String = require("melange/string.js"); function field(optionsOpt, label, number, type_, name) { diff --git a/jscomp/test/dist/jscomp/test/ocaml_re_test.js b/jscomp/test/dist/jscomp/test/ocaml_re_test.js index d1306040b7..aa113b4b26 100644 --- a/jscomp/test/dist/jscomp/test/ocaml_re_test.js +++ b/jscomp/test/dist/jscomp/test/ocaml_re_test.js @@ -18,7 +18,6 @@ let Stdlib__Char = require("melange/char.js"); let Stdlib__Format = require("melange/format.js"); let Stdlib__Hashtbl = require("melange/hashtbl.js"); let Stdlib__List = require("melange/list.js"); -let Stdlib__Seq = require("melange/seq.js"); let Stdlib__String = require("melange/string.js"); const suites = { diff --git a/jscomp/test/dist/jscomp/test/ocaml_typedtree_test.js b/jscomp/test/dist/jscomp/test/ocaml_typedtree_test.js index 3b95ad8f0f..66e04cb1b5 100644 --- a/jscomp/test/dist/jscomp/test/ocaml_typedtree_test.js +++ b/jscomp/test/dist/jscomp/test/ocaml_typedtree_test.js @@ -7,7 +7,6 @@ let Caml_bytes = require("melange.js/caml_bytes.js"); let Caml_exceptions = require("melange.js/caml_exceptions.js"); let Caml_external_polyfill = require("melange.js/caml_external_polyfill.js"); let Caml_format = require("melange.js/caml_format.js"); -let Caml_int32 = require("melange.js/caml_int32.js"); let Caml_int64 = require("melange.js/caml_int64.js"); let Caml_io = require("melange.js/caml_io.js"); let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); diff --git a/jscomp/test/dist/jscomp/test/test_functor_dead_code.js b/jscomp/test/dist/jscomp/test/test_functor_dead_code.js index 4e1d25f80c..b6a6f3a751 100644 --- a/jscomp/test/dist/jscomp/test/test_functor_dead_code.js +++ b/jscomp/test/dist/jscomp/test/test_functor_dead_code.js @@ -1,13 +1,7 @@ // Generated by Melange 'use strict'; -let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); -let Caml_option = require("melange.js/caml_option.js"); let Curry = require("melange.js/curry.js"); -let Stdlib = require("melange/stdlib.js"); -let Stdlib__List = require("melange/list.js"); -let Stdlib__Seq = require("melange/seq.js"); -let Stdlib__String = require("melange/string.js"); function is_empty(param) { if (param) { diff --git a/jscomp/test/dist/jscomp/test/test_int_map_find.js b/jscomp/test/dist/jscomp/test/test_int_map_find.js index 59a793ef3a..1c2eaf0f4f 100644 --- a/jscomp/test/dist/jscomp/test/test_int_map_find.js +++ b/jscomp/test/dist/jscomp/test/test_int_map_find.js @@ -3,11 +3,8 @@ let Caml = require("melange.js/caml.js"); let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); -let Caml_option = require("melange.js/caml_option.js"); let Curry = require("melange.js/curry.js"); -let Stdlib = require("melange/stdlib.js"); let Stdlib__List = require("melange/list.js"); -let Stdlib__Seq = require("melange/seq.js"); const compare = Caml.caml_int_compare; diff --git a/jscomp/test/dist/jscomp/test/test_non_export.js b/jscomp/test/dist/jscomp/test/test_non_export.js index 2c965ba93e..18d1b2691c 100644 --- a/jscomp/test/dist/jscomp/test/test_non_export.js +++ b/jscomp/test/dist/jscomp/test/test_non_export.js @@ -1,14 +1,6 @@ // Generated by Melange 'use strict'; -let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); -let Caml_obj = require("melange.js/caml_obj.js"); -let Caml_option = require("melange.js/caml_option.js"); -let Curry = require("melange.js/curry.js"); -let Stdlib = require("melange/stdlib.js"); -let Stdlib__List = require("melange/list.js"); -let Stdlib__Seq = require("melange/seq.js"); -let Stdlib__String = require("melange/string.js"); /* Not a pure module */ diff --git a/jscomp/test/dist/jscomp/test/test_string_map.js b/jscomp/test/dist/jscomp/test/test_string_map.js index ea4740db6e..206cf8e8de 100644 --- a/jscomp/test/dist/jscomp/test/test_string_map.js +++ b/jscomp/test/dist/jscomp/test/test_string_map.js @@ -3,11 +3,8 @@ let Caml = require("melange.js/caml.js"); let Caml_js_exceptions = require("melange.js/caml_js_exceptions.js"); -let Caml_option = require("melange.js/caml_option.js"); let Curry = require("melange.js/curry.js"); let Stdlib = require("melange/stdlib.js"); -let Stdlib__List = require("melange/list.js"); -let Stdlib__Seq = require("melange/seq.js"); const compare = Caml.caml_string_compare;