diff options
Diffstat (limited to 'lib/compiler/src')
-rw-r--r-- | lib/compiler/src/beam_jump.erl | 14 |
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. |