aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_block.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2016-03-11 09:51:50 +0100
committerBjörn Gustavsson <[email protected]>2016-03-11 09:51:50 +0100
commit276b0431229104601448d2ef36be31b610f591f0 (patch)
tree904108aa8df9601377ad4105f247ec951e5cc894 /lib/compiler/src/beam_block.erl
parenta5b3398960e4be823944c532adccf53397625abb (diff)
parentc2035ebb8b7bbdeee1ff03a348ba39edef1050b1 (diff)
downloadotp-276b0431229104601448d2ef36be31b610f591f0.tar.gz
otp-276b0431229104601448d2ef36be31b610f591f0.tar.bz2
otp-276b0431229104601448d2ef36be31b610f591f0.zip
Merge branch 'bjorn/compiler/opt/OTP-12951'
* bjorn/compiler/opt/OTP-12951: beam_block: Eliminate unsafe optimization
Diffstat (limited to 'lib/compiler/src/beam_block.erl')
-rw-r--r--lib/compiler/src/beam_block.erl10
1 files changed, 7 insertions, 3 deletions
diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl
index 10dbaf462c..d1052303e0 100644
--- a/lib/compiler/src/beam_block.erl
+++ b/lib/compiler/src/beam_block.erl
@@ -58,6 +58,13 @@ blockify(Is) ->
blockify([{loop_rec,{f,Fail},{x,0}},{loop_rec_end,_Lbl},{label,Fail}|Is], Acc) ->
%% Useless instruction sequence.
blockify(Is, Acc);
+blockify([{get_map_elements,F,S,{list,Gets}}|Is0], Acc) ->
+ %% A get_map_elements instruction is only safe at the beginning of
+ %% a block because of the failure label.
+ {Ss,Ds} = beam_utils:split_even(Gets),
+ I = {set,Ds,[S|Ss],{get_map_elements,F}},
+ {Block,Is} = collect_block(Is0, [I]),
+ blockify(Is, [{block,Block}|Acc]);
blockify([I|Is0]=IsAll, Acc) ->
case collect(I) of
error -> blockify(Is0, [I|Acc]);
@@ -101,9 +108,6 @@ collect({get_list,S,D1,D2}) -> {set,[D1,D2],[S],get_list};
collect(remove_message) -> {set,[],[],remove_message};
collect({put_map,F,Op,S,D,R,{list,Puts}}) ->
{set,[D],[S|Puts],{alloc,R,{put_map,Op,F}}};
-collect({get_map_elements,F,S,{list,Gets}}) ->
- {Ss,Ds} = beam_utils:split_even(Gets),
- {set,Ds,[S|Ss],{get_map_elements,F}};
collect({'catch'=Op,R,L}) ->
{set,[R],[],{try_catch,Op,L}};
collect({'try'=Op,R,L}) ->