diff options
author | Björn Gustavsson <[email protected]> | 2016-11-12 12:31:31 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2016-11-18 11:58:35 +0100 |
commit | 4c76ea1116faa3efd797c39539131b9262b6fa36 (patch) | |
tree | 1721afd97adbe9fd48d092e9200a09d9b0e1cc53 /lib/compiler/src | |
parent | 9f3c69458c1258c21e44c35d487eceb2394fab74 (diff) | |
download | otp-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/compiler/src')
-rw-r--r-- | lib/compiler/src/beam_dead.erl | 10 |
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); |