Skip to content

Commit 4587b75

Browse files
committed
Compiler: keep Int32 and Nativeint in the IR for the js backend
1 parent 7be82c2 commit 4587b75

File tree

8 files changed

+59
-78
lines changed

8 files changed

+59
-78
lines changed

compiler/lib/code.ml

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,6 @@ let with_invariant = Debug.find "invariant"
801801
let check_defs = false
802802

803803
let invariant { blocks; start; _ } =
804-
let target = Config.target () in
805804
if with_invariant ()
806805
then (
807806
assert (Addr.Map.mem start blocks);
@@ -816,28 +815,15 @@ let invariant { blocks; start; _ } =
816815
assert (not (Var.ISet.mem defs x));
817816
Var.ISet.add defs x)
818817
in
819-
let check_constant = function
820-
| NativeInt _ | Int32 _ ->
821-
assert (
822-
match target with
823-
| `Wasm -> true
824-
| _ -> false)
825-
| String _ | NativeString _ | Float _ | Float_array _ | Int _ | Int64 _
826-
| Tuple (_, _, _) -> ()
827-
in
828-
let check_prim_arg = function
829-
| Pc c -> check_constant c
830-
| Pv _ -> ()
831-
in
832818
let check_expr = function
833819
| Apply _ -> ()
834820
| Block (_, _, _, _) -> ()
835821
| Field (_, _, _) -> ()
836822
| Closure (l, cont) ->
837823
List.iter l ~f:define;
838824
check_cont cont
839-
| Constant c -> check_constant c
840-
| Prim (_, args) -> List.iter ~f:check_prim_arg args
825+
| Constant _ -> ()
826+
| Prim (_, _) -> ()
841827
| Special _ -> ()
842828
in
843829
let check_instr i =

compiler/lib/eval.ml

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,6 @@ let float_binop_aux (l : constant list) (f : float -> float -> 'a) : 'a option =
4949
let args =
5050
match l with
5151
| [ Float i; Float j ] -> Some (i, j)
52-
| [ Int i; Int j ] -> Some (Targetint.to_float i, Targetint.to_float j)
53-
| [ Int i; Float j ] -> Some (Targetint.to_float i, j)
54-
| [ Float i; Int j ] -> Some (i, Targetint.to_float j)
5552
| _ -> None
5653
in
5754
match args with
@@ -66,7 +63,6 @@ let float_binop (l : constant list) (f : float -> float -> float) : constant opt
6663
let float_unop (l : constant list) (f : float -> float) : constant option =
6764
match l with
6865
| [ Float i ] -> Some (Float (f i))
69-
| [ Int i ] -> Some (Float (f (Targetint.to_float i)))
7066
| _ -> None
7167

7268
let bool' b = Int Targetint.(if b then one else zero)
@@ -76,18 +72,14 @@ let bool b = Some (bool' b)
7672
let float_unop_bool (l : constant list) (f : float -> bool) =
7773
match l with
7874
| [ Float i ] -> bool (f i)
79-
| [ Int i ] -> bool (f (Targetint.to_float i))
8075
| _ -> None
8176

8277
let float_binop_bool l f =
8378
match float_binop_aux l f with
8479
| Some b -> bool b
8580
| None -> None
8681

87-
let int32 i =
88-
match Config.target () with
89-
| `JavaScript -> Some (Int (Targetint.of_int32_exn i))
90-
| `Wasm -> Some (Int32 i)
82+
let int32 i = Some (Int32 i)
9183

9284
let int32_unop (l : constant list) (f : int32 -> int32) : constant option =
9385
match l with
@@ -362,14 +354,14 @@ let eval_prim x =
362354
| _ -> None)
363355
| _ -> None
364356

365-
let the_length_of ~target info x =
357+
let the_length_of info x =
366358
get_approx
367359
info
368360
(fun x ->
369361
match Flow.Info.def info x with
370362
| Some (Constant (String s)) -> Some (Targetint.of_int_exn (String.length s))
371363
| Some (Prim (Extern "caml_create_string", [ arg ]))
372-
| Some (Prim (Extern "caml_create_bytes", [ arg ])) -> the_int ~target info arg
364+
| Some (Prim (Extern "caml_create_bytes", [ arg ])) -> the_int info arg
373365
| None | Some _ -> None)
374366
None
375367
(fun u v ->
@@ -391,9 +383,6 @@ let is_int info x =
391383
(fun x ->
392384
match Flow.Info.def info x with
393385
| Some (Constant (Int _)) -> Y
394-
| Some (Constant (NativeInt _ | Int32 _)) ->
395-
(* These Wasm-specific constants are boxed *)
396-
N
397386
| Some (Block (_, _, _, _) | Constant _) -> N
398387
| None | Some _ -> Unknown)
399388
Unknown
@@ -404,9 +393,6 @@ let is_int info x =
404393
| _ -> Unknown)
405394
x
406395
| Pc (Int _) -> Y
407-
| Pc (NativeInt _ | Int32 _) ->
408-
(* These Wasm-specific constants are boxed *)
409-
N
410396
| Pc _ -> N
411397

412398
let the_tag_of info x get =
@@ -509,7 +495,7 @@ let eval_instr ~target info i =
509495
let c =
510496
match s with
511497
| Pc (String s) -> Some (Targetint.of_int_exn (String.length s))
512-
| Pv v -> the_length_of ~target info v
498+
| Pv v -> the_length_of info v
513499
| _ -> None
514500
in
515501
match c with
@@ -591,7 +577,7 @@ let eval_instr ~target info i =
591577
(* Avoid duplicating the constant here as it would cause an
592578
allocation *)
593579
arg
594-
| Some (Int32 _ | NativeInt _), `JavaScript -> assert false
580+
| Some ((Int32 _ | NativeInt _) as c), `JavaScript -> Pc c
595581
| Some ((Float _ | NativeString _) as c), `JavaScript -> Pc c
596582
| Some (String _ as c), `JavaScript
597583
when Config.Flag.use_js_string () -> Pc c

compiler/lib/flow.ml

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ let the_def_of info x =
344344
(fun x ->
345345
match info.info_defs.(Var.idx x) with
346346
| Expr (Constant (Float _ | Int _ | NativeString _) as e) -> Some e
347+
| Expr (Constant (Int32 _ | NativeInt _) as e) -> Some e
347348
| Expr (Constant (String _) as e) when Config.Flag.safe_string () -> Some e
348349
| Expr e -> if Var.ISet.mem info.info_possibly_mutable x then None else Some e
349350
| _ -> None)
@@ -370,10 +371,10 @@ let constant_identical ~(target : [ `JavaScript | `Wasm ]) a b =
370371
false (* Strings are boxed in Wasm and are possibly different objects *)
371372
| Int32 _, Int32 _, `Wasm ->
372373
false (* [Int32]s are boxed in Wasm and are possibly different objects *)
373-
| Int32 _, Int32 _, `JavaScript -> assert false
374+
| Int32 a, Int32 b, `JavaScript -> Int32.equal a b
374375
| NativeInt _, NativeInt _, `Wasm ->
375376
false (* [NativeInt]s are boxed in Wasm and are possibly different objects *)
376-
| NativeInt _, NativeInt _, `JavaScript -> assert false
377+
| NativeInt a, NativeInt b, `JavaScript -> Int32.equal a b
377378
(* All other values may be distinct objects and thus different by [caml_js_equals]. *)
378379
| Int64 _, Int64 _, _ -> false
379380
| Tuple _, Tuple _, _ -> false
@@ -388,10 +389,11 @@ let the_const_of ~target info x =
388389
get_approx
389390
info
390391
(fun x ->
391-
match info.info_defs.(Var.idx x) with
392-
| Expr (Constant ((Float _ | Int _ | NativeString _) as c)) -> Some c
393-
| Expr (Constant (String _ as c)) when Config.Flag.safe_string () -> Some c
394-
| Expr (Constant c) ->
392+
match info.info_defs.(Var.idx x), target with
393+
| Expr (Constant ((Float _ | Int _ | NativeString _) as c)), _ -> Some c
394+
| Expr (Constant ((Int32 _ | NativeInt _) as c)), `JavaScript -> Some c
395+
| Expr (Constant (String _ as c)), _ when Config.Flag.safe_string () -> Some c
396+
| Expr (Constant c), _ ->
395397
if Var.ISet.mem info.info_possibly_mutable x then None else Some c
396398
| _ -> None)
397399
None
@@ -402,10 +404,23 @@ let the_const_of ~target info x =
402404
x
403405
| Pc c -> Some c
404406

