Skip to content

Commit 0fa14b9

Browse files
committed
Improve elimination of call to caml_js_strict_equals
1 parent 61c00c2 commit 0fa14b9

File tree

1 file changed

+37
-21
lines changed

1 file changed

+37
-21
lines changed

compiler/lib-wasm/gc_target.ml

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -540,30 +540,46 @@ module Value = struct
540540

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

543+
let may_be_js js x =
544+
let* ty = expression_type x in
545+
match ty with
546+
| None -> return true
547+
| Some (Ref { typ; _ }) -> heap_type_sub (Type js) typ
548+
| Some (I32 | I64 | F32 | F64) -> return false
549+
543550
let eq_gen ~negate x y =
544-
let xv = Code.Var.fresh () in
545-
let yv = Code.Var.fresh () in
551+
let* x = x in
552+
let* y = y in
546553
let* js = Type.js_type in
547-
let n =
548-
if_expr
549-
I32
550-
(* We mimic an "and" on the two conditions, but in a way that is nicer to the
554+
let* bx = may_be_js js x in
555+
let* by = may_be_js js y in
556+
if bx && by
557+
then
558+
let xv = Code.Var.fresh () in
559+
let yv = Code.Var.fresh () in
560+
let n =
561+
if_expr
562+
I32
563+
(* We mimic an "and" on the two conditions, but in a way that is nicer to the
551564
binaryen optimizer. *)
552-
(if_expr
553-
I32
554-
(ref_test (ref js) (load xv))
555-
(ref_test (ref js) (load yv))
556-
(Arith.const 0l))
557-
(caml_js_strict_equals (load xv) (load yv)
558-
>>| (fun e -> W.RefCast ({ nullable = false; typ = I31 }, e))
559-
>>| fun e -> W.I31Get (S, e))
560-
(ref_eq (load xv) (load yv))
561-
in
562-
seq
563-
(let* () = store xv x in
564-
let* () = store yv y in
565-
return ())
566-
(if negate then Arith.eqz n else n)
565+
(if_expr
566+
I32
567+
(ref_test (ref js) (load xv))
568+
(ref_test (ref js) (load yv))
569+
(Arith.const 0l))
570+
(caml_js_strict_equals (load xv) (load yv)
571+
>>| (fun e -> W.RefCast ({ nullable = false; typ = I31 }, e))
572+
>>| fun e -> W.I31Get (S, e))
573+
(ref_eq (load xv) (load yv))
574+
in
575+
seq
576+
(let* () = store xv (return x) in
577+
let* () = store yv (return y) in
578+
return ())
579+
(if negate then Arith.eqz n else n)
580+
else
581+
let n = ref_eq (return x) (return y) in
582+
if negate then Arith.eqz n else n
567583

568584
let eq x y = eq_gen ~negate:false x y
569585

0 commit comments

Comments
 (0)