Simplify variables bindings in environment

This commit is contained in:
Ulf Norell 2019-04-08 13:28:41 +02:00
parent 66413ae7fe
commit 961af8ba93

View File

@ -43,7 +43,7 @@
Op =:= 'OR' orelse Op =:= 'OR' orelse
Op =:= 'ELEMENT')). Op =:= 'ELEMENT')).
-record(env, { args = [], stack = [], locals = [], tailpos = true }). -record(env, { vars = [], locals = [], tailpos = true }).
%% -- Debugging -------------------------------------------------------------- %% -- Debugging --------------------------------------------------------------
@ -95,22 +95,25 @@ function_to_scode(Name, Args, Body, ResType, Options) ->
%% -- Environment functions -- %% -- Environment functions --
init_env(Args) -> init_env(Args) ->
#env{ args = Args, stack = [], tailpos = true }. #env{ vars = [ {X, {arg, I}} || {I, {X, _}} <- with_ixs(Args) ],
tailpos = true }.
push_env(Type, Env) -> next_var(#env{ vars = Vars }) ->
Env#env{ stack = [Type | Env#env.stack] }. 1 + lists:max([-1 | [J || {_, {var, J}} <- Vars]]).
bind_local(Name, Env = #env{ locals = Locals }) -> bind_var(Name, Var, Env = #env{ vars = Vars }) ->
I = length(Locals), Env#env{ vars = [{Name, Var} | Vars] }.
{I, Env#env{ locals = [{Name, I} | Locals] }}.
bind_local(Name, Env) ->
I = next_var(Env),
{I, bind_var(Name, {var, I}, Env)}.
notail(Env) -> Env#env{ tailpos = false }. notail(Env) -> Env#env{ tailpos = false }.
lookup_var(Env = #env{ args = Args, locals = Locals }, X) -> lookup_var(Env = #env{ vars = Vars }, X) ->
case {lists:keyfind(X, 1, Locals), keyfind_index(X, 1, Args)} of case lists:keyfind(X, 1, Vars) of
{false, false} -> error({unbound_variable, X, Env}); false -> error({unbound_variable, X, Env});
{false, Arg} -> {arg, Arg}; {_, Var} -> Var
{{_, Local}, _} -> {var, Local}
end. end.
%% -- The compiler -- %% -- The compiler --
@ -129,9 +132,9 @@ to_scode(Env, {tuple, As}) ->
[[ to_scode(Env, A) || A <- As ], [[ to_scode(Env, A) || A <- As ],
aeb_fate_code:tuple(N)]; aeb_fate_code:tuple(N)];
to_scode(Env, {binop, Type, Op, A, B}) -> to_scode(Env, {binop, _Type, Op, A, B}) ->
[ to_scode(notail(Env), B), [ to_scode(notail(Env), B),
to_scode(push_env(Type, Env), A), to_scode(Env, A),
binop_to_scode(Op) ]; binop_to_scode(Op) ];
to_scode(Env, {'if', Dec, Then, Else}) -> to_scode(Env, {'if', Dec, Then, Else}) ->
@ -181,10 +184,8 @@ split_to_scode(_, Split = {split, _, _, _}) ->
catchall_to_scode(Env, X, Alts) -> catchall_to_scode(Env, X, Alts, []). catchall_to_scode(Env, X, Alts) -> catchall_to_scode(Env, X, Alts, []).
catchall_to_scode(Env, X, [{'case', {var, Y}, Split} | _], Acc) -> catchall_to_scode(Env, X, [{'case', {var, Y}, Split} | _], Acc) ->
I = lookup_var(Env, X), Env1 = bind_var(Y, lookup_var(Env, X), Env),
{J, Env1} = bind_local(Y, Env), {split_to_scode(Env1, Split), lists:reverse(Acc)};
{[aeb_fate_code:store({var, J}, I),
split_to_scode(Env1, Split)], lists:reverse(Acc)};
catchall_to_scode(Env, X, [Alt | Alts], Acc) -> catchall_to_scode(Env, X, [Alt | Alts], Acc) ->
catchall_to_scode(Env, X, Alts, [Alt | Acc]); catchall_to_scode(Env, X, Alts, [Alt | Acc]);
catchall_to_scode(_, _, [], Acc) -> {missing, lists:reverse(Acc)}. catchall_to_scode(_, _, [], Acc) -> {missing, lists:reverse(Acc)}.
@ -658,6 +659,8 @@ r_write_to_dead_var({Ann, {'STORE', R = {var, _}, A}}, Code) when A /= ?a ->
false -> false ->
case Code of case Code of
[] -> {[], []}; [] -> {[], []};
[switch_body, {Ann1, I} | Code1] ->
{[], [switch_body, {merge_ann(Ann, Ann1), I} | Code1]};
[{Ann1, I} | Code1] -> [{Ann1, I} | Code1] ->
{[], [{merge_ann(Ann, Ann1), I} | Code1]} {[], [{merge_ann(Ann, Ann1), I} | Code1]}
end; end;
@ -710,7 +713,6 @@ to_basic_blocks(Funs, Options) ->
|| {Name, {{Args, Res}, Code}} <- maps:to_list(Funs) ]). || {Name, {{Args, Res}, Code}} <- maps:to_list(Funs) ]).
bb(_Name, Code, _Options) -> bb(_Name, Code, _Options) ->
io:format("Code = ~p\n", [Code]),
Blocks0 = blocks(Code), Blocks0 = blocks(Code),
Blocks = optimize_blocks(Blocks0), Blocks = optimize_blocks(Blocks0),
Labels = maps:from_list([ {Ref, I} || {I, {Ref, _}} <- with_ixs(Blocks) ]), Labels = maps:from_list([ {Ref, I} || {I, {Ref, _}} <- with_ixs(Blocks) ]),