Skip to content

Commit 7fe359b

Browse files
authored
Async inline (#5755)
* Prevent inlining of async functions Fixes #5754 * Update CHANGELOG.md * Refactor logic to disable inlining of async functions. * Prevent all async function beta reductions.
1 parent 8278bf0 commit 7fe359b

16 files changed

+140
-79
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@
1212
1313
# 10.1.0-rc.3
1414

15+
#### :bug: Bug Fix
16+
1517
- Fix issue where the JSX key type is not an optional string https://github.com/rescript-lang/syntax/pull/693
1618

19+
- Prevent inlining of async functions https://github.com/rescript-lang/rescript-compiler/issues/5754
20+
1721
# 10.1.0-rc.2
1822

1923
#### :bug: Bug Fix

jscomp/core/lam_analysis.ml

+4
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ let destruct_pattern (body : Lam.t) params args =
244244
| Some _ | None -> false)
245245
| _ -> false
246246

247+
(* Async functions cannot be beta reduced *)
248+
let lfunction_can_be_beta_reduced (lfunction : Lam.lfunction) =
249+
not lfunction.attr.async
250+
247251
(** Hints to inlining *)
248252
let ok_to_inline_fun_when_app (m : Lam.lfunction) (args : Lam.t list) =
249253
match m.attr.inline with

jscomp/core/lam_analysis.mli

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ val no_side_effects : Lam.t -> bool
2929

3030
val size : Lam.t -> int
3131

32+
val lfunction_can_be_beta_reduced : Lam.lfunction -> bool
33+
3234
val ok_to_inline_fun_when_app : Lam.lfunction -> Lam.t list -> bool
3335

3436
val small_inline_size : int

jscomp/core/lam_beta_reduce.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
]}
4545
we can bound [x] to [100] in a single step
4646
*)
47-
let propogate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list)
47+
let propagate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list)
4848
(body : Lam.t) (args : Lam.t list) =
4949
match Lam_beta_reduce_util.simple_beta_reduce params body args with
5050
| Some x -> x
@@ -73,7 +73,7 @@ let propogate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list)
7373
| _ -> ());
7474
Lam_util.refine_let ~kind:Strict param arg l)
7575

76-
let propogate_beta_reduce_with_map (meta : Lam_stats.t)
76+
let propagate_beta_reduce_with_map (meta : Lam_stats.t)
7777
(map : Lam_var_stats.stats Map_ident.t) params body args =
7878
match Lam_beta_reduce_util.simple_beta_reduce params body args with
7979
| Some x -> x

jscomp/core/lam_beta_reduce.mli

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ val no_names_beta_reduce : Ident.t list -> Lam.t -> Lam.t list -> Lam.t
4242
the obvious example is parameter
4343
*)
4444

45-
val propogate_beta_reduce :
45+
val propagate_beta_reduce :
4646
Lam_stats.t -> Ident.t list -> Lam.t -> Lam.t list -> Lam.t
4747

48-
val propogate_beta_reduce_with_map :
48+
val propagate_beta_reduce_with_map :
4949
Lam_stats.t ->
5050
Lam_var_stats.stats Map_ident.t ->
5151
Ident.t list ->

jscomp/core/lam_compile.ml