405-
let the_int ~target info x =
406-
match the_const_of ~target info x with
407-
| Some (Int i) -> Some i
408-
| _ -> None
407+
let the_int info x =
408+
match x with
409+
| Pv x ->
410+
get_approx
411+
info
412+
(fun x ->
413+
match info.info_defs.(Var.idx x) with
414+
| Expr (Constant (Int c)) -> Some c
415+
| _ -> None)
416+
None
417+
(fun u v ->
418+
match u, v with
419+
| Some i, Some j when Targetint.equal i j -> u
420+
| _ -> None)
421+
x
422+
| Pc (Int c) -> Some c
423+
| Pc _ -> None
409424

410425
let the_string_of ~target info x =
411426
match the_const_of info ~target x with

compiler/lib/flow.mli

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ val the_native_string_of :
6363

6464
val the_block_contents_of : Info.t -> Code.prim_arg -> Code.Var.t array option
6565

66-
val the_int :
67-
target:[ `JavaScript | `Wasm ] -> Info.t -> Code.prim_arg -> Targetint.t option
66+
val the_int : Info.t -> Code.prim_arg -> Targetint.t option
6867

6968
val f : ?skip_param:bool -> Code.program -> Code.program * Info.t

compiler/lib/generate.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -515,8 +515,7 @@ let rec constant_rec ~ctx x level instrs =
515515
in
516516
Mlvalue.Block.make ~tag ~args:l, instrs)
517517
| Int i -> targetint i, instrs
518-
| Int32 _ | NativeInt _ ->
519-
assert false (* Should not be produced when compiling to Javascript *)
518+
| Int32 i | NativeInt i -> targetint (Targetint.of_int32_exn i), instrs
520519

