From f9a323d10a9f5da305cbdec632d6bdf7ad4770b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Muska=C5=82a?= Date: Sat, 26 Aug 2017 15:15:01 +0200 Subject: Optimise equality comparisons * In both loader and compiler, make sure constants are always the second operand - many passes of the compiler assume that's always the case. * In loader rewrite is_eq_exact with same arguments to skip the instruction and with different constants move one to an x register to maintain the properly outlined above. * The same (but in reverse) is done with the is_ne_exact, where we rewrite to an unconditional jump or add a move to an x register. * All of the above allow to replace is_eq_exact_fss with is_eq_exact_fyy and is_ne_exact_fss with is_ne_exact_fSS as those are the only possibilities left. --- lib/compiler/src/beam_utils.erl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'lib/compiler/src/beam_utils.erl') diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl index 52ed1c7ca0..a4c65397df 100644 --- a/lib/compiler/src/beam_utils.erl +++ b/lib/compiler/src/beam_utils.erl @@ -32,6 +32,11 @@ -import(lists, [map/2,member/2,sort/1,reverse/1,splitwith/2]). +-define(is_const(Val), (element(1, Val) =:= integer orelse + element(1, Val) =:= float orelse + element(1, Val) =:= atom orelse + element(1, Val) =:= literal)). + %% instruction() describes all instructions that are used during optimzation %% (from beam_a to beam_z). -type instruction() :: atom() | tuple(). @@ -197,10 +202,20 @@ bif_to_test('>', [A,B], Fail) -> {test,is_lt,Fail,[B,A]}; bif_to_test('<', [_,_]=Ops, Fail) -> {test,is_lt,Fail,Ops}; bif_to_test('>=', [_,_]=Ops, Fail) -> {test,is_ge,Fail,Ops}; bif_to_test('==', [A,nil], Fail) -> {test,is_nil,Fail,[A]}; +bif_to_test('==', [nil,A], Fail) -> {test,is_nil,Fail,[A]}; +bif_to_test('==', [C,A], Fail) when ?is_const(C) -> + {test,is_eq,Fail,[A,C]}; bif_to_test('==', [_,_]=Ops, Fail) -> {test,is_eq,Fail,Ops}; +bif_to_test('/=', [C,A], Fail) when ?is_const(C) -> + {test,is_ne,Fail,[A,C]}; bif_to_test('/=', [_,_]=Ops, Fail) -> {test,is_ne,Fail,Ops}; bif_to_test('=:=', [A,nil], Fail) -> {test,is_nil,Fail,[A]}; +bif_to_test('=:=', [nil,A], Fail) -> {test,is_nil,Fail,[A]}; +bif_to_test('=:=', [C,A], Fail) when ?is_const(C) -> + {test,is_eq_exact,Fail,[A,C]}; bif_to_test('=:=', [_,_]=Ops, Fail) -> {test,is_eq_exact,Fail,Ops}; +bif_to_test('=/=', [C,A], Fail) when ?is_const(C) -> + {test,is_ne_exact,Fail,[A,C]}; bif_to_test('=/=', [_,_]=Ops, Fail) -> {test,is_ne_exact,Fail,Ops}; bif_to_test(is_record, [_,_,_]=Ops, Fail) -> {test,is_record,Fail,Ops}. -- cgit v1.2.3