diff options
author | Björn Gustavsson <[email protected]> | 2018-11-27 16:05:23 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2019-01-14 13:36:01 +0100 |
commit | 48f20bd589fa69b79bda86731560513801ac89f0 (patch) | |
tree | 2126d1c42b2a98c9873417db5ffb282617a21af2 /erts/emulator/beam/erl_process.h | |
parent | f548ea888e4c63546160dcb68ee84a167ca38f8f (diff) | |
download | otp-48f20bd589fa69b79bda86731560513801ac89f0.tar.gz otp-48f20bd589fa69b79bda86731560513801ac89f0.tar.bz2 otp-48f20bd589fa69b79bda86731560513801ac89f0.zip |
Introduce subtraction of types
Introduce subtraction of types to allow some redundant tests to be
eliminated.
Consider this function:
foo(L) when is_list(L) ->
case L of
[_|_] -> non_empty;
[] -> empty
end.
After entering the body of the function, L is known to be either
a cons cell or nil (otherwise the is_list/1 guard would have failed).
If the L is not a cons cell, it must be nil. Therefore, the test
for nil in the second clause of the case can be eliminated.
Here is the SSA code with some additonal comments for the function
before the optimization:
function t:foo(_0) {
0:
@ssa_bool = bif:is_list _0
br @ssa_bool, label 4, label 3
4:
%% _0 is now a list (cons or nil).
@ssa_bool:8 = is_nonempty_list _0
br @ssa_bool:8, label 9, label 7
9:
ret literal non_empty
7:
%% _0 is not a cons (or we wouldn't be here).
%% Subtracting cons from the previously known type list
%% gives that _0 must be nil.
@ssa_bool:10 = bif:'=:=' _0, literal []
br @ssa_bool:10, label 11, label 6
11:
ret literal empty
6:
_6 = put_tuple literal case_clause, _0
%% t.erl:5
@ssa_ret:12 = call remote (literal erlang):(literal error)/1, _6
ret @ssa_ret:12
3:
_9 = put_list _0, literal []
%% t.erl:4
@ssa_ret:13 = call remote (literal erlang):(literal error)/2, literal function_clause, _9
ret @ssa_ret:13
}
Type subtraction gives us that _0 must be nil in block 7, allowing us to
remove the comparison of _0 with nil. The code for the function can be simplified
to:
function t:foo(_0) {
0:
@ssa_bool = bif:is_list _0
br @ssa_bool, label 4, label 3
4:
@ssa_bool:8 = is_nonempty_list _0
br @ssa_bool:8, label 9, label 11
9:
ret literal non_empty
11:
ret literal empty
3:
_9 = put_list _0, literal []
%% t.erl:4
@ssa_ret:13 = call remote (literal erlang):(literal error)/2, literal function_clause, _9
ret @ssa_ret:13
}
Diffstat (limited to 'erts/emulator/beam/erl_process.h')
0 files changed, 0 insertions, 0 deletions