Skip to content

Commit 74db480

Browse files
vouillonhhugo
authored andcommitted
Switch to a bit representation of floats
1 parent 7c49e3b commit 74db480

File tree

8 files changed

+62
-88
lines changed

8 files changed

+62
-88
lines changed

compiler/lib-wasm/gc_target.ml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,12 +1025,15 @@ module Constant = struct
10251025
return (Const_named ("str_" ^ s), W.ArrayNewFixed (ty, l))
10261026
| Float f ->
10271027
let* ty = Type.float_type in
1028-
return (Const, W.StructNew (ty, [ Const (F64 f) ]))
1028+
return (Const, W.StructNew (ty, [ Const (F64 (Int64.float_of_bits f)) ]))
10291029
| Float_array l ->
10301030
let l = Array.to_list l in
10311031
let* ty = Type.float_array_type in
10321032
(*ZZZ Boxed array? *)
1033-
return (Const, W.ArrayNewFixed (ty, List.map ~f:(fun f -> W.Const (F64 f)) l))
1033+
return
1034+
( Const
1035+
, W.ArrayNewFixed
1036+
(ty, List.map ~f:(fun f -> W.Const (F64 (Int64.float_of_bits f))) l) )
10341037
| Int64 i ->
10351038
let* e = Memory.make_int64 (return (W.Const (I64 i))) in
10361039
return (Const, e)

compiler/lib/code.ml

Lines changed: 13 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,8 @@ end
268268
type constant =
269269
| String of string
270270
| NativeString of Native_string.t
271-
| Float of float
272-
| Float_array of float array
271+
| Float of Int64.t
272+
| Float_array of Int64.t array
273273
| Int of Targetint.t
274274
| Int32 of Int32.t
275275
| Int64 of Int64.t
@@ -299,8 +299,14 @@ module Constant = struct
299299
| Int32 a, Int32 b -> Some (Int32.equal a b)
300300
| Int64 a, Int64 b -> Some (Int64.equal a b)
301301
| NativeInt a, NativeInt b -> Some (Int32.equal a b)
302-
| Float_array a, Float_array b -> Some (Array.equal Float.ieee_equal a b)
303-
| Float a, Float b -> Some (Float.ieee_equal a b)
302+
| Float_array a, Float_array b ->
303+
Some
304+
(Array.equal
305+
(fun f g -> Float.ieee_equal (Int64.float_of_bits f) (Int64.float_of_bits g))
306+
a
307+
b)
308+
| Float a, Float b ->
309+
Some (Float.ieee_equal (Int64.float_of_bits a) (Int64.float_of_bits b))
304310
| String _, NativeString _ | NativeString _, String _ -> None
305311
| Int _, Float _ | Float _, Int _ -> None
306312
| Tuple ((0 | 254), _, _), Float_array _ -> None
@@ -349,33 +355,6 @@ module Constant = struct
349355
| NativeInt _, (Int _ | Int32 _)
350356
| (Int32 _ | NativeInt _), Float _
351357
| Float _, (Int32 _ | NativeInt _) -> None
352-
353-
let rec equal c c' =
354-
match c, c' with
355-
| String s, String s' -> String.equal s s'
356-
| NativeString s, NativeString s' -> Native_string.equal s s'
357-
| Float f, Float f' -> Float.bitwise_equal f f'
358-
| Float_array a, Float_array a' -> Array.equal Float.bitwise_equal a a'
359-
| Int i, Int i' -> Targetint.equal i i'
360-
| Int32 i, Int32 i' | NativeInt i, NativeInt i' -> Int32.equal i i'
361-
| Int64 i, Int64 i' -> Int64.equal i i'
362-
| Tuple (t, a, kind), Tuple (t', a', kind') -> (
363-
t = t'
364-
&& Array.equal equal a a'
365-
&&
366-
match kind, kind' with
367-
| Array, Array | NotArray, NotArray | Unknown, Unknown -> true
368-
| (Array | NotArray | Unknown), _ -> false)
369-
| ( ( String _
370-
| NativeString _
371-
| Float _
372-
| Float_array _
373-
| Int _
374-
| Int32 _
375-
| NativeInt _
376-
| Int64 _
377-
| Tuple _ )
378-
, _ ) -> false
379358
end
380359

