Skip to content

Commit c0e67e9

Browse files
committed
Track the names of constructors when compining switch statements.
1 parent 05a6ac5 commit c0e67e9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1218
-956
lines changed

jscomp/core/lam.ml

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ type apply_status =
3131

3232

3333
module Types = struct
34+
type switch_names = {consts: string array; blocks: string array}
35+
3436
type switch =
3537
{ sw_numconsts: bool; (* TODO: refine its representation *)
3638
sw_consts: (int * t) list;
@@ -92,7 +94,7 @@ module Types = struct
9294
| Llet of Lam_compat.let_kind * ident * t * t
9395
| Lletrec of (ident * t) list * t
9496
| Lprim of prim_info
95-
| Lswitch of t * switch
97+
| Lswitch of t * switch * switch_names
9698
| Lstringswitch of t * (string * t) list * t option
9799
| Lstaticraise of int * t list
98100
| Lstaticcatch of t * (int * ident list) * t
@@ -106,6 +108,8 @@ module Types = struct
106108
end
107109

108110
module X = struct
111+
type switch_names = Types.switch_names = {consts: string array; blocks: string array}
112+
109113
type switch
110114
= Types.switch
111115
=
@@ -148,7 +152,7 @@ module X = struct
148152
| Llet of Lam_compat.let_kind * ident * t * t
149153
| Lletrec of (ident * t) list * t
150154
| Lprim of prim_info
151-
| Lswitch of t * switch
155+
| Lswitch of t * switch * switch_names
152156
| Lstringswitch of t * (string * t) list * t option
153157
| Lstaticraise of int * t list
154158
| Lstaticcatch of t * (int * ident list) * t
@@ -192,12 +196,12 @@ let inner_map
192196
let args = Ext_list.map args f in
193197
Lprim { args; primitive; loc}
194198

195-
| Lswitch(arg, {sw_consts; sw_numconsts; sw_blocks; sw_numblocks; sw_failaction}) ->
199+
| Lswitch(arg, {sw_consts; sw_numconsts; sw_blocks; sw_numblocks; sw_failaction}, names) ->
196200
let arg = f arg in
197201
let sw_consts = Ext_list.map_snd sw_consts f in
198202
let sw_blocks = Ext_list.map_snd sw_blocks f in
199203
let sw_failaction = Ext_option.map sw_failaction f in
200-
Lswitch(arg, { sw_consts; sw_blocks; sw_failaction; sw_numblocks; sw_numconsts})
204+
Lswitch(arg, { sw_consts; sw_blocks; sw_failaction; sw_numblocks; sw_numconsts}, names)
201205
| Lstringswitch (arg,cases,default) ->
202206
let arg = f arg in
203207
let cases = Ext_list.map_snd cases f in
@@ -382,15 +386,15 @@ and eq_approx_list ls ls1 = Ext_list.for_all2_no_exn ls ls1 eq_approx
382386

383387

384388

385-
let switch lam (lam_switch : switch) : t =
389+
let switch lam (lam_switch : switch) names : t =
386390
match lam with
387391
| Lconst ((Const_pointer (i,_) | (Const_int i)))
388392
->
389393
Ext_list.assoc_by_int lam_switch.sw_consts i lam_switch.sw_failaction
390394
| Lconst (Const_block (i,_,_)) ->
391395
Ext_list.assoc_by_int lam_switch.sw_blocks i lam_switch.sw_failaction
392396
| _ ->
393-
Lswitch(lam,lam_switch)
397+
Lswitch(lam,lam_switch,names)
394398

395399
let stringswitch (lam : t) cases default : t =
396400
match lam with
@@ -727,13 +731,15 @@ let if_ (a : t) (b : t) (c : t) : t =
727731
begin match c with
728732
| Lswitch ( Lvar yy as switch_arg,
729733
({sw_blocks = []; sw_numblocks = true; sw_consts ;
730-
sw_numconsts; sw_failaction = None} as body)
734+
sw_numconsts; sw_failaction = None} as body),
735+
names
731736
)
732737
when Ident.same xx yy
733738
&& complete_range sw_consts ~start:0 ~finish:range
734739
->
735740
Lswitch(switch_arg,
736-
{ body with sw_failaction = Some b; sw_numconsts = false })
741+
{ body with sw_failaction = Some b; sw_numconsts = false },
742+
names)
737743
| _ -> Lifthenelse(a,b,c)
738744
end
739745
| _ -> Lifthenelse (a,b,c))

jscomp/core/lam.mli

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

2929
type ident = Ident.t
3030

31+
type switch_names = {consts: string array; blocks: string array}
3132

