Skip to content

Commit 9c6ed30

Browse files
authored
Unboxed numbers (#1165)
1 parent 4e08295 commit 9c6ed30

35 files changed

+270
-16
lines changed

backend/cmm_helpers.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2658,6 +2658,10 @@ let machtype_of_layout (layout : Lambda.layout) =
26582658
match layout with
26592659
| Ptop -> Misc.fatal_error "No machtype for layout [Ptop]"
26602660
| Pbottom -> Misc.fatal_error "No unique machtype for layout [Pbottom]"
2661+
| Punboxed_float -> typ_float
2662+
| Punboxed_int _ ->
2663+
(* Only 64-bit architectures, so this is always [typ_int] *)
2664+
typ_int
26612665
| Pvalue _ -> typ_val
26622666

26632667
let final_curry_function nlocal arity result =
@@ -3998,4 +4002,6 @@ let kind_of_layout (layout : Lambda.layout) =
39984002
| Ptop | Pbottom ->
39994003
(* This is incorrect but only used for unboxing *)
40004004
Vval Pgenval
4005+
| Punboxed_float -> Vfloat
4006+
| Punboxed_int _ -> Vint
40014007
| Pvalue kind -> Vval kind

backend/cmmgen.ml

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ let rec transl env e =
664664
| Pandbint _ | Porbint _ | Pxorbint _ | Plslbint _ | Plsrbint _
665665
| Pasrbint _ | Pbintcomp (_, _) | Pstring_load _ | Pbytes_load _
666666
| Pbytes_set _ | Pbigstring_load _ | Pbigstring_set _
667+
| Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
667668
| Pbbswap _), _)
668669
->
669670
fatal_error "Cmmgen.transl:prim"
@@ -806,6 +807,8 @@ and transl_catch (kind : Cmm.value_kind) env nfail ids body handler dbg =
806807
Misc.fatal_errorf
807808
"Variable %a with layout [Pbottom] can't be compiled"
808809
VP.print id
810+
| Punboxed_float | Punboxed_int _ ->
811+
u := No_unboxing
809812
| Pvalue kind ->
810813
let strict = is_strict kind in
811814
u := join_unboxed_number_kind ~strict !u
@@ -817,12 +820,12 @@ and transl_catch (kind : Cmm.value_kind) env nfail ids body handler dbg =
817820
let body = transl env_body body in
818821
let new_env, rewrite, ids =
819822
List.fold_right
820-
(fun (id, _kind, u) (env, rewrite, ids) ->
823+
(fun (id, layout, u) (env, rewrite, ids) ->
821824
match !u with
822825
| No_unboxing | Boxed (_, true) | No_result ->
823826
env,
824827
(fun x -> x) :: rewrite,
825-
(id, Cmm.typ_val) :: ids
828+
(id, machtype_of_layout layout) :: ids
826829
| Boxed (bn, false) ->
827830
let unboxed_id = V.create_local (VP.name id) in
828831
add_unboxed_id (VP.var id) unboxed_id bn env,
@@ -937,7 +940,15 @@ and transl_prim_1 env p arg dbg =
937940
offsetint n (transl env arg) dbg
938941
| Poffsetref n ->
939942
offsetref n (transl env arg) dbg
943+
| Punbox_int bi ->
944+
transl_unbox_int dbg env bi arg
945+
| Pbox_int (bi, m) ->
946+
box_int dbg bi m (transl env arg)
940947
(* Floating-point operations *)
948+
| Punbox_float ->
949+
transl_unbox_float dbg env arg
950+
| Pbox_float m ->
951+
box_float dbg m (transl env arg)
941952
| Pfloatofint m ->
942953
box_float dbg m (Cop(Cfloatofint, [untag_int(transl env arg) dbg], dbg))
943954
| Pintoffloat ->
@@ -1172,6 +1183,7 @@ and transl_prim_2 env p arg1 arg2 dbg =
11721183
| Pnegbint _ | Pbigarrayref (_, _, _, _) | Pbigarrayset (_, _, _, _)
11731184
| Pbigarraydim _ | Pbytes_set _ | Pbigstring_set _ | Pbbswap _
11741185
| Pprobe_is_enabled _
1186+
| Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
11751187
->
11761188
fatal_errorf "Cmmgen.transl_prim_2: %a"
11771189
Printclambda_primitives.primitive p
@@ -1232,6 +1244,7 @@ and transl_prim_3 env p arg1 arg2 arg3 dbg =
12321244
| Pbigarrayref (_, _, _, _) | Pbigarrayset (_, _, _, _) | Pbigarraydim _
12331245
| Pstring_load _ | Pbytes_load _ | Pbigstring_load _ | Pbbswap _
12341246
| Pprobe_is_enabled _
1247+
| Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
12351248
->
12361249
fatal_errorf "Cmmgen.transl_prim_3: %a"
12371250
Printclambda_primitives.primitive p
@@ -1305,6 +1318,16 @@ and transl_let env str (layout : Lambda.layout) id exp transl_body =
13051318
there may be constant closures inside that need lifting out. *)
13061319
let _cbody : expression = transl_body env in
13071320
cexp
1321+
| Punboxed_float | Punboxed_int _ -> begin
1322+
let cexp = transl env exp in
1323+
let cbody = transl_body env in
1324+
match str with
1325+
| (Immutable | Immutable_unique) ->
1326+
Clet(id, cexp, cbody)
1327+
| Mutable ->
1328+
let typ = machtype_of_layout layout in
1329+
Clet_mut(id, typ, cexp, cbody)
1330+
end
13081331
| Pvalue kind ->
13091332
transl_let_value env str kind id exp transl_body
13101333

middle_end/clambda_primitives.ml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ type primitive =
122122
| Popaque
123123
(* Probes *)
124124
| Pprobe_is_enabled of { name : string }
125+
| Punbox_float
126+
| Pbox_float of alloc_mode
127+
| Punbox_int of boxed_integer
128+
| Pbox_int of boxed_integer * alloc_mode
125129

126130
and integer_comparison = Lambda.integer_comparison =
127131
Ceq | Cne | Clt | Cgt | Cle | Cge
@@ -144,6 +148,8 @@ and value_kind = Lambda.value_kind =
144148
and layout = Lambda.layout =
145149
| Ptop
146150
| Pvalue of value_kind
151+
| Punboxed_float
152+
| Punboxed_int of boxed_integer
147153
| Pbottom
148154

149155
and block_shape = Lambda.block_shape
@@ -171,4 +177,8 @@ and raise_kind = Lambda.raise_kind =
171177

172178
let equal (x: primitive) (y: primitive) = x = y
173179

174-
let result_layout _p = Lambda.layout_any_value
180+
let result_layout (p : primitive) =
181+
match p with
182+
| Punbox_float -> Lambda.Punboxed_float
183+
| Punbox_int bi -> Lambda.Punboxed_int bi
184+
| _ -> Lambda.layout_any_value

middle_end/clambda_primitives.mli

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ type primitive =
125125
| Popaque
126126
(* Probes *)
127127
| Pprobe_is_enabled of { name : string }
128+
| Punbox_float
129+
| Pbox_float of alloc_mode
130+
| Punbox_int of boxed_integer
131+
| Pbox_int of boxed_integer * alloc_mode
128132

129133
and integer_comparison = Lambda.integer_comparison =
130134
Ceq | Cne | Clt | Cgt | Cle | Cge
@@ -147,6 +151,8 @@ and value_kind = Lambda.value_kind =
147151
and layout = Lambda.layout =
148152
| Ptop
149153
| Pvalue of value_kind
154+
| Punboxed_float
155+
| Punboxed_int of boxed_integer
150156
| Pbottom
151157

152158
and block_shape = Lambda.block_shape

middle_end/closure/closure.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ let is_gc_ignorable kind =
6161
match kind with
6262
| Ptop -> Misc.fatal_error "[Ptop] can't be stored in a closure."
6363
| Pbottom -> Misc.fatal_error "[Pbottom] should not be stored in a closure."
64+
| Punboxed_float -> true
65+
| Punboxed_int _ -> true
6466
| Pvalue Pintval -> true
6567
| Pvalue (Pgenval | Pfloatval | Pboxedintval _ | Pvariant _ | Parrayval _) -> false
6668

middle_end/convert_primitives.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ let convert (prim : Lambda.primitive) : Clambda_primitives.primitive =
154154
~native_name:"caml_obj_dup"
155155
~native_repr_args:[P.Prim_global, P.Same_as_ocaml_repr]
156156
~native_repr_res:(P.Prim_global, P.Same_as_ocaml_repr))
157+
| Punbox_float -> Punbox_float
158+
| Pbox_float m -> Pbox_float m
159+
| Punbox_int bi -> Punbox_int bi
160+
| Pbox_int (bi, m) -> Pbox_int (bi, m)
157161
| Pobj_magic _
158162
| Pbytes_to_string
159163
| Pbytes_of_string

