aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2015-02-03 18:08:13 +0100
committerBjörn Gustavsson <[email protected]>2015-03-09 09:59:36 +0100
commit5e07cf899d657a787e7d4f32c1ad7f44037a011f (patch)
treec222e4a1826c3eb9dff751617f6a390badbf721f
parent5a6c78379cbbdf945d78a6b9d3c2c8d37db71607 (diff)
downloadotp-5e07cf899d657a787e7d4f32c1ad7f44037a011f.tar.gz
otp-5e07cf899d657a787e7d4f32c1ad7f44037a011f.tar.bz2
otp-5e07cf899d657a787e7d4f32c1ad7f44037a011f.zip
Replace '==' with '=:=' when both operands are integers
'=:=' is a cheaper operation than '==', so we should always use '=:=' if the result will be the same as if '==' were used.
-rw-r--r--lib/compiler/src/sys_core_fold.erl22
1 files changed, 14 insertions, 8 deletions
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index 570b943a40..b9ce6476c3 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -829,16 +829,16 @@ eval_rel_op(Call, '=:=', [Term,#c_literal{val=true}], Sub) ->
maybe -> Call;
no -> #c_literal{val=false}
end;
-eval_rel_op(Call, '==', Ops, _Sub) ->
- case is_exact_eq_ok(Ops) of
+eval_rel_op(Call, '==', Ops, Sub) ->
+ case is_exact_eq_ok(Ops, Sub) of
true ->
Name = #c_literal{anno=cerl:get_ann(Call),val='=:='},
Call#c_call{name=Name};
false ->
Call
end;
-eval_rel_op(Call, '/=', Ops, _Sub) ->
- case is_exact_eq_ok(Ops) of
+eval_rel_op(Call, '/=', Ops, Sub) ->
+ case is_exact_eq_ok(Ops, Sub) of
true ->
Name = #c_literal{anno=cerl:get_ann(Call),val='=/='},
Call#c_call{name=Name};
@@ -847,11 +847,17 @@ eval_rel_op(Call, '/=', Ops, _Sub) ->
end;
eval_rel_op(Call, _, _, _) -> Call.
-is_exact_eq_ok([#c_literal{val=Lit}|_]) ->
+is_exact_eq_ok([A,B]=L, Sub) ->
+ case is_int_type(A, Sub) =:= yes andalso is_int_type(B, Sub) =:= yes of
+ true -> true;
+ false -> is_exact_eq_ok_1(L)
+ end.
+
+is_exact_eq_ok_1([#c_literal{val=Lit}|_]) ->
is_non_numeric(Lit);
-is_exact_eq_ok([_|T]) ->
- is_exact_eq_ok(T);
-is_exact_eq_ok([]) -> false.
+is_exact_eq_ok_1([_|T]) ->
+ is_exact_eq_ok_1(T);
+is_exact_eq_ok_1([]) -> false.
is_non_numeric([H|T]) ->
is_non_numeric(H) andalso is_non_numeric(T);