Skip to content

Commit

Permalink
Revert "Revert "Add a proper top and bottom layout" (ocaml-flambda#1169
Browse files Browse the repository at this point in the history
…)" (ocaml-flambda#1191)

This reverts commit 5123d61.
  • Loading branch information
Ekdohibs authored Mar 10, 2023
1 parent 7c605e8 commit 4e08295
Show file tree
Hide file tree
Showing 21 changed files with 204 additions and 40 deletions.
13 changes: 11 additions & 2 deletions backend/cmm_helpers.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2654,7 +2654,11 @@ let rec make_curry_apply result narity args_type args clos n =
:: args)
newclos (n - 1) )

let machtype_of_layout = function Lambda.Pvalue _ -> typ_val
let machtype_of_layout (layout : Lambda.layout) =
match layout with
| Ptop -> Misc.fatal_error "No machtype for layout [Ptop]"
| Pbottom -> Misc.fatal_error "No unique machtype for layout [Pbottom]"
| Pvalue _ -> typ_val

let final_curry_function nlocal arity result =
let last_arg = V.create_local "arg" in
Expand Down Expand Up @@ -3989,4 +3993,9 @@ let transl_attrib : Lambda.check_attribute -> Cmm.codegen_option list = function
| Assert p -> [Assert (transl_property p)]
| Assume p -> [Assume (transl_property p)]