middle_end/flambda/closure_offsets.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ let add_closure_offsets
7777
Misc.fatal_error
7878
"[Pbottom] should have been eliminated as dead code \
7979
and not stored in a closure."
80+
| Punboxed_float -> true
81+
| Punboxed_int _ -> true
8082
| Pvalue Pintval -> true
8183
| Pvalue _ -> false)
8284
free_vars

middle_end/flambda/flambda_to_clambda.ml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,8 @@ and to_clambda_set_of_closures t env
703703
Misc.fatal_error
704704
"[Pbottom] should have been eliminated as dead code \
705705
and not stored in a closure."
706+
| Punboxed_float -> true
707+
| Punboxed_int _ -> true
706708
| Pvalue Pintval -> true
707709
| Pvalue _ -> false)
708710
free_vars
@@ -752,7 +754,11 @@ and to_clambda_closed_set_of_closures t env symbol
752754
in
753755
let body =
754756
let body, body_layout = to_clambda t env_body function_decl.body in
755-
assert(Lambda.compatible_layout body_layout function_decl.return_layout);
757+
if not (Lambda.compatible_layout body_layout function_decl.return_layout) then
758+
Misc.fatal_errorf "Incompatible layouts:@.body: %[email protected]: %a@.%a@."
759+
Printlambda.layout body_layout
760+
Printlambda.layout function_decl.return_layout
761+
Printclambda.clambda body;
756762
Un_anf.apply ~ppf_dump:t.ppf_dump ~what:symbol body
757763
in
758764
assert (

middle_end/flambda2/from_lambda/closure_conversion.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,8 @@ let close_primitive acc env ~let_bound_var named (prim : Lambda.primitive) ~args
693693
| Pbigstring_load_32 _ | Pbigstring_load_64 _ | Pbigstring_set_16 _
694694
| Pbigstring_set_32 _ | Pbigstring_set_64 _ | Pctconst _ | Pbswap16
695695
| Pbbswap _ | Pint_as_pointer | Popaque _ | Pprobe_is_enabled _ | Pobj_dup
696-
| Pobj_magic _ ->
696+
| Pobj_magic _ | Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
697+
->
697698
(* Inconsistent with outer match *)
698699
assert false
699700
in

middle_end/flambda2/from_lambda/lambda_to_flambda.ml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,8 @@ let primitive_can_raise (prim : Lambda.primitive) =
953953
| Pbigstring_set_32 true
954954
| Pbigstring_set_64 true
955955
| Pctconst _ | Pbswap16 | Pbbswap _ | Pint_as_pointer | Popaque _
956-
| Pprobe_is_enabled _ | Pobj_dup | Pobj_magic _ ->
956+
| Pprobe_is_enabled _ | Pobj_dup | Pobj_magic _ | Pbox_float _ | Punbox_float
957+
| Punbox_int _ | Pbox_int _ ->
957958
false
958959

959960
let primitive_result_kind (prim : Lambda.primitive) :
@@ -1014,7 +1015,8 @@ let primitive_result_kind (prim : Lambda.primitive) :
10141015
| Pmulbint (bi, _)
10151016
| Pbintofint (bi, _)
10161017
| Pcvtbint (_, bi, _)
1017-
| Pbbswap (bi, _) -> (
1018+
| Pbbswap (bi, _)
1019+
| Pbox_int (bi, _) -> (
10181020
match bi with
10191021
| Pint32 -> Flambda_kind.With_subkind.boxed_int32
10201022
| Pint64 -> Flambda_kind.With_subkind.boxed_int64
@@ -1035,6 +1037,13 @@ let primitive_result_kind (prim : Lambda.primitive) :
10351037
(_, _, (Pbigarray_complex32 | Pbigarray_complex64 | Pbigarray_unknown), _)
10361038
| Pint_as_pointer | Pobj_dup ->
10371039
Flambda_kind.With_subkind.any_value
1040+
| Pbox_float _ -> Flambda_kind.With_subkind.boxed_float
1041+
| Punbox_float -> Flambda_kind.With_subkind.naked_float
1042+
| Punbox_int bi -> (
1043+
match bi with
1044+
| Pint32 -> Flambda_kind.With_subkind.naked_int32
1045+
| Pint64 -> Flambda_kind.With_subkind.naked_int64
1046+
| Pnativeint -> Flambda_kind.With_subkind.naked_nativeint)
10381047

10391048
type cps_continuation =
10401049
| Tail of Continuation.t

middle_end/flambda2/from_lambda/lambda_to_flambda_primitives.ml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,22 @@ let convert_lprim ~big_endian (prim : L.primitive) (args : Simple.t list)
722722
( Float_comp (Yielding_bool (convert_float_comparison comp)),
723723
unbox_float arg1,
724724
unbox_float arg2 ))
725+
| Punbox_float, [arg] -> Unary (Unbox_number Naked_float, arg)
726+
| Pbox_float mode, [arg] ->
727+
Unary
728+
( Box_number
729+
( Naked_float,
730+
Alloc_mode.For_allocations.from_lambda mode ~current_region ),
731+
arg )
732+
| Punbox_int bi, [arg] ->
733+
let kind = boxable_number_of_boxed_integer bi in
734+
Unary (Unbox_number kind, arg)
735+
| Pbox_int (bi, mode), [arg] ->
736+
let kind = boxable_number_of_boxed_integer bi in
737+
Unary
738+
( Box_number
739+
(kind, Alloc_mode.For_allocations.from_lambda mode ~current_region),
740+
arg )
725741
| Pfield_computed sem, [obj; field] ->
726742
let block_access : P.Block_access_kind.t =
727743
Values { tag = Unknown; size = Unknown; field_kind = Any_value }
@@ -1168,7 +1184,8 @@ let convert_lprim ~big_endian (prim : L.primitive) (args : Simple.t list)
11681184
| Pintofbint _ | Pnegbint _ | Popaque _ | Pduprecord _ | Parraylength _
11691185
| Pduparray _ | Pfloatfield _ | Pcvtbint _ | Poffsetref _ | Pbswap16
11701186
| Pbbswap _ | Pisint _ | Pint_as_pointer | Pbigarraydim _ | Pobj_dup
1171-
| Pobj_magic _ ),
1187+
| Pobj_magic _ | Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
1188+
),
11721189
([] | _ :: _ :: _) ) ->
11731190
Misc.fatal_errorf
11741191
"Closure_conversion.convert_primitive: Wrong arity for unary primitive \

