aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2015-01-12 14:51:23 +0100
committerBjörn Gustavsson <[email protected]>2015-03-09 09:59:37 +0100
commit8997433288cb571f155c509f402d0ba4fdba5025 (patch)
tree25930ba0c17b0bb93ec7aff700259e3961a428e6 /lib/compiler
parent0a0d39d351fc2008447bb4a5e22e48f429fe4d93 (diff)
downloadotp-8997433288cb571f155c509f402d0ba4fdba5025.tar.gz
otp-8997433288cb571f155c509f402d0ba4fdba5025.tar.bz2
otp-8997433288cb571f155c509f402d0ba4fdba5025.zip
beam_bool: Correct initialized_regs/2
initialized_regs/2 did not handle allocating instructions; instead treating them as any other 'set' instruction. The consequences could be one or both of the following: Going past the allocating instruction (looking at more instructions) would mean that initialized_regs/2 could return registers that were not actually initialized. That could mean that MustBeKilled in ensure_opt_safe/6 could contain too few registers, and that the code that followed tried to use an uninitialized register. The beam_validator should have detected that problem. Not taking account the number of live registers in the allocating instruction could mean that some registers were not found to be initialized, which could mean that MustBeKilled would contain too many registers. That would mean a missed optimization.
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/beam_bool.erl3
1 files changed, 3 insertions, 0 deletions
diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl
index a452d30b61..5ed9c16d61 100644
--- a/lib/compiler/src/beam_bool.erl
+++ b/lib/compiler/src/beam_bool.erl
@@ -787,6 +787,9 @@ is_not_used(R, Is, Label, #st{ll=Ll}) ->
initialized_regs(Is) ->
initialized_regs(Is, ordsets:new()).
+initialized_regs([{set,Dst,_Src,{alloc,Live,_}}|_], Regs0) ->
+ Regs = add_init_regs(free_vars_regs(Live), Regs0),
+ add_init_regs(Dst, Regs);
initialized_regs([{set,Dst,Src,_}|Is], Regs) ->
initialized_regs(Is, add_init_regs(Dst, add_init_regs(Src, Regs)));
initialized_regs([{test,_,_,Src}|Is], Regs) ->