Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

delay cmj optimizations #475

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
12 changes: 7 additions & 5 deletions jscomp/core/js_implementation.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -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
Expand Down
208 changes: 100 additions & 108 deletions jscomp/core/lam_compile_main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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) =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does "coercion" mean in this context?

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 *)
Expand All @@ -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
Expand All @@ -148,7 +133,7 @@ let compile
let lam =
let lam =
lam
|> _d "flattern1"
|> _d "flatten1"
|> Lam_pass_exits.simplify_exits
|> _d "simplyf_exits"
anmonteiro marked this conversation as resolved.
Show resolved Hide resolved
|> (fun lam -> Lam_pass_collect.collect_info meta lam;
Expand Down Expand Up @@ -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
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 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
)
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
Expand All @@ -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
Expand All @@ -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}
Expand Down
7 changes: 5 additions & 2 deletions jscomp/core/lam_compile_main.mli
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 2 additions & 0 deletions jscomp/test/demo_int_map.js
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
1 change: 1 addition & 0 deletions jscomp/test/flow_parser_reg_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
2 changes: 2 additions & 0 deletions jscomp/test/map_find_test.js
Original file line number Diff line number Diff line change
@@ -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;

Expand Down
2 changes: 2 additions & 0 deletions jscomp/test/map_test.js
Original file line number Diff line number Diff line change
@@ -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;

Expand Down
1 change: 1 addition & 0 deletions jscomp/test/ocaml_parsetree_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
1 change: 1 addition & 0 deletions jscomp/test/ocaml_proto_test.js
Original file line number Diff line number Diff line change
@@ -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");
Expand Down
1 change: 1 addition & 0 deletions jscomp/test/ocaml_re_test.js
Original file line number Diff line number Diff line change
@@ -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");
Expand Down
1 change: 1 addition & 0 deletions jscomp/test/ocaml_typedtree_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
Loading