aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_jump.erl
diff options
context:
space:
mode:
authorMichał Muskała <[email protected]>2018-06-06 19:10:05 +0200
committerMichał Muskała <[email protected]>2018-06-08 02:57:42 +0200
commit7fed1e036b0c70aaa1e738a403379bab96745e63 (patch)
treed1f38432ad404dd195a00477a1e36b4b59171155 /lib/compiler/src/beam_jump.erl
parentcfc2b4ff4a6a2c46a3e2458eb87fd089e610783a (diff)
downloadotp-7fed1e036b0c70aaa1e738a403379bab96745e63.tar.gz
otp-7fed1e036b0c70aaa1e738a403379bab96745e63.tar.bz2
otp-7fed1e036b0c70aaa1e738a403379bab96745e63.zip
Optimise beam_jump
This is an alternative to #1832. The optimisation relies on special-casing the common pattern of "renaming" a label by direct jump to another label. The change makes beam_jump recognise couple more opportunities for optimisation. The optimisation additionally avoids superfluous list concatenations by only flattening the accumulator at the very end.
Diffstat (limited to 'lib/compiler/src/beam_jump.erl')
-rw-r--r--lib/compiler/src/beam_jump.erl21
1 files changed, 13 insertions, 8 deletions
diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl
index c33de217bd..19c26d4ef9 100644
--- a/lib/compiler/src/beam_jump.erl
+++ b/lib/compiler/src/beam_jump.erl
@@ -164,17 +164,19 @@ share(Is0) ->
share_1([{label,L}=Lbl|Is], Dict0, Lbls0, [_|_]=Seq, Acc) ->
case maps:find(Seq, Dict0) of
- error ->
- Dict = maps:put(Seq, L, Dict0),
- share_1(Is, Dict, Lbls0, [], [Lbl|Seq ++ Acc]);
- {ok,Label} ->
+ error ->
+ Dict = maps:put(Seq, L, Dict0),
+ share_1(Is, Dict, Lbls0, [], [[Lbl|Seq]|Acc]);
+ {ok,Label} ->
Lbls = maps:put(L, Label, Lbls0),
- share_1(Is, Dict0, Lbls, [], [Lbl,{jump,{f,Label}}|Acc])
+ share_1(Is, Dict0, Lbls, [], [[Lbl,{jump,{f,Label}}]|Acc])
end;
-share_1([{func_info,_,_,_}|_]=Is, _, Lbls, [], Acc) when Lbls =/= #{} ->
- beam_utils:replace_labels(Acc, Is, Lbls, fun(Old) -> Old end);
+share_1([{func_info,_,_,_}|_]=Is0, _, Lbls, [], Acc0) when Lbls =/= #{} ->
+ lists:foldl(fun(Is, Acc) ->
+ beam_utils:replace_labels(Is, Acc, Lbls, fun(Old) -> Old end)
+ end, Is0, Acc0);
share_1([{func_info,_,_,_}|_]=Is, _, Lbls, [], Acc) when Lbls =:= #{} ->
- reverse(Acc, Is);
+ lists:foldl(fun lists:reverse/2, Is, Acc);
share_1([{'catch',_,_}=I|Is], Dict0, Lbls0, Seq, Acc) ->
{Dict,Lbls} = clean_non_sharable(Dict0, Lbls0),
share_1(Is, Dict, Lbls, [I|Seq], Acc);
@@ -187,6 +189,9 @@ share_1([{try_case,_}=I|Is], Dict0, Lbls0, Seq, Acc) ->
share_1([{catch_end,_}=I|Is], Dict0, Lbls0, Seq, Acc) ->
{Dict,Lbls} = clean_non_sharable(Dict0, Lbls0),
share_1(Is, Dict, Lbls, [I|Seq], Acc);
+share_1([{jump,{f,To}}=I,{label,L}=Lbl|Is], Dict0, Lbls0, _Seq, Acc) ->
+ Lbls = maps:put(L, To, Lbls0),
+ share_1(Is, Dict0, Lbls, [], [[Lbl,I]|Acc]);
share_1([I|Is], Dict, Lbls, Seq, Acc) ->
case is_unreachable_after(I) of
false ->