Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 21 additions & 13 deletions lib/compiler/src/beam_ssa_pre_codegen.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2870,9 +2870,9 @@ reserve_call_args(Args) ->
reserve_call_args(Args, 0, #{}).

reserve_call_args([#b_var{}=Var|As], X, Xs) ->
reserve_call_args(As, X+1, Xs#{Var=>{x,X}});
reserve_call_args(As, X+1, Xs#{Var => {x,X}});
reserve_call_args([#b_literal{}|As], X, Xs) ->
reserve_call_args(As, X+1, Xs);
reserve_call_args(As, X+1, Xs#{{x,X} => hole});
reserve_call_args([], _, Xs) -> Xs.

reserve_xreg(V, Xs, Res) ->
Expand All @@ -2898,21 +2898,29 @@ reserve_xreg(V, Xs, Res) ->
%% invoking the garbage collector.

res_xregs_prune(Xs, Used, Res) when map_size(Xs) =/= 0 ->
%% The number of safe registers is the number of the X registers
%% used after this point. The actual number of safe registers may
%% be higher than this number, but this is a conservative safe
%% estimate.
NumSafe = foldl(fun(V, N) ->
case Res of
#{V:={x,_}} -> N + 1;
#{V:=_} -> N;
#{} -> N + 1
%% Calculate a conservative estimate for the number of safe
%% registers based on the used X register after this point. The
%% actual number of safe registers may be higher than this number.
NumSafe0 = foldl(fun(V, N) ->
%% Count the number of used variables
%% allocated to X registers.
case Res of
#{V := {x,_}} -> N + 1;
#{V := _} -> N;
#{} -> N + 1
end
end, 0, Used),
NumSafe = foldl(fun(X, N) ->
%% Decrement the count if there are holes.
case Xs of
#{{x,X} := hole} -> N - 1;
#{} -> N
end
end, 0, Used),
end, NumSafe0, seq(0, NumSafe0-1)),

%% Remove unsafe registers from the list of potential
%% preferred registers.
maps:filter(fun(_, {x,X}) -> X < NumSafe end, Xs);
#{Var => Reg || Var := {x,X}=Reg <- Xs, X < NumSafe};
res_xregs_prune(Xs, _Used, _Res) -> Xs.

%%%
Expand Down
16 changes: 16 additions & 0 deletions lib/compiler/test/beam_ssa_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,9 @@ grab_bag(_Config) ->

{'EXIT',{if_clause,[_|_]}} = catch grab_bag_20(),

6 = grab_bag_21(id(64)),
{'EXIT',{badarith,_}} = catch grab_bag_21(id(a)),

ok.

grab_bag_1() ->
Expand Down Expand Up @@ -1164,6 +1167,19 @@ grab_bag_20() ->
error
end}.

%% With the `no_copt` and `no_ssa_opt` options, an internal
%% consistency error would be reported:
%%
%% Internal consistency check failed - please report this bug.
%% Instruction: {test_heap,2,2}
%% Error: {{x,0},not_live}:
grab_bag_21(A) ->
_ = id(0),
grab_bag_21(ok, A div 10, node(), [-1]).

grab_bag_21(_, D, _, _) ->
D.

redundant_br(_Config) ->
{false,{x,y,z}} = redundant_br_1(id({x,y,z})),
{true,[[a,b,c]]} = redundant_br_1(id([[[a,b,c]]])),
Expand Down