diff options
author | Björn Gustavsson <[email protected]> | 2016-03-09 16:14:36 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2016-03-10 12:13:26 +0100 |
commit | c2035ebb8b7bbdeee1ff03a348ba39edef1050b1 (patch) | |
tree | b989521f1cb8ad041604b49d0814c4032f4a69a1 /lib/kernel/test | |
parent | c7be5e1cde88becf729d7f3fbd84e7e3a623efb0 (diff) | |
download | otp-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/kernel/test')
0 files changed, 0 insertions, 0 deletions