Skip to content

Commit 79a5e09

Browse files
committed
Inline uncurried application when it is safe
1 parent 9513dcc commit 79a5e09

14 files changed

+307
-70
lines changed

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ subset of the arguments, and return a curried type with the remaining ones https
2222
- Add support for uncurried externals https://github.com/rescript-lang/rescript-compiler/pull/5815 https://github.com/rescript-lang/rescript-compiler/pull/5819 https://github.com/rescript-lang/rescript-compiler/pull/5830
2323
- Parser/Printer: unify uncurried functions of arity 0, and of arity 1 taking unit. There's now only arity 1 in the source language. https://github.com/rescript-lang/rescript-compiler/pull/5825
2424
- Add support for default arguments in uncurried functions https://github.com/rescript-lang/rescript-compiler/pull/5835
25-
25+
- Inline uncurried application when it is safe
2626

2727
#### :boom: Breaking Change
2828

jscomp/core/lam_pass_remove_alias.ml

+54-4
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,49 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
6464
| Some (OptionalBlock (l, _)) -> l
6565
| _ -> if p = Pval_from_option_not_nest then lvar else x)
6666
| Lglobal_module _ -> lam
67+
| Lprim { primitive = Pfull_apply; args = Lvar v :: ap_args as args; loc }
68+
-> (
69+
(* Inline uncurried application when safe *)
70+
let normal () =
71+
Lam.prim ~primitive:Pfull_apply ~args:(Ext_list.map args simpl) loc
72+
in
73+
let ap_args = Ext_list.map ap_args simpl in
74+
match Hash_ident.find_opt meta.ident_tbl v with
75+
| Some
76+
(FunctionId
77+
{
78+
lambda =
79+
Some
80+
( Lfunction
81+
({ params; body; attr = { is_a_functor = false } } as m),
82+
rec_flag );
83+
})
84+
when Ext_list.same_length ap_args params
85+
&& Lam_analysis.lfunction_can_be_beta_reduced m
86+
&& Lam_analysis.ok_to_inline_fun_when_app m ap_args -> (
87+
let param_map =
88+
Lam_closure.is_closed_with_map meta.export_idents params body
89+
in
90+
let is_export_id = Set_ident.mem meta.export_idents v in
91+
match (is_export_id, param_map) with
92+
| false, (_, param_map) | true, (true, param_map) -> (
93+
match rec_flag with
94+
| Lam_rec ->
95+
Lam_beta_reduce.propagate_beta_reduce_with_map meta
96+
param_map params body ap_args
97+
| Lam_self_rec -> normal ()
98+
| Lam_non_rec ->
99+
if
100+
Ext_list.exists ap_args (fun lam ->
101+
Lam_hit.hit_variable v lam)
102+
(*avoid nontermination, e.g, `g(g)`*)
103+
then normal ()
104+
else
105+
simpl
106+
(Lam_beta_reduce.propagate_beta_reduce_with_map meta
107+
param_map params body ap_args))
108+
| _ -> normal ())
109+
| _ -> normal ())
67110
| Lprim { primitive; args; loc } ->
68111
Lam.prim ~primitive ~args:(Ext_list.map args simpl) loc
69112
| Lifthenelse
@@ -160,8 +203,9 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
160203
Some
161204
( Lfunction ({ params; body; attr = { is_a_functor } } as m),
162205
rec_flag );
163-
}) when Lam_analysis.lfunction_can_be_beta_reduced m ->
164-
if Ext_list.same_length ap_args params (* && false *) then
206+
})
207+
when Lam_analysis.lfunction_can_be_beta_reduced m ->
208+
if Ext_list.same_length ap_args params then
165209
if
166210
is_a_functor
167211
(* && (Set_ident.mem v meta.export_idents) && false *)
@@ -211,8 +255,14 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
211255
else normal ()
212256
else normal ()
213257
| Some _ | None -> normal ())
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 ->
258+
| Lapply
259+
{
260+
ap_func = Lfunction ({ params; body } as lfunction);
261+
ap_args = args;
262+
_;
263+
}
264+
when Ext_list.same_length params args
265+
&& Lam_analysis.lfunction_can_be_beta_reduced lfunction ->
216266
simpl (Lam_beta_reduce.propagate_beta_reduce meta params body args)
217267
(* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *)
218268
(* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *)

