Skip to content

Commit 824efea

Browse files
vouillonhhugo
andauthored
Use the type analysis to avoid using JavasScript strict equality (#2040)
If we know that one of the compared values is not a JavaScript value, we can directly use physical equality. --------- Co-authored-by: Hugo Heuzard <[email protected]>
1 parent a53bd09 commit 824efea

File tree

4 files changed

+36
-11
lines changed

4 files changed

+36
-11
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
* Compiler: directly write Wasm binary modules (#2000, #2003)
4444
* Compiler: rewrote inlining pass (#1935, #2018, #2027)
4545
* Compiler/wasm: optimize integer operations (#2032)
46+
* Compiler/wasm: use type analysis to remove some unnecessary uses of JavasScript strict equality (#2040)
4647

4748
## Bug fixes
4849
* Compiler: fix stack overflow issues with double translation (#1869)

compiler/lib-wasm/gc_target.ml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ module Value = struct
540540

541541
let ( >>| ) x f = map f x
542542

543-
let eq_gen ~negate x y =
543+
let js_eqeqeq ~negate x y =
544544
let xv = Code.Var.fresh () in
545545
let yv = Code.Var.fresh () in
546546
let* js = Type.js_type in
@@ -565,9 +565,15 @@ module Value = struct
565565
return ())
566566
(if negate then Arith.eqz n else n)
567567

568-
let eq x y = eq_gen ~negate:false x y
568+
let phys_eq x y =
569+
let* x = x in
570+
let* y = y in
571+
return (W.RefEq (x, y))
569572

570-
let neq x y = eq_gen ~negate:true x y
573+
let phys_neq x y =
574+
let* x = x in
575+
let* y = y in
576+
Arith.eqz (return (W.RefEq (x, y)))
571577

572578
let ult = Arith.ult
573579

compiler/lib-wasm/generate.ml

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,15 +215,31 @@ module Generate (Target : Target_sig.S) = struct
215215
(transl_prim_arg ctx ~typ:(Int Normalized) x)
216216
(transl_prim_arg ctx ~typ:(Int Normalized) y)
217217

218-
let translate_int_equality ctx op op' x y =
218+
let translate_int_equality ctx ~negate x y =
219219
match get_type ctx x, get_type ctx y with
220220
| (Int Normalized as typ), Int Normalized ->
221-
op (transl_prim_arg ctx ~typ x) (transl_prim_arg ctx ~typ y)
221+
(if negate then Arith.( <> ) else Arith.( = ))
222+
(transl_prim_arg ctx ~typ x)
223+
(transl_prim_arg ctx ~typ y)
222224
| Int (Normalized | Unnormalized), Int (Normalized | Unnormalized) ->
223-
op
225+
(if negate then Arith.( <> ) else Arith.( = ))
224226
Arith.(transl_prim_arg ctx ~typ:(Int Unnormalized) x lsl const 1l)
225227
Arith.(transl_prim_arg ctx ~typ:(Int Unnormalized) y lsl const 1l)
226-
| _ -> op' (transl_prim_arg ctx ~typ:Top x) (transl_prim_arg ctx ~typ:Top y)
228+
| Top, Top ->
229+
Value.js_eqeqeq
230+
~negate
231+
(transl_prim_arg ctx ~typ:Top x)
232+
(transl_prim_arg ctx ~typ:Top y)
233+
| Bot, _ | _, Bot ->
234+
(* this is deadcode *)
235+
(if negate then Value.phys_neq else Value.phys_eq)
236+
(transl_prim_arg ctx ~typ:Top x)
237+
(transl_prim_arg ctx ~typ:Top y)
238+
| (Int _ | Number _ | Tuple _), _ | _, (Int _ | Number _ | Tuple _) ->
239+
(* Only Top may contain JavaScript values *)
240+
(if negate then Value.phys_neq else Value.phys_eq)
241+
(transl_prim_arg ctx ~typ:Top x)
242+
(transl_prim_arg ctx ~typ:Top y)
227243

228244
let internal_primitives =
229245
let h = String.Hashtbl.create 128 in
@@ -864,8 +880,8 @@ module Generate (Target : Target_sig.S) = struct
864880
| Prim (Lt, [ x; y ]) -> translate_int_comparison ctx Arith.( < ) x y
865881
| Prim (Le, [ x; y ]) -> translate_int_comparison ctx Arith.( <= ) x y
866882
| Prim (Ult, [ x; y ]) -> translate_int_comparison ctx Arith.ult x y
867-
| Prim (Eq, [ x; y ]) -> translate_int_equality ctx Arith.( = ) Value.eq x y
868-
| Prim (Neq, [ x; y ]) -> translate_int_equality ctx Arith.( <> ) Value.neq x y
883+
| Prim (Eq, [ x; y ]) -> translate_int_equality ctx ~negate:false x y
884+
| Prim (Neq, [ x; y ]) -> translate_int_equality ctx ~negate:true x y
869885
| Prim (Array_get, [ x; y ]) ->
870886
Memory.array_get
871887
(transl_prim_arg ctx x)

compiler/lib-wasm/target_sig.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,11 @@ module type S = sig
124124

125125
val le : expression -> expression -> expression
126126

127-
val eq : expression -> expression -> expression
127+
val js_eqeqeq : negate:bool -> expression -> expression -> expression
128128

129-
val neq : expression -> expression -> expression
129+
val phys_eq : expression -> expression -> expression
130+
131+
val phys_neq : expression -> expression -> expression
130132

131133
val ult : expression -> expression -> expression
132134

0 commit comments

Comments
 (0)