diff options
author | Björn Gustavsson <[email protected]> | 2015-01-11 15:05:05 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2015-03-09 09:59:37 +0100 |
commit | e72e049f25dc001111a6a98ea95a3e7bc3c53c1b (patch) | |
tree | 47d4d712d97716e1e47667bfd61ab7cd2d9de1d4 /lib/compiler/src | |
parent | 8997433288cb571f155c509f402d0ba4fdba5025 (diff) | |
download | otp-e72e049f25dc001111a6a98ea95a3e7bc3c53c1b.tar.gz otp-e72e049f25dc001111a6a98ea95a3e7bc3c53c1b.tar.bz2 otp-e72e049f25dc001111a6a98ea95a3e7bc3c53c1b.zip |
beam_peep: Optimize away redundant use of is_boolean tests
Diffstat (limited to 'lib/compiler/src')
-rw-r--r-- | lib/compiler/src/beam_peep.erl | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/lib/compiler/src/beam_peep.erl b/lib/compiler/src/beam_peep.erl index 97a8c7ba70..5abacc8d5d 100644 --- a/lib/compiler/src/beam_peep.erl +++ b/lib/compiler/src/beam_peep.erl @@ -108,14 +108,14 @@ peep([{test,Op,_,Ops}=I|Is], SeenTests0, Acc) -> %% has succeeded. peep(Is, gb_sets:empty(), [I|Acc]); true -> - Test = {Op,Ops}, - case gb_sets:is_element(Test, SeenTests0) of + case is_test_redundant(Op, Ops, SeenTests0) of true -> - %% This test has already succeeded and + %% This test or a similar test has already succeeded and %% is therefore redundant. peep(Is, SeenTests0, Acc); false -> %% Remember that we have seen this test. + Test = {Op,Ops}, SeenTests = gb_sets:insert(Test, SeenTests0), peep(Is, SeenTests, [I|Acc]) end @@ -136,6 +136,15 @@ peep([I|Is], _, Acc) -> peep(Is, gb_sets:empty(), [I|Acc]); peep([], _, Acc) -> reverse(Acc). +is_test_redundant(Op, Ops, Seen) -> + gb_sets:is_element({Op,Ops}, Seen) orelse + is_test_redundant_1(Op, Ops, Seen). + +is_test_redundant_1(is_boolean, [R], Seen) -> + gb_sets:is_element({is_eq_exact,[R,{atom,false}]}, Seen) orelse + gb_sets:is_element({is_eq_exact,[R,{atom,true}]}, Seen); +is_test_redundant_1(_, _, _) -> false. + kill_seen(Dst, Seen0) -> gb_sets:from_ordset(kill_seen_1(gb_sets:to_list(Seen0), Dst)). |