diff options
author | Björn Gustavsson <[email protected]> | 2018-11-02 10:16:59 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2018-11-02 10:16:59 +0100 |
commit | ad8ef2bda1fa8cc337e581dca0c67cfc756f5e4f (patch) | |
tree | 634f5c219153593919a3ffe7d3f1c4caa502d4d4 /lib/compiler | |
parent | 9c33f00f78724ce0f68fef1dfc6ab4810d8c45f1 (diff) | |
parent | 3e742b1d270069ede1aa8b6ae69c83fc6e71f814 (diff) | |
download | otp-ad8ef2bda1fa8cc337e581dca0c67cfc756f5e4f.tar.gz otp-ad8ef2bda1fa8cc337e581dca0c67cfc756f5e4f.tar.bz2 otp-ad8ef2bda1fa8cc337e581dca0c67cfc756f5e4f.zip |
Merge branch 'maint'
* maint:
Fix bug when beam_jump removes put_tuple instructions
Conflicts:
lib/compiler/src/beam_jump.erl
lib/compiler/test/beam_jump_SUITE.erl
Diffstat (limited to 'lib/compiler')
-rw-r--r-- | lib/compiler/src/beam_jump.erl | 15 | ||||
-rw-r--r-- | lib/compiler/test/beam_jump_SUITE.erl | 18 |
2 files changed, 26 insertions, 7 deletions
diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl index d694bd2a5b..edc4522cc7 100644 --- a/lib/compiler/src/beam_jump.erl +++ b/lib/compiler/src/beam_jump.erl @@ -128,7 +128,7 @@ %%% on the program state. %%% --import(lists, [foldl/3,mapfoldl/3,reverse/1,reverse/2]). +-import(lists, [dropwhile/2,foldl/3,mapfoldl/3,reverse/1,reverse/2]). -type instruction() :: beam_utils:instruction(). @@ -522,14 +522,19 @@ opt_useless_loads([{test,_,{f,L},_}=I|Is], L, St) -> opt_useless_loads(Is, _L, St) -> {Is,St}. -opt_useless_block_loads([{set,[Dst],_,_}=I|Is], L, Index) -> - BlockJump = [{block,Is},{jump,{f,L}}], +opt_useless_block_loads([{set,[Dst],_,_}=I|Is0], L, Index) -> + BlockJump = [{block,Is0},{jump,{f,L}}], case beam_utils:is_killed(Dst, BlockJump, Index) of true -> - %% The register is killed and not used, we can remove the load + %% The register is killed and not used, we can remove the load. + %% Remove any `put` instructions in case we just + %% removed a `put_tuple` instruction. + Is = dropwhile(fun({set,_,_,put}) -> true; + (_) -> false + end, Is0), opt_useless_block_loads(Is, L, Index); false -> - [I|opt_useless_block_loads(Is, L, Index)] + [I|opt_useless_block_loads(Is0, L, Index)] end; opt_useless_block_loads([I|Is], L, Index) -> [I|opt_useless_block_loads(Is, L, Index)]; diff --git a/lib/compiler/test/beam_jump_SUITE.erl b/lib/compiler/test/beam_jump_SUITE.erl index f6cddbf1b1..40eb6f06c3 100644 --- a/lib/compiler/test/beam_jump_SUITE.erl +++ b/lib/compiler/test/beam_jump_SUITE.erl @@ -22,7 +22,7 @@ -export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1, init_per_group/2,end_per_group/2, undefined_label/1,ambiguous_catch_try_state/1, - unsafe_move_elimination/1]). + unsafe_move_elimination/1,build_tuple/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -34,7 +34,8 @@ groups() -> [{p,[parallel], [undefined_label, ambiguous_catch_try_state, - unsafe_move_elimination + unsafe_move_elimination, + build_tuple ]}]. init_per_suite(Config) -> @@ -112,6 +113,19 @@ unsafe_move_elimination(Left, Right, Simple0) -> end, {id({Left,Right,Simple}),Simple}. +-record(message2, {id, p1}). +-record(message3, {id, p1, p2}). + +build_tuple(_Config) -> + {'EXIT',{{badrecord,message3},_}} = (catch do_build_tuple(#message2{})), + ok. + +do_build_tuple(Message) -> + if is_record(Message, message2) -> + Res = {res, rand:uniform(100)}, + {Message#message3.id, Res} + end. + id(I) -> I. |