3233
type switch =
3334
{ sw_numconsts: bool;
@@ -65,7 +66,7 @@ and t = private
6566
| Llet of Lam_compat.let_kind * ident * t * t
6667
| Lletrec of (ident * t) list * t
6768
| Lprim of prim_info
68-
| Lswitch of t * switch
69+
| Lswitch of t * switch * switch_names
6970
| Lstringswitch of t * (string * t) list * t option
7071
| Lstaticraise of int * t list
7172
| Lstaticcatch of t * (int * ident list) * t
@@ -115,7 +116,7 @@ val letrec : (ident * t) list -> t -> t
115116
val if_ : t -> t -> t -> t
116117

117118
(** constant folding*)
118-
val switch : t -> switch -> t
119+
val switch : t -> switch -> switch_names -> t
119120
(** constant folding*)
120121
val stringswitch : t -> (string * t) list -> t option -> t
121122

jscomp/core/lam_analysis.ml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ let rec no_side_effects (lam : Lam.t) : bool =
217217
-> false
218218
)
219219
| Llet (_,_, arg,body) -> no_side_effects arg && no_side_effects body
220-
| Lswitch (_,_) -> false
220+
| Lswitch _ -> false
221221
| Lstringswitch (_,_,_) -> false
222222
| Lstaticraise _ -> false
223223
| Lstaticcatch _ -> false
@@ -302,7 +302,7 @@ let rec size (lam : Lam.t) =
302302
args; _} -> size_lams (size fn) args
303303
(* | Lfunction(_, params, l) -> really_big () *)
304304
| Lfunction {body} -> size body
305-
| Lswitch(_, _) -> really_big ()
305+
| Lswitch _ -> really_big ()
306306
| Lstringswitch(_,_,_) -> really_big ()
307307
| Lstaticraise (i,ls) ->
308308
Ext_list.fold_left ls 1 (fun acc x -> size x + acc)
@@ -361,11 +361,11 @@ let destruct_pattern (body : Lam.t) params args =
361361
| x::xs, [] -> assert false
362362
in
363363
match body with
364-
| Lswitch (Lvar v , switch)
364+
| Lswitch (Lvar v , switch, names)
365365
->
366366
begin match aux v params args with
367367
| Some (Lam.Lconst _ as lam) ->
368-
size (Lam.switch lam switch) < small_inline_size
368+
size (Lam.switch lam switch names) < small_inline_size
369369
| Some _ | None -> false
370370
end
371371
| Lifthenelse(Lvar v, then_, else_)

jscomp/core/lam_arity_analysis.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ let rec get_arity (meta : Lam_stats.t) (lam : Lam.t) : Lam_arity.t =
110110
sw_blocks;
111111
sw_numblocks = _;
112112
sw_numconsts = _;
113-
}) ->
113+
}, _names) ->
114114
all_lambdas meta (
115115
let rest =
116116
Ext_list.map_append sw_consts

jscomp/core/lam_bounded_vars.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ let rewrite (map : _ Ident_hashtbl.t)
120120
sw_blocks;
121121
sw_numblocks;
122122
sw_numconsts;
123-
}) ->
123+
}, names) ->
124124
let l = aux l in
125125
Lam.switch l
126126
{sw_consts =
@@ -130,6 +130,7 @@ let rewrite (map : _ Ident_hashtbl.t)
130130
sw_numblocks = sw_numblocks;
131131
sw_failaction = option_map sw_failaction
132132
}
133+
names
133134
| Lstringswitch(l, sw, d) ->
134135
let l = aux l in
135136
Lam.stringswitch l

jscomp/core/lam_check.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ let check file lam =
7474
| Lletrec(decl, body) ->
7575
check_list_snd decl cxt;
7676
check_staticfails body cxt
77-
| Lswitch(arg, sw) ->
77+
| Lswitch(arg, sw, _names) ->
7878
check_staticfails arg cxt ;
7979
check_list_snd sw.sw_consts cxt;
8080
check_list_snd sw.sw_blocks cxt;
@@ -127,7 +127,7 @@ let check file lam =
127127
iter_list_snd decl;
128128
iter body
129129

130-
| Lswitch(arg, sw) ->
130+
| Lswitch(arg, sw, _names) ->
131131
iter arg;
132132
iter_list_snd sw.sw_consts;
133133
iter_list_snd sw.sw_blocks;

jscomp/core/lam_closure.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ let free_variables
104104
sw_failaction;
105105
sw_numconsts;
106106
sw_numblocks
107-
})) ->
107+
}), _names) ->
108108
iter top arg;
109109
let top = Lam_var_stats.new_position_after_lam arg top in
110110
List.iter (fun (_, case) -> iter top case) sw_consts;

jscomp/core/lam_compile.ml

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -512,17 +512,21 @@ and compile_general_cases
512512
[switch ?default ?declaration switch_exp body]
513513
)
514514

