diff options
author | Björn Gustavsson <[email protected]> | 2010-10-12 10:08:18 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2010-10-12 14:15:36 +0200 |
commit | f6a2fb81fd87e671ceed85261a1c28a6082f010c (patch) | |
tree | faf8abfab935ac33adcb3fece584fd6d1017a341 /lib/compiler/test | |
parent | 499082d25170aa7edf922a6aee0465a7ffb144d4 (diff) | |
download | otp-f6a2fb81fd87e671ceed85261a1c28a6082f010c.tar.gz otp-f6a2fb81fd87e671ceed85261a1c28a6082f010c.tar.bz2 otp-f6a2fb81fd87e671ceed85261a1c28a6082f010c.zip |
beam_block: Do optimizations in the safe order
Moving of allocation instructions upwards in the instruction
stream (in order to enable further optimizations) in beam_block,
is implemented with the assumption that if a register {x,X}
contains a valid term, then all other x register with lower
numbers than X also contain valid terms. That assumption is
true after code generation.
The beam_utils:live_opt/1 optimization, however, may invalidate
that assumption. For instance, if a receive statement exports a
variable that is used, but the return value of the receive statement
is not used, then {x,1} but not {x,0} contains a valid term at the
end of the receive statement. If the receive statement is
followed by
{bif,self,{f,0},[],{x,0}}.
{test_heap,NumberOfWords,2}.
moving the allocation upwards will produce
{test_heap,NumberOfWords,2}.
{bif,self,{f,0},[],{x,0}}.
which will cause the beam_validator pass to scream loudly that
{x,0} is not live at the test_heap instruction.
Fix the problem by doing the optimizations in reverse order.
Reported-by: Jim Engquist
Diffstat (limited to 'lib/compiler/test')
-rw-r--r-- | lib/compiler/test/receive_SUITE.erl | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl index fca3f0387b..2a592dd669 100644 --- a/lib/compiler/test/receive_SUITE.erl +++ b/lib/compiler/test/receive_SUITE.erl @@ -21,7 +21,7 @@ -module(receive_SUITE). -export([all/1,init_per_testcase/2,fin_per_testcase/2, - recv/1,coverage/1,otp_7980/1,ref_opt/1]). + recv/1,coverage/1,otp_7980/1,ref_opt/1,export/1]). -include("test_server.hrl"). @@ -36,7 +36,7 @@ fin_per_testcase(_Case, Config) -> all(suite) -> test_lib:recompile(?MODULE), - [recv,coverage,otp_7980,ref_opt]. + [recv,coverage,otp_7980,ref_opt,export]. -record(state, {ena = true}). @@ -205,4 +205,25 @@ collect_recv_opt_instrs(Code) -> end] || {function,_,_,_,Is} <- Code], lists:append(L). +export(Config) when is_list(Config) -> + Ref = make_ref(), + ?line self() ! {result,Ref,42}, + ?line 42 = export_1(Ref), + ?line {error,timeout} = export_1(Ref), + ok. + +export_1(Reference) -> + id(Reference), + receive + {result,Reference,Result} -> + Result + after 1 -> + Result = {error,timeout} + end, + %% Result ({x,1}) is used, but not the return value ({x,0}) + %% of the receive. Used to be incorrectly optimized + %% by beam_block. + id({build,self()}), + Result. + id(I) -> I. |