aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2012-09-05 16:28:50 +0200
committerBjörn Gustavsson <[email protected]>2012-10-10 15:38:06 +0200
commite1aa422290b09a68bd761cbd0e70bd48442009b3 (patch)
tree6c7f62a81e1433d97620daee01719ffe85077208 /lib/compiler
parente199e2471a6468a1908638d1b9fb863ea39e4d0e (diff)
downloadotp-e1aa422290b09a68bd761cbd0e70bd48442009b3.tar.gz
otp-e1aa422290b09a68bd761cbd0e70bd48442009b3.tar.bz2
otp-e1aa422290b09a68bd761cbd0e70bd48442009b3.zip
beam_bsm: Handle calls slightly better
We were too conservative when handling a call when there were copies of the match context in both x and y registers. Don't give up if there is are copies of the match context in y registers, as long as those copies are killed by the code that follows the call.
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/beam_bsm.erl15
1 files changed, 9 insertions, 6 deletions
diff --git a/lib/compiler/src/beam_bsm.erl b/lib/compiler/src/beam_bsm.erl
index e5429a9a9f..37053e1cc4 100644
--- a/lib/compiler/src/beam_bsm.erl
+++ b/lib/compiler/src/beam_bsm.erl
@@ -336,13 +336,16 @@ btb_call(Arity, Lbl, Regs0, Is, D0) ->
%% First handle the call as if it were a tail call.
D = btb_tail_call(Lbl, Regs, D0),
- %% No problem so far, but now we must make sure that
- %% we don't have any copies of the match context
- %% tucked away in an y register.
+ %% No problem so far (the called function can handle a
+ %% match context). Now we must make sure that the rest
+ %% of this function following the call does not attempt
+ %% to use the match context in case there is a copy
+ %% tucked away in a y register.
RegList = btb_context_regs(Regs),
- case [R || {y,_}=R <- RegList] of
- [] -> D;
- [_|_] -> btb_error({multiple_uses,RegList})
+ YRegs = [R || {y,_}=R <- RegList],
+ case btb_are_all_killed(YRegs, Is, D) of
+ true -> D;
+ false -> btb_error({multiple_uses,RegList})
end;
true ->
%% No match context in any x register. It could have been