let kind_of_layout (Lambda.Pvalue kind) = Vval kind
let kind_of_layout (layout : Lambda.layout) =
match layout with
| Ptop | Pbottom ->
(* This is incorrect but only used for unboxing *)
Vval Pgenval
| Pvalue kind -> Vval kind
49 changes: 41 additions & 8 deletions backend/cmmgen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -506,9 +506,19 @@ let rec transl env e =
| Ugeneric_apply(clos, args, args_layout, result_layout, kind, dbg) ->
let clos = transl env clos in
let args = List.map (transl env) args in
let args_type = List.map machtype_of_layout args_layout in
let return = machtype_of_layout result_layout in
generic_apply (mut_from_env env clos) clos args args_type return kind dbg
if List.mem Pbottom args_layout then
(* [machtype_of_layout] will fail on Pbottom, convert it to a sequence
and remove the call, preserving the execution order. *)
List.fold_left2 (fun rest arg arg_layout ->
if arg_layout = Pbottom then
arg
else
Csequence(remove_unit arg, rest)
) (Ctuple []) args args_layout
else
let args_type = List.map machtype_of_layout args_layout in
let return = machtype_of_layout result_layout in
generic_apply (mut_from_env env clos) clos args args_type return kind dbg
| Usend(kind, met, obj, args, args_layout, result_layout, pos, dbg) ->
let met = transl env met in
let obj = transl env obj in
Expand Down Expand Up @@ -787,10 +797,19 @@ and transl_catch (kind : Cmm.value_kind) env nfail ids body handler dbg =
each argument. *)
let report args =
List.iter2
(fun (_id, Pvalue kind, u) c ->
let strict = is_strict kind in
u := join_unboxed_number_kind ~strict !u
(is_unboxed_number_cmm c)
(fun (id, (layout : Lambda.layout), u) c ->
match layout with
| Ptop ->
Misc.fatal_errorf "Variable %a with layout [Ptop] can't be compiled"
VP.print id
| Pbottom ->
Misc.fatal_errorf
"Variable %a with layout [Pbottom] can't be compiled"
VP.print id
| Pvalue kind ->
let strict = is_strict kind in
u := join_unboxed_number_kind ~strict !u
(is_unboxed_number_cmm c)
)
ids args
in
Expand Down Expand Up @@ -1235,7 +1254,7 @@ and transl_unbox_sized size dbg env exp =
| Thirty_two -> transl_unbox_int dbg env Pint32 exp
| Sixty_four -> transl_unbox_int dbg env Pint64 exp

and transl_let env str (Pvalue kind : Lambda.layout) id exp transl_body =
and transl_let_value env str (kind : Lambda.value_kind) id exp transl_body =
let dbg = Debuginfo.none in
let cexp = transl env exp in
let unboxing =
Expand Down Expand Up @@ -1275,6 +1294,20 @@ and transl_let env str (Pvalue kind : Lambda.layout) id exp transl_body =
| Mutable, bn -> Clet_mut (v, typ_of_boxed_number bn, cexp, body)
end

and transl_let env str (layout : Lambda.layout) id exp transl_body =
match layout with
| Ptop ->
Misc.fatal_errorf "Variable %a with layout [Ptop] can't be compiled"
VP.print id
| Pbottom ->
let cexp = transl env exp in
(* N.B. [body] must still be traversed even if [exp] will never return:
there may be constant closures inside that need lifting out. *)
let _cbody : expression = transl_body env in
cexp
| Pvalue kind ->
transl_let_value env str kind id exp transl_body

and make_catch (kind : Cmm.value_kind) ncatch body handler dbg =
match body with
| Cexit (Lbl nexit,[],[]) when nexit=ncatch -> handler
Expand Down
2 changes: 2 additions & 0 deletions middle_end/clambda_primitives.ml
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,9 @@ and value_kind = Lambda.value_kind =
| Parrayval of array_kind

and layout = Lambda.layout =
| Ptop
| Pvalue of value_kind
| Pbottom

and block_shape = Lambda.block_shape
and boxed_integer = Primitive.boxed_integer =
Expand Down
2 changes: 2 additions & 0 deletions middle_end/clambda_primitives.mli
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ and value_kind = Lambda.value_kind =
| Parrayval of array_kind

and layout = Lambda.layout =
| Ptop
| Pvalue of value_kind
| Pbottom

and block_shape = Lambda.block_shape
and boxed_integer = Primitive.boxed_integer =
Expand Down
2 changes: 2 additions & 0 deletions middle_end/closure/closure.ml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ let rec add_to_closure_env env_param pos cenv = function

let is_gc_ignorable kind =
match kind with
| Ptop -> Misc.fatal_error "[Ptop] can't be stored in a closure."
| Pbottom -> Misc.fatal_error "[Pbottom] should not be stored in a closure."
| Pvalue Pintval -> true
| Pvalue (Pgenval | Pfloatval | Pboxedintval _ | Pvariant _ | Parrayval _) -> false

Expand Down
10 changes: 9 additions & 1 deletion middle_end/flambda/closure_offsets.ml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,15 @@ let add_closure_offsets
in
let gc_invisible_free_vars, gc_visible_free_vars =
Variable.Map.partition (fun _ (free_var : Flambda.specialised_to) ->
match free_var.kind with Pvalue Pintval -> true | Pvalue _ -> false)
match free_var.kind with
| Ptop ->
Misc.fatal_error "[Ptop] can't be stored in a closure."
| Pbottom ->
Misc.fatal_error
"[Pbottom] should have been eliminated as dead code \
and not stored in a closure."
| Pvalue Pintval -> true
| Pvalue _ -> false)
free_vars
in
let free_variable_offsets, free_variable_pos =
Expand Down
5 changes: 5 additions & 0 deletions middle_end/flambda/flambda_to_clambda.ml
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,11 @@ and to_clambda_set_of_closures t env
let not_scanned_fv, scanned_fv =
Variable.Map.partition (fun _ (free_var : Flambda.specialised_to) ->
match free_var.kind with
| Ptop -> Misc.fatal_error "[Ptop] can't be stored in a closure."
| Pbottom ->
Misc.fatal_error
"[Pbottom] should have been eliminated as dead code \
and not stored in a closure."
| Pvalue Pintval -> true
| Pvalue _ -> false)
free_vars
Expand Down
7 changes: 6 additions & 1 deletion middle_end/flambda2/kinds/flambda_kind.ml
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,12 @@ module With_subkind = struct
| Parrayval Paddrarray -> value_array
| Parrayval Pgenarray -> generic_array

let from_lambda (Pvalue vk : Lambda.layout) = from_lambda_value_kind vk
let from_lambda (layout : Lambda.layout) =
match layout with
| Pvalue vk -> from_lambda_value_kind vk
| Ptop -> Misc.fatal_error "Can't convert layout [Ptop] to flambda kind"
| Pbottom ->
Misc.fatal_error "Can't convert layout [Pbottom] to flambda kind"

include Container_types.Make (struct
type nonrec t = t
Expand Down
6 changes: 5 additions & 1 deletion middle_end/printclambda.ml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ let rec value_kind0 ppf kind =
non_consts

let value_kind kind = Format.asprintf "%a" value_kind0 kind
let layout (Lambda.Pvalue kind) = value_kind kind
let layout (layout : Lambda.layout) =
match layout with
| Pvalue kind -> value_kind kind
| Ptop -> ":top"
| Pbottom -> ":bottom"

let rec structured_constant ppf = function
| Uconst_float x -> fprintf ppf "%F" x
Expand Down
14 changes: 11 additions & 3 deletions ocaml/asmcomp/cmm_helpers.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2239,7 +2239,11 @@ let rec make_curry_apply result narity args_type args clos n =
:: args)
newclos (n - 1) )