+3-3
Original file line numberDiff line numberDiff line change
@@ -221,14 +221,14 @@ and compile_external_field_apply (appinfo : Lam.apply) (module_id : Ident.t)
221221
in
222222
let ap_args = appinfo.ap_args in
223223
match ident_info.persistent_closed_lambda with
224-
| Some (Lfunction { params; body; _ })
225-
when Ext_list.same_length params ap_args ->
224+
| Some (Lfunction ({ params; body; _ } as lfunction))
225+
when Ext_list.same_length params ap_args && Lam_analysis.lfunction_can_be_beta_reduced lfunction ->
226226
(* TODO: serialize it when exporting to save compile time *)
227227
let _, param_map =
228228
Lam_closure.is_closed_with_map Set_ident.empty params body
229229
in
230230
compile_lambda lambda_cxt
231-
(Lam_beta_reduce.propogate_beta_reduce_with_map lambda_cxt.meta
231+
(Lam_beta_reduce.propagate_beta_reduce_with_map lambda_cxt.meta
232232
param_map params body ap_args)
233233
| _ ->
234234
let args_code, args =

jscomp/core/lam_pass_count.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ let collect_occurs lam : occ_tbl =
143143
List.iter (fun (_v, l) -> count bv l) bindings;
144144
count bv body
145145
(* Note there is a difference here when do beta reduction for *)
146-
| Lapply { ap_func = Lfunction { params; body }; ap_args = args; _ }
147-
when Ext_list.same_length params args ->
146+
| Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ }
147+
when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction ->
148148
count bv (Lam_beta_reduce.no_names_beta_reduce params body args)
149149
(* | Lapply{fn = Lfunction{function_kind = Tupled; params; body}; *)
150150
(* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *)

jscomp/core/lam_pass_lets_dce.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t =
147147
end
148148
| Lsequence(l1, l2) -> Lam.seq (simplif l1) (simplif l2)
149149

150-
| Lapply{ap_func = Lfunction{params; body}; ap_args = args; _}
151-
when Ext_list.same_length params args ->
150+
| Lapply{ap_func = Lfunction ({params; body} as lfunction); ap_args = args; _}
151+
when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction ->
152152
simplif (Lam_beta_reduce.no_names_beta_reduce params body args)
153153
(* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *)
154154
(* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *)

jscomp/core/lam_pass_lets_dce.pp.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t =
146146
end
147147
| Lsequence(l1, l2) -> Lam.seq (simplif l1) (simplif l2)
148148

149-
| Lapply{ap_func = Lfunction{params; body}; ap_args = args; _}
150-
when Ext_list.same_length params args ->
149+
| Lapply{ap_func = Lfunction ({params; body} as lfunction); ap_args = args; _}
150+
when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction ->
151151
simplif (Lam_beta_reduce.no_names_beta_reduce params body args)
152152
(* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *)
153153
(* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *)

jscomp/core/lam_pass_remove_alias.ml

+8-8
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
138138
| Some v -> v <> Parameter
139139
| None -> true)
140140
| _ -> true) ->
141-
simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args)
141+
simpl (Lam_beta_reduce.propagate_beta_reduce meta params body args)
142142
| _ -> Lam.apply (simpl l1) (Ext_list.map args simpl) ap_info)
143143
(* Function inlining interact with other optimizations...
144144
@@ -160,7 +160,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
160160
Some
161161
( Lfunction ({ params; body; attr = { is_a_functor } } as m),
162162
rec_flag );
163-
}) ->
163+
}) when Lam_analysis.lfunction_can_be_beta_reduced m ->
164164
if Ext_list.same_length ap_args params (* && false *) then
165165
if
166166
is_a_functor
@@ -174,7 +174,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
174174
(* Check: recursive applying may result in non-termination *)
175175
(* Ext_log.dwarn __LOC__ "beta .. %s/%d" v.name v.stamp ; *)
176176
simpl
177-
(Lam_beta_reduce.propogate_beta_reduce meta params body
177+
(Lam_beta_reduce.propagate_beta_reduce meta params body
178178
ap_args)
179179
else if
180180
(* Lam_analysis.size body < Lam_analysis.small_inline_size *)
@@ -194,7 +194,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
194194
| false, (_, param_map) | true, (true, param_map) -> (
195195
match rec_flag with
196196
| Lam_rec ->
197-
Lam_beta_reduce.propogate_beta_reduce_with_map meta
197+
Lam_beta_reduce.propagate_beta_reduce_with_map meta
198198
param_map params body ap_args
199199
| Lam_self_rec -> normal ()
200200
| Lam_non_rec ->
@@ -205,15 +205,15 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
205205
then normal ()
206206
else
207207
simpl
208-
(Lam_beta_reduce.propogate_beta_reduce_with_map meta
208+
(Lam_beta_reduce.propagate_beta_reduce_with_map meta
209209
param_map params body ap_args))
210210
| _ -> normal ()
211211
else normal ()
212212
else normal ()
213213
| Some _ | None -> normal ())
214-
| Lapply { ap_func = Lfunction { params; body }; ap_args = args; _ }
215-
when Ext_list.same_length params args ->
216-
simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args)
214+
| Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ }
215+
when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction ->
216+
simpl (Lam_beta_reduce.propagate_beta_reduce meta params body args)
217217
(* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *)
218218
(* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *)
219219
(* (\** TODO: keep track of this parameter in ocaml trunk, *)

jscomp/test/async_inline.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict';
2+
3+
4+
async function willBeInlined(param) {
5+
return 3;
6+
}
7+
8+
var inlined = willBeInlined(undefined);
9+
10+
function wrapSomethingAsync(param) {
11+
((async function (param) {
12+
var test = await Promise.resolve("Test");
13+
console.log(test);
14+
})(777));
15+
}
16+
17+
exports.willBeInlined = willBeInlined;
18+
exports.inlined = inlined;
19+
exports.wrapSomethingAsync = wrapSomethingAsync;
20+
/* inlined Not a pure module */

jscomp/test/async_inline.res

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
let willBeInlined = async () => 3
2+
3+
let inlined = willBeInlined ()
4+
5+
let wrapSomethingAsync: unit => unit = () => {
6+
let _ = (
7+
async (_) => {
8+
let test = await Js.Promise.resolve("Test")
9+
Js.log(test)
10+
}
11+
)(777)
12+
}

jscomp/test/build.ninja

+2-1
Large diffs are not rendered by default.

lib/4.06.1/unstable/js_compiler.ml

+25-19
Original file line numberDiff line numberDiff line change
@@ -91322,6 +91322,8 @@ val no_side_effects : Lam.t -> bool
9132291322

9132391323
val size : Lam.t -> int
9132491324

91325+
val lfunction_can_be_beta_reduced : Lam.lfunction -> bool
91326+
9132591327
val ok_to_inline_fun_when_app : Lam.lfunction -> Lam.t list -> bool
9132691328

9132791329
val small_inline_size : int
@@ -91578,6 +91580,10 @@ let destruct_pattern (body : Lam.t) params args =
9157891580
| Some _ | None -> false)
9157991581
| _ -> false
9158091582

