aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_dead.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2016-03-09 16:14:36 +0100
committerBjörn Gustavsson <[email protected]>2016-03-10 12:13:26 +0100
commitc2035ebb8b7bbdeee1ff03a348ba39edef1050b1 (patch)
treeb989521f1cb8ad041604b49d0814c4032f4a69a1 /lib/compiler/src/beam_dead.erl
parentc7be5e1cde88becf729d7f3fbd84e7e3a623efb0 (diff)
downloadotp-c2035ebb8b7bbdeee1ff03a348ba39edef1050b1.tar.gz
otp-c2035ebb8b7bbdeee1ff03a348ba39edef1050b1.tar.bz2
otp-c2035ebb8b7bbdeee1ff03a348ba39edef1050b1.zip
beam_block: Eliminate unsafe optimization
Consider this code: %% Start of block get_tuple_element Tuple 0 Element get_map_elements Fail Map [Key => Dest] . . . move Element UltimateDest %% End of block Fail: %% Code that uses Element. beam_block (more precisely, otp_tuple_element/1) would incorrectly transform the code to this: %% Start of block get_map_elements Fail Map [Key => Dest] . . . get_tuple_element Tuple 0 UltimateDest %% End of block Fail: %% Code that uses Element. That is, the code at label Fail would use register Element, which is either uninitalized or contains the wrong value. We could fix this problem by always keeping label information at hand when optimizing blocks so that we could check the code at the failure label for get_map_elements. That would require changes to beam_block and beam_utils. We might consider doing that in the future if it turns out be worth it. For now, I have decided that I want to keep the simplicity of blocks (allowing them to be optimized without keeping label information). That could be achieved by not including get_map_elements in blocks. Another way, which I have chosen, is to only allow get_map_elements as the first instruction in the block. For background on the bug: c288ab8 introduced the beam_reorder pass and 5f431276 introduced opt_tuple_element() in beam_block.
Diffstat (limited to 'lib/compiler/src/beam_dead.erl')
0 files changed, 0 insertions, 0 deletions