Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorng committed Nov 14, 2024
1 parent 9d985f5 commit 715d605
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 23 deletions.
37 changes: 22 additions & 15 deletions lib/compiler/src/beam_ssa_opt.erl
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,9 @@ ssa_opt_linearize({#opt_st{ssa=Blocks}=St, FuncDb}) ->
{St#opt_st{ssa=beam_ssa:linearize(Blocks)}, FuncDb}.

ssa_opt_type_continue({#opt_st{ssa=Linear0,args=Args,anno=Anno}=St0, FuncDb0}) ->
io:format("~p\n", [Linear0]),
{Linear, FuncDb} = beam_ssa_type:opt_continue(Linear0, Args, Anno, FuncDb0),
io:format("~p\n", [Linear]),
{St0#opt_st{ssa=Linear}, FuncDb}.

ssa_opt_type_finish({#opt_st{args=Args,anno=Anno0}=St0, FuncDb0}) ->
Expand Down Expand Up @@ -1853,8 +1855,8 @@ do_reduce_try([{L, Blk} | Bs]=Bs0, Ws0) ->
end;
true ->
Ws1 = sets:del_element(L, Ws0),
#b_blk{is=Is0} = Blk,
case reduce_try_is(Is0, []) of
#b_blk{is=Is0,last=Last} = Blk,
case reduce_try_is(Is0, Last, []) of
{safe,Is} ->
%% This block does not execute any instructions
%% that would require a try. Analyze successors.
Expand All @@ -1877,25 +1879,26 @@ do_reduce_try([], Ws) ->
true = sets:is_empty(Ws), %Assertion.
[].

reduce_try_is([#b_set{op=kill_try_tag}|Is], Acc) ->
reduce_try_is([#b_set{op=kill_try_tag}|Is], _Last, Acc) ->
%% Remove this kill_try_tag instruction. If there was a landingpad
%% instruction in this block, it has already been removed. Preserve
%% all other instructions in the block.
{done,reverse(Acc, Is)};
reduce_try_is([#b_set{op=extract}|_], _Acc) ->
reduce_try_is([#b_set{op=extract}|_], _Last, _Acc) ->
%% The error reason is accessed.
unsafe;
reduce_try_is([#b_set{op=landingpad}|Is], Acc) ->
reduce_try_is(Is, Acc);
reduce_try_is([#b_set{op={succeeded,body}}=I0|Is], Acc) ->
reduce_try_is([#b_set{op=landingpad}|Is], Last, Acc) ->
reduce_try_is(Is, Last, Acc);
reduce_try_is([#b_set{op={succeeded,body}}=I0|Is], Last, Acc) ->
%% If we reached this point, it means that the previous instruction
%% has no side effects. We must now convert the flavor of the
%% succeeded to the `guard`, since the try/catch will be removed.
I = I0#b_set{op={succeeded,guard}},
reduce_try_is(Is, [I|Acc]);
reduce_try_is(Is, Last, [I|Acc]);
reduce_try_is([#b_set{anno=Anno,op=call,args=[#b_remote{mod=#b_literal{val=M},
name=#b_literal{val=F},
arity=A}=R0|Args0]}=I0|Is],
Last,
Acc) ->
%% Rewrite binary_to_(existing_)atom/1 call to binary_to_(existing_)atom/2.
{I1, Args1} = if {M, F, A} =:= {erlang, binary_to_atom, 1} orelse
Expand All @@ -1905,28 +1908,32 @@ reduce_try_is([#b_set{anno=Anno,op=call,args=[#b_remote{mod=#b_literal{val=M},
true -> {I0, Args0}
end,
%% Remove try-catch for bifs that can be written as guards.
io:format("~p\n", [Last]),
Unsafe = maps:get(unsafe_opt, Last#b_br.anno, false),
case beam_ssa:can_be_guard_bif(M, F, A) of
true ->
I = I1#b_set{op={bif,F},args=Args1},
reduce_try_is(Is, [I|Acc]);
false ->
reduce_try_is(Is, Last, [I|Acc]);
false when not Unsafe ->
case beam_opcodes:is_pbif(M, F, A) of
true ->
I = I0#b_set{anno=Anno#{pseudo_bif => true}},
reduce_try_is(Is, [I|Acc]);
reduce_try_is(Is, Last, [I|Acc]);
false -> unsafe
end
end;
false ->
unsafe
end;
reduce_try_is([#b_set{op=Op}=I|Is], Acc) ->
reduce_try_is([#b_set{op=Op}=I|Is], Last, Acc) ->
IsSafe = case Op of
phi -> true;
_ -> beam_ssa:no_side_effect(I)
end,
case IsSafe of
true -> reduce_try_is(Is, [I|Acc]);
true -> reduce_try_is(Is, Last, [I|Acc]);
false -> unsafe
end;
reduce_try_is([], Acc) ->
reduce_try_is([], _Last, Acc) ->
{safe,reverse(Acc)}.

%% Removes try/catch expressions whose expressions will never throw.
Expand Down
15 changes: 13 additions & 2 deletions lib/compiler/src/beam_ssa_type.erl
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,10 @@ opt_bs([{L, #b_blk{is=Is0,last=Last0}=Blk0} | Bs],
{Last2, Ls1} = update_successors(Last1, Ts, Ds, Ls0, UsedOnce),

Last = opt_anno_types(Last2, Ts),
io:format("Last1 ~p\n", [Last1]),
io:format("Last2 ~p\n", [Last2]),
io:format("Last ~p\n", [Last]),
io:nl(),

Ls = Ls1#{ L := {outgoing, Ts} }, %Assertion.

Expand Down Expand Up @@ -964,8 +968,15 @@ update_anno_types_1([], _, _, ArgTypes) -> ArgTypes.
%%%

simplify_terminator(#b_br{bool=Bool}=Br0, Ts, Ds, Sub) ->
Br = beam_ssa:normalize(Br0#b_br{bool=simplify_arg(Bool, Ts, Sub)}),
simplify_not(Br, Ts, Ds, Sub);
case beam_ssa:normalize(Br0#b_br{bool=simplify_arg(Bool, Ts, Sub)}) of
Br0 ->
simplify_not(Br0, Ts, Ds, Sub);
Br1 ->
Br = Br1#b_br{anno=(Br1#b_br.anno)#{unsafe_opt => true}},
Res = simplify_not(Br, Ts, Ds, Sub),
io:format("~p: ~p\n", [?LINE,Res]),
Res
end;
simplify_terminator(#b_switch{arg=Arg0,fail=Fail,list=List0}=Sw0,
Ts, Ds, Sub) ->
Arg = simplify_arg(Arg0, Ts, Sub),
Expand Down
18 changes: 12 additions & 6 deletions lib/compiler/test/bif_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -316,12 +316,18 @@ non_throwing(_Config) ->
ok.

non_throwing_pure(_Config) ->
[0] = non_throwing_pure1(<<0>>),
error = non_throwing_pure1(a),
[0] = non_throwing_pure2(<<0>>),
error = non_throwing_pure2(a),
<<0>> = non_throwing_pure3(<<0>>),
error = non_throwing_pure3(a).
[0] = non_throwing_pure1(id(<<0>>)),
error = non_throwing_pure1(id(a)),
[0] = non_throwing_pure2(id(<<0>>)),
error = non_throwing_pure2(id(a)),
<<0>> = non_throwing_pure3(id(<<0>>)),
error = non_throwing_pure3(id(a)),

try binary_to_list(a)
catch _:_ -> error
end,

ok.

non_throwing_pure1(A) ->
try binary_to_list(A)
Expand Down

0 comments on commit 715d605

Please sign in to comment.