aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2018-04-26 22:22:56 +0200
committerBjörn Gustavsson <[email protected]>2018-04-27 10:20:41 +0200
commit9b347a42a23540eab2f3fd8bf75190a69b5ebb31 (patch)
tree82d0b2428bcf098a73446c9fdf364357314cfbdd /lib/compiler
parent56e88f364a32b471b03e2364c2eb84783642ad88 (diff)
downloadotp-9b347a42a23540eab2f3fd8bf75190a69b5ebb31.tar.gz
otp-9b347a42a23540eab2f3fd8bf75190a69b5ebb31.tar.bz2
otp-9b347a42a23540eab2f3fd8bf75190a69b5ebb31.zip
Correct beam_utils:is_killed/3 (again)
beam_utils:is_killed/3 could incorrectly indicate that a register was killed. The previous fix is 5da6b91ecab6c.
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/beam_utils.erl19
1 files changed, 10 insertions, 9 deletions
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl
index 1ddad30328..f57a7af1ab 100644
--- a/lib/compiler/src/beam_utils.erl
+++ b/lib/compiler/src/beam_utils.erl
@@ -377,7 +377,7 @@ check_liveness(R, [{test,_,{f,Fail},As}|Is], St0) ->
{killed,St1} ->
check_liveness(R, Is, St1);
{exit_not_used,St1} ->
- check_liveness(R, Is, St1);
+ not_used(check_liveness(R, Is, St1));
{not_used,St1} ->
not_used(check_liveness(R, Is, St1));
{used,_}=Used ->
@@ -395,14 +395,14 @@ check_liveness(R, [{select,_,_,Fail,Branches}|_], St) ->
check_liveness_everywhere(R, [Fail|Branches], St);
check_liveness(R, [{jump,{f,F}}|_], St) ->
check_liveness_at(R, F, St);
-check_liveness(R, [{case_end,Used}|_], St) ->
- check_liveness_ret(R, Used, St);
+check_liveness(R, [{case_end,Used}|_], St) ->
+ check_liveness_exit(R, Used, St);
check_liveness(R, [{try_case_end,Used}|_], St) ->
- check_liveness_ret(R, Used, St);
+ check_liveness_exit(R, Used, St);
check_liveness(R, [{badmatch,Used}|_], St) ->
- check_liveness_ret(R, Used, St);
-check_liveness(_, [if_end|_], St) ->
- {killed,St};
+ check_liveness_exit(R, Used, St);
+check_liveness(R, [if_end|_], St) ->
+ check_liveness_exit(R, ignore, St);
check_liveness(R, [{func_info,_,_,Ar}|_], St) ->
case R of
{x,X} when X < Ar -> {used,St};
@@ -658,8 +658,9 @@ check_liveness_at(R, Lbl, #live{lbl=Ll,res=ResMemorized}=St0) ->
not_used({used,_}=Res) -> Res;
not_used({_,St}) -> {not_used,St}.
-check_liveness_ret(R, R, St) -> {used,St};
-check_liveness_ret(_, _, St) -> {killed,St}.
+check_liveness_exit(R, R, St) -> {used,St};
+check_liveness_exit({x,_}, _, St) -> {killed,St};
+check_liveness_exit({y,_}, _, St) -> {exit_not_used,St}.
%% check_liveness_block(Reg, [Instruction], State) ->
%% {killed | not_used | used | alloc_used | transparent,State'}