Mark closure conversion as untyped

since it doesn't correctly propagate and update types. (Ideally it would, but
otherwise it would be better to remove the type annotations on the fly instead
of introducing wrong ones then cleaning them up).
This commit is contained in:
Louis Gesbert 2024-01-30 16:58:41 +01:00
parent e8e112d7f7
commit 7a4ac4364b
5 changed files with 58 additions and 27 deletions

View File

@ -238,13 +238,12 @@ module Passes = struct
Message.raise_error Message.raise_error
"Option --avoid-exceptions is not compatible with option --trace" "Option --avoid-exceptions is not compatible with option --trace"
| true, _, Untyped _ -> | true, _, Untyped _ ->
Program.untype Lcalc.From_dcalc.translate_program_without_exceptions
(Lcalc.From_dcalc.translate_program_without_exceptions (Shared_ast.Typing.program ~leave_unresolved:ErrorOnAny prg)
(Shared_ast.Typing.program ~leave_unresolved:ErrorOnAny prg))
| true, _, Typed _ -> | true, _, Typed _ ->
Lcalc.From_dcalc.translate_program_without_exceptions prg Lcalc.From_dcalc.translate_program_without_exceptions prg
| false, _, Typed _ -> | false, _, Typed _ ->
Program.untype (Lcalc.From_dcalc.translate_program_with_exceptions prg) Lcalc.From_dcalc.translate_program_with_exceptions prg
| false, _, Untyped _ -> | false, _, Untyped _ ->
Lcalc.From_dcalc.translate_program_with_exceptions Lcalc.From_dcalc.translate_program_with_exceptions
(Shared_ast.Typing.program ~leave_unresolved:ErrorOnAny prg) (Shared_ast.Typing.program ~leave_unresolved:ErrorOnAny prg)
@ -258,21 +257,21 @@ module Passes = struct
else prg else prg
in in
let prg = let prg =
if not closure_conversion then prg if not closure_conversion then (
Message.emit_debug "Retyping lambda calculus...";
Typing.program ~leave_unresolved:LeaveAny prg)
else ( else (
Message.emit_debug "Performing closure conversion..."; Message.emit_debug "Performing closure conversion...";
let prg = Lcalc.Closure_conversion.closure_conversion prg in let prg = Lcalc.Closure_conversion.closure_conversion prg in
let prg = Bindlib.unbox prg in
let prg = let prg =
if optimize then ( if optimize then (
Message.emit_debug "Optimizing lambda calculus..."; Message.emit_debug "Optimizing lambda calculus...";
Optimizations.optimize_program prg) Optimizations.optimize_program prg)
else prg else prg
in in
prg) Message.emit_debug "Retyping lambda calculus...";
Typing.program ~leave_unresolved:LeaveAny prg)
in in
Message.emit_debug "Retyping lambda calculus...";
let prg = Typing.program ~leave_unresolved:LeaveAny prg in
let prg, type_ordering = let prg, type_ordering =
if monomorphize_types then ( if monomorphize_types then (
Message.emit_debug "Monomorphizing types..."; Message.emit_debug "Monomorphizing types...";

View File

@ -124,7 +124,7 @@ let rec transform_closures_expr :
~args:new_args ~tys m ) ~args:new_args ~tys m )
| EAbs { binder; tys } -> | EAbs { binder; tys } ->
(* λ x.t *) (* λ x.t *)
let binder_mark = m in let binder_mark = Expr.with_ty m (TAny, Expr.mark_pos m) in
let binder_pos = Expr.mark_pos binder_mark in let binder_pos = Expr.mark_pos binder_mark in
(* Converting the closure. *) (* Converting the closure. *)
let vars, body = Bindlib.unmbind binder in let vars, body = Bindlib.unmbind binder in
@ -153,11 +153,11 @@ let rec transform_closures_expr :
(List.map (fun _ -> any_ty) extra_vars_list) (List.map (fun _ -> any_ty) extra_vars_list)
(List.mapi (List.mapi
(fun i _ -> (fun i _ ->
Expr.etupleaccess Expr.make_tupleaccess
~e:(Expr.evar closure_env_var binder_mark) (Expr.evar closure_env_var binder_mark)
~index:i i
~size:(List.length extra_vars_list) (List.length extra_vars_list)
binder_mark) binder_pos)
extra_vars_list) extra_vars_list)
new_body binder_pos) new_body binder_pos)
binder_pos binder_pos
@ -174,7 +174,7 @@ let rec transform_closures_expr :
Expr.make_let_in code_var Expr.make_let_in code_var
(TAny, Expr.pos e) (TAny, Expr.pos e)
new_closure new_closure
(Expr.etuple (Expr.make_tuple
((Bindlib.box_var code_var, binder_mark) ((Bindlib.box_var code_var, binder_mark)
:: [ :: [
Expr.eappop ~op:Operator.ToClosureEnv Expr.eappop ~op:Operator.ToClosureEnv
@ -243,6 +243,18 @@ let rec transform_closures_expr :
| EApp { f = e1; args; tys } -> | EApp { f = e1; args; tys } ->
let free_vars, new_e1 = (transform_closures_expr ctx) e1 in let free_vars, new_e1 = (transform_closures_expr ctx) e1 in
let code_env_var = Var.make "code_and_env" in let code_env_var = Var.make "code_and_env" in
let code_env_expr =
let pos = Expr.pos e1 in
Expr.evar code_env_var
(Expr.with_ty (Mark.get e1)
( TTuple
[
( TArrow ((TClosureEnv, pos) :: tys, (TAny, Expr.pos e)),
Expr.pos e );
TClosureEnv, pos;
],
pos ))
in
let env_var = Var.make "env" in let env_var = Var.make "env" in
let code_var = Var.make "code" in let code_var = Var.make "code" in
let free_vars, new_args = let free_vars, new_args =
@ -254,16 +266,13 @@ let rec transform_closures_expr :
in in
let call_expr = let call_expr =
let m1 = Mark.get e1 in let m1 = Mark.get e1 in
let pos = Expr.mark_pos m in
let env_arg_ty = TClosureEnv, Expr.pos e1 in let env_arg_ty = TClosureEnv, Expr.pos e1 in
Expr.make_multiple_let_in [| code_var; env_var |] let fun_ty = TArrow (env_arg_ty :: tys, (TAny, Expr.pos e)), Expr.pos e in
[TArrow (env_arg_ty :: tys, (TAny, Expr.pos e)), Expr.pos e; env_arg_ty] Expr.make_multiple_let_in [| code_var; env_var |] [fun_ty; env_arg_ty]
[ [
Expr.etupleaccess Expr.make_tupleaccess code_env_expr 0 2 pos;
~e:(Bindlib.box_var code_env_var, m1) Expr.make_tupleaccess code_env_expr 1 2 pos;
~index:0 ~size:2 m;
Expr.etupleaccess
~e:(Bindlib.box_var code_env_var, m1)
~index:1 ~size:2 m;
] ]
(Expr.eapp (Expr.eapp
~f:(Bindlib.box_var code_var, m1) ~f:(Bindlib.box_var code_var, m1)
@ -653,6 +662,9 @@ let hoist_closures_program (p : 'm program) : 'm program Bindlib.box =
(** {1 Closure conversion}*) (** {1 Closure conversion}*)
let closure_conversion (p : 'm program) : 'm program Bindlib.box = let closure_conversion (p : 'm program) : untyped program =
let new_p = transform_closures_program p in let new_p = transform_closures_program p in
hoist_closures_program (Bindlib.unbox new_p) let new_p = hoist_closures_program (Bindlib.unbox new_p) in
(* FIXME: either fix the types of the marks, or remove the types annotations
during the main processing (rather than requiring a new traversal) *)
Program.untype (Bindlib.unbox new_p)

View File

@ -21,4 +21,4 @@
After closure conversion, closure hoisting is perform and all closures end After closure conversion, closure hoisting is perform and all closures end
up as toplevel definitions. *) up as toplevel definitions. *)
val closure_conversion : 'm Ast.program -> 'm Ast.program Bindlib.box val closure_conversion : 'm Ast.program -> Shared_ast.untyped Ast.program

View File

@ -933,6 +933,23 @@ let make_tuple el m0 =
in in
etuple el m etuple el m
let make_tupleaccess e index size pos =
let m =
map_mark
(fun _ -> pos)
(function
| TTuple tl, _ -> (
try List.nth tl index
with Failure _ ->
Message.raise_internal_error "Trying to build invalid tuple access")
| TAny, pos -> TAny, pos
| ty ->
Message.raise_internal_error "Unexpected non-tuple type annotation %a"
Print.typ_debug ty)
(Mark.get e)
in
etupleaccess ~e ~index ~size m
let make_app f args tys pos = let make_app f args tys pos =
let mark = let mark =
fold_marks fold_marks

View File

@ -366,6 +366,9 @@ val make_tuple :
(** Builds a tuple; the mark argument is only used as witness and for position (** Builds a tuple; the mark argument is only used as witness and for position
when building 0-uples *) when building 0-uples *)
val make_tupleaccess :
('a any, 'm) boxed_gexpr -> int -> int -> Pos.t -> ('a, 'm) boxed_gexpr
(** {2 Transformations} *) (** {2 Transformations} *)
val skip_wrappers : ('a, 'm) gexpr -> ('a, 'm) gexpr val skip_wrappers : ('a, 'm) gexpr -> ('a, 'm) gexpr