<feed xmlns='http://www.w3.org/2005/Atom'>
<title>otp.git/lib/debugger/test, branch OTP-22.0.4</title>
<subtitle>Mirror of Erlang/OTP repository.
</subtitle>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/'/>
<entry>
<title>beam_ssa_type: Propagate the 'none' type from calls</title>
<updated>2019-02-11T05:36:12+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bjorn@erlang.org</email>
</author>
<published>2019-02-04T09:03:55+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=4763811e1d67a0d2ac3442d4694b4e1dee1b4364'/>
<id>4763811e1d67a0d2ac3442d4694b4e1dee1b4364</id>
<content type='text'>
Consider this pseudo code:

    f(...) -&gt;
      Val = case Expr of
        ... -&gt;
          ... ;
        ... -&gt;
          ... ;
        ... -&gt;
          my_abort(something_went_wrong)
      end,
      %% Here follows code that uses Val.
      .
      .
      .

    my_abort(Reason) -&gt;
      throw({error,Reason}).

The first two clauses in the case will probably provide some
information about the type of the variable `Var`, information
that would be useful for optimizing the code that follows the
case.

However, the third clause would ruin everything. The call
to `my_abort/1` could return anything, and thus `Val` could
also have any type.

294d66a295f6 introduced module-level type analysis, which will in
general keep track of the return type of a local function
call. However, it does not improve the optimization for this specific
function. When a function never returns, that is, when its type is
`none`, it does not propagate the `none` type, but instead pretends
that the return type is `any`.

This commit extends the handling of functions that don't return to
properly handle the `none` type. Any instructions that directly
follows the function that does not return will be discarded, and the
call will be rewritten to a tail-recursive call.

For this specific example, it means that the type for `Val` deduced
from the first two clauses will be retained and can be used for
optimizing the code after the case.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Consider this pseudo code:

    f(...) -&gt;
      Val = case Expr of
        ... -&gt;
          ... ;
        ... -&gt;
          ... ;
        ... -&gt;
          my_abort(something_went_wrong)
      end,
      %% Here follows code that uses Val.
      .
      .
      .

    my_abort(Reason) -&gt;
      throw({error,Reason}).

The first two clauses in the case will probably provide some
information about the type of the variable `Var`, information
that would be useful for optimizing the code that follows the
case.

However, the third clause would ruin everything. The call
to `my_abort/1` could return anything, and thus `Val` could
also have any type.

294d66a295f6 introduced module-level type analysis, which will in
general keep track of the return type of a local function
call. However, it does not improve the optimization for this specific
function. When a function never returns, that is, when its type is
`none`, it does not propagate the `none` type, but instead pretends
that the return type is `any`.

This commit extends the handling of functions that don't return to
properly handle the `none` type. Any instructions that directly
follows the function that does not return will be discarded, and the
call will be rewritten to a tail-recursive call.

For this specific example, it means that the type for `Val` deduced
from the first two clauses will be retained and can be used for
optimizing the code after the case.
</pre>
</div>
</content>
</entry>
<entry>
<title>Update copyright year</title>
<updated>2018-06-18T12:51:18+00:00</updated>
<author>
<name>Henrik Nord</name>
<email>henrik@erlang.org</email>
</author>
<published>2018-06-18T12:51:18+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=5ca92e2eac1e84fd22f60e7abc3aa2b0ff1cb42b'/>
<id>5ca92e2eac1e84fd22f60e7abc3aa2b0ff1cb42b</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Do not treat binaries as top level in dbg_ieval</title>
<updated>2018-03-07T10:12:57+00:00</updated>
<author>
<name>José Valim</name>
<email>jose.valim@plataformatec.com.br</email>
</author>
<published>2018-03-07T10:12:55+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=a403cb1ed2cbab02fad23ac47b170dee1f22d7ec'/>
<id>a403cb1ed2cbab02fad23ac47b170dee1f22d7ec</id>
<content type='text'>
Prior to this change, calls inside binaries were
treated as top level which would cause the `Fun(Arg)`
call inside `&lt;&lt;Fun(Arg)/binary&gt;&gt;` to return an internal
dbg_ieval tuple and ultimately error with badarg.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Prior to this change, calls inside binaries were
treated as top level which would cause the `Fun(Arg)`
call inside `&lt;&lt;Fun(Arg)/binary&gt;&gt;` to return an internal
dbg_ieval tuple and ultimately error with badarg.
</pre>
</div>
</content>
</entry>
<entry>
<title>Avoid using the efile driver in test suites</title>
<updated>2017-11-17T14:33:05+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bjorn@erlang.org</email>
</author>
<published>2017-11-17T13:20:05+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=1107083935fbdb8f8a7ece9549d8203652c4fec6'/>
<id>1107083935fbdb8f8a7ece9549d8203652c4fec6</id>
<content type='text'>
The efile driver will soon be reimplemented as a BIF.