91583+
(* Async functions cannot be beta reduced *)
91584+
let lfunction_can_be_beta_reduced (lfunction : Lam.lfunction) =
91585+
not lfunction.attr.async
91586+
9158191587
(** Hints to inlining *)
9158291588
let ok_to_inline_fun_when_app (m : Lam.lfunction) (args : Lam.t list) =
9158391589
match m.attr.inline with
@@ -94288,10 +94294,10 @@ val no_names_beta_reduce : Ident.t list -> Lam.t -> Lam.t list -> Lam.t
9428894294
the obvious example is parameter
9428994295
*)
9429094296

94291-
val propogate_beta_reduce :
94297+
val propagate_beta_reduce :
9429294298
Lam_stats.t -> Ident.t list -> Lam.t -> Lam.t list -> Lam.t
9429394299

94294-
val propogate_beta_reduce_with_map :
94300+
val propagate_beta_reduce_with_map :
9429594301
Lam_stats.t ->
9429694302
Lam_var_stats.stats Map_ident.t ->
9429794303
Ident.t list ->
@@ -94367,7 +94373,7 @@ end = struct
9436794373
]}
9436894374
we can bound [x] to [100] in a single step
9436994375
*)
94370-
let propogate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list)
94376+
let propagate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list)
9437194377
(body : Lam.t) (args : Lam.t list) =
9437294378
match Lam_beta_reduce_util.simple_beta_reduce params body args with
9437394379
| Some x -> x
@@ -94396,7 +94402,7 @@ let propogate_beta_reduce (meta : Lam_stats.t) (params : Ident.t list)
9439694402
| _ -> ());
9439794403
Lam_util.refine_let ~kind:Strict param arg l)
9439894404

