Skip to content

Commit 3180611

Browse files
committed
Compiler: introduce Targetint
1 parent 74672ae commit 3180611

22 files changed

+467
-371
lines changed

compiler/lib/code.ml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ type constant =
327327
| NativeString of Native_string.t
328328
| Float of float
329329
| Float_array of float array
330-
| Int of Int32.t
330+
| Int of Targetint.t
331331
| Int32 of Int32.t
332332
| Int64 of Int64.t
333333
| NativeInt of Int32.t (* Native int are 32bit on all known backend *)
@@ -352,7 +352,8 @@ module Constant = struct
352352
| Some s, Some c -> same := Some (s && c)
353353
done;
354354
!same
355-
| Int a, Int b | Int32 a, Int32 b -> Some (Int32.equal a b)
355+
| Int a, Int b -> Some (Targetint.equal a b)
356+
| Int32 a, Int32 b -> Some (Int32.equal a b)
356357
| Int64 a, Int64 b -> Some (Int64.equal a b)
357358
| NativeInt a, NativeInt b -> Some (Int32.equal a b)
358359
| Float_array a, Float_array b -> Some (Array.equal Float.ieee_equal a b)
@@ -497,7 +498,7 @@ module Print = struct
497498
Format.fprintf f "%.12g" a.(i)
498499
done;
499500
Format.fprintf f "|]"
500-
| Int i -> Format.fprintf f "%ld" i
501+
| Int i -> Format.fprintf f "%s" (Targetint.to_string i)
501502
| Int32 i -> Format.fprintf f "%ldl" i
502503
| Int64 i -> Format.fprintf f "%LdL" i
503504
| NativeInt i -> Format.fprintf f "%ldn" i

compiler/lib/code.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ type constant =
173173
| NativeString of Native_string.t
174174
| Float of float
175175
| Float_array of float array
176-
| Int of Int32.t
176+
| Int of Targetint.t
177177
| Int32 of Int32.t (** Only produced when compiling to WebAssembly. *)
178178
| Int64 of Int64.t
179179
| NativeInt of Int32.t (** Only produced when compiling to WebAssembly. *)

compiler/lib/config.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,4 +191,7 @@ let target () =
191191
| (`JavaScript | `Wasm) as t -> t
192192

