Skip to content

Commit 224fc33

Browse files
committed
Don't noop conversion between ints/float with the same runtime repr.
Previously, primitives taking float arguments could receive Int/Int32/NativeInt/Float arg
1 parent 184c470 commit 224fc33

File tree

10 files changed

+87
-87
lines changed

10 files changed

+87
-87
lines changed

compiler/lib/code.ml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,6 @@ let with_invariant = Debug.find "invariant"
843843
let check_defs = false
844844

845845
let invariant { blocks; start; _ } =
846-
let target = Config.target () in
847846
if with_invariant ()
848847
then (
849848
assert (Addr.Map.mem start blocks);
@@ -859,11 +858,7 @@ let invariant { blocks; start; _ } =
859858
Var.ISet.add defs x)
860859
in
861860
let check_constant = function
862-
| NativeInt _ | Int32 _ ->
863-
assert (
864-
match target with
865-
| `Wasm -> true
866-
| _ -> false)
861+
| NativeInt _ | Int32 _ -> ()
867862
| String _ | NativeString _ | Float _ | Float_array _ | Int _ | Int64 _
868863
| Tuple (_, _, _) -> ()
869864
in

compiler/lib/eval.ml

Lines changed: 4 additions & 14 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)
@@ -155,14 +151,14 @@ let eval_prim x =
155151
| _ -> None)
156152
| _ -> None
157153

158-
let the_length_of ~target info x =
154+
let the_length_of info x =
159155
get_approx
160156
info
161157
(fun x ->
162158
match Flow.Info.def info x with
163159
| Some (Constant (String s)) -> Some (Targetint.of_int_exn (String.length s))
164160
| Some (Prim (Extern "caml_create_string", [ arg ]))
165-
| Some (Prim (Extern "caml_create_bytes", [ arg ])) -> the_int ~target info arg
161+
| Some (Prim (Extern "caml_create_bytes", [ arg ])) -> the_int info arg
166162
| None | Some _ -> None)
167163
None
168164
(fun u v ->
@@ -184,9 +180,6 @@ let is_int info x =
184180
(fun x ->
185181
match Flow.Info.def info x with
186182
| Some (Constant (Int _)) -> Y
187-
| Some (Constant (NativeInt _ | Int32 _)) ->
188-
(* These Wasm-specific constants are boxed *)
189-
N
190183
| Some (Block (_, _, _, _) | Constant _) -> N
191184
| None | Some _ -> Unknown)
192185
Unknown
@@ -197,9 +190,6 @@ let is_int info x =
197190
| _ -> Unknown)
198191
x
199192
| Pc (Int _) -> Y
200-
| Pc (NativeInt _ | Int32 _) ->
201-
(* These Wasm-specific constants are boxed *)
202-
N
203193
| Pc _ -> N
204194

205195
let the_tag_of info x get =
@@ -302,7 +292,7 @@ let eval_instr ~target info i =
302292
let c =
303293
match s with
304294
| Pc (String s) -> Some (Targetint.of_int_exn (String.length s))
305-
| Pv v -> the_length_of ~target info v
295+
| Pv v -> the_length_of info v
306296
| _ -> None
307297
in
308298
match c with
@@ -384,7 +374,7 @@ let eval_instr ~target info i =
384374
(* Avoid duplicating the constant here as it would cause an
385375
allocation *)
386376
arg
387-
| Some (Int32 _ | NativeInt _), `JavaScript -> assert false
377+
| Some ((Int32 _ | NativeInt _) as c), `JavaScript -> Pc c
388378
| Some ((Float _ | NativeString _) as c), `JavaScript -> Pc c
389379
| Some (String _ as c), `JavaScript
390380
when Config.Flag.use_js_string () -> Pc c

compiler/lib/flow.ml

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -370,10 +370,10 @@ let constant_identical ~(target : [ `JavaScript | `Wasm ]) a b =
370370
false (* Strings are boxed in Wasm and are possibly different objects *)
371371
| Int32 _, Int32 _, `Wasm ->
372372
false (* [Int32]s are boxed in Wasm and are possibly different objects *)
373-
| Int32 _, Int32 _, `JavaScript -> assert false
373+
| Int32 a, Int32 b, `JavaScript -> Int32.equal a b
374374
| NativeInt _, NativeInt _, `Wasm ->
375375
false (* [NativeInt]s are boxed in Wasm and are possibly different objects *)
376-
| NativeInt _, NativeInt _, `JavaScript -> assert false
376+
| NativeInt a, NativeInt b, `JavaScript -> Int32.equal a b
377377
(* All other values may be distinct objects and thus different by [caml_js_equals]. *)
378378
| Int64 _, Int64 _, _ -> false
379379
| Tuple _, Tuple _, _ -> false
@@ -388,10 +388,11 @@ let the_const_of ~target info x =
388388
get_approx
389389
info
390390
(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) ->
391+
match info.info_defs.(Var.idx x), target with
392+
| Expr (Constant ((Float _ | Int _ | NativeString _) as c)), _ -> Some c
393+
| Expr (Constant ((Int32 _ | NativeInt _) as c)), `JavaScript -> Some c
394+
| Expr (Constant (String _ as c)), _ when Config.Flag.safe_string () -> Some c
395+
| Expr (Constant c), _ ->
395396
if Var.ISet.mem info.info_possibly_mutable x then None else Some c
396397
| _ -> None)
397398
None
@@ -402,10 +403,23 @@ let the_const_of ~target info x =
402403
x
403404
| Pc c -> Some c
404405

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