94399-
let propogate_beta_reduce_with_map (meta : Lam_stats.t)
94405+
let propagate_beta_reduce_with_map (meta : Lam_stats.t)
9440094406
(map : Lam_var_stats.stats Map_ident.t) params body args =
9440194407
match Lam_beta_reduce_util.simple_beta_reduce params body args with
9440294408
| Some x -> x
@@ -99765,14 +99771,14 @@ and compile_external_field_apply (appinfo : Lam.apply) (module_id : Ident.t)
9976599771
in
9976699772
let ap_args = appinfo.ap_args in
9976799773
match ident_info.persistent_closed_lambda with
99768-
| Some (Lfunction { params; body; _ })
99769-
when Ext_list.same_length params ap_args ->
99774+
| Some (Lfunction ({ params; body; _ } as lfunction))
99775+
when Ext_list.same_length params ap_args && Lam_analysis.lfunction_can_be_beta_reduced lfunction ->
9977099776
(* TODO: serialize it when exporting to save compile time *)
9977199777
let _, param_map =
9977299778
Lam_closure.is_closed_with_map Set_ident.empty params body
9977399779
in
9977499780
compile_lambda lambda_cxt
99775-
(Lam_beta_reduce.propogate_beta_reduce_with_map lambda_cxt.meta
99781+
(Lam_beta_reduce.propagate_beta_reduce_with_map lambda_cxt.meta
9977699782
param_map params body ap_args)
9977799783
| _ ->
9977899784
let args_code, args =
@@ -257925,8 +257931,8 @@ let collect_occurs lam : occ_tbl =
257925257931
List.iter (fun (_v, l) -> count bv l) bindings;
257926257932
count bv body
257927257933
(* Note there is a difference here when do beta reduction for *)
257928-
| Lapply { ap_func = Lfunction { params; body }; ap_args = args; _ }
257929-
when Ext_list.same_length params args ->
257934+
| Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ }
257935+
when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction ->
257930257936
count bv (Lam_beta_reduce.no_names_beta_reduce params body args)
257931257937
(* | Lapply{fn = Lfunction{function_kind = Tupled; params; body}; *)
257932257938
(* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *)
@@ -258306,8 +258312,8 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t =
258306258312
end
258307258313
| Lsequence(l1, l2) -> Lam.seq (simplif l1) (simplif l2)
258308258314

258309-
| Lapply{ap_func = Lfunction{params; body}; ap_args = args; _}
258310-
when Ext_list.same_length params args ->
258315+
| Lapply{ap_func = Lfunction ({params; body} as lfunction); ap_args = args; _}
258316+
when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction ->
258311258317
simplif (Lam_beta_reduce.no_names_beta_reduce params body args)
258312258318
(* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *)
258313258319
(* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *)
@@ -258606,7 +258612,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
258606258612
| Some v -> v <> Parameter
258607258613
| None -> true)
258608258614
| _ -> true) ->
258609-
simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args)
258615+
simpl (Lam_beta_reduce.propagate_beta_reduce meta params body args)
258610258616
| _ -> Lam.apply (simpl l1) (Ext_list.map args simpl) ap_info)
258611258617
(* Function inlining interact with other optimizations...
258612258618

@@ -258628,7 +258634,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
258628258634
Some
258629258635
( Lfunction ({ params; body; attr = { is_a_functor } } as m),
258630258636
rec_flag );
258631-
}) ->
258637+
}) when Lam_analysis.lfunction_can_be_beta_reduced m ->
258632258638
if Ext_list.same_length ap_args params (* && false *) then
258633258639
if
258634258640
is_a_functor
@@ -258642,7 +258648,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
258642258648
(* Check: recursive applying may result in non-termination *)
258643258649
(* Ext_log.dwarn __LOC__ "beta .. %s/%d" v.name v.stamp ; *)
258644258650
simpl
258645-
(Lam_beta_reduce.propogate_beta_reduce meta params body
258651+
(Lam_beta_reduce.propagate_beta_reduce meta params body
258646258652
ap_args)
258647258653
else if
258648258654
(* Lam_analysis.size body < Lam_analysis.small_inline_size *)
@@ -258662,7 +258668,7 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
258662258668
| false, (_, param_map) | true, (true, param_map) -> (
258663258669
match rec_flag with
258664258670
| Lam_rec ->
258665-
Lam_beta_reduce.propogate_beta_reduce_with_map meta
258671+
Lam_beta_reduce.propagate_beta_reduce_with_map meta
258666258672
param_map params body ap_args
258667258673
| Lam_self_rec -> normal ()
258668258674
| Lam_non_rec ->
@@ -258673,15 +258679,15 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
258673258679
then normal ()
258674258680
else
258675258681
simpl
258676-
(Lam_beta_reduce.propogate_beta_reduce_with_map meta
258682+
(Lam_beta_reduce.propagate_beta_reduce_with_map meta
258677258683
param_map params body ap_args))
258678258684
| _ -> normal ()
258679258685
else normal ()
258680258686
else normal ()
258681258687
| Some _ | None -> normal ())
258682-
| Lapply { ap_func = Lfunction { params; body }; ap_args = args; _ }
258683-
when Ext_list.same_length params args ->
258684-
simpl (Lam_beta_reduce.propogate_beta_reduce meta params body args)
258688+
| Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ }
258689+
when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction ->
258690+
simpl (Lam_beta_reduce.propagate_beta_reduce meta params body args)
258685258691
(* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *)
258686258692
(* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *)
258687258693
(* (\** TODO: keep track of this parameter in ocaml trunk, *)

0 commit comments

Comments
 (0)