Skip to content

Commit 0fa87ae

Browse files
committed
Make aggressive lambda lifting opt-in
1 parent d1f9b14 commit 0fa87ae

File tree

6 files changed

+45
-24
lines changed

6 files changed

+45
-24
lines changed

compiler/bin-js_of_ocaml/build_fs.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ function jsoo_create_file_extern(name,content){
8080
~standalone:true
8181
~wrap_with_fun:`Iife
8282
~link:`Needed
83+
~lambda_lift_all:false
8384
~formatter:pfs_fmt
8485
~source_map:false
8586
code

compiler/bin-js_of_ocaml/cmd_arg.ml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ type t =
7878
; fs_external : bool
7979
; keep_unit_names : bool
8080
; effects : Config.effects_backend
81+
; lambda_lift_all : bool
8182
}
8283

8384
let set_param =
@@ -306,6 +307,14 @@ let options =
306307
None
307308
& info [ "effects" ] ~docv:"KIND" ~doc)
308309
in
310+
let lambda_lift_all =
311+
let doc =
312+
"Lambda-lift all functions in the compilation result. This can improve \
313+
the performance of some programs on some engines (such as V8). \
314+
Ignored when effects are enabled."
315+
in
316+
Arg.(value & flag & info [ "lambda-lift-all" ] ~doc)
317+
in
309318
let build_t
310319
common
311320
set_param
@@ -335,6 +344,7 @@ let options =
335344
js_files
336345
keep_unit_names
337346
effects
347+
lambda_lift_all
338348
shape_files =
339349
let inline_source_content = not sourcemap_don't_inline_content in
340350
let chop_extension s = try Filename.chop_extension s with Invalid_argument _ -> s in
@@ -406,6 +416,7 @@ let options =
406416
; source_map
407417
; keep_unit_names
408418
; effects
419+
; lambda_lift_all
409420
; shape_files
410421
}
411422
in
@@ -440,6 +451,7 @@ let options =
440451
$ js_files
441452
$ keep_unit_names
442453
$ effects
454+
$ lambda_lift_all
443455
$ shape_files)
444456
in
445457
Term.ret t
@@ -662,6 +674,7 @@ let options_runtime_only =
662674
; keep_unit_names = false
663675
; effects
664676
; shape_files = []
677+
; lambda_lift_all = false
665678
}
666679
in
667680
let t =

compiler/bin-js_of_ocaml/cmd_arg.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ type t =
5151
; fs_external : bool
5252
; keep_unit_names : bool
5353
; effects : Config.effects_backend
54+
; lambda_lift_all : bool
5455
}
5556

5657
val options : t Cmdliner.Term.t

