Skip to content

Commit 9bb0228

Browse files
authored
Merge pull request rescript-lang#3711 from BuckleScript/code_gen_no_inline_self_recur
[code gen] not inlining self recursive functions
2 parents 3a60c0e + 6a8b0d2 commit 9bb0228

14 files changed

+160
-44
lines changed

jscomp/core/lam_analysis.ml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,10 @@ let destruct_pattern (body : Lam.t) params args =
377377
| _ -> false
378378

379379
(** Hints to inlining *)
380-
let ok_to_inline_fun_when_app ~body params args =
380+
let ok_to_inline_fun_when_app
381+
~(body : Lam.t)
382+
(params : Ident.t list)
383+
(args : Lam.t list) =
381384
let s = size body in
382385
s < small_inline_size ||
383386
(destruct_pattern body params args) ||

jscomp/core/lam_coercion.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ let handle_exports (meta : Lam_stats.t)
144144
(FunctionId{arity ; lambda =
145145
match lam with
146146
| Lfunction _ ->
147-
Some (lam, Non_rec)
147+
Some (lam, Lam_non_rec)
148148
| _ -> None })
149149
);
150150
{ acc with

jscomp/core/lam_id_kind.ml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,13 @@
2828

2929

3030
type rec_flag =
31-
| Rec
32-
| Non_rec
31+
| Lam_rec
32+
| Lam_non_rec
33+
| Lam_self_rec
34+
(* only a
35+
single mutual
36+
recursive function
37+
*)
3338

3439

3540
type function_id = {

jscomp/core/lam_id_kind.mli

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424

2525

2626
type rec_flag =
27-
| Rec
28-
| Non_rec
27+
| Lam_rec
28+
| Lam_non_rec
2929

3030
(* TODO: This may contain some closure environment,
3131
check how it will interact with dead code elimination
3232
*)
33+
| Lam_self_rec
34+
(* not inlining in this case *)
3335
type function_id = {
3436
mutable arity : Lam_arity.t;
3537
lambda : (Lam.t * rec_flag) option ;

jscomp/core/lam_pass_collect.ml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,13 @@ let collect_helper (meta : Lam_stats.t) (lam : Lam.t) =
143143
List.iter (fun p -> Ident_hashtbl.add meta.ident_tbl p Parameter ) params;
144144
collect l
145145
| Llet (kind,ident,arg,body) ->
146-
collect_bind Non_rec kind ident arg ; collect body
146+
collect_bind Lam_non_rec kind ident arg ; collect body
147147
| Lletrec (bindings, body) ->
148-
List.iter (fun (ident,arg) -> collect_bind Rec Strict ident arg ) bindings;
148+
(match bindings with
149+
| [ident, arg] -> collect_bind Lam_self_rec Strict ident arg
150+
| _ ->
151+
Ext_list.iter bindings
152+
(fun (ident,arg) -> collect_bind Lam_rec Strict ident arg )) ;
149153
collect body
150154
| Lglobal_module _ -> ()
151155
| Lprim {args; _} -> List.iter collect args

jscomp/core/lam_pass_remove_alias.ml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,14 @@ let simplify_alias
234234
match is_export_id, param_map with
235235
| false, (_, param_map)
236236
| true, (true, param_map) ->
237-
if rec_flag = Rec then
238-
Lam_beta_reduce.propogate_beta_reduce_with_map meta param_map params body args
239-
else
240-
simpl (Lam_beta_reduce.propogate_beta_reduce_with_map meta param_map params body args)
237+
begin match rec_flag with
238+
239+
| Lam_rec -> Lam_beta_reduce.propogate_beta_reduce_with_map meta param_map params body args
240+
| Lam_self_rec -> normal ()
241+
| Lam_non_rec ->
242+
simpl
243+
(Lam_beta_reduce.propogate_beta_reduce_with_map meta param_map params body args)
244+
end
241245
| _ -> normal ()
242246
else
243247
normal ()

jscomp/test/build.ninja

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ build test/gpr_3566_drive_test.cmi test/gpr_3566_drive_test.cmj : cc test/gpr_35
302302
build test/gpr_3566_test.cmi test/gpr_3566_test.cmj : cc test/gpr_3566_test.ml | $stdlib
303303
build test/gpr_3595_test.cmi test/gpr_3595_test.cmj : cc test/gpr_3595_test.ml | test/mt.cmj $stdlib
304304
build test/gpr_3609_test.cmi test/gpr_3609_test.cmj : cc test/gpr_3609_test.ml | $stdlib
305+
build test/gpr_3697_test.cmi test/gpr_3697_test.cmj : cc test/gpr_3697_test.ml | $stdlib
305306
build test/gpr_373_test.cmi test/gpr_373_test.cmj : cc test/gpr_373_test.ml | $stdlib
306307
build test/gpr_405_test.cmj : cc_cmi test/gpr_405_test.ml | test/gpr_405_test.cmi $stdlib
307308
build test/gpr_405_test.cmi : cc test/gpr_405_test.mli | $stdlib

jscomp/test/gpr_3697_test.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use strict';
2+
3+
var Block = require("../../lib/js/block.js");
4+
var CamlinternalLazy = require("../../lib/js/camlinternalLazy.js");
5+
6+
function fix(param) {
7+
return /* Fix */[Block.__(246, [(function (param) {
8+
return fix(/* () */0);
9+
})])];
10+
}
11+
12+
function unfixLeak(_param) {
13+
while(true) {
14+
var param = _param;
15+
var f = param[0];
16+
var tag = f.tag | 0;
17+
_param = tag === 250 ? f[0] : (
18+
tag === 246 ? CamlinternalLazy.force_lazy_block(f) : f
19+
);
20+
continue ;
21+
};
22+
}
23+
24+
function unfix(p) {
25+
while(true) {
26+
var match = p[0];
27+
var match$1 = match[0];
28+
var tag = match$1.tag | 0;
29+
p[0] = tag === 250 ? match$1[0] : (
30+
tag === 246 ? CamlinternalLazy.force_lazy_block(match$1) : match$1
31+
);
32+
};
33+
return /* () */0;
34+
}
35+
36+
exports.fix = fix;
37+
exports.unfixLeak = unfixLeak;
38+
exports.unfix = unfix;
39+
/* No side effect */

jscomp/test/gpr_3697_test.ml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
type 'a t = Fix of 'a t lazy_t
2+
3+
let rec fix () = Fix (lazy (fix ()))
4+
5+
6+
let rec unfixLeak (Fix f) =
7+
unfixLeak @@ Lazy.force f
8+
9+
10+
let unfix p =
11+
while true do
12+
p := match !p with (Fix lazy h) -> h
13+
done
14+
(* ;; unfixLeak (fix ()) *)
15+
16+
(* ;; unfix (ref (fix ())) *)

jscomp/test/rec_value_test.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -465,16 +465,14 @@ function fake_inline_minus(n) {
465465
return n + 1 | 0;
466466
}
467467

468-
function fake_inline(n) {
469-
return n + 1 | 0;
470-
}
468+
var fake_inline = fake_inline_minus;
469+
470+
var fake_inline_inlie2 = fake_inline_minus(3);
471471

472472
Mt.from_pair_suites("Rec_value_test", suites);
473473

474474
var v$1 = 3;
475475

476-
var fake_inline_inlie2 = 4;
477-
478476
exports.x = x;
479477
exports.a = a;
480478
exports.b = b;

0 commit comments

Comments
 (0)