jscomp/test/arity_deopt.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

33
var Mt = require("./mt.js");
4-
var Curry = require("../../lib/js/curry.js");
54

65
var suites = {
76
contents: /* [] */0
@@ -50,13 +49,13 @@ function f3(x) {
5049
};
5150
}
5251

53-
eq("File \"arity_deopt.ml\", line 45, characters 7-14", 6, f0(1, 2, 3));
52+
eq("File \"arity_deopt.ml\", line 45, characters 7-14", 6, 6);
5453

5554
eq("File \"arity_deopt.ml\", line 46, characters 11-18", 6, (function (y, z) {
5655
return (1 + y | 0) + z | 0;
5756
})(2, 3));
5857

59-
eq("File \"arity_deopt.ml\", line 47, characters 15-22", 6, Curry._1(f2(1, 2), 3));
58+
eq("File \"arity_deopt.ml\", line 47, characters 15-22", 6, 6);
6059

6160
eq("File \"arity_deopt.ml\", line 48, characters 15-22", 6, (function (y, z) {
6261
return (1 + y | 0) + z | 0;

jscomp/test/attr_test.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ function u(x, y) {
55
return x + y | 0;
66
}
77

8-
var h = u(1, 2);
8+
var h = 3;
99

1010
function max2(x, y) {
1111
return x + y;
1212
}
1313

14-
var hh = max2(1, 2);
14+
var hh = 1 + 2;
1515

1616
function f(x) {
1717
des(x, (function () {
@@ -24,4 +24,4 @@ exports.h = h;
2424
exports.max2 = max2;
2525
exports.hh = hh;
2626
exports.f = f;
27-
/* h Not a pure module */
27+
/* No side effect */

jscomp/test/bs_rest_test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ function xxx(prim) {
1212
return x(prim);
1313
}
1414

15-
var u = xxx(3);
15+
var u = x(3);
1616

17-
var xx = xxx("3");
17+
var xx = x("3");
1818

1919
exports.v = v;
2020
exports.xxx = xxx;

jscomp/test/internal_unused_test.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ function f(param) {
1515

1616
var c = 5;
1717

18-
function h(a, b) {
19-
return a + b | 0;
20-
}
21-
2218
var h1 = 2;
2319

2420
var h2 = h1 + 1 | 0;
@@ -39,7 +35,7 @@ console.log(h2);
3935

4036
console.log(c);
4137

42-
console.log(h(1, 2));
38+
console.log(3);
4339

4440
function H($star) {
4541
return {};

jscomp/test/ppx_apply_test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function unary(a) {
3737
return a + 3 | 0;
3838
}
3939

40-
var xx = unary(3);
40+
var xx = 6;
4141

4242
eq("File \"ppx_apply_test.ml\", line 17, characters 5-12", u, 3);
4343

jscomp/test/uncurried_cast.js

+10-8
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ var Uncurried = {
2222
var E = /* @__PURE__ */Caml_exceptions.create("Uncurried_cast.E");
2323

2424
function testRaise(param) {
25-
return raise({
26-
RE_EXN_ID: E
27-
});
25+
throw {
26+
RE_EXN_ID: E,
27+
Error: new Error()
28+
};
2829
}
2930

30-
var l = map({
31+
var l = Belt_List.mapU({
3132
hd: 1,
3233
tl: {
3334
hd: 2,
@@ -76,12 +77,13 @@ var StandardNotation = {
7677
};
7778

7879
function testRaise$1(param) {
79-
return raise({
80-
RE_EXN_ID: E
81-
});
80+
throw {
81+
RE_EXN_ID: E,
82+
Error: new Error()
83+
};
8284
}
8385

84-
var l$1 = map({
86+
var l$1 = Belt_List.mapU({
8587
hd: 1,
8688
tl: {
8789
hd: 2,

jscomp/test/uncurried_pipe.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ function addC(x, y) {
99
return x + y | 0;
1010
}
1111

12-
var v7 = add(3, 4);
12+
var v7 = 7;
1313

14-
var v17 = add(10, add(3, 4));
14+
var v17 = 17;
1515

16-
var v27 = add(20, 7);
16+
var v27 = 27;
1717

18-
var v37 = 30 + add(3, 4) | 0;
18+
var v37 = 37;
1919

2020
function unary(x) {
2121
return x + 1 | 0;
@@ -31,20 +31,20 @@ var StandardNotation = {
3131
unary: unary
3232
};
3333

34-
var v7$1 = add(3, 4);
34+
var v7$1 = 7;
3535

36-
var v17$1 = add(10, add(3, 4));
36+
var v17$1 = 17;
3737

38-
var v27$1 = add(20, 7);
38+
var v27$1 = 27;
3939

40-
var v37$1 = 30 + add(3, 4) | 0;
40+
var v37$1 = 37;
4141

42-
var v100 = unary(99);
42+
var v100 = 100;
4343

4444
exports.StandardNotation = StandardNotation;
4545
exports.v7 = v7$1;
4646
exports.v17 = v17$1;
4747
exports.v27 = v27$1;
4848
exports.v37 = v37$1;
4949
exports.v100 = v100;
50-
/* v7 Not a pure module */
50+
/* No side effect */

jscomp/test/uncurry_glob_test.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,16 @@ function f(param) {
1212
return 3;
1313
}
1414

15-
f(undefined);
16-
1715
function $plus$great(a, h) {
1816
return h(a);
1917
}
2018

2119
function u(h) {
22-
return $plus$great(3, h);
20+
return h(3);
2321
}
2422

2523
exports.M = M;
2624
exports.f = f;
2725
exports.$plus$great = $plus$great;
2826
exports.u = u;
29-
/* Not a pure module */
27+
/* No side effect */

jscomp/test/uncurry_test.js

+59-17
Original file line numberDiff line numberDiff line change
@@ -366,23 +366,65 @@ function f22(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a1
366366
];
367367
}
368368

369-
console.log(f0(undefined));
370-
371-
console.log(f1(0));
372-
373-
console.log(f2(0, 1));
374-
375-
console.log(f3(0, 1, 2));
376-
377-
console.log(f4(0, 1, 2, 3));
378-
379-
console.log(f5(0, 1, 2, 3, 4));
380-
381-
console.log(f6(0, 1, 2, 3, 4, 5));
382-
383-
console.log(f7(0, 1, 2, 3, 4, 5, 6));
384-
385-
console.log(f8(0, 1, 2, 3, 4, 5, 6, 7));
369+
console.log(0);
370+
371+
console.log(0);
372+
373+
console.log([
374+
0,
375+
1
376+
]);
377+
378+
console.log([
379+
0,
380+
1,
381+
2
382+
]);
383+
384+
console.log([
385+
0,
386+
1,
387+
2,
388+
3
389+
]);
390+
391+
console.log([
392+
0,
393+
1,
394+
2,
395+
3,
396+
4
397+
]);
398+
399+
console.log([
400+
0,
401+
1,
402+
2,
403+
3,
404+
4,
405+
5
406+
]);
407+
408+
console.log([
409+
0,
410+
1,
411+
2,
412+
3,
413+
4,
414+
5,
415+
6
416+
]);
417+
418+
console.log([
419+
0,
420+
1,
421+
2,
422+
3,
423+
4,
424+
5,
425+
6,
426+
7
427+
]);
386428

387429
console.log(f9(0, 1, 2, 3, 4, 5, 6, 7, 8));
388430

0 commit comments

Comments
 (0)