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

Inline uncurried application when it is safe #5847

Merged
merged 2 commits into from
Nov 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ subset of the arguments, and return a curried type with the remaining ones https
- 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
- 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
- Add support for default arguments in uncurried functions https://github.com/rescript-lang/rescript-compiler/pull/5835

- Inline uncurried application when it is safe https://github.com/rescript-lang/rescript-compiler/pull/5847

#### :boom: Breaking Change

Expand Down
58 changes: 54 additions & 4 deletions jscomp/core/lam_pass_remove_alias.ml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,49 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
| Some (OptionalBlock (l, _)) -> l
| _ -> if p = Pval_from_option_not_nest then lvar else x)
| Lglobal_module _ -> lam
| Lprim { primitive = Pfull_apply; args = Lvar v :: ap_args as args; loc }
-> (
(* Inline uncurried application when safe *)
let normal () =
Lam.prim ~primitive:Pfull_apply ~args:(Ext_list.map args simpl) loc
in
let ap_args = Ext_list.map ap_args simpl in
match Hash_ident.find_opt meta.ident_tbl v with
| Some
(FunctionId
{
lambda =
Some
( Lfunction
({ params; body; attr = { is_a_functor = false } } as m),
rec_flag );
})
when Ext_list.same_length ap_args params
&& Lam_analysis.lfunction_can_be_beta_reduced m
&& Lam_analysis.ok_to_inline_fun_when_app m ap_args -> (
let param_map =
Lam_closure.is_closed_with_map meta.export_idents params body
in
let is_export_id = Set_ident.mem meta.export_idents v in
match (is_export_id, param_map) with
| false, (_, param_map) | true, (true, param_map) -> (
match rec_flag with
| Lam_rec ->
Lam_beta_reduce.propagate_beta_reduce_with_map meta
param_map params body ap_args
| Lam_self_rec -> normal ()
| Lam_non_rec ->
if
Ext_list.exists ap_args (fun lam ->
Lam_hit.hit_variable v lam)
(*avoid nontermination, e.g, `g(g)`*)
then normal ()
else
simpl
(Lam_beta_reduce.propagate_beta_reduce_with_map meta
param_map params body ap_args))
| _ -> normal ())
| _ -> normal ())
| Lprim { primitive; args; loc } ->
Lam.prim ~primitive ~args:(Ext_list.map args simpl) loc
| Lifthenelse
Expand Down Expand Up @@ -160,8 +203,9 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
Some
( Lfunction ({ params; body; attr = { is_a_functor } } as m),
rec_flag );
}) when Lam_analysis.lfunction_can_be_beta_reduced m ->
if Ext_list.same_length ap_args params (* && false *) then
})
when Lam_analysis.lfunction_can_be_beta_reduced m ->
if Ext_list.same_length ap_args params then
if
is_a_functor
(* && (Set_ident.mem v meta.export_idents) && false *)
Expand Down Expand Up @@ -211,8 +255,14 @@ let simplify_alias (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
else normal ()
else normal ()
| Some _ | None -> normal ())
| Lapply { ap_func = Lfunction ({ params; body } as lfunction); ap_args = args; _ }
when Ext_list.same_length params args && Lam_analysis.lfunction_can_be_beta_reduced lfunction ->
| Lapply
{
ap_func = Lfunction ({ params; body } as lfunction);
ap_args = args;
_;
}
when Ext_list.same_length params args
&& Lam_analysis.lfunction_can_be_beta_reduced lfunction ->
simpl (Lam_beta_reduce.propagate_beta_reduce meta params body args)
(* | Lapply{ fn = Lfunction{function_kind = Tupled; params; body}; *)
(* args = [Lprim {primitive = Pmakeblock _; args; _}]; _} *)
Expand Down
5 changes: 2 additions & 3 deletions jscomp/test/arity_deopt.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';

var Mt = require("./mt.js");
var Curry = require("../../lib/js/curry.js");

var suites = {
contents: /* [] */0
Expand Down Expand Up @@ -50,13 +49,13 @@ function f3(x) {
};
}

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

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

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

