Refactor argument inlining optimization

This commit is contained in:
Ulf Norell 2019-11-11 11:09:18 +01:00
parent d4c5c610ee
commit 35b20800c9

View File

@ -1200,38 +1200,42 @@ r_inline_store({i, _, {'STORE', R, R}}, Code) ->
r_inline_store(I = {i, _, {'STORE', R = {var, _}, A}}, Code) -> r_inline_store(I = {i, _, {'STORE', R = {var, _}, A}}, Code) ->
%% Not when A is var unless updating the annotations properly. %% Not when A is var unless updating the annotations properly.
Inline = case A of Inline = case A of
{arg, _} -> true; {arg, _} -> true;
?i(_) -> true; ?i(_) -> true;
_ -> false {store, _} -> true;
_ -> false
end, end,
if Inline -> r_inline_store([I], R, A, Code); if Inline -> r_inline_store([I], false, R, A, Code);
true -> false end; true -> false end;
r_inline_store(_, _) -> false. r_inline_store(_, _) -> false.
r_inline_store(Acc, R, A, [switch_body | Code]) -> r_inline_store(Acc, Progress, R, A, [switch_body | Code]) ->
r_inline_store([switch_body | Acc], R, A, Code); r_inline_store([switch_body | Acc], Progress, R, A, Code);
r_inline_store(Acc, R, A, [{i, Ann, I} | Code]) -> r_inline_store(Acc, Progress, R, A, [{i, Ann, I} | Code]) ->
#{ write := W, pure := Pure } = attributes(I), #{ write := W } = attributes(I),
Inl = fun(X) when X == R -> A; (X) -> X end, Inl = fun(X) when X == R -> A; (X) -> X end,
case not live_in(R, Ann) orelse not Pure orelse lists:member(W, [R, A]) of case live_in(R, Ann) of
true -> false; false -> false; %% No more reads of R
false -> true ->
case op_view(I) of {I1, Progress1} =
{Op, S, As} -> case op_view(I) of
case lists:member(R, As) of {Op, S, As} ->
true -> case lists:member(R, As) of
Acc1 = [{i, Ann, from_op_view(Op, S, lists:map(Inl, As))} | Acc], true -> {from_op_view(Op, S, lists:map(Inl, As)), true};
case r_inline_store(Acc1, R, A, Code) of false -> {I, Progress}
false -> {lists:reverse(Acc1), Code}; end;
{_, _} = Res -> Res _ -> {I, Progress}
end; end,
false -> Acc1 = [{i, Ann, I1} | Acc],
r_inline_store([{i, Ann, I} | Acc], R, A, Code) %% Stop if write to R or A
end; case lists:member(W, [R, A]) of
_ -> r_inline_store([{i, Ann, I} | Acc], R, A, Code) true when Progress1 -> {lists:reverse(Acc1), Code};
true -> false;
false -> r_inline_store(Acc1, Progress1, R, A, Code)
end end
end; end;
r_inline_store(_Acc, _, _, _) -> false. r_inline_store(Acc, true, _, _, Code) -> {lists:reverse(Acc), Code};
r_inline_store(_, false, _, _, _) -> false.
%% Shortcut write followed by final read %% Shortcut write followed by final read
r_one_shot_var({i, Ann1, I}, [{i, Ann2, J} | Code]) -> r_one_shot_var({i, Ann1, I}, [{i, Ann2, J} | Code]) ->
@ -1254,7 +1258,7 @@ r_one_shot_var(_, _) -> false.
r_write_to_dead_var({i, _, {'STORE', ?void, ?a}}, _) -> false; %% Avoid looping r_write_to_dead_var({i, _, {'STORE', ?void, ?a}}, _) -> false; %% Avoid looping
r_write_to_dead_var({i, Ann, I}, Code) -> r_write_to_dead_var({i, Ann, I}, Code) ->
case op_view(I) of case op_view(I) of
{_Op, R = {var, _}, As} -> {_Op, R, As} when R /= ?a ->
case live_out(R, Ann) of case live_out(R, Ann) of
false -> false ->
%% Subtle: we still have to pop the stack if any of the arguments %% Subtle: we still have to pop the stack if any of the arguments