Skip to content

Commit 44c2d4f

Browse files
committed
optimize single exit cases
1 parent e7d1a27 commit 44c2d4f

File tree

3 files changed

+85
-14
lines changed

3 files changed

+85
-14
lines changed

jscomp/core/lam_compile.ml

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ let change_tail_type_in_try
3737
| Not_tail | Maybe_tail_is_return Tail_in_try
3838
-> x
3939

40+
let change_tail_type_in_static
41+
(x : Lam_compile_context.tail_type)
42+
: Lam_compile_context.tail_type =
43+
match x with
44+
| Maybe_tail_is_return (Tail_with_name ({in_staticcatch=false} as z) ) ->
45+
Maybe_tail_is_return (Tail_with_name {z with in_staticcatch=true})
46+
| Maybe_tail_is_return (Tail_with_name {in_staticcatch=true} )
47+
| Not_tail | Maybe_tail_is_return Tail_in_try
48+
-> x
49+
4050
(* assume outer is [Lstaticcatch] *)
4151
let rec flat_catches
4252
(acc : Lam_compile_context.handler list) (x : Lam.t)
@@ -262,7 +272,7 @@ and compile_recursive_let ~all_bindings
262272
let output =
263273
compile_lambda
264274
{ cxt with
265-
continuation = EffectCall (Maybe_tail_is_return (Tail_with_name (Some ret )));
275+
continuation = EffectCall (Maybe_tail_is_return (Tail_with_name {label = Some ret; in_staticcatch = false} ));
266276
jmp_table = Lam_compile_context.empty_handler_map} body in
267277
let result =
268278
if ret.triggered then
@@ -640,13 +650,16 @@ and compile_stringswitch l cases default (lambda_cxt : Lam_compile_context.t) =
640650
default: (exit 1))
641651
with (1) 2))
642652
*)
643-
and compile_staticraise i (largs : Lam.t list) lambda_cxt =
653+
and compile_staticraise i (largs : Lam.t list) (lambda_cxt : Lam_compile_context.t) =
644654
(* [i] is the jump table, [largs] is the arguments passed to [Lstaticcatch]*)
645655
match Lam_compile_context.find_exn lambda_cxt i with
646656
| {exit_id; bindings ; order_id} ->
647657
Ext_list.fold_right2 largs bindings
648-
(Js_output.make [S.assign exit_id (E.small_int order_id)]
649-
~value:E.undefined)
658+
(
659+
Js_output.make
660+
(if order_id >= 0 then [S.assign exit_id (E.small_int order_id)]
661+
else [])
662+
)
650663
(fun larg bind acc ->
651664
let new_output =
652665
match larg with
@@ -695,6 +708,31 @@ and compile_staticraise i (largs : Lam.t list) lambda_cxt =
695708
and compile_staticcatch (lam : Lam.t) (lambda_cxt : Lam_compile_context.t)=
696709
let code_table, body = flatten_nested_caches lam in
697710
let exit_id = Ext_ident.create_tmp ~name:"exit" () in
711+
match lambda_cxt.continuation, code_table with
712+
| EffectCall (Maybe_tail_is_return (Tail_with_name ({in_staticcatch = false} as z))),
713+
[ code_table ] (* tail position and only one exit code *)
714+
->
715+
let jmp_table, handler =
716+
Lam_compile_context.add_pseudo_jmp
717+
lambda_cxt.jmp_table
718+
exit_id code_table in
719+
let new_cxt =
720+
{lambda_cxt with
721+
jmp_table = jmp_table ;
722+
continuation =
723+
EffectCall (Maybe_tail_is_return (Tail_with_name { z with in_staticcatch = true}))
724+
} in
725+
726+
let lbody = compile_lambda new_cxt body in
727+
let declares =
728+
Ext_list.map code_table.bindings
729+
(fun x -> S.declare_variable ~kind:Variable x) in
730+
Js_output.append_output (Js_output.make declares)
731+
(Js_output.append_output lbody
732+
(compile_lambda lambda_cxt handler ))
733+
| _ ->
734+
735+
698736
let exit_expr = E.var exit_id in
699737
let jmp_table, handlers =
700738
Lam_compile_context.add_jmps lambda_cxt.jmp_table exit_id code_table in
@@ -1256,7 +1294,7 @@ and compile_apply
12561294
) in
12571295
match fn, lambda_cxt.continuation with
12581296
| (Lvar fn_id,
1259-
(EffectCall (Maybe_tail_is_return (Tail_with_name (Some ret))) | NeedValue (Maybe_tail_is_return (Tail_with_name (Some ret)))))
1297+
(EffectCall (Maybe_tail_is_return (Tail_with_name ( {label = Some ret}))) | NeedValue (Maybe_tail_is_return (Tail_with_name ( {label = Some ret})))))
12601298
when Ident.same ret.id fn_id ->
12611299
ret.triggered <- true;
12621300
(* Here we mark [finished] true, since the continuation
@@ -1439,7 +1477,7 @@ and compile_prim (prim_info : Lam.prim_info) (lambda_cxt : Lam_compile_context.t
14391477
*)
14401478
(Js_output.output_as_block
14411479
( compile_lambda
1442-
{ lambda_cxt with continuation = EffectCall ( Maybe_tail_is_return (Tail_with_name None));
1480+
{ lambda_cxt with continuation = EffectCall ( Maybe_tail_is_return (Tail_with_name {label = None; in_staticcatch=false}));
14431481
jmp_table = Lam_compile_context.empty_handler_map}
14441482
body)))
14451483
| _ -> assert false)
@@ -1492,7 +1530,7 @@ and compile_lambda
14921530
(Js_output.output_as_block
14931531
( compile_lambda
14941532
{ lambda_cxt with
1495-
continuation = EffectCall (Maybe_tail_is_return (Tail_with_name None));
1533+
continuation = EffectCall (Maybe_tail_is_return (Tail_with_name {label =None; in_staticcatch=false}));
14961534
jmp_table = Lam_compile_context.empty_handler_map}
14971535
body)))
14981536
| Lapply appinfo ->

