aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_validator.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2014-12-08 12:33:12 +0100
committerBjörn Gustavsson <[email protected]>2015-01-09 13:18:44 +0100
commit7b10ff77235532923558a30759ed9b5fe6d994a5 (patch)
tree98bdf359c9df1f077335dfe16ca7c621cc5a3777 /lib/compiler/src/beam_validator.erl
parent4f7edc376ee61238699f68c8721ab23ee56eafee (diff)
downloadotp-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/beam_validator.erl')
0 files changed, 0 insertions, 0 deletions