521520
let constant ~ctx x level =
522521
let expr, instr = constant_rec ~ctx x level [] in
@@ -1606,7 +1605,8 @@ and translate_instr ctx expr_queue loc instr =
16061605
| 1, _
16071606
when Config.Flag.compact () && ((not (Config.Flag.pretty ())) || not (keep_name x))
16081607
-> enqueue expr_queue x loc e'
1609-
| 1, Constant (Int _ | Float _) -> enqueue expr_queue x loc e'
1608+
| 1, Constant (Int _ | Int32 _ | NativeInt _ | Float _) ->
1609+
enqueue expr_queue x loc e'
16101610
| _ ->
16111611
flush_queue
16121612
expr_queue

compiler/lib/ocaml_compiler.ml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,9 @@ let rec constant_of_const c : Code.constant =
2626
| Const_base (Const_char c) -> Int (Targetint.of_int_exn (Char.code c))
2727
| Const_base (Const_string (s, _, _)) -> String s
2828
| Const_base (Const_float s) -> Float (float_of_string s)
29-
| Const_base (Const_int32 i) -> (
30-
match Config.target () with
31-
| `JavaScript -> Int (Targetint.of_int32_warning_on_overflow i)
32-
| `Wasm -> Int32 i)
29+
| Const_base (Const_int32 i) -> Int32 i
3330
| Const_base (Const_int64 i) -> Int64 i
34-
| Const_base (Const_nativeint i) -> (
35-
match Config.target () with
36-
| `JavaScript -> Int (Targetint.of_nativeint_warning_on_overflow i)
37-
| `Wasm -> NativeInt (Int32.of_nativeint_warning_on_overflow i))
31+
| Const_base (Const_nativeint i) -> NativeInt (Int32.of_nativeint_warning_on_overflow i)
3832
| Const_immstring s -> String s
3933
| Const_float_array sl ->
4034
let l = List.map ~f:(fun f -> float_of_string f) sl in

compiler/lib/parse_bytecode.ml

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ end
403403
module Constants : sig
404404
val parse : Obj.t -> Code.constant
405405

