Skip to content

Commit 6978f47

Browse files
committed
Integer optimizations
Avoid unnecessary conversions between 31- and 32-bit integers
1 parent eb6da60 commit 6978f47

File tree

7 files changed

+501
-246
lines changed

7 files changed

+501
-246
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
* Compiler: deadcode elimination of cyclic values (#1978)
4141
* Compiler: directly write Wasm binary modules (#2000, #2003)
4242
* Compiler: rewrote inlining pass (#1935, #2018, #2027)
43+
* Compiler/wasm: optimize integer operations (#2032)
4344

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

compiler/lib-wasm/curry.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ module Make (Target : Target_sig.S) = struct
298298
Memory.allocate
299299
~tag:0
300300
~deadcode_sentinal:(Code.Var.fresh ())
301+
~load
301302
(List.map ~f:(fun x -> `Var x) (List.tl l))
302303
in
303304
let* make_iterator =

compiler/lib-wasm/gc_target.ml

Lines changed: 47 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -455,13 +455,11 @@ module Value = struct
455455
let* i = i in
456456
return (W.RefTest ({ nullable = false; typ = I31 }, i))
457457

458-
let not i = val_int (Arith.eqz (int_val i))
458+
let not i = Arith.eqz i
459459

460-
let binop op i i' = val_int (op (int_val i) (int_val i'))
460+
let lt = Arith.( < )
461461

462-
let lt = binop Arith.( < )
463-
464-
let le = binop Arith.( <= )
462+
let le = Arith.( <= )
465463

466464
let ref_eq i i' =
467465
let* i = i in
@@ -571,41 +569,41 @@ module Value = struct
571569
(let* () = store xv x in
572570
let* () = store yv y in
573571
return ())
574-
(val_int (if negate then Arith.eqz n else n))
572+
(if negate then Arith.eqz n else n)
575573

576574
let eq x y = eq_gen ~negate:false x y
577575

578576
let neq x y = eq_gen ~negate:true x y
579577

580-
let ult = binop Arith.(ult)
578+
let ult = Arith.ult
581579

582580
let is_int i =
583581
let* i = i in
584-
val_int (return (W.RefTest ({ nullable = false; typ = I31 }, i)))
582+
return (W.RefTest ({ nullable = false; typ = I31 }, i))
585583

586-
let int_add = binop Arith.( + )
584+
let int_add = Arith.( + )
587585

588-
let int_sub = binop Arith.( - )
586+
let int_sub = Arith.( - )
589587

590-
let int_mul = binop Arith.( * )
588+
let int_mul = Arith.( * )
591589

592-
let int_div = binop Arith.( / )
590+
let int_div = Arith.( / )
593591

594-
let int_mod = binop Arith.( mod )
592+
let int_mod = Arith.( mod )
595593

596-
let int_neg i = val_int Arith.(const 0l - int_val i)
594+
let int_neg i = Arith.(const 0l - i)
597595

598-
let int_or = binop Arith.( lor )
596+
let int_or = Arith.( lor )
599597

600-
let int_and = binop Arith.( land )
598+
let int_and = Arith.( land )
601599

602-
let int_xor = binop Arith.( lxor )
600+
let int_xor = Arith.( lxor )
603601

604-
let int_lsl = binop Arith.( lsl )
602+
let int_lsl = Arith.( lsl )
605603

606-
let int_lsr i i' = val_int Arith.((int_val i land const 0x7fffffffl) lsr int_val i')
604+
let int_lsr i i' = Arith.((i land const 0x7fffffffl) lsr i')
607605

608-
let int_asr = binop Arith.( asr )
606+
let int_asr = Arith.( asr )
609607
end
610608

611609
module Memory = struct
@@ -657,7 +655,7 @@ module Memory = struct
657655
let* ty = Type.float_type in
658656
wasm_struct_get ty (wasm_cast ty e) 0
659657

660-
let allocate ~tag ~deadcode_sentinal l =
658+
let allocate ~tag ~deadcode_sentinal ~load l =
661659
if tag = 254
662660
then
663661
let* l =
@@ -728,23 +726,22 @@ module Memory = struct
728726
let* e = float_array_length (load a) in
729727
instr (W.Push e))
730728

731-
let array_get e e' = wasm_array_get e Arith.(Value.int_val e' + const 1l)
729+
let array_get e e' = wasm_array_get e Arith.(e' + const 1l)
732730

733-
let array_set e e' e'' = wasm_array_set e Arith.(Value.int_val e' + const 1l) e''
731+
let array_set e e' e'' = wasm_array_set e Arith.(e' + const 1l) e''
734732

735-
let float_array_get e e' =
736-
box_float (wasm_array_get ~ty:Type.float_array_type e (Value.int_val e'))
733+
let float_array_get e e' = box_float (wasm_array_get ~ty:Type.float_array_type e e')
737734

738735
let float_array_set e e' e'' =
739-
wasm_array_set ~ty:Type.float_array_type e (Value.int_val e') (unbox_float e'')
736+
wasm_array_set ~ty:Type.float_array_type e e' (unbox_float e'')
740737

741738
let gen_array_get e e' =
742739
let a = Code.Var.fresh_n "a" in
743740
let i = Code.Var.fresh_n "i" in
744741
block_expr
745742
{ params = []; result = [ Type.value ] }
746743
(let* () = store a e in
747-
let* () = store ~typ:I32 i (Value.int_val e') in
744+
let* () = store ~typ:I32 i e' in
748745
let* () =
749746
drop
750747
(block_expr
@@ -771,7 +768,7 @@ module Memory = struct
771768
let i = Code.Var.fresh_n "i" in
772769
let v = Code.Var.fresh_n "v" in
773770
let* () = store a e in
774-
let* () = store ~typ:I32 i (Value.int_val e') in
771+
let* () = store ~typ:I32 i e' in
775772
let* () = store v e'' in
776773
block
777774
{ params = []; result = [] }
@@ -801,11 +798,9 @@ module Memory = struct
801798
let* e = wasm_cast ty e in
802799
return (W.ArrayLen e)
803800

804-
let bytes_get e e' =
805-
Value.val_int (wasm_array_get ~ty:Type.string_type e (Value.int_val e'))
801+
let bytes_get e e' = wasm_array_get ~ty:Type.string_type e e'
806802

807-
let bytes_set e e' e'' =
808-
wasm_array_set ~ty:Type.string_type e (Value.int_val e') (Value.int_val e'')
803+
let bytes_set e e' e'' = wasm_array_set ~ty:Type.string_type e e' e''
809804

810805
let field e idx = wasm_array_get e (Arith.const (Int32.of_int (idx + 1)))
811806

@@ -1032,23 +1027,26 @@ module Constant = struct
10321027
return (Const, e)
10331028

10341029
let translate c =
1035-
let* const, c = translate_rec c in
1036-
match const with
1037-
| Const ->
1038-
let* b = is_small_constant c in
1039-
if b then return c else store_in_global c
1040-
| Const_named name -> store_in_global ~name c
1041-
| Mutated ->
1042-
let name = Code.Var.fresh_n "const" in
1043-
let* () =
1044-
register_global
1045-
~constant:true
1046-
name
1047-
{ mut = true; typ = Type.value }
1048-
(W.RefI31 (Const (I32 0l)))
1049-
in
1050-
let* () = register_init_code (instr (W.GlobalSet (name, c))) in
1051-
return (W.GlobalGet name)
1030+
match c with
1031+
| Code.Int i -> return (W.Const (I32 (Targetint.to_int32 i)))
1032+
| _ -> (
1033+
let* const, c = translate_rec c in
1034+
match const with
1035+
| Const ->
1036+
let* b = is_small_constant c in
1037+
if b then return c else store_in_global c
1038+
| Const_named name -> store_in_global ~name c
1039+
| Mutated ->
1040+
let name = Code.Var.fresh_n "const" in
1041+
let* () =
1042+
register_global
1043+
~constant:true
1044+
name
1045+
{ mut = true; typ = Type.value }
1046+
(W.RefI31 (Const (I32 0l)))
1047+
in
1048+
let* () = register_init_code (instr (W.GlobalSet (name, c))) in
1049+
return (W.GlobalGet name))
10521050
end
10531051

10541052
module Closure = struct

0 commit comments

Comments
 (0)