193193
let set_target (t : [ `JavaScript | `Wasm ]) =
194+
(match t with
195+
| `JavaScript -> Targetint.set_num_bits 32
196+
| `Wasm -> Targetint.set_num_bits 31);
194197
target_ := (t :> [ `JavaScript | `Wasm | `None ])

compiler/lib/effects.ml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ let cps_branch ~st ~src (pc, args) loc =
300300
(* We are jumping to a block that is also used as a continuation.
301301
We pass it a dummy argument. *)
302302
let x = Var.fresh () in
303-
[ x ], [ Let (x, Constant (Int 0l)), noloc ]
303+
[ x ], [ Let (x, Constant (Int Targetint.zero)), noloc ]
304304
else args, []
305305
in
306306
(* We check the stack depth only for backward edges (so, at
@@ -402,7 +402,9 @@ let cps_last ~st ~alloc_jump_closures pc ((last, last_loc) : last * loc) ~k :
402402
( x'
403403
, Prim
404404
( Extern "caml_maybe_attach_backtrace"
405-
, [ Pv x; Pc (Int (if force then 1l else 0l)) ] ) )
405+
, [ Pv x
406+
; Pc (Int (if force then Targetint.one else Targetint.zero))
407+
] ) )
406408
, noloc )
407409
]
408410
in
@@ -483,7 +485,8 @@ let cps_instr ~st (instr : instr) : instr =
483485
| Pc (Int a) ->
484486
Let
485487
( x
486-
, Prim (Extern "caml_alloc_dummy_function", [ size; Pc (Int (Int32.succ a)) ])
488+
, Prim
489+
(Extern "caml_alloc_dummy_function", [ size; Pc (Int (Targetint.succ a)) ])
487490
)
488491
| _ -> assert false)
489492
| Let (x, Apply { f; args; _ }) when not (Var.Set.mem x st.cps_needed) ->
@@ -562,7 +565,7 @@ let cps_block ~st ~k pc block =
562565
[ arg; k' ]
563566
loc)
564567
| Prim (Extern "%perform", [ Pv effect_ ]) ->
565-
perform_effect ~effect_ ~continuation:(Pc (Int 0l)) loc
568+
perform_effect ~effect_ ~continuation:(Pc (Int Targetint.zero)) loc
566569
| Prim (Extern "%reperform", [ Pv effect_; continuation ]) ->
567570
perform_effect ~effect_ ~continuation loc
568571
| _ -> None

compiler/lib/eval.ml

Lines changed: 57 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -29,81 +29,29 @@ let set_static_env s value = Hashtbl.add static_env s value
2929

3030
let get_static_env s = try Some (Hashtbl.find static_env s) with Not_found -> None
3131

32-
module type Int = sig
33-
include Arith_ops
34-
35-
val int_unop : constant list -> (t -> t) -> constant option
36-
37-
val int_binop : constant list -> (t -> t -> t) -> constant option
38-
39-
val shift_op : constant list -> (t -> int -> t) -> constant option
40-
41-
val of_int32_warning_on_overflow : int32 -> t
42-
43-
val to_int32 : t -> int32
44-
45-
val numbits : int
46-
end
47-
48-
module Int32 = struct
49-
include Int32
50-
51-
let int_unop l f =
52-
match l with
53-
| [ Int i ] -> Some (Int (f i))
54-
| _ -> None
55-
56-
let int_binop l f =
57-
match l with
58-
| [ Int i; Int j ] -> Some (Int (f i j))
59-
| _ -> None
60-
61-
(* For when the underlying function takes an [int] (not [t]) as its second argument *)
62-
let shift_op l f =
63-
match l with
64-
| [ Int i; Int j ] -> Some (Int (f i (to_int j)))
65-
| _ -> None
66-
67-
let numbits = 32
68-
69-
let of_int32_warning_on_overflow = Fun.id
70-
71-
let to_int32 = Fun.id
72-
end
73-
74-
module Int31 : Int = struct
75-
include Int31
76-
77-
let int_unop l f =
78-
match l with
79-
| [ Int i ] -> Some (Int (to_int32 (f (of_int32_warning_on_overflow i))))
80-
| _ -> None
81-
82-
let int_binop l f =
83-
match l with
84-
| [ Int i; Int j ] ->
85-
Some
86-
(Int
87-
(to_int32
88-
(f (of_int32_warning_on_overflow i) (of_int32_warning_on_overflow j))))
89-
| _ -> None
32+
let int_unop l f =
33+
match l with
34+
| [ Int i ] -> Some (Int (f i))
35+
| _ -> None
9036

91-
let shift_op l f =
92-
match l with
93-
| [ Int i; Int j ] ->
94-
Some (Int (to_int32 (f (of_int32_warning_on_overflow i) (Int32.to_int j))))
95-
| _ -> None
37+
let int_binop l f =
38+
match l with
39+
| [ Int i; Int j ] -> Some (Int (f i j))
40+
| _ -> None
9641

97-
let numbits = 31
98-
end
42+
(* For when the underlying function takes an [int] (not [t]) as its second argument *)
43+
let shift_op l f =
44+
match l with
45+
| [ Int i; Int j ] -> Some (Int (f i (Targetint.to_int_exn j)))
46+
| _ -> None
9947

10048
let float_binop_aux (l : constant list) (f : float -> float -> 'a) : 'a option =
10149
let args =
10250
match l with
10351
| [ Float i; Float j ] -> Some (i, j)
104-
| [ Int i; Int j ] -> Some (Int32.to_float i, Int32.to_float j)
105-
| [ Int i; Float j ] -> Some (Int32.to_float i, j)
106-
| [ Float i; Int j ] -> Some (i, Int32.to_float 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)
10755
| _ -> None
10856
in
10957
match args with
@@ -118,10 +66,10 @@ let float_binop (l : constant list) (f : float -> float -> float) : constant opt
11866
let float_unop (l : constant list) (f : float -> float) : constant option =
11967
match l with
12068
| [ Float i ] -> Some (Float (f i))
121-
| [ Int i ] -> Some (Float (f (Int32.to_float i)))
69+
| [ Int i ] -> Some (Float (f (Targetint.to_float i)))
12270
| _ -> None
12371

124-
let bool' b = Int (if b then 1l else 0l)
72+
let bool' b = Int Targetint.(if b then one else zero)
12573

12674
let bool b = Some (bool' b)
12775

@@ -130,36 +78,31 @@ let float_binop_bool l f =
13078
| Some b -> bool b
13179
| None -> None
13280

133-
let eval_prim ~target x =
81+
let eval_prim x =
13482
match x with
135-
| Not, [ Int i ] -> bool Int32.(i = 0l)
136-
| Lt, [ Int i; Int j ] -> bool Int32.(i < j)
137-
| Le, [ Int i; Int j ] -> bool Int32.(i <= j)
138-
| Eq, [ Int i; Int j ] -> bool Int32.(i = j)
139-
| Neq, [ Int i; Int j ] -> bool Int32.(i <> j)
140-
| Ult, [ Int i; Int j ] -> bool (Int32.(j < 0l) || Int32.(i < j))
83+
| Not, [ Int i ] -> bool (Targetint.is_zero i)
84+
| Lt, [ Int i; Int j ] -> bool Targetint.(i < j)
85+
| Le, [ Int i; Int j ] -> bool Targetint.(i <= j)
86+
| Eq, [ Int i; Int j ] -> bool Targetint.(i = j)
87+
| Neq, [ Int i; Int j ] -> bool Targetint.(i <> j)
88+
| Ult, [ Int i; Int j ] -> bool (Targetint.(j < zero) || Targetint.(i < j))
14189
| Extern name, l -> (
142-
let (module Int : Int) =
143-
match target with
144-
| `JavaScript -> (module Int32)
145-
| `Wasm -> (module Int31)
146-
in
14790
let name = Primitive.resolve name in
14891
match name, l with
14992
(* int *)
150-
| "%int_add", _ -> Int.int_binop l Int.add
151-
| "%int_sub", _ -> Int.int_binop l Int.sub
152-
| "%direct_int_mul", _ -> Int.int_binop l Int.mul
153-
| "%direct_int_div", [ _; Int 0l ] -> None
154-
| "%direct_int_div", _ -> Int.int_binop l Int.div
155-
| "%direct_int_mod", _ -> Int.int_binop l Int.rem
156-
| "%int_and", _ -> Int.int_binop l Int.logand
157-
| "%int_or", _ -> Int.int_binop l Int.logor
158-
| "%int_xor", _ -> Int.int_binop l Int.logxor
159-
| "%int_lsl", _ -> Int.shift_op l Int.shift_left
160-
| "%int_lsr", _ -> Int.shift_op l Int.shift_right_logical
161-
| "%int_asr", _ -> Int.shift_op l Int.shift_right
162-
| "%int_neg", _ -> Int.int_unop l Int.neg
93+
| "%int_add", _ -> int_binop l Targetint.add
94+
| "%int_sub", _ -> int_binop l Targetint.sub
95+
| "%direct_int_mul", _ -> int_binop l Targetint.mul
96+
| "%direct_int_div", [ _; Int x ] when Targetint.is_zero x -> None
97+
| "%direct_int_div", _ -> int_binop l Targetint.div
98+
| "%direct_int_mod", _ -> int_binop l Targetint.rem
99+
| "%int_and", _ -> int_binop l Targetint.logand
100+
| "%int_or", _ -> int_binop l Targetint.logor
101+
| "%int_xor", _ -> int_binop l Targetint.logxor
102+
| "%int_lsl", _ -> shift_op l Targetint.shift_left
103+
| "%int_lsr", _ -> shift_op l Targetint.shift_right_logical
104+
| "%int_asr", _ -> shift_op l Targetint.shift_right
105+
| "%int_neg", _ -> int_unop l Targetint.neg
163106
(* float *)
164107
| "caml_eq_float", _ -> float_binop_bool l Float.( = )
165108
| "caml_neq_float", _ -> float_binop_bool l Float.( <> )
@@ -172,9 +115,10 @@ let eval_prim ~target x =
172115
| "caml_mul_float", _ -> float_binop l ( *. )
173116
| "caml_div_float", _ -> float_binop l ( /. )
174117
| "caml_fmod_float", _ -> float_binop l mod_float
175-
| "caml_int_of_float", [ Float f ] ->
176-
Some
177-
(Int (Int32.of_float f |> Int.of_int32_warning_on_overflow |> Int.to_int32))
118+
| "caml_int_of_float", [ Float f ] -> (
119+
match Targetint.of_float_opt f with
120+
| None -> None
121+
| Some f -> Some (Int f))
178122
(* Math *)
179123
| "caml_neg_float", _ -> float_unop l ( ~-. )
180124
| "caml_abs_float", _ -> float_unop l abs_float
@@ -192,9 +136,9 @@ let eval_prim ~target x =
192136
| "caml_sqrt_float", _ -> float_unop l sqrt
193137
| "caml_tan_float", _ -> float_unop l tan
194138
| ("caml_string_get" | "caml_string_unsafe_get"), [ String s; Int pos ] ->
195-
let pos = Int32.to_int pos in
139+
let pos = Targetint.to_int_exn pos in
196140
if Config.Flag.safe_string () && pos >= 0 && pos < String.length s
197-
then Some (Int (Int32.of_int (Char.code s.[pos])))
141+
then Some (Int (Targetint.of_int_exn (Char.code s.[pos])))
198142
else None
199143
| "caml_string_equal", [ String s1; String s2 ] -> bool (String.equal s1 s2)
200144
| "caml_string_notequal", [ String s1; String s2 ] ->
@@ -203,10 +147,11 @@ let eval_prim ~target x =
203147
match get_static_env s with
204148
| Some env -> Some (String env)
205149
| None -> None)
206-
| "caml_sys_const_word_size", [ _ ] -> Some (Int 32l)
207-
| "caml_sys_const_int_size", [ _ ] -> Some (Int (Int32.of_int Int.numbits))
208-
| "caml_sys_const_big_endian", [ _ ] -> Some (Int 0l)
209-
| "caml_sys_const_naked_pointers_checked", [ _ ] -> Some (Int 0l)
150+
| "caml_sys_const_word_size", [ _ ] -> Some (Int (Targetint.of_int_exn 32))
151+
| "caml_sys_const_int_size", [ _ ] ->
152+
Some (Int (Targetint.of_int_exn (Targetint.num_bits ())))
153+
| "caml_sys_const_big_endian", [ _ ] -> Some (Int Targetint.zero)
154+
| "caml_sys_const_naked_pointers_checked", [ _ ] -> Some (Int Targetint.zero)
210155
| _ -> None)
211156
| _ -> None
212157

@@ -215,14 +160,14 @@ let the_length_of ~target info x =
215160
info
216161
(fun x ->
217162
match Flow.Info.def info x with
218-
| Some (Constant (String s)) -> Some (Int32.of_int (String.length s))
163+
| Some (Constant (String s)) -> Some (Targetint.of_int_exn (String.length s))
219164
| Some (Prim (Extern "caml_create_string", [ arg ]))
220165
| Some (Prim (Extern "caml_create_bytes", [ arg ])) -> the_int ~target info arg
221166
| None | Some _ -> None)
222167
None
223168
(fun u v ->
224169
match u, v with
225-
| Some l, Some l' when Int32.(l = l') -> Some l
170+
| Some l, Some l' when Targetint.(l = l') -> Some l
226171
| _ -> None)
227172
x
228173

@@ -292,7 +237,7 @@ let the_cont_of info x (a : cont array) =
292237
(fun x ->
293238
match Flow.Info.def info x with
294239
| Some (Prim (Extern "%direct_obj_tag", [ b ])) -> the_tag_of info b get
295-
| Some (Constant (Int j)) -> get (Int32.to_int j)
240+
| Some (Constant (Int j)) -> get (Targetint.to_int_exn j)
296241
| None | Some _ -> None)
297242
None
298243
(fun u v ->
@@ -304,7 +249,7 @@ let the_cont_of info x (a : cont array) =
304249
(* If [constant_js_equal a b = Some v], then [caml_js_equals a b = v]). *)
305250
let constant_js_equal a b =
306251
match a, b with
307-
| Int i, Int j -> Some (Int32.equal i j)
252+
| Int i, Int j -> Some (Targetint.equal i j)
308253
| Float a, Float b -> Some (Float.ieee_equal a b)
309254
| NativeString a, NativeString b -> Some (Native_string.equal a b)
310255
| String a, String b when Config.Flag.use_js_string () -> Some (String.equal a b)
@@ -356,7 +301,7 @@ let eval_instr ~target info ((x, loc) as i) =
356301
| Let (x, Prim (Extern "caml_ml_string_length", [ s ])) -> (
357302
let c =
358303
match s with
359-
| Pc (String s) -> Some (Int32.of_int (String.length s))
304+
| Pc (String s) -> Some (Targetint.of_int_exn (String.length s))
360305
| Pv v -> the_length_of ~target info v
361306
| _ -> None
362307
in
@@ -391,7 +336,7 @@ let eval_instr ~target info ((x, loc) as i) =
391336
| Let (x, Prim (Extern "%direct_obj_tag", [ y ])) -> (
392337
match the_tag_of info y (fun x -> Some x) with
393338
| Some tag ->
394-
let c = Constant (Int (Int32.of_int tag)) in
339+
let c = Constant (Int (Targetint.of_int_exn tag)) in
395340
Flow.Info.update_def info x c;
396341
[ Let (x, c), loc ]
397342
| None -> [ i ])
@@ -415,7 +360,6 @@ let eval_instr ~target info ((x, loc) as i) =
415360
| _ -> false)
416361
then
417362
eval_prim
418-
~target
419363
( prim
420364
, List.map prim_args' ~f:(function
421365
| Some c -> c
@@ -461,11 +405,10 @@ let the_cond_of info x =
461405
info
462406
(fun x ->
463407
match Flow.Info.def info x with
464-
| Some (Constant (Int 0l)) -> Zero
408+
| Some (Constant (Int x)) -> if Targetint.is_zero x then Zero else Non_zero
465409
| Some
466410
(Constant
467-
( Int _
468-
| Int32 _
411+
( Int32 _
469412
| NativeInt _
470413
| Float _
471414
| Tuple _

compiler/lib/flow.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ let the_def_of info x =
345345
= true]) and if both are floats, they are bitwise equal. *)
346346
let constant_identical ~(target : [ `JavaScript | `Wasm ]) a b =
347347
match a, b, target with
348-
| Int i, Int j, _ -> Int32.equal i j
348+
| Int i, Int j, _ -> Targetint.equal i j
349349
| Float a, Float b, `JavaScript -> Float.bitwise_equal a b
350350
| Float _, Float _, `Wasm -> false
351351
| NativeString a, NativeString b, `JavaScript -> Native_string.equal a b

compiler/lib/flow.mli

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ val the_string_of :
6161
val the_native_string_of :
6262
target:[ `JavaScript | `Wasm ] -> Info.t -> Code.prim_arg -> Code.Native_string.t option
6363

64-
val the_int : target:[ `JavaScript | `Wasm ] -> Info.t -> Code.prim_arg -> int32 option
64+
val the_int :
65+
target:[ `JavaScript | `Wasm ] -> Info.t -> Code.prim_arg -> Targetint.t option
6566

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

0 commit comments

Comments
 (0)