diff options
author | Björn Gustavsson <[email protected]> | 2015-01-12 14:51:23 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2015-03-09 09:59:37 +0100 |
commit | 8997433288cb571f155c509f402d0ba4fdba5025 (patch) | |
tree | 25930ba0c17b0bb93ec7aff700259e3961a428e6 /lib/compiler | |
parent | 0a0d39d351fc2008447bb4a5e22e48f429fe4d93 (diff) | |
download | otp-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.erl | 3 |
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) -> |