aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2016-11-12 12:31:31 +0100
committerBjörn Gustavsson <[email protected]>2016-11-18 11:58:35 +0100
commit4c76ea1116faa3efd797c39539131b9262b6fa36 (patch)
tree1721afd97adbe9fd48d092e9200a09d9b0e1cc53 /lib
parent9f3c69458c1258c21e44c35d487eceb2394fab74 (diff)
downloadotp-4c76ea1116faa3efd797c39539131b9262b6fa36.tar.gz
otp-4c76ea1116faa3efd797c39539131b9262b6fa36.tar.bz2
otp-4c76ea1116faa3efd797c39539131b9262b6fa36.zip
beam_dead: Remove redundant 'or' instruction
In practice, this optimization will only apply to contrived guards that are almost never used in real applications. The only reason we add this optimization is to help approach the goal of zero tolerance for 'bif' instructions instead of 'test' instructions in guards.
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/src/beam_dead.erl10
1 files changed, 10 insertions, 0 deletions
diff --git a/lib/compiler/src/beam_dead.erl b/lib/compiler/src/beam_dead.erl
index 8ea949425e..9087586b58 100644
--- a/lib/compiler/src/beam_dead.erl
+++ b/lib/compiler/src/beam_dead.erl
@@ -379,6 +379,14 @@ backward([{kill,_}=I|Is], D, [{line,_},Exit|_]=Acc) ->
false -> backward(Is, D, [I|Acc]);
true -> backward(Is, D, Acc)
end;
+backward([{bif,'or',{f,To0},[Dst,{atom,false}],Dst}=I|Is], D,
+ [{test,is_eq_exact,{f,To},[Dst,{atom,true}]}|_]=Acc) ->
+ case shortcut_label(To0, D) of
+ To ->
+ backward(Is, D, Acc);
+ _ ->
+ backward(Is, D, [I|Acc])
+ end;
backward([I|Is], D, Acc) ->
backward(Is, D, [I|Acc]);
backward([], _D, Acc) -> Acc.
@@ -397,6 +405,8 @@ shortcut_select_list([Lit,{f,To0}|T], Reg, D, Acc) ->
shortcut_select_list(T, Reg, D, [{f,To},Lit|Acc]);
shortcut_select_list([], _, _, Acc) -> reverse(Acc).
+shortcut_label(0, _) ->
+ 0;
shortcut_label(To0, D) ->
case beam_utils:code_at(To0, D) of
[{jump,{f,To}}|_] -> shortcut_label(To, D);