aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_utils.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2010-12-02 17:22:02 +0100
committerBjörn Gustavsson <[email protected]>2010-12-02 17:22:02 +0100
commit41ccca51c28d23094f57e826060ef8dbf424f39b (patch)
treee23784a69ba6e96fabd937ee17363681ceffbddc /lib/compiler/src/beam_utils.erl
parent35a497151d6b9e6e2e42ffc4423adb305933f700 (diff)
parent2b03fbacf1ac0c06a84439baac90d418916a1778 (diff)
downloadotp-41ccca51c28d23094f57e826060ef8dbf424f39b.tar.gz
otp-41ccca51c28d23094f57e826060ef8dbf424f39b.tar.bz2
otp-41ccca51c28d23094f57e826060ef8dbf424f39b.zip
Merge branch 'bjorn/fix-compiler-bugs/OTP-8949' into dev
* bjorn/fix-compiler-bugs/OTP-8949: beam_utils: Fix check_liveness/3 for receive loops beam_utils: Fix liveness analysis for gc_bif instructions
Diffstat (limited to 'lib/compiler/src/beam_utils.erl')
-rw-r--r--lib/compiler/src/beam_utils.erl36
1 files changed, 23 insertions, 13 deletions
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl
index 761d4ffec0..45cdf8a659 100644
--- a/lib/compiler/src/beam_utils.erl
+++ b/lib/compiler/src/beam_utils.erl
@@ -407,16 +407,23 @@ check_liveness(R, [{bif,Op,{f,Fail},Ss,D}|Is], St0) ->
Other ->
Other
end;
-check_liveness(R, [{gc_bif,Op,{f,Fail},_,Ss,D}|Is], St0) ->
- case check_liveness_fail(R, Op, Ss, Fail, St0) of
- {killed,St} = Killed ->
- case member(R, Ss) of
- true -> {used,St};
- false when R =:= D -> Killed;
- false -> check_liveness(R, Is, St)
- end;
- Other ->
- Other
+check_liveness(R, [{gc_bif,Op,{f,Fail},Live,Ss,D}|Is], St0) ->
+ case R of
+ {x,X} when X >= Live ->
+ {killed,St0};
+ {x,_} ->
+ {used,St0};
+ _ ->
+ case check_liveness_fail(R, Op, Ss, Fail, St0) of
+ {killed,St}=Killed ->
+ case member(R, Ss) of
+ true -> {used,St};
+ false when R =:= D -> Killed;
+ false -> check_liveness(R, Is, St)
+ end;
+ Other ->
+ Other
+ end
end;
check_liveness(R, [{bs_add,{f,0},Ss,D}|Is], St) ->
case member(R, Ss) of
@@ -482,10 +489,13 @@ check_liveness(R, [{bs_context_to_binary,S}|Is], St) ->
S -> {used,St};
_ -> check_liveness(R, Is, St)
end;
-check_liveness(R, [{loop_rec,{f,_},{x,0}}|Is], St) ->
+check_liveness(R, [{loop_rec,{f,_},{x,0}}|_], St) ->
case R of
- {x,_} -> {killed,St};
- _ -> check_liveness(R, Is, St)
+ {x,_} ->
+ {killed,St};
+ _ ->
+ %% y register. Rarely happens. Be very conversative.
+ {unknown,St}
end;
check_liveness(R, [{loop_rec_end,{f,Fail}}|_], St) ->
check_liveness_at(R, Fail, St);