Skip to content

WIP: Poison constants #379

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: flambda2.0-stable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compilerlibs/Makefile.compilerlibs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ MIDDLE_END_FLAMBDA_TYPES=\
middle_end/flambda/types/basic/or_bottom.cmo \
middle_end/flambda/types/basic/string_info.cmo \
middle_end/flambda/types/basic/or_unknown_or_bottom.cmo \
middle_end/flambda/types/basic/or_unknown_or_bottom_or_poison.cmo \
middle_end/flambda/types/structures/code_age_relation.cmo \
middle_end/flambda/types/structures/type_structure_intf.cmo \
middle_end/flambda/types/structures/product_intf.cmo \
Expand Down
17 changes: 17 additions & 0 deletions flambdatest/mlexamples/unboxing_need_poison.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
type ('a, 'b) t = A of int * 'a | B of 'b

let[@inline] f b y z g =
let v =
if b then
A (42, g y)
else
B (g z)
in
match v with
| A (_, a) -> a + 2
| B c -> c + 2

let[@inline] g x = 12

let test b y z =
f b y z g
15 changes: 15 additions & 0 deletions middle_end/flambda/basic/reg_width_const.ml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ let kind t =
| Naked_int32 _ -> K.naked_int32
| Naked_int64 _ -> K.naked_int64
| Naked_nativeint _ -> K.naked_nativeint
| Poison k -> begin
match k with
| Naked_immediate -> K.naked_immediate
| Value -> K.value
| Naked_float -> K.naked_float
| Naked_int32 -> K.naked_int32
| Naked_int64 -> K.naked_int64
| Naked_nativeint -> K.naked_nativeint
end

let of_descr (descr : Descr.t) =
match descr with
Expand All @@ -36,3 +45,9 @@ let of_descr (descr : Descr.t) =
| Naked_int32 i -> naked_int32 i
| Naked_int64 i -> naked_int64 i
| Naked_nativeint i -> naked_nativeint i
| Poison Naked_immediate -> naked_immediate_poison
| Poison Value -> value_poison
| Poison Naked_float -> naked_float_poison
| Poison Naked_int32 -> naked_int32_poison
| Poison Naked_int64 -> naked_int64_poison
| Poison Naked_nativeint -> naked_nativeint_poison
78 changes: 77 additions & 1 deletion middle_end/flambda/compilenv_deps/reg_width_things.ml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,56 @@ let const_flags = 2
let simple_flags = 3

module Const_data = struct
module Kind = struct
type t =
| Value
| Naked_immediate
| Naked_float
| Naked_int32
| Naked_int64
| Naked_nativeint

let compare t1 t2 =
match t1, t2 with
| Value, Value -> 0
| Value, _ -> 1
| _, Value -> -1
| Naked_immediate, Naked_immediate -> 0
| Naked_immediate, _ -> 1
| _, Naked_immediate -> -1
| Naked_float, Naked_float -> 0
| Naked_float, _ -> 1
| _, Naked_float -> -1
| Naked_int32, Naked_int32 -> 0
| Naked_int32, _ -> 1
| _, Naked_int32 -> -1
| Naked_int64, Naked_int64 -> 0
| Naked_int64, _ -> 1
| _, Naked_int64 -> -1
| Naked_nativeint, Naked_nativeint -> 0

let equal k1 k2 =
match k1, k2 with
| Value, Value
| Naked_immediate, Naked_immediate
| Naked_float, Naked_float
| Naked_int32, Naked_int32
| Naked_int64, Naked_int64
| Naked_nativeint, Naked_nativeint ->
true
| ( Value | Naked_immediate | Naked_float
| Naked_int32 | Naked_int64 | Naked_nativeint ), _ ->
false
end

type t =
| Naked_immediate of Target_imm.t
| Tagged_immediate of Target_imm.t
| Naked_float of Numbers.Float_by_bit_pattern.t
| Naked_int32 of Int32.t
| Naked_int64 of Int64.t
| Naked_nativeint of Targetint.t
| Poison of Kind.t

let flags = const_flags

Expand Down Expand Up @@ -71,6 +114,24 @@ module Const_data = struct
(Flambda_colours.naked_number ())
Targetint.print n
(Flambda_colours.normal ())
| Poison kind ->
let colour =
match kind with
| Value -> Flambda_colours.tagged_immediate
| Naked_immediate | Naked_float | Naked_int32
| Naked_int64 | Naked_nativeint ->
Flambda_colours.naked_number
in
let poison =
if !Clflags.flambda_unicode then
"\u{2620}"
else
"Poison"
in
Format.fprintf ppf "@<0>%s%s@<0>%s"
(colour ())
poison
(Flambda_colours.normal ())