eq("File \"arity_deopt.ml\", line 48, characters 15-22", 6, (function (y, z) {
return (1 + y | 0) + z | 0;
Expand Down
32 changes: 32 additions & 0 deletions jscomp/test/async_inline.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,41 @@ async function broken$1(someAsyncFunction) {

var broken$2 = broken$1;

function curriedId(x) {
return x;
}

async function curriedIdAsync(x) {
return x;
}

function uncurriedId(x) {
return x;
}

async function uncurriedIdAsync(x) {
return x;
}

var tcia = curriedIdAsync(3);

var tui = 3;

var tuia = uncurriedIdAsync(3);

var tci = 3;

exports.willBeInlined = willBeInlined;
exports.inlined = inlined;
exports.wrapSomethingAsync = wrapSomethingAsync;
exports.M = M;
exports.broken = broken$2;
exports.curriedId = curriedId;
exports.curriedIdAsync = curriedIdAsync;
exports.uncurriedId = uncurriedId;
exports.uncurriedIdAsync = uncurriedIdAsync;
exports.tci = tci;
exports.tcia = tcia;
exports.tui = tui;
exports.tuia = tuia;
/* inlined Not a pure module */
10 changes: 10 additions & 0 deletions jscomp/test/async_inline.res
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,13 @@ let broken = async (someAsyncFunction) => {
}

let broken = someAsyncFunction => broken(someAsyncFunction)

let curriedId = x => x
let curriedIdAsync = async x => x
let uncurriedId = (.x ) => x
let uncurriedIdAsync = async (.x ) => x

let tci = curriedId(3)
let tcia = curriedIdAsync(3)
let tui = uncurriedId(. 3)
let tuia = uncurriedIdAsync(. 3)
6 changes: 3 additions & 3 deletions jscomp/test/attr_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ function u(x, y) {
return x + y | 0;
}

var h = u(1, 2);
var h = 3;

function max2(x, y) {
return x + y;
}

var hh = max2(1, 2);
var hh = 1 + 2;

function f(x) {
des(x, (function () {
Expand All @@ -24,4 +24,4 @@ exports.h = h;
exports.max2 = max2;
exports.hh = hh;
exports.f = f;
/* h Not a pure module */
/* No side effect */
4 changes: 2 additions & 2 deletions jscomp/test/bs_rest_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ function xxx(prim) {
return x(prim);
}

var u = xxx(3);
var u = x(3);

var xx = xxx("3");
var xx = x("3");

exports.v = v;
exports.xxx = xxx;
Expand Down
6 changes: 1 addition & 5 deletions jscomp/test/internal_unused_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ function f(param) {

var c = 5;

function h(a, b) {
return a + b | 0;
}

var h1 = 2;

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

console.log(c);

console.log(h(1, 2));
console.log(3);

function H($star) {
return {};
Expand Down
2 changes: 1 addition & 1 deletion jscomp/test/ppx_apply_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function unary(a) {
return a + 3 | 0;
}

var xx = unary(3);
var xx = 6;

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

Expand Down
18 changes: 10 additions & 8 deletions jscomp/test/uncurried_cast.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ var Uncurried = {
var E = /* @__PURE__ */Caml_exceptions.create("Uncurried_cast.E");

function testRaise(param) {
return raise({
RE_EXN_ID: E
});
throw {
RE_EXN_ID: E,
Error: new Error()
};
}

var l = map({
var l = Belt_List.mapU({
hd: 1,
tl: {
hd: 2,
Expand Down Expand Up @@ -76,12 +77,13 @@ var StandardNotation = {
};

function testRaise$1(param) {
return raise({
RE_EXN_ID: E
});
throw {
RE_EXN_ID: E,
Error: new Error()
};
}

var l$1 = map({
var l$1 = Belt_List.mapU({
hd: 1,
tl: {
hd: 2,
Expand Down
20 changes: 10 additions & 10 deletions jscomp/test/uncurried_pipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ function addC(x, y) {
return x + y | 0;
}

var v7 = add(3, 4);
var v7 = 7;

var v17 = add(10, add(3, 4));
var v17 = 17;

var v27 = add(20, 7);
var v27 = 27;

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

function unary(x) {
return x + 1 | 0;
Expand All @@ -31,20 +31,20 @@ var StandardNotation = {
unary: unary
};

var v7$1 = add(3, 4);
var v7$1 = 7;

var v17$1 = add(10, add(3, 4));
var v17$1 = 17;

var v27$1 = add(20, 7);
var v27$1 = 27;

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

var v100 = unary(99);
var v100 = 100;

exports.StandardNotation = StandardNotation;
exports.v7 = v7$1;
exports.v17 = v17$1;
exports.v27 = v27$1;
exports.v37 = v37$1;
exports.v100 = v100;
/* v7 Not a pure module */
/* No side effect */
6 changes: 2 additions & 4 deletions jscomp/test/uncurry_glob_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,16 @@ function f(param) {
return 3;
}

f(undefined);

function $plus$great(a, h) {
return h(a);
}

function u(h) {
return $plus$great(3, h);
return h(3);
}

exports.M = M;
exports.f = f;
exports.$plus$great = $plus$great;
exports.u = u;
/* Not a pure module */
/* No side effect */
Loading