summaryrefslogtreecommitdiff
path: root/lib/compiler/src/beam_ssa_recv.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler/src/beam_ssa_recv.erl')
-rw-r--r--lib/compiler/src/beam_ssa_recv.erl52
1 files changed, 34 insertions, 18 deletions
diff --git a/lib/compiler/src/beam_ssa_recv.erl b/lib/compiler/src/beam_ssa_recv.erl
index 9d6e749fb7..f1d58ffb16 100644
--- a/lib/compiler/src/beam_ssa_recv.erl
+++ b/lib/compiler/src/beam_ssa_recv.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2018-2021. All Rights Reserved.
+%% Copyright Ericsson AB 2018-2022. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -217,25 +217,37 @@ scan_is([#b_set{op=new_try_tag,dst=Dst}], Blk, Lbl, _Blocks, FuncId, State) ->
%% ignore that branch.
#b_br{bool=Dst,succ=Succ} = Blk#b_blk.last, %Assertion.
scan_add_edge({FuncId, Lbl}, {FuncId, Succ}, State);
-scan_is([#b_set{op=call,dst=Dst,args=[#b_remote{} | _]}=Call | Is],
- Blk, Lbl, Blocks, FuncId, State0) ->
- case {Is, Blk#b_blk.last} of
- {[], #b_ret{arg=Dst}} ->
- scan_is(Is, Blk, Lbl, Blocks, FuncId, State0);
- {[#b_set{op={succeeded,body}}], #b_br{bool=Bool,succ=Succ}} ->
- #b_var{} = Bool, %Assertion.
+scan_is([#b_set{op=call,dst=Dst,args=[#b_remote{} | _]}=Call,
+ #b_set{op={succeeded,body}}],
+ #b_blk{last=#b_br{succ=Succ}}, Lbl, Blocks, FuncId, State0) ->
+ case Blocks of
+ #{ Succ := #b_blk{is=[],last=#b_ret{arg=Dst}}} ->
+ %% External tail call, ignore it altogether.
+ State0;
+ #{} ->
State = si_remote_call(Call, Lbl, Succ, Blocks, FuncId, State0),
- scan_is(Is, Blk, Lbl, Blocks, FuncId, State);
- _ ->
- State = si_remote_call(Call, Lbl, Lbl, Blocks, FuncId, State0),
- scan_is(Is, Blk, Lbl, Blocks, FuncId, State)
+ scan_add_edge({FuncId, Lbl}, {FuncId, Succ}, State)
+ end;
+scan_is([#b_set{op=call,args=[#b_remote{} | _]}=Call | Is],
+ Blk, Lbl, Blocks, FuncId, State0) ->
+ %% Remote call that always succeeds.
+ State = si_remote_call(Call, Lbl, Lbl, Blocks, FuncId, State0),
+ scan_is(Is, Blk, Lbl, Blocks, FuncId, State);
+scan_is([#b_set{op=call,dst=Dst,args=[#b_local{}=Callee | Args]},
+ #b_set{op={succeeded,body},args=[Dst]}],
+ #b_blk{last=#b_br{succ=Succ}},
+ Lbl, Blocks, FuncId, State0) ->
+ case Blocks of
+ #{ Succ := #b_blk{is=[],last=#b_ret{arg=Dst}}} ->
+ %% Local tail call, don't add any edges.
+ scan_add_call(tail, Args, Callee, Lbl, FuncId, State0);
+ #{} ->
+ State = scan_add_call(body, Args, Callee, Lbl, FuncId, State0),
+ scan_add_edge({FuncId, Lbl}, {FuncId, Succ}, State)
end;
-scan_is([#b_set{op=call,dst=Dst,args=[#b_local{}=Callee | Args]}],
- #b_blk{last=#b_ret{arg=Dst}}, Lbl, _Blocks, FuncId, State) ->
- scan_add_call(tail, Args, Callee, Lbl, FuncId, State);
-scan_is([#b_set{op=call,dst=Dst,args=[#b_local{}=Callee | Args]} | Is],
+scan_is([#b_set{op=call,args=[#b_local{}=Callee | Args]} | Is],
Blk, Lbl, Blocks, FuncId, State0) ->
- [#b_set{op={succeeded,body},args=[Dst]}] = Is, %Assertion.
+ %% Local call that always succeeds.
State = scan_add_call(body, Args, Callee, Lbl, FuncId, State0),
scan_is(Is, Blk, Lbl, Blocks, FuncId, State);
scan_is([_I | Is], Blk, Lbl, Blocks, FuncId, State) ->
@@ -894,7 +906,11 @@ coi_creations([], _Blocks, _Defs) ->
[].
make_warning(Term, Anno, Where) ->
- {File, Line} = maps:get(location, Anno, Where),
+ {File, Line} =
+ case maps:get(location, Anno, Where) of
+ {_, _} = Location -> Location;
+ _ -> {"no_file", none}
+ end,
{File,[{Line,?MODULE,Term}]}.
format_opt_info(matches_any_message) ->