jscomp/core/lam_compile_context.ml

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,14 @@ type return_label = {
4646
mutable triggered : bool
4747
}
4848

49+
type tail = {
50+
label : return_label option;
51+
in_staticcatch : bool;
52+
}
53+
4954
type maybe_tail =
5055
| Tail_in_try
51-
| Tail_with_name of return_label option
56+
| Tail_with_name of tail
5257

5358
type tail_type =
5459
| Not_tail
@@ -94,11 +99,18 @@ type handler = {
9499
bindings : Ident.t list;
95100
}
96101

97-
(* always keep key id positive, specifically no [0] generated *)
102+
(* always keep key id positive, specifically no [0] generated
103+
return a tuple
104+
[tbl, handlers]
105+
[tbl] is used for compiling [staticraise]
106+
[handlers] is used for compiling [staticcatch]
107+
*)
98108
let add_jmps
99109
(m : jmp_table)
100-
exit_id code_table
101-
=
110+
(exit_id : Ident.t)
111+
(code_table : handler list)
112+
: jmp_table * (int * Lam.t) list
113+
=
102114
let map, handlers =
103115
Ext_list.fold_left_with_offset
104116
code_table (m,[])
@@ -112,6 +124,17 @@ let add_jmps
112124
) in
113125
map, List.rev handlers
114126

127+
let add_pseudo_jmp
128+
(m : jmp_table)
129+
(exit_id : Ident.t) (* TODO not needed, remove it later *)
130+
(code_table : handler) :
131+
jmp_table * Lam.t
132+
=
133+
HandlerMap.add m
134+
code_table.label {exit_id; bindings = code_table.bindings; order_id = -1},
135+
code_table.handler
136+
137+
115138

116139
let find_exn cxt i =
117140
Int_map.find_exn cxt.jmp_table i

jscomp/core/lam_compile_context.mli

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,13 @@ type value = {
5757

5858
type let_kind = Lam_compat.let_kind
5959

60+
type tail = {
61+
label : return_label option;
62+
in_staticcatch : bool;
63+
}
6064
type maybe_tail =
6165
| Tail_in_try
62-
| Tail_with_name of return_label option
66+
| Tail_with_name of tail
6367

6468
type tail_type =
6569
| Not_tail
@@ -81,7 +85,7 @@ type continuation =
8185

8286

8387

84-
type jmp_table
88+
type jmp_table = value Int_map.t
8589

8690
val continuation_is_return:
8791
continuation ->
@@ -94,7 +98,7 @@ type t = {
9498
meta : Lam_stats.t ;
9599
}
96100

97-
val empty_handler_map : jmp_table
101+
val empty_handler_map : jmp_table
98102

99103
type handler = {
100104
label : jbl_label ;
@@ -108,6 +112,12 @@ val add_jmps :
108112
handler list ->
109113
jmp_table * (jbl_label * Lam.t) list
110114

115+
val add_pseudo_jmp :
116+
jmp_table ->
117+
Ident.t ->
118+
handler ->
119+
jmp_table * Lam.t
120+
111121

112122
val find_exn :
113123
t ->

0 commit comments

Comments
 (0)