<feed xmlns='http://www.w3.org/2005/Atom'>
<title>otp.git/lib/compiler/test/receive_SUITE_data, branch maint</title>
<subtitle>Mirror of Erlang/OTP repository.
</subtitle>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/'/>
<entry>
<title>Introduce a new SSA-based intermediate format</title>
<updated>2018-08-24T07:57:06+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bjorn@erlang.org</email>
</author>
<published>2018-02-01T07:33:10+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=6bee2ac7d11668888d93ec4f93730bcae3e5fa79'/>
<id>6bee2ac7d11668888d93ec4f93730bcae3e5fa79</id>
<content type='text'>
v3_codegen is replaced by three new passes:

* beam_kernel_to_ssa which translates the Kernel Erlang format
  to a new SSA-based intermediate format.

* beam_ssa_pre_codegen which prepares the SSA-based format
  for code generation, including register allocation. Registers
  are allocated using the linear scan algorithm.

* beam_ssa_codegen which generates BEAM assembly code from the
  SSA-based format.

It easier and more effective to optimize the SSA-based format before X
and Y registers have been assigned.  The current optimization passes
constantly have to make sure no "holes" in the X register assignments
are created (that is, that no X register becomes undefined that an
allocation instruction depends on).

This commit also introduces the following optimizations:

* Replacing of tuple matching of records with the is_tagged_tuple
instruction. (Replacing beam_record.)

* Sinking of get_tuple_element instructions to just before the first
use of the extracted values. As well as potentially avoiding
extracting tuple elements when they are not actually used on all
executions paths, this optimization could also reduce the number
values that will need to be stored in Y registers. (Similar to
beam_reorder, but more effective.)

* Live optimizations, removing the definition of a variable that is
not subsequently used (provided that the operation has no side
effects), as well strength reduction of binary matching by replacing
the extraction of value from a binary with a skip instruction. (Used
to be done by beam_block, beam_utils, and v3_codegen.)

* Removal of redundant bs_restore2 instructions. (Formerly done
by beam_bs.)

* Type-based optimizations across branches. More effective than
the old beam_type pass that only did type-based optimizations in
basic blocks.

* Optimization of floating point instructions. (Formerly done
by beam_type.)

* Optimization of receive statements to introduce recv_mark and
recv_set instructions. More effective with far fewer restrictions
on what instructions are allowed between creating the reference
and entering the receive statement.

* Common subexpression elimination. (Formerly done by beam_block.)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
v3_codegen is replaced by three new passes:

* beam_kernel_to_ssa which translates the Kernel Erlang format
  to a new SSA-based intermediate format.

* beam_ssa_pre_codegen which prepares the SSA-based format
  for code generation, including register allocation. Registers
  are allocated using the linear scan algorithm.

* beam_ssa_codegen which generates BEAM assembly code from the
  SSA-based format.

It easier and more effective to optimize the SSA-based format before X
and Y registers have been assigned.  The current optimization passes
constantly have to make sure no "holes" in the X register assignments
are created (that is, that no X register becomes undefined that an
allocation instruction depends on).

This commit also introduces the following optimizations:

* Replacing of tuple matching of records with the is_tagged_tuple
instruction. (Replacing beam_record.)

* Sinking of get_tuple_element instructions to just before the first
use of the extracted values. As well as potentially avoiding
extracting tuple elements when they are not actually used on all
executions paths, this optimization could also reduce the number
values that will need to be stored in Y registers. (Similar to
beam_reorder, but more effective.)

* Live optimizations, removing the definition of a variable that is
not subsequently used (provided that the operation has no side
effects), as well strength reduction of binary matching by replacing
the extraction of value from a binary with a skip instruction. (Used
to be done by beam_block, beam_utils, and v3_codegen.)

* Removal of redundant bs_restore2 instructions. (Formerly done
by beam_bs.)

* Type-based optimizations across branches. More effective than
the old beam_type pass that only did type-based optimizations in
basic blocks.

* Optimization of floating point instructions. (Formerly done
by beam_type.)

* Optimization of receive statements to introduce recv_mark and
recv_set instructions. More effective with far fewer restrictions
on what instructions are allowed between creating the reference
and entering the receive statement.

* Common subexpression elimination. (Formerly done by beam_block.)
</pre>
</div>
</content>
</entry>
<entry>
<title>Use a set to store ref registers in beam_receive</title>
<updated>2013-04-19T09:47:00+00:00</updated>
<author>
<name>Anthony Ramine</name>
<email>n.oxyde@gmail.com</email>
</author>
<published>2013-04-09T20:20:00+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=8aa46fd40d759de2d6a13fbafb5e88cdf1047220'/>
<id>8aa46fd40d759de2d6a13fbafb5e88cdf1047220</id>
<content type='text'>
In some circumstances, as when inlining code, when some optimization
passes are disabled or with hand-written but semantically correct Core
Erlang or BEAM assembly, a fresh reference may be live in more than one
register:

    ...
    {allocate_zero,2,2}.
    ...
    {call_ext,0,{extfunc,erlang,make_ref,0}}. % Ref in [x0]
    ...
    {move,{x,0},{y,0}}. % Ref in [x0,y0]
    {move,{y,1},{x,0}}. % Ref in [y0]
    ...
    {move,{y,0},{x,0}}. % Ref in [x0,y0]
    {move,{x,0},{y,1}}. % Ref in [x0,y0,y1]
  {label,5}.
    {loop_rec,{f,6},{x,0}}. % Ref in [y0,y1]
    ...
    {loop_rec_end,{f,5}}.
  {label,6}.
    {wait,{f,5}}.
    ...