let output _ _ = Misc.fatal_error "[output] not yet implemented"

Expand All @@ -88,6 +149,8 @@ module Const_data = struct
Int64.compare n1 n2
| Naked_nativeint n1, Naked_nativeint n2 ->
Targetint.compare n1 n2
| Poison k1, Poison k2 ->
Kind.compare k1 k2
| Naked_immediate _, _ -> -1
| _, Naked_immediate _ -> 1
| Tagged_immediate _, _ -> -1
Expand All @@ -98,6 +161,8 @@ module Const_data = struct
| _, Naked_int32 _ -> 1
| Naked_int64 _, _ -> -1
| _, Naked_int64 _ -> 1
| Naked_nativeint _, _ -> -1
| _, Naked_nativeint _ -> 1

let equal t1 t2 =
if t1 == t2 then true
Expand All @@ -115,8 +180,11 @@ module Const_data = struct
Int64.equal n1 n2
| Naked_nativeint n1, Naked_nativeint n2 ->
Targetint.equal n1 n2
| Poison k1, Poison k2 ->
Kind.equal k1 k2
| (Naked_immediate _ | Tagged_immediate _ | Naked_float _
| Naked_int32 _ | Naked_int64 _ | Naked_nativeint _), _ -> false
| Naked_int32 _ | Naked_int64 _ | Naked_nativeint _
| Poison _ ), _ -> false

let hash t =
match t with
Expand All @@ -126,6 +194,7 @@ module Const_data = struct
| Naked_int32 n -> Hashtbl.hash n
| Naked_int64 n -> Hashtbl.hash n
| Naked_nativeint n -> Targetint.hash n
| Poison k -> Hashtbl.hash k
end)
end

Expand Down Expand Up @@ -288,6 +357,13 @@ module Const = struct
let const_one = tagged_immediate Target_imm.one
let const_unit = const_zero

let naked_immediate_poison = create (Poison Naked_immediate)
let value_poison = create (Poison Value)
let naked_float_poison = create (Poison Naked_float)
let naked_int32_poison = create (Poison Naked_int32)
let naked_int64_poison = create (Poison Naked_int64)
let naked_nativeint_poison = create (Poison Naked_nativeint)

let descr t = find_data t

module T0 = struct
Expand Down
32 changes: 25 additions & 7 deletions middle_end/flambda/compilenv_deps/reg_width_things.mli
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,32 @@ module Const : sig
val naked_int64 : Int64.t -> t
val naked_nativeint : Targetint.t -> t

val naked_immediate_poison : t
val value_poison : t
val naked_float_poison : t
val naked_int32_poison : t
val naked_int64_poison : t
val naked_nativeint_poison : t

module Descr : sig
type t = private
| Naked_immediate of Target_imm.t
| Tagged_immediate of Target_imm.t
| Naked_float of Numbers.Float_by_bit_pattern.t
| Naked_int32 of Int32.t
| Naked_int64 of Int64.t
| Naked_nativeint of Targetint.t
module Kind : sig
type t = private
| Value
| Naked_immediate
| Naked_float
| Naked_int32
| Naked_int64
| Naked_nativeint
end

type t = private
| Naked_immediate of Target_imm.t
| Tagged_immediate of Target_imm.t
| Naked_float of Numbers.Float_by_bit_pattern.t
| Naked_int32 of Int32.t
| Naked_int64 of Int64.t
| Naked_nativeint of Targetint.t
| Poison of Kind.t

include Identifiable.S with type t := t
end
Expand Down
7 changes: 7 additions & 0 deletions middle_end/flambda/parser/flambda_to_fexpr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,13 @@ let const c : Fexpr.const =
Naked_int64 i
| Naked_nativeint i ->
Naked_nativeint (i |> Targetint.to_int64)
| Poison Naked_immediate
| Poison Value
| Poison Naked_float
| Poison Naked_int32
| Poison Naked_int64
| Poison Naked_nativeint ->
Misc.fatal_errorf "TODO: Poison constants"

