diff options
author | Björn Gustavsson <[email protected]> | 2014-12-08 12:33:12 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2015-01-09 13:18:44 +0100 |
commit | 7b10ff77235532923558a30759ed9b5fe6d994a5 (patch) | |
tree | 98bdf359c9df1f077335dfe16ca7c621cc5a3777 /lib/compiler/src/erl_bifs.erl | |
parent | 4f7edc376ee61238699f68c8721ab23ee56eafee (diff) | |
download | otp-7b10ff77235532923558a30759ed9b5fe6d994a5.tar.gz otp-7b10ff77235532923558a30759ed9b5fe6d994a5.tar.bz2 otp-7b10ff77235532923558a30759ed9b5fe6d994a5.zip |
beam_dead: Optimize branches from relational conditionals
The BEAM compiler translates code such as:
is_hex_digit(D) when $0 =< D, D =< $9 -> true;
is_hex_digit(D) when $a =< D, D =< $z -> true;
is_hex_digit(D) when $A =< D, D =< $Z -> true;
is_hex_digit(_) -> false.
to something like this:
L0: test is_ge L1 {x,0} 48
test is_ge L1 57 {x,0}
move true {x,0}
return.
L1: test is_ge L2 {x,0} 97
test is_ge L2 122 {x,0}
move true {x,0}
return
L2: test is_ge L3 {x,0} 65
test is_ge L3 90 {x,0}
move true {x,0}
return
L3: move false {x,0}
return
We can see that tests will be repeated even if they cannot possibly
succeed. For instance, if we pass in {x,0} equal to 32, the first
test that {x,0} is greater than or equal to 48 at L0 will fail.
The control will transfer to L1, where it will be tested whether
{x,0} is greater than 97. That test will fail and control
will pass to L2, where again the test will fail.
The compiler can do better by short-circuiting repeating tests:
L0: test is_ge L3 {x,0} 48
test is_ge L1 57 {x,0}
move true {x,0}
return.
L1: test is_ge L2 {x,0} 97
test is_ge L3 122 {x,0}
move true {x,0}
return
L2: test is_ge L3 {x,0} 65
test is_ge L3 90 {x,0}
move true {x,0}
return
L3: move false {x,0}
return
Diffstat (limited to 'lib/compiler/src/erl_bifs.erl')
0 files changed, 0 insertions, 0 deletions