Pass beam_receive expects a single live register for the ref when it
encounters the loop_rec instruction and crashes with the following
reason:

$ erlc t.S
...
crash reason: {{case_clause,
                   {'EXIT',
                       {{case_clause,[{y,1},{y,0}]},
                        [{beam_receive,opt_recv,5,
                             [{file,"beam_receive.erl"},{line,154}]},
                         ...]}}},
               ...}

This commit teaches beam_receive how to use a set of registers instead
of a single one when tracking fresh references, thus avoiding the crash.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In some circumstances, as when inlining code, when some optimization
passes are disabled or with hand-written but semantically correct Core
Erlang or BEAM assembly, a fresh reference may be live in more than one
register:

    ...
    {allocate_zero,2,2}.
    ...
    {call_ext,0,{extfunc,erlang,make_ref,0}}. % Ref in [x0]
    ...
    {move,{x,0},{y,0}}. % Ref in [x0,y0]
    {move,{y,1},{x,0}}. % Ref in [y0]
    ...
    {move,{y,0},{x,0}}. % Ref in [x0,y0]
    {move,{x,0},{y,1}}. % Ref in [x0,y0,y1]
  {label,5}.
    {loop_rec,{f,6},{x,0}}. % Ref in [y0,y1]
    ...
    {loop_rec_end,{f,5}}.
  {label,6}.
    {wait,{f,5}}.
    ...

Pass beam_receive expects a single live register for the ref when it
encounters the loop_rec instruction and crashes with the following
reason:

$ erlc t.S
...
crash reason: {{case_clause,
                   {'EXIT',
                       {{case_clause,[{y,1},{y,0}]},
                        [{beam_receive,opt_recv,5,
                             [{file,"beam_receive.erl"},{line,154}]},
                         ...]}}},
               ...}

This commit teaches beam_receive how to use a set of registers instead
of a single one when tracking fresh references, thus avoiding the crash.
</pre>
</div>
</content>
</entry>
<entry>
<title>Use erlang:demonitor(Ref, [flush]) where applicable</title>
<updated>2013-04-05T11:06:24+00:00</updated>
<author>
<name>Loïc Hoguin</name>
<email>essen@ninenines.eu</email>
</author>
<published>2013-04-05T11:06:24+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=c82e9fad33302ff24fdddbd50f110c06d4eb81d4'/>
<id>c82e9fad33302ff24fdddbd50f110c06d4eb81d4</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>beam_receive: Optimize receives using refs created by spawn_monitor/{1,3}</title>
<updated>2012-10-09T13:24:40+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bjorn@erlang.org</email>
</author>
<published>2012-08-29T11:07:27+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=83cfc8c8414edc956d7e8e3a1402c17bf35421a6'/>
<id>83cfc8c8414edc956d7e8e3a1402c17bf35421a6</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>beam_jump: Don't move a block which can be entered via a fallthrough</title>
<updated>2012-10-09T13:24:39+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bjorn@erlang.org</email>
</author>
<published>2012-08-28T13:06:31+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=d3f886a225adfa196ec5fbc55ea6ebcae8c42197'/>
<id>d3f886a225adfa196ec5fbc55ea6ebcae8c42197</id>
<content type='text'>
beam_jump moves short code sequences ending in an instruction that causes
an exception to the end of the function, in the hope that a jump around
the moved blocked can be replaced with a fallthrough. Therefore, moving
a block that is entered via a fallthrough defeats the purpose of the
optimization.

Also add two more test cases for the beam_receive module to ensure that
all lines are still covered.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
beam_jump moves short code sequences ending in an instruction that causes
an exception to the end of the function, in the hope that a jump around
the moved blocked can be replaced with a fallthrough. Therefore, moving
a block that is entered via a fallthrough defeats the purpose of the
optimization.

Also add two more test cases for the beam_receive module to ensure that
all lines are still covered.
</pre>
</div>
</content>
</entry>
<entry>
<title>compiler test: Test optimization of receive statements</title>
<updated>2010-05-11T06:54:26+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bjorn@erlang.org</email>
</author>
<published>2010-04-22T11:37:18+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=f39e0b6bbc5f5d9f6a55b87847bcad7707309883'/>
<id>f39e0b6bbc5f5d9f6a55b87847bcad7707309883</id>
<content type='text'>
We don't attempt to run the generated code, but use beam_disasm
and check for the presence or absence (as appropriate) of the
recv_mark/1 and recv_set/1 instructions.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We don't attempt to run the generated code, but use beam_disasm
and check for the presence or absence (as appropriate) of the
recv_mark/1 and recv_set/1 instructions.
</pre>
</div>
</content>
</entry>
</feed>