515-
and compile_cases cxt switch_exp table default =
515+
and compile_cases ~is_tag cxt switch_exp table default names =
516516
compile_general_cases
517-
E.small_int
517+
(fun i ->
518+
let comment = match (if is_tag then names.Lam.blocks.(i) else names.consts.(i)) with
519+
| s -> Some s
520+
| exception Invalid_argument _ -> Some "NotFound" in
521+
{(E.small_int i) with comment})
518522
E.int_equal
519523
cxt
520524
(fun ?default ?declaration e clauses ->
521525
S.int_switch ?default ?declaration e clauses)
522526
switch_exp
523527
table
524528
default
525-
and compile_switch switch_arg sw (lambda_cxt : Lam_compile_context.t) =
529+
and compile_switch switch_arg sw (lambda_cxt : Lam_compile_context.t) names =
526530
(* TODO: if default is None, we can do some optimizations
527531
Use switch vs if/then/else
528532
@@ -558,20 +562,20 @@ and compile_switch switch_arg sw (lambda_cxt : Lam_compile_context.t) =
558562
| { block; value = Some e } ->
559563
block @
560564
(if sw_numconsts && sw_consts = [] then
561-
compile_cases cxt (E.tag e) sw_blocks sw_blocks_default
565+
compile_cases ~is_tag:true cxt (E.tag e) sw_blocks sw_blocks_default names
562566
else if sw_numblocks && sw_blocks = [] then
563-
compile_cases cxt e sw_consts sw_num_default
567+
compile_cases ~is_tag:false cxt e sw_consts sw_num_default names
564568
else
565569
(* [e] will be used twice *)
566570
let dispatch e =
567571
S.if_
568572
(E.is_type_number e )
569-
(compile_cases cxt e sw_consts sw_num_default
573+
(compile_cases ~is_tag:false cxt e sw_consts sw_num_default names
570574
)
571575
(* default still needed, could simplified*)
572576
~else_:
573-
(compile_cases cxt (E.tag e ) sw_blocks
574-
sw_blocks_default) in
577+
(compile_cases ~is_tag:true cxt (E.tag e ) sw_blocks
578+
sw_blocks_default names) in
575579
match e.expression_desc with
576580
| J.Var _ -> [ dispatch e]
577581
| _ ->
@@ -752,15 +756,15 @@ and compile_staticcatch (lam : Lam.t) (lambda_cxt : Lam_compile_context.t)=
752756
Js_output.append_output
753757
(Js_output.make (S.declare_variable ~kind:Variable v :: declares) )
754758
(Js_output.append_output lbody (Js_output.make (
755-
compile_cases new_cxt exit_expr handlers NonComplete) ~value:(E.var v )))
759+
compile_cases ~is_tag:false new_cxt exit_expr handlers NonComplete {consts=[||]; blocks=[||]}) ~value:(E.var v )))
756760
| Declare (kind, id)
757761
(* declare first this we will do branching*) ->
758762
let declares = S.declare_variable ~kind id :: declares in
759763
let new_cxt = {lambda_cxt with jmp_table = jmp_table; continuation = Assign id } in
760764
let lbody = compile_lambda new_cxt body in
761765
Js_output.append_output (Js_output.make declares)
762766
(Js_output.append_output lbody
763-
(Js_output.make (compile_cases new_cxt exit_expr handlers NonComplete)))
767+
(Js_output.make (compile_cases ~is_tag:false new_cxt exit_expr handlers NonComplete {consts=[||]; blocks=[||]})))
764768
(* place holder -- tell the compiler that
765769
we don't know if it's complete
766770
*)
@@ -769,13 +773,13 @@ and compile_staticcatch (lam : Lam.t) (lambda_cxt : Lam_compile_context.t)=
769773
let lbody = compile_lambda new_cxt body in
770774
Js_output.append_output (Js_output.make declares)
771775
(Js_output.append_output lbody
772-
(Js_output.make (compile_cases new_cxt exit_expr handlers NonComplete)))
776+
(Js_output.make (compile_cases ~is_tag:false new_cxt exit_expr handlers NonComplete {consts=[||]; blocks=[||]})))
773777
| Assign _ ->
774778
let new_cxt = {lambda_cxt with jmp_table = jmp_table } in
775779
let lbody = compile_lambda new_cxt body in
776780
Js_output.append_output (Js_output.make declares)
777781
(Js_output.append_output lbody
778-
(Js_output.make (compile_cases new_cxt exit_expr handlers NonComplete)))
782+
(Js_output.make (compile_cases ~is_tag:false new_cxt exit_expr handlers NonComplete {consts=[||]; blocks=[||]})))
779783

