aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_ssa_dead.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-05-18 08:01:02 +0200
committerBjörn Gustavsson <[email protected]>2019-05-20 14:31:04 +0200
commit57ca436f4ef42b55b5b0ab4c1abd73935c6d6cd1 (patch)
treee053c951944e1e5c82fabaa403aeb94c9da71753 /lib/compiler/src/beam_ssa_dead.erl
parentfe2b1323a3866ed0a9712e9d12e1f8f84793ec47 (diff)
downloadotp-57ca436f4ef42b55b5b0ab4c1abd73935c6d6cd1.tar.gz
otp-57ca436f4ef42b55b5b0ab4c1abd73935c6d6cd1.tar.bz2
otp-57ca436f4ef42b55b5b0ab4c1abd73935c6d6cd1.zip
Improve optimization of redundant tests
The `beam_ssa_dead` pass is supposed to eliminate tests that are determined to be redundant based on the outcome of a previous test. For example, in the following example that repeats a guard test, the second clause can never be executed: foo(A) when A >= 42 -> one; foo(A) when A >= 42 -> two; foo(_) -> three. `beam_ssa_dead` should have eliminated the second clause, but didn't: {test,is_ge,{f,5},[{x,0},{integer,42}]}. {move,{atom,one},{x,0}}. return. {label,5}. {test,is_ge,{f,6},[{x,0},{integer,42}]}. {move,{atom,two},{x,0}}. return. {label,6}. {move,{atom,three},{x,0}}. return. Correct the optimization of four different combinations of relational operations that were too conservate. To ensure the correctness of the optimization, also add an exahaustive test of all combinations of relational operations with one variable and one literal. (Also remove the weak and now redundant coverage tests in `beam_ssa_SUITE`.) With this correction, the following code will be generated for the example: {test,is_ge,{f,5},[{x,0},{integer,42}]}. {move,{atom,one},{x,0}}. return. {label,5}. {move,{atom,three},{x,0}}. return. Thanks to Dániel Szoboszlay (@dszoboszlay), whose talk at Code BEAM STO 2019 made me aware of this missed opportunity for optimization.
Diffstat (limited to 'lib/compiler/src/beam_ssa_dead.erl')
-rw-r--r--lib/compiler/src/beam_ssa_dead.erl8
1 files changed, 4 insertions, 4 deletions
diff --git a/lib/compiler/src/beam_ssa_dead.erl b/lib/compiler/src/beam_ssa_dead.erl
index bb43a550ae..423bc88c3b 100644
--- a/lib/compiler/src/beam_ssa_dead.erl
+++ b/lib/compiler/src/beam_ssa_dead.erl
@@ -719,8 +719,8 @@ will_succeed_1('=/=', A, '=:=', B) when A =:= B -> no;
will_succeed_1('<', A, '=:=', B) when B >= A -> no;
will_succeed_1('<', A, '=/=', B) when B >= A -> yes;
will_succeed_1('<', A, '<', B) when B >= A -> yes;
-will_succeed_1('<', A, '=<', B) when B > A -> yes;
-will_succeed_1('<', A, '>=', B) when B > A -> no;
+will_succeed_1('<', A, '=<', B) when B >= A -> yes;
+will_succeed_1('<', A, '>=', B) when B >= A -> no;
will_succeed_1('<', A, '>', B) when B >= A -> no;
will_succeed_1('=<', A, '=:=', B) when B > A -> no;
@@ -740,9 +740,9 @@ will_succeed_1('>=', A, '>', B) when B < A -> yes;
will_succeed_1('>', A, '=:=', B) when B =< A -> no;
will_succeed_1('>', A, '=/=', B) when B =< A -> yes;
will_succeed_1('>', A, '<', B) when B =< A -> no;
-will_succeed_1('>', A, '=<', B) when B < A -> no;
+will_succeed_1('>', A, '=<', B) when B =< A -> no;
will_succeed_1('>', A, '>=', B) when B =< A -> yes;
-will_succeed_1('>', A, '>', B) when B < A -> yes;
+will_succeed_1('>', A, '>', B) when B =< A -> yes;
will_succeed_1('==', A, '==', B) ->
if