Skip to content

Commit 2af3d1b

Browse files
committed
Better logic to simplify and/or.
Current logic for code generated by untagged unions pattern matching only focuses on certain cases of x == b where b is a boolean. There are more cases, and there are other constants than booleans: nil, undefined.
1 parent 3b93359 commit 2af3d1b

File tree

1 file changed

+65
-13
lines changed

1 file changed

+65
-13
lines changed

compiler/core/js_exp_make.ml

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -662,31 +662,43 @@ let bin ?comment (op : J.binop) (e0 : t) (e1 : t) : t =
662662
be careful for side effect
663663
*)
664664

665-
let rec filter_bool (e : t) ~j ~b =
665+
type filter_const = Ctrue | Cnull
666+
667+
let rec filter_const (e : t) ~j ~b:eq ~const =
666668
match e.expression_desc with
667669
| Bin (And, e1, e2) -> (
668-
match (filter_bool e1 ~j ~b, filter_bool e2 ~j ~b) with
670+
match
671+
(filter_const e1 ~j ~b:eq ~const, filter_const e2 ~j ~b:eq ~const)
672+
with
669673
| None, None -> None
670674
| Some e, None | None, Some e -> Some e
671675
| Some e1, Some e2 -> Some {e with expression_desc = Bin (And, e1, e2)})
672676
| Bin (Or, e1, e2) -> (
673-
match (filter_bool e1 ~j ~b, filter_bool e2 ~j ~b) with
677+
match
678+
(filter_const e1 ~j ~b:eq ~const, filter_const e2 ~j ~b:eq ~const)
679+
with
674680
| None, _ | _, None -> None
675681
| Some e1, Some e2 -> Some {e with expression_desc = Bin (Or, e1, e2)})
676682
| Bin (EqEqEq, {expression_desc = Var i}, {expression_desc = Bool b1})
677683
| Bin (EqEqEq, {expression_desc = Bool b1}, {expression_desc = Var i})
678-
when Js_op_util.same_vident i j ->
679-
if b1 = b then None else Some e
684+
when Js_op_util.same_vident i j && const = Ctrue ->
685+
if b1 = eq then None else Some e
680686
| Bin (NotEqEq, {expression_desc = Var i}, {expression_desc = Bool b1})
681687
| Bin (NotEqEq, {expression_desc = Bool b1}, {expression_desc = Var i})
682-
when Js_op_util.same_vident i j ->
683-
if b1 <> b then None else Some e
688+
when Js_op_util.same_vident i j && const = Ctrue ->
689+
if b1 <> eq then None else Some e
684690
| Bin
685691
( NotEqEq,
686692
{expression_desc = Typeof {expression_desc = Var i}},
687-
{expression_desc = Str {txt}} )
688-
when Js_op_util.same_vident i j ->
689-
if txt <> "bool" then None else assert false
693+
{expression_desc = Str {txt = "bool"}} )
694+
when Js_op_util.same_vident i j && const = Ctrue ->
695+
None
696+
| Bin
697+
( NotEqEq,
698+
{expression_desc = Typeof {expression_desc = Var i}},
699+
{expression_desc = Str {txt = "string"}} )
700+
when Js_op_util.same_vident i j && (const = Cnull || const = Ctrue) ->
701+
None
690702
| Js_not
691703
{
692704
expression_desc =
@@ -695,7 +707,7 @@ let rec filter_bool (e : t) ~j ~b =
695707
[{expression_desc = Var i}],
696708
_ );
697709
}
698-
when Js_op_util.same_vident i j ->
710+
when Js_op_util.same_vident i j && (const = Ctrue || const = Cnull) ->
699711
None
700712
| _ -> Some e
701713

@@ -714,8 +726,32 @@ let and_ ?comment (e1 : t) (e2 : t) : t =
714726
)
715727
when Js_op_util.same_vident i j ->
716728
e2
717-
| _, Bin (EqEqEq, {expression_desc = Var j}, {expression_desc = Bool b}) -> (
718-
match filter_bool e1 ~j ~b with
729+
| ( _,
730+
Bin
731+
( ((EqEqEq | NotEqEq) as op),
732+
{expression_desc = Var j},
733+
{expression_desc = Bool b} ) )
734+
| ( Bin
735+
( ((EqEqEq | NotEqEq) as op),
736+
{expression_desc = Var j},
737+
{expression_desc = Bool b} ),
738+
_ ) -> (
739+
match
740+
filter_const e1 ~j ~b:(if op = EqEqEq then b else not b) ~const:Ctrue
741+
with
742+
| None -> e2
743+
| Some e1 -> {expression_desc = Bin (And, e1, e2); comment})
744+
| ( _,
745+
Bin
746+
( ((EqEqEq | NotEqEq) as op),
747+
{expression_desc = Var j},
748+
{expression_desc = Null} ) )
749+
| ( Bin
750+
( ((EqEqEq | NotEqEq) as op),
751+
{expression_desc = Var j},
752+
{expression_desc = Null} ),
753+
_ ) -> (
754+
match filter_const e1 ~j ~b:(op = EqEqEq) ~const:Cnull with
719755
| None -> e2
720756
| Some e1 -> {expression_desc = Bin (And, e1, e2); comment})
721757
| _, _ -> {expression_desc = Bin (And, e1, e2); comment}
@@ -729,6 +765,22 @@ let or_ ?comment (e1 : t) (e2 : t) =
729765
| Var i, Bin (Or, l, ({expression_desc = Var j; _} as r))
730766
when Js_op_util.same_vident i j ->
731767
{e2 with expression_desc = Bin (Or, r, l)}
768+
| ( _,
769+
Bin
770+
( ((EqEqEq | NotEqEq) as op),
771+
{expression_desc = Var j},
772+
{expression_desc = Null} ) ) -> (
773+
match filter_const e1 ~j ~b:(op <> EqEqEq) ~const:Cnull with
774+
| None -> e2
775+
| Some e1 -> {expression_desc = Bin (Or, e1, e2); comment})
776+
| ( Bin
777+
( ((EqEqEq | NotEqEq) as op),
778+
{expression_desc = Var j},
779+
{expression_desc = Null} ),
780+
_ ) -> (
781+
match filter_const e2 ~j ~b:(op <> EqEqEq) ~const:Cnull with
782+
| None -> e1
783+
| Some e2 -> {expression_desc = Bin (Or, e1, e2); comment})
732784
| _, _ -> {expression_desc = Bin (Or, e1, e2); comment}
733785

734786
(* return a value of type boolean *)

0 commit comments

Comments
 (0)