let simple env s =
Simple.pattern_match s
Expand Down
5 changes: 4 additions & 1 deletion middle_end/flambda/simplify/simplify_named.ml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ let record_any_symbol_projection dacc (defining_expr : Simplified_named.t)
Simple.pattern_match index
~const:(fun const ->
match Reg_width_const.descr const with
| Poison Value -> None
| Tagged_immediate imm ->
Simple.pattern_match' block
~const:(fun _ -> None)
Expand All @@ -80,7 +81,9 @@ let record_any_symbol_projection dacc (defining_expr : Simplified_named.t)
(SP.Projection.block_load ~index)))
~var:(fun _ -> None)
| Naked_immediate _ | Naked_float _
| Naked_int32 _ | Naked_int64 _ | Naked_nativeint _ ->
| Naked_int32 _ | Naked_int64 _ | Naked_nativeint _
| Poison ( Naked_immediate | Naked_float | Naked_int32
| Naked_int64 | Naked_nativeint )->
Misc.fatal_errorf "Kind error for [Block_load] index:@ \
%a@ =@ %a"
Bindable_let_bound.print bindable_let_bound
Expand Down
7 changes: 6 additions & 1 deletion middle_end/flambda/simplify/simplify_static_const.ml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,13 @@ let simplify_field_of_block dacc (field : Field_of_block.t) =
~const:(fun const ->
match Reg_width_const.descr const with
| Tagged_immediate imm -> Field_of_block.Tagged_immediate imm, ty
| Poison Value ->
(* CR pchambart: This should be "invalid" and propagate up *)
field, T.bottom K.value
| Naked_immediate _ | Naked_float _ | Naked_int32 _
| Naked_int64 _ | Naked_nativeint _ ->
| Naked_int64 _ | Naked_nativeint _
| Poison ( Naked_immediate | Naked_float | Naked_int32
| Naked_int64 | Naked_nativeint ) ->
(* CR mshinwell: This should be "invalid" and propagate up *)
field, ty)

Expand Down
1 change: 1 addition & 0 deletions middle_end/flambda/simplify/simplify_switch_expr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ let rebuild_switch ~simplify_let dacc ~arms ~scrutinee ~scrutinee_ty uacc
normal_case ~identity_arms ~not_arms
else
normal_case ~identity_arms ~not_arms
| Poison _
| Naked_immediate _ | Naked_float _ | Naked_int32 _
| Naked_int64 _ | Naked_nativeint _ ->
normal_case ~identity_arms ~not_arms
Expand Down
9 changes: 9 additions & 0 deletions middle_end/flambda/to_cmm/un_cps.ml
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,22 @@ let const _env cst =
match Reg_width_const.descr cst with
| Naked_immediate i ->
C.targetint (targetint_of_imm i)
| Poison Naked_immediate ->
C.targetint (targetint_of_imm Target_imm.zero)
| Tagged_immediate i ->
C.targetint (tag_targetint (targetint_of_imm i))
| Poison Value ->
C.targetint (tag_targetint (targetint_of_imm Target_imm.zero))
| Naked_float f ->
C.float (Numbers.Float_by_bit_pattern.to_float f)
| Poison Naked_float ->
C.float 0.
| Naked_int32 i -> C.int32 i
| Poison Naked_int32 -> C.int32 0l
| Naked_int64 i -> C.int64 i
| Poison Naked_int64 -> C.int64 0L
| Naked_nativeint t -> C.targetint t
| Poison Naked_nativeint -> C.targetint Targetint.zero

let default_of_kind (k : Flambda_kind.t) =
match k with
Expand Down
14 changes: 14 additions & 0 deletions middle_end/flambda/to_cmm/un_cps_static.ml
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,31 @@ let const_static _env cst =
match Reg_width_const.descr cst with
| Naked_immediate i ->
[C.cint (nativeint_of_targetint (targetint_of_imm i))]
| Poison Naked_immediate ->
(* CR pchambart: Should we use something more noticeable than 0 ? *)
[C.cint 0n]
| Tagged_immediate i ->
[C.cint (nativeint_of_targetint (tag_targetint (targetint_of_imm i)))]
| Poison Value ->
[C.cint 1n]
| Naked_float f ->
[C.cfloat (Numbers.Float_by_bit_pattern.to_float f)]
| Poison Naked_float ->
[C.cfloat 0.]
| Naked_int32 i ->
[C.cint (Nativeint.of_int32 i)]
| Poison Naked_int32 ->
[C.cint 0n]
| Naked_int64 i ->
if C.arch32 then todo() (* split int64 on 32-bit archs *)
else [C.cint (Int64.to_nativeint i)]
| Poison Naked_int64 ->
if C.arch32 then todo() (* split int64 on 32-bit archs *)
else [C.cint 0n]
| Naked_nativeint t ->
[C.cint (nativeint_of_targetint t)]
| Poison Naked_nativeint ->
[C.cint 0n]

let simple_static env s =
Simple.pattern_match s
Expand Down
Loading