Instead of opening a port based on efile, use hd(erlang:ports()).  It
is a reasonable safe assumption that the runtime will continue to use
use at least some ports.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The efile driver will soon be reimplemented as a BIF.

Instead of opening a port based on efile, use hd(erlang:ports()).  It
is a reasonable safe assumption that the runtime will continue to use
use at least some ports.
</pre>
</div>
</content>
</entry>
<entry>
<title>debugger: Fix handling of locations and annotations</title>
<updated>2017-03-08T13:11:49+00:00</updated>
<author>
<name>Hans Bolinder</name>
<email>hasse@erlang.org</email>
</author>
<published>2017-02-10T15:00:32+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=bce73eb11441c3593304ccc88d6145ba1fbeffa1'/>
<id>bce73eb11441c3593304ccc88d6145ba1fbeffa1</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Update test cases for erlang:hash/2 removal</title>
<updated>2017-01-25T10:56:29+00:00</updated>
<author>
<name>Björn-Egil Dahlberg</name>
<email>egil@erlang.org</email>
</author>
<published>2016-08-01T12:49:47+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=52097fab56edbbd8c6f8a57ec3b3f33aa60c5bb9'/>
<id>52097fab56edbbd8c6f8a57ec3b3f33aa60c5bb9</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix overridden BIFs</title>
<updated>2016-09-02T12:24:36+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bjorn@erlang.org</email>
</author>
<published>2016-08-15T13:34:06+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=0baa07cdf2754748bbc2d969bf83f08c0976fb78'/>
<id>0baa07cdf2754748bbc2d969bf83f08c0976fb78</id>
<content type='text'>
The filters in a list comprehension can be guard expressions or
an ordinary expressions.

If a guard expression is used as a filter, an exception will basically
mean the same as 'false':

  t() -&gt;
    L = [{some_tag,42},an_atom],
    [X || X &lt;- L, element(1, X) =:= some_tag]
    %% Returns [{some_tag,42}]

On the other hand, if an ordinary expression is used as a filter, there
will be an exception:

  my_element(N, T) -&gt; element(N, T).

  t() -&gt;
    L = [{some_tag,42},an_atom],
    [X || X &lt;- L, my_element(1, X) =:= some_tag]
    %% Causes a 'badarg' exception when element(1, an_atom) is evaluated

It has been allowed for several releases to override a BIF with
a local function. Thus, if we define a function called element/2,
it will be called instead of the BIF element/2 within the module.
We must use the "erlang:" prefix to call the BIF.

Therefore, the following code is expected to work the same way as in
our second example above:

-compile({no_auto_import,[element/2]}).

element(N, T) -&gt;
    erlang:element(N, T).

t() -&gt;
    L = [{some_tag,42},an_atom],
    [X || X &lt;- L, element(1, X) =:= some_tag].
    %% Causes a 'badarg' exception when element(1, an_atom) is evaluated

But the compiler refuses to compile the code with the following
diagnostic:

  call to local/imported function element/2 is illegal in guard
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The filters in a list comprehension can be guard expressions or
an ordinary expressions.

If a guard expression is used as a filter, an exception will basically
mean the same as 'false':

  t() -&gt;
    L = [{some_tag,42},an_atom],
    [X || X &lt;- L, element(1, X) =:= some_tag]
    %% Returns [{some_tag,42}]

On the other hand, if an ordinary expression is used as a filter, there
will be an exception:

  my_element(N, T) -&gt; element(N, T).

  t() -&gt;
    L = [{some_tag,42},an_atom],
    [X || X &lt;- L, my_element(1, X) =:= some_tag]
    %% Causes a 'badarg' exception when element(1, an_atom) is evaluated

It has been allowed for several releases to override a BIF with
a local function. Thus, if we define a function called element/2,
it will be called instead of the BIF element/2 within the module.
We must use the "erlang:" prefix to call the BIF.

Therefore, the following code is expected to work the same way as in
our second example above:

-compile({no_auto_import,[element/2]}).

element(N, T) -&gt;
    erlang:element(N, T).

t() -&gt;
    L = [{some_tag,42},an_atom],
    [X || X &lt;- L, element(1, X) =:= some_tag].
    %% Causes a 'badarg' exception when element(1, an_atom) is evaluated

But the compiler refuses to compile the code with the following
diagnostic:

  call to local/imported function element/2 is illegal in guard
