Optimize single variable closure envs
This commit is contained in:
parent
26b7c5bf12
commit
4c872c4690
@ -740,19 +740,35 @@ lambda_lift(FCode = #{ functions := Funs }) ->
|
|||||||
init_lambda_funs() -> put(?lambda_key, #{}).
|
init_lambda_funs() -> put(?lambda_key, #{}).
|
||||||
get_lambda_funs() -> erase(?lambda_key).
|
get_lambda_funs() -> erase(?lambda_key).
|
||||||
|
|
||||||
add_lambda_fun(Name, Def) ->
|
add_lambda_fun(Def) ->
|
||||||
|
Name = fresh_fun(),
|
||||||
Funs = get(?lambda_key),
|
Funs = get(?lambda_key),
|
||||||
put(?lambda_key, Funs#{ Name => Def }).
|
put(?lambda_key, Funs#{ Name => Def }),
|
||||||
|
Name.
|
||||||
|
|
||||||
lambda_lift_fun(_, Def = #{ body := Body }) ->
|
lambda_lift_fun(_, Def = #{ body := Body }) ->
|
||||||
Def#{ body := lambda_lift_expr(Body) }.
|
Def#{ body := lambda_lift_expr(Body) }.
|
||||||
|
|
||||||
|
lifted_fun([Z], Xs, Body) ->
|
||||||
|
#{ attrs => [private],
|
||||||
|
args => [{Z, any} | [{X, any} || X <- Xs]],
|
||||||
|
return => any,
|
||||||
|
body => Body };
|
||||||
|
lifted_fun(FVs, Xs, Body) ->
|
||||||
|
Z = "%env",
|
||||||
|
Proj = fun({I, Y}, E) -> {'let', Y, {proj, {var, Z}, I - 1}, E} end,
|
||||||
|
#{ attrs => [private],
|
||||||
|
args => [{Z, any} | [{X, any} || X <- Xs]],
|
||||||
|
return => any,
|
||||||
|
body => lists:foldr(Proj, Body, indexed(FVs))
|
||||||
|
}.
|
||||||
|
|
||||||
lambda_lift_expr({lam, Xs, Body}) ->
|
lambda_lift_expr({lam, Xs, Body}) ->
|
||||||
Fun = fresh_fun(),
|
|
||||||
FVs = free_vars({lam, Xs, Body}),
|
FVs = free_vars({lam, Xs, Body}),
|
||||||
Body1 = lambda_lift_expr(Body),
|
Body1 = lambda_lift_expr(Body),
|
||||||
add_lambda_fun(Fun, lifted_fun(FVs, Xs, Body1)),
|
Fun = add_lambda_fun(lifted_fun(FVs, Xs, Body1)),
|
||||||
{closure, Fun, length(Xs), {tuple, [{var, Y} || Y <- FVs]}};
|
Tup = fun([Y]) -> Y; (Ys) -> {tuple, Ys} end,
|
||||||
|
{closure, Fun, length(Xs), Tup([{var, Y} || Y <- FVs])};
|
||||||
lambda_lift_expr(Expr) ->
|
lambda_lift_expr(Expr) ->
|
||||||
case Expr of
|
case Expr of
|
||||||
{int, _} -> Expr;
|
{int, _} -> Expr;
|
||||||
@ -784,17 +800,6 @@ lambda_lift_expr(Expr) ->
|
|||||||
|
|
||||||
lambda_lift_exprs(As) -> [lambda_lift_expr(A) || A <- As].
|
lambda_lift_exprs(As) -> [lambda_lift_expr(A) || A <- As].
|
||||||
|
|
||||||
lifted_fun(FVs, Xs, Body) ->
|
|
||||||
Z = fresh_name(),
|
|
||||||
Proj = fun({I, Y}, E) -> {'let', Y, {proj, {var, Z}, I - 1}, E} end,
|
|
||||||
#{ attrs => [private],
|
|
||||||
args => [{Z, any} | [{X, any} || X <- Xs]],
|
|
||||||
return => any,
|
|
||||||
body => lists:foldr(Proj, Body, indexed(FVs))
|
|
||||||
}.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%% -- Optimisations ----------------------------------------------------------
|
%% -- Optimisations ----------------------------------------------------------
|
||||||
|
|
||||||
%% - Deadcode elimination
|
%% - Deadcode elimination
|
||||||
@ -1181,7 +1186,11 @@ pp_fexpr({proj, E, I}) ->
|
|||||||
pp_fexpr({lam, Xs, A}) ->
|
pp_fexpr({lam, Xs, A}) ->
|
||||||
pp_par([pp_fexpr({tuple, [{var, X} || X <- Xs]}), pp_text("=>"),
|
pp_par([pp_fexpr({tuple, [{var, X} || X <- Xs]}), pp_text("=>"),
|
||||||
prettypr:nest(2, pp_fexpr(A))]);
|
prettypr:nest(2, pp_fexpr(A))]);
|
||||||
pp_fexpr({closure, Fun, _Ar, {tuple, FVs}}) ->
|
pp_fexpr({closure, Fun, _Ar, ClEnv}) ->
|
||||||
|
FVs = case ClEnv of
|
||||||
|
{tuple, Xs} -> Xs;
|
||||||
|
{var, _} -> [ClEnv]
|
||||||
|
end,
|
||||||
pp_call(pp_text("__CLOSURE__"), [{def, Fun} | FVs]);
|
pp_call(pp_text("__CLOSURE__"), [{def, Fun} | FVs]);
|
||||||
pp_fexpr({set_proj, E, I, A}) ->
|
pp_fexpr({set_proj, E, I, A}) ->
|
||||||
pp_beside(pp_fexpr(E), pp_braces(pp_beside([pp_text(I), pp_text(" = "), pp_fexpr(A)])));
|
pp_beside(pp_fexpr(E), pp_braces(pp_beside([pp_text(I), pp_text(" = "), pp_fexpr(A)])));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user