aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_jump.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2012-08-28 15:06:31 +0200
committerBjörn Gustavsson <[email protected]>2012-10-09 15:24:39 +0200
commitd3f886a225adfa196ec5fbc55ea6ebcae8c42197 (patch)
treebb705c5206ac12714023deef619a3d09e7902d99 /lib/compiler/src/beam_jump.erl
parentb17da0957f6441e41579d2bad40a8977c4098c0f (diff)
downloadotp-d3f886a225adfa196ec5fbc55ea6ebcae8c42197.tar.gz
otp-d3f886a225adfa196ec5fbc55ea6ebcae8c42197.tar.bz2
otp-d3f886a225adfa196ec5fbc55ea6ebcae8c42197.zip
beam_jump: Don't move a block which can be entered via a fallthrough
beam_jump moves short code sequences ending in an instruction that causes an exception to the end of the function, in the hope that a jump around the moved blocked can be replaced with a fallthrough. Therefore, moving a block that is entered via a fallthrough defeats the purpose of the optimization. Also add two more test cases for the beam_receive module to ensure that all lines are still covered.
Diffstat (limited to 'lib/compiler/src/beam_jump.erl')
-rw-r--r--lib/compiler/src/beam_jump.erl14
1 files changed, 10 insertions, 4 deletions
diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl
index 79cdc8e179..e7025ea6e8 100644
--- a/lib/compiler/src/beam_jump.erl
+++ b/lib/compiler/src/beam_jump.erl
@@ -46,10 +46,13 @@
%%% such as a jump that never transfers control to the instruction
%%% following it.
%%%
-%%% (2) case_end, if_end, and badmatch, and function calls that cause an
-%%% exit (such as calls to exit/1) are moved to the end of the function.
-%%% The purpose is to allow further optimizations at the place from
-%%% which the code was moved.
+%%% (2) Short sequences starting with a label and ending in case_end, if_end,
+%%% and badmatch, and function calls that cause an exit (such as calls
+%%% to exit/1) are moved to the end of the function, but only if the
+%%% the block is not entered via a fallthrough. The purpose of this move
+%%% is to allow further optimizations at the place from which the
+%%% code was moved (a jump around the block could be replaced with a
+%%% fallthrough).
%%%
%%% (3) Any unreachable code is removed. Unreachable code is code
%%% after jump, call_last and other instructions which never
@@ -232,6 +235,9 @@ extract_seq_1([{line,_}=Line|Is], Acc) ->
extract_seq_1(Is, [Line|Acc]);
extract_seq_1([{label,_},{func_info,_,_,_}|_], _) ->
no;
+extract_seq_1([{label,Lbl},{jump,{f,Lbl}}|_], _) ->
+ %% Don't move a sequence which have a fallthrough entering it.
+ no;
extract_seq_1([{label,_}=Lbl|Is], Acc) ->
{yes,[Lbl|Acc],Is};
extract_seq_1(_, _) -> no.