780784
and compile_sequand
781785
(l : Lam.t) (r : Lam.t) (lambda_cxt : Lam_compile_context.t) =
@@ -1587,8 +1591,11 @@ and compile_lambda
15871591
compile_ifthenelse predicate t_branch f_branch lambda_cxt
15881592
| Lstringswitch(l, cases, default) ->
15891593
compile_stringswitch l cases default lambda_cxt
1590-
| Lswitch(switch_arg, sw) ->
1591-
compile_switch switch_arg sw lambda_cxt
1594+
| Lswitch(switch_arg, sw, names) ->
1595+
(* Format.eprintf "XXX Lswitch consts:%d blocks:%d@."
1596+
(Array.length names.consts)
1597+
(Array.length names.blocks); *)
1598+
compile_switch switch_arg sw lambda_cxt names
15921599
| Lstaticraise(i, largs) ->
15931600
compile_staticraise i largs lambda_cxt
15941601
| Lstaticcatch _ ->

jscomp/core/lam_convert.ml

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ let exception_id_destructed (l : Lam.t) (fv : Ident.t): bool =
9696
hit fn || hit_list args
9797
| Lglobal_module _ (* global persistent module, play safe *)
9898
-> false
99-
| Lswitch(arg, sw) ->
99+
| Lswitch(arg, sw, _names) ->
100100
hit arg ||
101101
hit_list_snd sw.sw_consts ||
102102
hit_list_snd sw.sw_blocks ||
@@ -623,9 +623,10 @@ let convert (exports : Ident_set.t) (lam : Lambda.lambda) : Lam.t * Lam_module_i
623623
#if OCAML_VERSION =~ ">4.03.0" then
624624
(e,s, _loc)
625625
#else
626-
(e,s)
626+
(e,s, names)
627627
#end
628-
-> convert_switch e s
628+
->
629+
convert_switch e s names
629630
| Lstringswitch (e, cases, default, _ ) ->
630631
Lam.stringswitch
631632
(convert_aux e)
@@ -726,7 +727,8 @@ let convert (exports : Ident_set.t) (lam : Lambda.lambda) : Lam.t * Lam_module_i
726727
sw_consts ;
727728
sw_blocks = []; sw_numblocks = true;
728729
sw_failaction = Some ifso
729-
} as px)
730+
} as px),
731+
names
730732
)
731733
when Ident.same switcher3 id &&
732734
not (Lam_hit.hit_variable id ifso ) &&
@@ -738,6 +740,7 @@ let convert (exports : Ident_set.t) (lam : Lambda.lambda) : Lam.t * Lam_module_i
738740
Ext_list.map sw_consts
739741
(fun (i,act) -> i - offset, act)
740742
}
743+
names
741744
| _ ->
742745
Lam.let_ kind id new_e new_body
743746
and convert_pipe (f : Lambda.lambda) (x : Lambda.lambda) outer_loc =
@@ -756,8 +759,9 @@ let convert (exports : Ident_set.t) (lam : Lambda.lambda) : Lam.t * Lam_module_i
756759
Lam.apply fn (Ext_list.append_one args x) outer_loc App_na
757760
| _ ->
758761
Lam.apply f [x] outer_loc App_na
759-
and convert_switch (e : Lambda.lambda) (s : Lambda.lambda_switch) =
762+
and convert_switch (e : Lambda.lambda) (s : Lambda.lambda_switch) (names : Lambda.switch_names) =
760763
let e = convert_aux e in
764+
let names = {Lam.consts=names.consts; blocks = names.blocks} in
761765
match s with
762766
| {
763767
sw_failaction = None ;
@@ -783,14 +787,16 @@ let convert (exports : Ident_set.t) (lam : Lambda.lambda) : Lam.t * Lam_module_i
783787
sw_numconsts =
784788
Ext_list.length_ge sw_consts sw_numconsts
785789
}
790+
names
786791
end
787792
| _ ->
788793
Lam.switch e
789794
{ sw_numconsts = Ext_list.length_ge s.sw_consts s.sw_numconsts ;
790795
sw_consts = Ext_list.map_snd s.sw_consts convert_aux;
791796
sw_numblocks = Ext_list.length_ge s.sw_blocks s.sw_numblocks;
792797
sw_blocks = Ext_list.map_snd s.sw_blocks convert_aux;
793-
sw_failaction =Ext_option.map s.sw_failaction convert_aux } in
798+
sw_failaction =Ext_option.map s.sw_failaction convert_aux }
799+
names in
794800
convert_aux lam , may_depends
795801

796802

jscomp/core/lam_exit_count.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ let count_helper (lam : Lam.t) : collection =
7575
Ext_list.iter_snd bindings count;
7676
count body
7777
| Lprim {args; _} -> List.iter count args
78-
| Lswitch(l, sw) ->
78+
| Lswitch(l, sw, _names) ->
7979
count_default sw ;
8080
count l;
8181
Ext_list.iter_snd sw.sw_consts count;

0 commit comments

Comments
 (0)