let machtype_of_layout = function Lambda.Pvalue _ -> typ_val
let machtype_of_layout (layout : Lambda.layout) =
match layout with
| Ptop -> Misc.fatal_error "No machtype for layout [Ptop]"
| Pbottom -> Misc.fatal_error "No unique machtype for layout [Pbottom]"
| Pvalue _ -> typ_val

let final_curry_function nlocal arity result =
let last_arg = V.create_local "arg" in
Expand Down Expand Up @@ -3140,5 +3144,9 @@ let emit_preallocated_blocks preallocated_blocks cont =
let c1 = emit_gc_roots_table ~symbols cont in
List.fold_left preallocate_block c1 preallocated_blocks

let kind_of_layout (Lambda.Pvalue kind) = Vval kind

let kind_of_layout (layout : Lambda.layout) =
match layout with
| Ptop | Pbottom ->
(* This is incorrect but only used for unboxing *)
Vval Pgenval
| Pvalue kind -> Vval kind
57 changes: 45 additions & 12 deletions ocaml/asmcomp/cmmgen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -448,9 +448,19 @@ let rec transl env e =
| Ugeneric_apply(clos, args, args_layout, result_layout, kind, dbg) ->
let clos = transl env clos in
let args = List.map (transl env) args in
let args_type = List.map machtype_of_layout args_layout in
let return = machtype_of_layout result_layout in
generic_apply (mut_from_env env clos) clos args args_type return kind dbg
if List.mem Pbottom args_layout then
(* [machtype_of_layout] will fail on Pbottom, convert it to a sequence
and remove the call, preserving the execution order. *)
List.fold_left2 (fun rest arg arg_layout ->
if arg_layout = Pbottom then
arg
else
Csequence(remove_unit arg, rest)
) (Ctuple []) args args_layout
else
let args_type = List.map machtype_of_layout args_layout in
let return = machtype_of_layout result_layout in
generic_apply (mut_from_env env clos) clos args args_type return kind dbg
| Usend(kind, met, obj, args, args_layout, result_layout, pos, dbg) ->
let met = transl env met in
let obj = transl env obj in
Expand Down Expand Up @@ -731,14 +741,23 @@ and transl_catch (kind : Cmm.value_kind) env nfail ids body handler dbg =
each argument. *)
let report args =
List.iter2
(fun (_id, Pvalue kind, u) c ->
let strict =
match kind with
| Pfloatval | Pboxedintval _ -> false
| Pintval | Pgenval | Pvariant _ | Parrayval _ -> true
in
u := join_unboxed_number_kind ~strict !u
(is_unboxed_number_cmm ~strict c)
(fun (id, (layout : Lambda.layout), u) c ->
match layout with
| Ptop ->
Misc.fatal_errorf "Variable %a with layout [Ptop] can't be compiled"
VP.print id
| Pbottom ->
Misc.fatal_errorf
"Variable %a with layout [Pbottom] can't be compiled"
VP.print id
| Pvalue kind ->
let strict =
match kind with
| Pfloatval | Pboxedintval _ -> false
| Pintval | Pgenval | Pvariant _ | Parrayval _ -> true
in
u := join_unboxed_number_kind ~strict !u
(is_unboxed_number_cmm ~strict c)
)
ids args
in
Expand Down Expand Up @@ -1181,7 +1200,7 @@ and transl_unbox_sized size dbg env exp =
| Thirty_two -> transl_unbox_int dbg env Pint32 exp
| Sixty_four -> transl_unbox_int dbg env Pint64 exp

and transl_let env str (Pvalue kind : Lambda.layout) id exp transl_body =
and transl_let_value env str (kind : Lambda.value_kind) id exp transl_body =
let dbg = Debuginfo.none in
let cexp = transl env exp in
let unboxing =
Expand Down Expand Up @@ -1233,6 +1252,20 @@ and transl_let env str (Pvalue kind : Lambda.layout) id exp transl_body =
| Mutable, bn -> Clet_mut (v, typ_of_boxed_number bn, cexp, body)
end

and transl_let env str (layout : Lambda.layout) id exp transl_body =
match layout with
| Ptop ->
Misc.fatal_errorf "Variable %a with layout [Ptop] can't be compiled"
VP.print id
| Pbottom ->
let cexp = transl env exp in
(* N.B. [body] must still be traversed even if [exp] will never return:
there may be constant closures inside that need lifting out. *)
let _cbody : expression = transl_body env in
cexp
| Pvalue kind ->
transl_let_value env str kind id exp transl_body

and make_catch (kind : Cmm.value_kind) ncatch body handler dbg = match body with
| Cexit (nexit,[]) when nexit=ncatch -> handler
| _ -> ccatch (ncatch, [], body, handler, dbg, kind)
Expand Down
31 changes: 24 additions & 7 deletions ocaml/lambda/lambda.ml
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,9 @@ and value_kind =
| Parrayval of array_kind

and layout =
| Ptop
| Pvalue of value_kind
| Pbottom

and block_shape =
value_kind list option
Expand Down Expand Up @@ -316,14 +318,30 @@ let rec equal_value_kind x y =
| (Pgenval | Pfloatval | Pboxedintval _ | Pintval | Pvariant _
| Parrayval _), _ -> false

let equal_layout (Pvalue x) (Pvalue y) = equal_value_kind x y
let equal_layout x y =
match x, y with
| Pvalue x, Pvalue y -> equal_value_kind x y
| Ptop, Ptop -> true
| Pbottom, Pbottom -> true
| _, _ -> false

let compatible_layout (Pvalue _) (Pvalue _) = true
let compatible_layout x y =
match x, y with
| Pbottom, _
| _, Pbottom -> true
| Pvalue _, Pvalue _ -> true
| Ptop, Ptop -> true
| Ptop, _ | _, Ptop -> false

let must_be_value layout =
match layout with
| Pvalue v -> v
(* | _ -> Misc.fatal_error "Layout is not a value" *)
| Pbottom ->
(* Here, we want to get the [value_kind] corresponding to
a [Pbottom] layout. Anything will do, we return [Pgenval]
as a default. *)
Pgenval
| _ -> Misc.fatal_error "Layout is not a value"

type structured_constant =
Const_base of constant
Expand Down Expand Up @@ -601,10 +619,9 @@ let layout_lazy_contents = Pvalue Pgenval
let layout_any_value = Pvalue Pgenval
let layout_letrec = layout_any_value

let layout_top = Pvalue Pgenval
let layout_bottom =
(* CR pchambart: this should be an actual bottom *)
Pvalue Pgenval
(* CR ncourant: use [Ptop] or remove this as soon as possible. *)
let layout_top = layout_any_value
let layout_bottom = Pbottom

let default_function_attribute = {
inline = Default_inline;
Expand Down
2 changes: 2 additions & 0 deletions ocaml/lambda/lambda.mli
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,9 @@ and value_kind =
| Parrayval of array_kind

and layout =
| Ptop
| Pvalue of value_kind
| Pbottom

and block_shape =
value_kind list option
Expand Down
8 changes: 7 additions & 1 deletion ocaml/lambda/printlambda.ml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,11 @@ and value_kind' ppf = function
| Pvariant { consts; non_consts; } ->
variant_kind value_kind' ppf ~consts ~non_consts

let layout ppf (Pvalue k) = value_kind ppf k
let layout ppf layout =
match layout with
| Pvalue k -> value_kind ppf k
| Ptop -> fprintf ppf "[top]"
| Pbottom -> fprintf ppf "[bottom]"

let return_kind ppf (mode, kind) =
let smode = alloc_mode mode in
Expand All @@ -109,6 +113,8 @@ let return_kind ppf (mode, kind) =
| Pvalue (Pboxedintval bi) -> fprintf ppf ": %s%s@ " smode (boxed_integer_name bi)
| Pvalue (Pvariant { consts; non_consts; }) ->
variant_kind value_kind' ppf ~consts ~non_consts
| Ptop -> fprintf ppf ": top@ "
| Pbottom -> fprintf ppf ": bottom@ "

let field_kind ppf = function
| Pgenval -> pp_print_string ppf "*"
Expand Down
2 changes: 2 additions & 0 deletions ocaml/middle_end/clambda_primitives.ml
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,9 @@ and value_kind = Lambda.value_kind =
| Parrayval of array_kind

and layout = Lambda.layout =
| Ptop
| Pvalue of value_kind
| Pbottom

and block_shape = Lambda.block_shape
and boxed_integer = Primitive.boxed_integer =
Expand Down
Loading

0 comments on commit 4e08295

Please sign in to comment.