381360
type loc =
@@ -461,12 +440,12 @@ module Print = struct
461440
| String s -> Format.fprintf f "%S" s
462441
| NativeString (Byte s) -> Format.fprintf f "%Sj" s
463442
| NativeString (Utf (Utf8 s)) -> Format.fprintf f "%Sj" s
464-
| Float fl -> Format.fprintf f "%.12g" fl
443+
| Float fl -> Format.fprintf f "%.12g" (Int64.float_of_bits fl)
465444
| Float_array a ->
466445
Format.fprintf f "[|";
467446
for i = 0 to Array.length a - 1 do
468447
if i > 0 then Format.fprintf f ", ";
469-
Format.fprintf f "%.12g" a.(i)
448+
Format.fprintf f "%.12g" (Int64.float_of_bits a.(i))
470449
done;
471450
Format.fprintf f "|]"
472451
| Int i -> Format.fprintf f "%s" (Targetint.to_string i)
@@ -819,24 +798,7 @@ let eq p1 p2 =
819798
| block2 ->
820799
List.equal ~eq:Var.equal block1.params block2.params
821800
&& Poly.equal block1.branch block2.branch
822-
&& List.equal
823-
~eq:(fun i i' ->
824-
match i, i' with
825-
| Let (x, Constant c), Let (x', Constant c') ->
826-
Var.equal x x' && Constant.equal c c'
827-
| Let (x, Prim (prim, args)), Let (x', Prim (prim', args')) ->
828-
Var.equal x x'
829-
&& Poly.equal prim prim'
830-
&& List.equal
831-
~eq:(fun a a' ->
832-
match a, a' with
833-
| Pc c, Pc c' -> Constant.equal c c'
834-
| _ -> Poly.equal a a')
835-
args
836-
args'
837-
| _ -> Poly.equal i i')
838-
block1.body
839-
block2.body)
801+
&& List.equal ~eq:Poly.equal block1.body block2.body)
840802
p1.blocks
841803
true
842804

compiler/lib/code.mli

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@ end
157157
type constant =
158158
| String of string
159159
| NativeString of Native_string.t
160-
| Float of float
161-
| Float_array of float array
160+
| Float of Int64.t
161+
| Float_array of Int64.t array
162162
| Int of Targetint.t
163163
| Int32 of Int32.t (** Only produced when compiling to WebAssembly. *)
164164
| Int64 of Int64.t

compiler/lib/eval.ml

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,12 @@ let shift_op l f =
4545
| [ Int i; Int j ] -> Some (Int (f i (Targetint.to_int_exn j)))
4646
| _ -> None
4747

48+
let float f : constant = Float (Int64.bits_of_float f)
49+
4850
let float_binop_aux (l : constant list) (f : float -> float -> 'a) : 'a option =
4951
let args =
5052
match l with
51-
| [ Float i; Float j ] -> Some (i, j)
53+
| [ Float i; Float j ] -> Some (Int64.float_of_bits i, Int64.float_of_bits j)
5254
| _ -> None
5355
in
5456
match args with
@@ -57,12 +59,12 @@ let float_binop_aux (l : constant list) (f : float -> float -> 'a) : 'a option =
5759

5860
let float_binop (l : constant list) (f : float -> float -> float) : constant option =
5961
match float_binop_aux l f with
60-
| Some x -> Some (Float x)
62+
| Some x -> Some (float x)
6163
| None -> None
6264

6365
let float_unop (l : constant list) (f : float -> float) : constant option =
6466
match l with
65-
| [ Float i ] -> Some (Float (f i))
67+
| [ Float i ] -> Some (float (f (Int64.float_of_bits i)))
6668
| _ -> None
6769

6870
let bool' b = Int Targetint.(if b then one else zero)
@@ -71,7 +73,7 @@ let bool b = Some (bool' b)
7173

7274
let float_unop_bool (l : constant list) (f : float -> bool) =
7375
match l with
74-
| [ Float i ] -> bool (f i)
76+
| [ Float i ] -> bool (f (Int64.float_of_bits i))
7577
| _ -> None
7678

7779
let float_binop_bool l f =
@@ -168,10 +170,10 @@ let eval_prim x =
168170
| "caml_div_float", _ -> float_binop l ( /. )
169171
| "caml_fmod_float", _ -> float_binop l mod_float
170172
| "caml_int_of_float", [ Float f ] -> (
171-
match Targetint.of_float_opt f with
173+
match Targetint.of_float_opt (Int64.float_of_bits f) with
172174
| None -> None
173175
| Some f -> Some (Int f))
174-
| "caml_float_of_int", [ Int i ] -> Some (Float (Targetint.to_float i))
176+
| "caml_float_of_int", [ Int i ] -> Some (float (Targetint.to_float i))
175177
(* Math *)
176178
| "caml_neg_float", _ -> float_unop l ( ~-. )
177179
| "caml_abs_float", _ -> float_unop l abs_float
@@ -209,16 +211,19 @@ let eval_prim x =
209211
| "caml_erfc_float", _ -> float_unop l Float.erfc
210212
| "caml_nextafter_float", _ -> float_binop l Float.next_after
211213
| "caml_float_compare", [ Float i; Float j ] ->
212-
Some (Int (Targetint.of_int_exn (Float.compare i j)))
214+
Some
215+
(Int
216+
(Targetint.of_int_exn
217+
(Float.compare (Int64.float_of_bits i) (Int64.float_of_bits j))))
213218
| "caml_ldexp_float", [ Float f; Int i ] ->
214-
Some (Float (ldexp f (Targetint.to_int_exn i)))
219+
Some (float (ldexp (Int64.float_of_bits f) (Targetint.to_int_exn i)))
215220
(* int32 *)
216-
| "caml_int32_bits_of_float", [ Float f ] -> int32 (Int32.bits_of_float f)
217-
| "caml_int32_float_of_bits", [ Int i ] ->
218-
Some (Float (Int32.float_of_bits (Targetint.to_int32 i)))
219-
| "caml_int32_float_of_bits", [ Int32 i ] -> Some (Float (Int32.float_of_bits i))
220-
| "caml_int32_of_float", [ Float f ] -> int32 (Int32.of_float f)
221-
| "caml_int32_to_float", [ Int32 i ] -> Some (Float (Int32.to_float i))
221+
| "caml_int32_bits_of_float", [ Float f ] ->
222+
int32 (Int32.bits_of_float (Int64.float_of_bits f))
223+
| "caml_int32_float_of_bits", [ Int32 i ] -> Some (float (Int32.float_of_bits i))
224+
| "caml_int32_of_float", [ Float f ] ->
225+
int32 (Int32.of_float (Int64.float_of_bits f))
226+
| "caml_int32_to_float", [ Int32 i ] -> Some (float (Int32.to_float i))
222227
| "caml_int32_neg", _ -> int32_unop l Int32.neg
223228
| "caml_int32_add", _ -> int32_binop l Int32.add
224229
| "caml_int32_sub", _ -> int32_binop l Int32.sub
@@ -240,13 +245,13 @@ let eval_prim x =
240245
| "caml_nativeint_of_int32", [ Int32 i ] -> Some (NativeInt i)
241246
| "caml_nativeint_to_int32", [ NativeInt i ] -> Some (Int32 i)
242247
(* nativeint *)
243-
| "caml_nativeint_bits_of_float", [ Float f ] -> nativeint (Int32.bits_of_float f)
244-
| "caml_nativeint_float_of_bits", [ Int i ] ->
245-
Some (Float (Int32.float_of_bits (Targetint.to_int32 i)))
248+
| "caml_nativeint_bits_of_float", [ Float f ] ->
249+
nativeint (Int32.bits_of_float (Int64.float_of_bits f))
246250
| "caml_nativeint_float_of_bits", [ NativeInt i ] ->
247-
Some (Float (Int32.float_of_bits i))
248-
| "caml_nativeint_of_float", [ Float f ] -> nativeint (Int32.of_float f)
249-
| "caml_nativeint_to_float", [ NativeInt i ] -> Some (Float (Int32.to_float i))
251+
Some (float (Int32.float_of_bits i))
252+
| "caml_nativeint_of_float", [ Float f ] ->
253+
nativeint (Int32.of_float (Int64.float_of_bits f))
254+
| "caml_nativeint_to_float", [ NativeInt i ] -> Some (float (Int32.to_float i))
250255
| "caml_nativeint_neg", _ -> nativeint_unop l Int32.neg
251256
| "caml_nativeint_add", _ -> nativeint_binop l Int32.add
252257
| "caml_nativeint_sub", _ -> nativeint_binop l Int32.sub
@@ -267,10 +272,11 @@ let eval_prim x =
267272
| "caml_nativeint_to_int", [ Int32 i ] -> Some (Int (Targetint.of_int32_truncate i))
268273
| "caml_nativeint_of_int", [ Int i ] -> nativeint (Targetint.to_int32 i)
269274
(* int64 *)
270-
| "caml_int64_bits_of_float", [ Float f ] -> int64 (Int64.bits_of_float f)
271-
| "caml_int64_float_of_bits", [ Int64 i ] -> Some (Float (Int64.float_of_bits i))
272-
| "caml_int64_of_float", [ Float f ] -> int64 (Int64.of_float f)
273-
| "caml_int64_to_float", [ Int64 i ] -> Some (Float (Int64.to_float i))
275+
| "caml_int64_bits_of_float", [ Float f ] -> int64 f
276+
| "caml_int64_float_of_bits", [ Int64 i ] -> Some (Float i)
277+
| "caml_int64_of_float", [ Float f ] ->
278+
int64 (Int64.of_float (Int64.float_of_bits f))
279+
| "caml_int64_to_float", [ Int64 i ] -> Some (float (Int64.to_float i))
274280
| "caml_int64_neg", _ -> int64_unop l Int64.neg
275281
| "caml_int64_add", _ -> int64_binop l Int64.add
276282
| "caml_int64_sub", _ -> int64_binop l Int64.sub
@@ -289,8 +295,7 @@ let eval_prim x =
289295
Some (Int (Targetint.of_int_exn (Int64.compare i j)))
290296
| "caml_int64_to_int", [ Int64 i ] ->
291297
Some (Int (Targetint.of_int32_truncate (Int64.to_int32 i)))
292-
| ( ("caml_int64_of_int" | "caml_int64_of_int32" | "caml_int64_of_nativeint")
293-
, [ Int i ] ) -> int64 (Int64.of_int32 (Targetint.to_int32 i))
298+
| "caml_int64_of_int", [ Int i ] -> int64 (Int64.of_int32 (Targetint.to_int32 i))
294299
| "caml_int64_to_int32", [ Int64 i ] -> int32 (Int64.to_int32 i)
295300
| "caml_int64_of_int32", [ Int32 i ] -> int64 (Int64.of_int32 i)
296301
| "caml_int64_to_nativeint", [ Int64 i ] -> nativeint (Int64.to_int32 i)
@@ -435,7 +440,8 @@ let rec int_predicate deep info pred x (i : Targetint.t) =
435440
let constant_js_equal a b =
436441
match a, b with
437442
| Int i, Int j -> Some (Targetint.equal i j)
438-
| Float a, Float b -> Some (Float.ieee_equal a b)
443+
| Float a, Float b ->
444+
Some (Float.ieee_equal (Int64.float_of_bits a) (Int64.float_of_bits b))
439445
| NativeString a, NativeString b -> Some (Native_string.equal a b)
440446
| String a, String b when Config.Flag.use_js_string () -> Some (String.equal a b)
441447
| Int _, Float _ | Float _, Int _ -> None

compiler/lib/flow.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ let the_def_of info x =
362362
let constant_identical ~(target : [ `JavaScript | `Wasm ]) a b =
363363
match a, b, target with
364364
| Int i, Int j, _ -> Targetint.equal i j
365-
| Float a, Float b, `JavaScript -> Float.bitwise_equal a b
365+
| Float a, Float b, `JavaScript -> Int64.equal a b
366366
| Float _, Float _, `Wasm -> false
367367
| NativeString a, NativeString b, `JavaScript -> Native_string.equal a b
368368
| NativeString _, NativeString _, `Wasm ->

compiler/lib/generate.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ let source_location ctx position pc =
386386

387387
(****)
388388

389-
let float_const f = J.ENum (J.Num.of_float f)
389+
let float_const f = J.ENum (J.Num.of_float (Int64.float_of_bits f))
390390

391391
let s_var name = J.EVar (J.ident (Utf8_string.of_string_exn name))
392392

compiler/lib/ocaml_compiler.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ let rec constant_of_const c : Code.constant =
2525
| Const_base (Const_int i) -> Int (Targetint.of_int_warning_on_overflow i)
2626
| Const_base (Const_char c) -> Int (Targetint.of_int_exn (Char.code c))
2727
| Const_base (Const_string (s, _, _)) -> String s
28-
| Const_base (Const_float s) -> Float (float_of_string s)
28+
| Const_base (Const_float s) -> Float (Int64.bits_of_float (float_of_string s))
2929
| Const_base (Const_int32 i) -> Int32 i
3030
| Const_base (Const_int64 i) -> Int64 i
3131
| Const_base (Const_nativeint i) -> NativeInt (Int32.of_nativeint_warning_on_overflow i)
3232
| Const_immstring s -> String s
3333
| Const_float_array sl ->
34-
let l = List.map ~f:(fun f -> float_of_string f) sl in
34+
let l = List.map ~f:(fun f -> Int64.bits_of_float (float_of_string f)) sl in
3535
Float_array (Array.of_list l)
3636
| Const_block (tag, l) ->
3737
let l = Array.of_list (List.map l ~f:constant_of_const) in

compiler/lib/parse_bytecode.ml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,12 @@ end = struct
442442
if tag = Obj.string_tag
443443
then String (Obj.magic x : string)
444444
else if tag = Obj.double_tag
445-
then Float (Obj.magic x : float)
445+
then Float (Int64.bits_of_float (Obj.magic x : float))
446446
else if tag = Obj.double_array_tag
447-
then Float_array (Array.init (Obj.size x) ~f:(fun i -> Obj.double_field x i))
447+
then
448+
Float_array
449+
(Array.init (Obj.size x) ~f:(fun i ->
450+
Int64.bits_of_float (Obj.double_field x i)))
448451
else if tag = Obj.custom_tag
449452
then
450453
match ident_of_custom x with

0 commit comments

Comments
 (0)