406-
val inlined : Code.constant -> bool
406+
val inlined : target:[ `JavaScript | `Wasm ] -> Code.constant -> bool
407407
end = struct
408408
(* In order to check that two custom objects share the same kind, we
409409
compare their identifier. The identifier is currently extracted
@@ -448,16 +448,12 @@ end = struct
448448
else if tag = Obj.custom_tag
449449
then
450450
match ident_of_custom x with
451-
| Some name when same_ident name ident_32 -> (
451+
| Some name when same_ident name ident_32 ->
452452
let i : int32 = Obj.magic x in
453-
match Config.target () with
454-
| `JavaScript -> Int (Targetint.of_int32_warning_on_overflow i)
455-
| `Wasm -> Int32 i)
456-
| Some name when same_ident name ident_native -> (
453+
Int32 i
454+
| Some name when same_ident name ident_native ->
457455
let i : nativeint = Obj.magic x in
458-
match Config.target () with
459-
| `JavaScript -> Int (Targetint.of_nativeint_warning_on_overflow i)
460-
| `Wasm -> NativeInt (Int32.of_nativeint_warning_on_overflow i))
456+
NativeInt (Int32.of_nativeint_warning_on_overflow i)
461457
| Some name when same_ident name ident_64 -> Int64 (Obj.magic x : int64)
462458
| Some name ->
463459
failwith
@@ -473,14 +469,18 @@ end = struct
473469
let i : int = Obj.magic x in
474470
Int (Targetint.of_int_warning_on_overflow i)
475471

476-
let inlined = function
472+
let inlined ~target c =
473+
match c with
477474
| String _ | NativeString _ -> false
478475
| Float _ -> true
479476
| Float_array _ -> false
480477
| Int64 _ -> false
481478
| Tuple _ -> false
482479
| Int _ -> true
483-
| Int32 _ | NativeInt _ -> false
480+
| Int32 _ | NativeInt _ -> (
481+
match target with
482+
| `JavaScript -> true
483+
| `Wasm -> false)
484484
end
485485

486486
let const32 i = Constant (Int (Targetint.of_int32_exn i))
@@ -740,14 +740,15 @@ let get_global state instrs i =
740740
if debug_parser () then Format.printf "(global access %a)@." Var.print x;
741741
x, State.set_accu state x, instrs
742742
| None -> (
743-
if i < Array.length g.constants && Constants.inlined g.constants.(i)
743+
let target = Config.target () in
744+
if i < Array.length g.constants && Constants.inlined ~target g.constants.(i)
744745
then
745746
(* Inlined constant *)
746747
let x, state = State.fresh_var state in
747748
let cst = g.constants.(i) in
748749
x, state, Let (x, Constant cst) :: instrs
749750
else
750-
match i < Array.length g.constants, Config.target () with
751+
match i < Array.length g.constants, target with
751752
| true, _ | false, `JavaScript ->
752753
(* Non-inlined constant, and reference to another compilation
753754
units in case of separate compilation (JavaScript).

compiler/lib/specialize_js.ml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ let specialize_instr ~target info i =
3030
Wasm to have a special case for this. *)
3131
match the_string_of ~target info y with
3232
| Some "%d" -> (
33-
match the_int ~target info z with
33+
match the_int info z with
3434
| Some i -> Let (x, Constant (String (Targetint.to_string i)))
3535
| None -> Let (x, Prim (Extern "%caml_format_int_special", [ z ])))
3636
| _ -> i)
3737
| Let (x, Prim (Extern "%caml_format_int_special", [ z ])), `JavaScript -> (
38-
match the_int ~target info z with
38+
match the_int info z with
3939
| Some i -> Let (x, Constant (String (Targetint.to_string i)))
4040
| None -> i)
4141
(* inline the String constant argument so that generate.ml can attempt to parse it *)
@@ -139,19 +139,19 @@ let specialize_instr ~target info i =
139139
(* Using * to multiply integers in JavaScript yields a float; and if the
140140
float is large enough, some bits can be lost. So, in the general case,
141141
we have to use Math.imul. There is no such issue in Wasm. *)
142-
match the_int ~target info y, the_int ~target info z with
142+
match the_int info y, the_int info z with
143143
| Some j, _ when Targetint.(abs j < limit) ->
144144
Let (x, Prim (Extern "%direct_int_mul", [ y; z ]))
145145
| _, Some j when Targetint.(abs j < limit) ->
146146
Let (x, Prim (Extern "%direct_int_mul", [ y; z ]))
147147
| _ -> i)
148148
| Let (x, Prim (Extern "%int_div", [ y; z ])), _ -> (
149-
match the_int ~target info z with
149+
match the_int info z with
150150
| Some j when not (Targetint.is_zero j) ->
151151
Let (x, Prim (Extern "%direct_int_div", [ y; z ]))
152152
| _ -> i)
153153
| Let (x, Prim (Extern "%int_mod", [ y; z ])), _ -> (
154-
match the_int ~target info z with
154+
match the_int info z with
155155
| Some j when not (Targetint.is_zero j) ->
156156
Let (x, Prim (Extern "%direct_int_mod", [ y; z ]))
157157
| _ -> i)
@@ -261,7 +261,7 @@ let specialize_instrs ~target info l =
261261
| "caml_array_get_addr" ) as prim)
262262
, [ y; z ] ) ) ->
263263
let idx =
264-
match the_int ~target info z with
264+
match the_int info z with
265265
| Some idx -> `Cst idx
266266
| None -> `Var z
267267
in
@@ -302,7 +302,7 @@ let specialize_instrs ~target info l =
302302
| "caml_array_set_addr" ) as prim)
303303
, [ y; z; t ] ) ) ->
304304
let idx =
305-
match the_int ~target info z with
305+
match the_int info z with
306306
| Some idx -> `Cst idx
307307
| None -> `Var z
308308
in

0 commit comments

Comments
 (0)