410424
let the_string_of ~target info x =
411425
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: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -511,8 +511,7 @@ let rec constant_rec ~ctx x level instrs =
511511
in
512512
Mlvalue.Block.make ~tag ~args:l, instrs)
513513
| Int i -> targetint i, instrs
514-
| Int32 _ | NativeInt _ ->
515-
assert false (* Should not be produced when compiling to Javascript *)
514+
| Int32 i | NativeInt i -> targetint (Targetint.of_int32_exn i), instrs
516515

517516
let constant ~ctx x level =
518517
let expr, instr = constant_rec ~ctx x level [] in
@@ -1457,15 +1456,21 @@ let rec translate_expr ctx loc x e level : (_ * J.statement_list) Expr_builder.t
14571456
return (add ca cb)
14581457
| Extern name, l -> (
14591458
let name = Primitive.resolve name in
1460-
match internal_prim name with
1461-
| Some f -> f l ctx loc
1462-
| None ->
1463-
if String.is_prefix name ~prefix:"%"
1464-
then failwith (Printf.sprintf "Unresolved internal primitive: %s" name);
1465-
let prim = Share.get_prim (runtime_fun ctx) name ctx.Ctx.share in
1466-
let* () = info ~need_loc:true (kind (Primitive.kind name)) in
1467-
let* args = list_map (fun x -> access' ~ctx x) l in
1468-
return (J.call prim args loc))
1459+
match name, l with
1460+
| "%identity-ints-repr", [ x ] ->
1461+
let* cx = access' ~ctx x in
1462+
return cx
1463+
| _ -> (
1464+
match internal_prim name with
1465+
| Some f -> f l ctx loc
1466+
| None ->
1467+
if String.is_prefix name ~prefix:"%"
1468+
then
1469+
failwith (Printf.sprintf "Unresolved internal primitive: %s" name);
1470+
let prim = Share.get_prim (runtime_fun ctx) name ctx.Ctx.share in
1471+
let* () = info ~need_loc:true (kind (Primitive.kind name)) in
1472+
let* args = list_map (fun x -> access' ~ctx x) l in
1473+
return (J.call prim args loc)))
14691474
| Not, [ x ] ->
14701475
let* cx = access' ~ctx x in
14711476
return (J.EBin (J.Minus, one, cx))
@@ -1532,7 +1537,8 @@ and translate_instr ctx expr_queue loc instr =
15321537
| 1, _
15331538
when Config.Flag.compact () && ((not (Config.Flag.pretty ())) || not (keep_name x))
15341539
-> enqueue expr_queue x loc e'
1535-
| 1, Constant (Int _ | Float _) -> enqueue expr_queue x loc e'
1540+
| 1, Constant (Int _ | Int32 _ | NativeInt _ | Float _) ->
1541+
enqueue expr_queue x loc e'
15361542
| _ ->
15371543
flush_queue
15381544
expr_queue
@@ -2211,6 +2217,8 @@ let f
22112217
p
22122218

22132219
let init () =
2220+
let identity_ints_repr = "%identity-ints-repr" in
2221+
assert (Primitive.is_pure identity_ints_repr);
22142222
List.iter
22152223
~f:(fun (nm, nm') -> Primitive.alias nm nm')
22162224
[ "%int_mul", "caml_mul"
@@ -2228,10 +2236,10 @@ let init () =
22282236
; "caml_int32_shift_left", "%int_lsl"
22292237
; "caml_int32_shift_right", "%int_asr"
22302238
; "caml_int32_shift_right_unsigned", "%int_lsr"
2231-
; "caml_int32_of_int", "%identity"
2232-
; "caml_int32_to_int", "%identity"
2239+
; "caml_int32_of_int", identity_ints_repr
2240+
; "caml_int32_to_int", identity_ints_repr
22332241
; "caml_int32_of_float", "caml_int_of_float"
2234-
; "caml_int32_to_float", "%identity"
2242+
; "caml_int32_to_float", identity_ints_repr
22352243
; "caml_int32_format", "caml_format_int"
22362244
; "caml_int32_of_string", "caml_int_of_string"
22372245
; "caml_int32_compare", "caml_int_compare"
@@ -2247,12 +2255,12 @@ let init () =
22472255
; "caml_nativeint_shift_left", "%int_lsl"
22482256
; "caml_nativeint_shift_right", "%int_asr"
22492257
; "caml_nativeint_shift_right_unsigned", "%int_lsr"
2250-
; "caml_nativeint_of_int", "%identity"
2251-
; "caml_nativeint_to_int", "%identity"
2258+
; "caml_nativeint_of_int", identity_ints_repr
2259+
; "caml_nativeint_to_int", identity_ints_repr
22522260
; "caml_nativeint_of_float", "caml_int_of_float"
2253-
; "caml_nativeint_to_float", "%identity"
2254-
; "caml_nativeint_of_int32", "%identity"
2255-
; "caml_nativeint_to_int32", "%identity"
2261+
; "caml_nativeint_to_float", identity_ints_repr
2262+
; "caml_nativeint_of_int32", identity_ints_repr
2263+
; "caml_nativeint_to_int32", identity_ints_repr
22562264
; "caml_nativeint_format", "caml_format_int"
22572265
; "caml_nativeint_of_string", "caml_int_of_string"
22582266
; "caml_nativeint_compare", "caml_int_compare"
@@ -2261,7 +2269,7 @@ let init () =
22612269
; "caml_int64_to_int", "caml_int64_to_int32"
22622270
; "caml_int64_of_nativeint", "caml_int64_of_int32"
22632271
; "caml_int64_to_nativeint", "caml_int64_to_int32"
2264-
; "caml_float_of_int", "%identity"
2272+
; "caml_float_of_int", identity_ints_repr
22652273
; "caml_array_get_float", "caml_array_get"
22662274
; "caml_floatarray_get", "caml_array_get"
22672275
; "caml_array_get_addr", "caml_array_get"

compiler/lib/ocaml_compiler.ml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,9 @@ let rec constant_of_const c : Code.constant =
2727
| ((Const_base (Const_string (s, _))) [@if ocaml_version < (4, 11, 0)])
2828
| ((Const_base (Const_string (s, _, _))) [@if ocaml_version >= (4, 11, 0)]) -> String s
2929
| Const_base (Const_float s) -> Float (float_of_string s)
30-
| Const_base (Const_int32 i) -> (
31-
match Config.target () with
32-
| `JavaScript -> Int (Targetint.of_int32_warning_on_overflow i)
33-
| `Wasm -> Int32 i)
30+
| Const_base (Const_int32 i) -> Int32 i
3431
| Const_base (Const_int64 i) -> Int64 i
35-
| Const_base (Const_nativeint i) -> (
36-
match Config.target () with
37-
| `JavaScript -> Int (Targetint.of_nativeint_warning_on_overflow i)
38-
| `Wasm -> NativeInt (Int32.of_nativeint_warning_on_overflow i))
32+
| Const_base (Const_nativeint i) -> NativeInt (Int32.of_nativeint_warning_on_overflow i)
3933
| Const_immstring s -> String s
4034
| Const_float_array sl ->
4135
let l = List.map ~f:(fun f -> float_of_string f) sl in

compiler/lib/parse_bytecode.ml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -453,16 +453,12 @@ end = struct
453453
else if tag = Obj.custom_tag
454454
then
455455
match ident_of_custom x with
456-
| Some name when same_ident name ident_32 -> (
456+
| Some name when same_ident name ident_32 ->
457457
let i : int32 = Obj.magic x in
458-
match Config.target () with
459-
| `JavaScript -> Int (Targetint.of_int32_warning_on_overflow i)
460-
| `Wasm -> Int32 i)
461-
| Some name when same_ident name ident_native -> (
458+
Int32 i
459+
| Some name when same_ident name ident_native ->
462460
let i : nativeint = Obj.magic x in
463-
match Config.target () with
464-
| `JavaScript -> Int (Targetint.of_nativeint_warning_on_overflow i)
465-
| `Wasm -> NativeInt (Int32.of_nativeint_warning_on_overflow i))
461+
NativeInt (Int32.of_nativeint_warning_on_overflow i)
466462
| Some name when same_ident name ident_64 -> Int64 (Obj.magic x : int64)
467463
| Some name ->
468464
failwith

compiler/lib/primitive.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,11 @@ let has_arity nm a = try Hashtbl.find arities (resolve nm) = a with Not_found ->
7676

7777
let is_pure nm =
7878
match nm with
79-
| "%identity" | "%direct_int_div" | "%direct_int_mod" | "%direct_int_mul" -> true
79+
| "%identity"
80+
| "%identity-ints-repr"
81+
| "%direct_int_div"
82+
| "%direct_int_mod"
83+
| "%direct_int_mul" -> true
8084
| _ -> Poly.(kind nm <> `Mutator)
8185

8286
let exists p = Hashtbl.mem kinds p

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)