compiler/bin-js_of_ocaml/compile.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ let run
156156
; keep_unit_names
157157
; include_runtime
158158
; effects
159+
; lambda_lift_all
159160
; shape_files
160161
} =
161162
let source_map_base =
@@ -279,6 +280,7 @@ let run
279280
~wrap_with_fun
280281
~source_map:(source_map_enabled source_map)
281282
~formatter
283+
~lambda_lift_all
282284
code
283285
| `File, formatter ->
284286
let fs_instr1, fs_instr2 =
@@ -300,6 +302,7 @@ let run
300302
~shapes
301303
?profile
302304
~link
305+
~lambda_lift_all
303306
~wrap_with_fun
304307
~source_map:(source_map_enabled source_map)
305308
~formatter

compiler/lib/driver.ml

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,21 @@ let collects_shapes ~shapes (p : Code.program) =
142142
map)
143143
else StringMap.empty
144144

145+
let all_functions p =
146+
let open Code in
147+
fold_closures
148+
p
149+
(fun name _ _ _ acc ->
150+
match name with
151+
| Some name -> Var.Set.add name acc
152+
| None -> acc)
153+
Var.Set.empty
154+
145155
let effects_and_exact_calls
146156
~keep_flow_data
147157
~deadcode_sentinal
148158
~shapes
159+
~lambda_lift_all
149160
(profile : Profile.t)
150161
p =
151162
let fast =
@@ -166,11 +177,8 @@ let effects_and_exact_calls
166177
else Deadcode.f pure_fun p
167178
in
168179
let p =
169-
match Config.(target (), effects ()) with
170-
| `JavaScript, `Disabled ->
171-
(* If effects are disabled, we lambda-lift aggressively. While not
172-
necessary, it results in a substantial gain in performance in some
173-
programs in Javascript. *)
180+
match lambda_lift_all, Config.target (), Config.effects () with
181+
| true, `JavaScript, `Disabled ->
174182
let to_lift = all_functions p in
175183
let p, _ = Lambda_lifting_simple.f ~to_lift p in
176184
p
@@ -707,17 +715,7 @@ let link_and_pack ?(standalone = true) ?(wrap_with_fun = `Iife) ?(link = `No) p
707715
|> pack ~wrap_with_fun ~standalone
708716
|> check_js
709717

710-
let all_functions p =
711-
let open Code in
712-
fold_closures
713-
p
714-
(fun name _ _ _ acc ->
715-
match name with
716-
| Some name -> Var.Set.add name acc
717-
| None -> acc)
718-
Var.Set.empty
719-
720-
let optimize ~shapes ~profile ~keep_flow_data p =
718+
let optimize ~shapes ~profile ~keep_flow_data ~lambda_lift_all p =
721719
let deadcode_sentinal =
722720
(* If deadcode is disabled, this field is just fresh variable *)
723721
Code.Var.fresh_n "dummy"
@@ -730,7 +728,7 @@ let optimize ~shapes ~profile ~keep_flow_data p =
730728
| O2 -> o2
731729
| O3 -> o3)
732730
+> specialize_js_once_after
733-
+> effects_and_exact_calls ~keep_flow_data ~deadcode_sentinal ~shapes profile
731+
+> effects_and_exact_calls ~keep_flow_data ~deadcode_sentinal ~shapes ~lambda_lift_all profile
734732
+> map_fst5
735733
(match Config.target (), Config.effects () with
736734
| `JavaScript, `Disabled -> Generate_closure.f
@@ -750,15 +748,15 @@ let optimize ~shapes ~profile ~keep_flow_data p =
750748

751749
let optimize_for_wasm ~shapes ~profile p =
752750
let optimized_code, global_flow_data =
753-
optimize ~shapes ~profile ~keep_flow_data:true p
751+
optimize ~shapes ~profile ~keep_flow_data:true ~lambda_lift_all:false p
754752
in
755753
( optimized_code
756754
, match global_flow_data with
757755
| Some data -> data
758756
| None -> Global_flow.f ~fast:false optimized_code.program )
759757

760-
let full ~standalone ~wrap_with_fun ~shapes ~profile ~link ~source_map ~formatter p =
761-
let optimized_code, _ = optimize ~shapes ~profile ~keep_flow_data:false p in
758+
let full ~standalone ~wrap_with_fun ~shapes ~profile ~link ~source_map ~formatter ~lambda_lift_all p =
759+
let optimized_code, _ = optimize ~shapes ~profile ~keep_flow_data:false ~lambda_lift_all p in
762760
let exported_runtime = not standalone in
763761
let emit formatter =
764762
generate ~exported_runtime ~wrap_with_fun ~warn_on_unhandled_effect:standalone
@@ -778,9 +776,9 @@ let full ~standalone ~wrap_with_fun ~shapes ~profile ~link ~source_map ~formatte
778776
shapes_v;
779777
emit formatter optimized_code, shapes_v
780778

781-
let full_no_source_map ~formatter ~shapes ~standalone ~wrap_with_fun ~profile ~link p =
779+
let full_no_source_map ~formatter ~shapes ~standalone ~wrap_with_fun ~profile ~link ~lambda_lift_all p =
782780
let (_ : Source_map.info * _) =
783-
full ~shapes ~standalone ~wrap_with_fun ~profile ~link ~source_map:false ~formatter p
781+
full ~shapes ~standalone ~wrap_with_fun ~profile ~link ~source_map:false ~formatter ~lambda_lift_all p
784782
in
785783
()
786784

@@ -792,17 +790,19 @@ let f
792790
~link
793791
~source_map
794792
~formatter
793+
~lambda_lift_all
795794
p =
796-
full ~standalone ~wrap_with_fun ~shapes ~profile ~link ~source_map ~formatter p
795+
full ~standalone ~wrap_with_fun ~shapes ~profile ~link ~source_map ~formatter ~lambda_lift_all p
797796

798797
let f'
799798
?(standalone = true)
800799
?(wrap_with_fun = `Iife)
801800
?(profile = Profile.O1)
801+
?(lambda_lift_all = false)
802802
~link
803803
formatter
804804
p =
805-
full_no_source_map ~formatter ~shapes:false ~standalone ~wrap_with_fun ~profile ~link p
805+
full_no_source_map ~formatter ~shapes:false ~standalone ~wrap_with_fun ~profile ~link ~lambda_lift_all p
806806

807807
let from_string ~prims ~debug s formatter =
808808
let p = Parse_bytecode.from_string ~prims ~debug s in
@@ -813,4 +813,5 @@ let from_string ~prims ~debug s formatter =
813813
~wrap_with_fun:`Anonymous
814814
~profile:O1
815815
~link:`No
816+
~lambda_lift_all:false
816817
p

compiler/lib/driver.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@ val f :
4343
-> link:[ `All | `All_from of string list | `Needed | `No ]
4444
-> source_map:bool
4545
-> formatter:Pretty_print.t
46+
-> lambda_lift_all:bool
4647
-> Code.program
4748
-> Source_map.info * Shape.t StringMap.t
4849

4950
val f' :
5051
?standalone:bool
5152
-> ?wrap_with_fun:[ `Iife | `Anonymous | `Named of string ]
5253
-> ?profile:Profile.t
54+
-> ?lambda_lift_all:bool
5355
-> link:[ `All | `All_from of string list | `Needed | `No ]
5456
-> Pretty_print.t
5557
-> Code.program

0 commit comments

Comments
 (0)