middle_end/flambda2/kinds/flambda_kind.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,10 @@ module With_subkind = struct
522522
| Ptop -> Misc.fatal_error "Can't convert layout [Ptop] to flambda kind"
523523
| Pbottom ->
524524
Misc.fatal_error "Can't convert layout [Pbottom] to flambda kind"
525+
| Punboxed_float -> naked_float
526+
| Punboxed_int Pint32 -> naked_int32
527+
| Punboxed_int Pint64 -> naked_int64
528+
| Punboxed_int Pnativeint -> naked_nativeint
525529

526530
include Container_types.Make (struct
527531
type nonrec t = t

middle_end/internal_variable_names.ml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,14 @@ let unbox_free_vars_of_closures = "unbox_free_vars_of_closures"
302302
let unit = "unit"
303303
let zero = "zero"
304304
let probe_handler = "probe_handler"
305+
let punbox_float = "Punbox_float"
306+
let pbox_float = "Pbox_float"
307+
let punbox_float_arg = "Punbox_float_arg"
308+
let pbox_float_arg = "Pbox_float_arg"
309+
let punbox_int = "Punbox_int"
310+
let pbox_int = "Pbox_int"
311+
let punbox_int_arg = "Punbox_int_arg"
312+
let pbox_int_arg = "Pbox_int_arg"
305313

306314
let anon_fn_with_loc (sloc: Lambda.scoped_location) =
307315
let loc = Debuginfo.Scoped_location.to_location sloc in
@@ -421,6 +429,10 @@ let of_primitive : Lambda.primitive -> string = function
421429
| Pprobe_is_enabled _ -> pprobe_is_enabled
422430
| Pobj_dup -> pobj_dup
423431
| Pobj_magic _ -> pobj_magic
432+
| Punbox_float -> punbox_float
433+
| Pbox_float _ -> pbox_float
434+
| Punbox_int _ -> punbox_int
435+
| Pbox_int _ -> pbox_int
424436

425437
let of_primitive_arg : Lambda.primitive -> string = function
426438
| Pbytes_of_string -> pbytes_of_string_arg
@@ -529,3 +541,7 @@ let of_primitive_arg : Lambda.primitive -> string = function
529541
| Pprobe_is_enabled _ -> pprobe_is_enabled_arg
530542
| Pobj_dup -> pobj_dup_arg
531543
| Pobj_magic _ -> pobj_magic_arg
544+
| Punbox_float -> punbox_float_arg
545+
| Pbox_float _ -> pbox_float_arg
546+
| Punbox_int _ -> punbox_int_arg
547+
| Pbox_int _ -> pbox_int_arg

middle_end/printclambda.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ let layout (layout : Lambda.layout) =
5656
| Pvalue kind -> value_kind kind
5757
| Ptop -> ":top"
5858
| Pbottom -> ":bottom"
59+
| Punboxed_float -> ":unboxed_float"
60+
| Punboxed_int Pint32 -> ":unboxed_int32"
61+
| Punboxed_int Pint64 -> ":unboxed_int64"
62+
| Punboxed_int Pnativeint -> ":unboxed_nativeint"
5963

6064
let rec structured_constant ppf = function
6165
| Uconst_float x -> fprintf ppf "%F" x

middle_end/printclambda_primitives.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,8 @@ let primitive ppf (prim:Clambda_primitives.primitive) =
230230
| Pint_as_pointer -> fprintf ppf "int_as_pointer"
231231
| Popaque -> fprintf ppf "opaque"
232232
| Pprobe_is_enabled {name} -> fprintf ppf "probe_is_enabled[%s]" name
233+
| Pbox_float m -> fprintf ppf "box_float.%s" (alloc_kind m)
234+
| Punbox_float -> fprintf ppf "unbox_float"
235+
| Pbox_int (bi, m) ->
236+
fprintf ppf "box_%s.%s" (boxed_integer_name bi) (alloc_kind m)
237+
| Punbox_int bi -> fprintf ppf "unbox_%s" (boxed_integer_name bi)

middle_end/semantics_of_primitives.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,10 @@ let for_primitive (prim : Clambda_primitives.primitive) =
8282
Arbitrary_effects, No_coeffects
8383
| Poffsetint _ -> No_effects, No_coeffects
8484
| Poffsetref _ -> Arbitrary_effects, Has_coeffects
85+
| Punbox_float | Punbox_int _
8586
| Pintoffloat
8687
| Pfloatcomp _ -> No_effects, No_coeffects
88+
| Pbox_float m | Pbox_int (_, m)
8789
| Pfloatofint m
8890
| Pnegfloat m
8991
| Pabsfloat m
@@ -210,8 +212,10 @@ let may_locally_allocate (prim:Clambda_primitives.primitive) : bool =
210212
-> false
211213
| Poffsetint _ -> false
212214
| Poffsetref _ -> false
215+
| Punbox_float | Punbox_int _
213216
| Pintoffloat
214217
| Pfloatcomp _ -> false
218+
| Pbox_float m | Pbox_int (_, m)
215219
| Pfloatofint m
216220
| Pnegfloat m
217221
| Pabsfloat m

ocaml/asmcomp/cmm_helpers.ml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2243,6 +2243,10 @@ let machtype_of_layout (layout : Lambda.layout) =
22432243
match layout with
22442244
| Ptop -> Misc.fatal_error "No machtype for layout [Ptop]"
22452245
| Pbottom -> Misc.fatal_error "No unique machtype for layout [Pbottom]"
2246+
| Punboxed_float -> typ_float
2247+
| Punboxed_int _ ->
2248+
(* Only 64-bit architectures, so this is always [typ_int] *)
2249+
typ_int
22462250
| Pvalue _ -> typ_val
22472251

22482252
let final_curry_function nlocal arity result =
@@ -3149,4 +3153,6 @@ let kind_of_layout (layout : Lambda.layout) =
31493153
| Ptop | Pbottom ->
31503154
(* This is incorrect but only used for unboxing *)
31513155
Vval Pgenval
3156+
| Punboxed_float -> Vfloat
3157+
| Punboxed_int _ -> Vint
31523158
| Pvalue kind -> Vval kind

0 commit comments

Comments
 (0)