</pre>
</div>
</content>
</entry>
<entry>
<title>debugger: Eliminate use of sys_pre_expand</title>
<updated>2016-09-01T13:16:03+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bjorn@erlang.org</email>
</author>
<published>2016-08-17T10:58:28+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=3db1a9683b05079f8adca4a0621b2a4f336ae7c9'/>
<id>3db1a9683b05079f8adca4a0621b2a4f336ae7c9</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Move expansion of strings in binaries to v3_core</title>
<updated>2016-08-04T11:22:14+00:00</updated>
<author>
<name>José Valim</name>
<email>jose.valim@plataformatec.com.br</email>
</author>
<published>2016-07-16T20:24:50+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=a5fcd4f26969a768950dc643eeed2fdb41a5dc41'/>
<id>a5fcd4f26969a768950dc643eeed2fdb41a5dc41</id>
<content type='text'>
This speeds up the compilation of binary literals
with string values in them. For example, compiling
a file with a ~340kB binary would yield the following
times by the compiler:

    Compiling "foo"
     parse_module       :   0.130 s    5327.6 kB
     transform_module   :   0.000 s    5327.6 kB
     lint_module        :   0.011 s    5327.8 kB
     expand_module      :   0.508 s   71881.2 kB
     v3_core            :   0.463 s      11.5 kB

Notice the increase in memory and processing time
in expand_module and v3_core. This happened because
expand_module would expand the string in binaries
into chars. For example, the binary &lt;&lt;"foo"&gt;&gt;, which
is represented as

    {bin, 1, [
      {bin_element, 1, {string, 1, "foo"}, default, default}
    ]}

would be converted to

    {bin, 1, [
      {bin_element, 1, {char, 1, $f}, default, default},
      {bin_element, 1, {char, 1, $o}, default, default},
      {bin_element, 1, {char, 1, $o}, default, default}
    ]}

However, v3_core would then traverse all of those
characters and convert it into an actual binary, as it
is a literal value.

This patch addresses this issue by moving the expansion
of string into chars to v3_core and only if a literal
value cannot not be built. This reduces the compilation
time of the file mentioned above to the values below:

    Compiling "bar"
     parse_module       :   0.134 s    5327.6 kB
     transform_module   :   0.000 s    5327.6 kB
     lint_module        :   0.005 s    5327.8 kB
     expand_module      :   0.000 s    5328.7 kB
     v3_core            :   0.013 s      11.2 kB
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This speeds up the compilation of binary literals
with string values in them. For example, compiling
a file with a ~340kB binary would yield the following
times by the compiler:

    Compiling "foo"
     parse_module       :   0.130 s    5327.6 kB
     transform_module   :   0.000 s    5327.6 kB
     lint_module        :   0.011 s    5327.8 kB
     expand_module      :   0.508 s   71881.2 kB
     v3_core            :   0.463 s      11.5 kB

Notice the increase in memory and processing time
in expand_module and v3_core. This happened because
expand_module would expand the string in binaries
into chars. For example, the binary &lt;&lt;"foo"&gt;&gt;, which
is represented as

    {bin, 1, [
      {bin_element, 1, {string, 1, "foo"}, default, default}
    ]}

would be converted to

    {bin, 1, [
      {bin_element, 1, {char, 1, $f}, default, default},
      {bin_element, 1, {char, 1, $o}, default, default},
      {bin_element, 1, {char, 1, $o}, default, default}
    ]}

However, v3_core would then traverse all of those
characters and convert it into an actual binary, as it
is a literal value.

This patch addresses this issue by moving the expansion
of string into chars to v3_core and only if a literal
value cannot not be built. This reduces the compilation
time of the file mentioned above to the values below:

    Compiling "bar"
     parse_module       :   0.134 s    5327.6 kB
     transform_module   :   0.000 s    5327.6 kB
     lint_module        :   0.005 s    5327.8 kB
     expand_module      :   0.000 s    5328.7 kB
     v3_core            :   0.013 s      11.2 kB
</pre>
</div>
</content>
</entry>
<entry>
<title>Remove ?line macros</title>
<updated>2016-04-18T06:47:32+00:00</updated>
<author>
<name>Björn Gustavsson</name>
<email>bjorn@erlang.org</email>
</author>
<published>2016-03-02T05:50:54+00:00</published>
<link rel='alternate' type='text/html' href='http://git.ninenines.eu/otp.git/commit/?id=5f91c7307220d629f76ef1a914a480ba2a3d018e'/>
<id>5f91c7307220d629f76ef1a914a480ba2a3d018e</id>
<content type='text'>
While we are it, also re-ident the files.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
While we are it, also re-ident the files.
</pre>
</div>
</content>
</entry>
</feed>
