Repository navigation
Improve the type analysis - #5999
Conversation
CT Test Results 4 files 367 suites 43m 42s ⏱️ For more details on these failures, see this check. Results for commit c412a61. ♻️ This comment has been updated with latest results. To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass. See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally. Artifacts// Erlang/OTP Github Action Bot |
But isn't this particular human wrong? (Because |
jhogberg
left a comment
There was a problem hiding this comment.
LGTM.
But isn't this particular human wrong?
(Because
Acan also be a float. Figuring out thatAmust be a number is OK though.)
There's an is_integer/1 test hiding in the first example. :-)
Yes, I need new glasses :( |
7dcd4e2 to
249aef8
Compare
098e03a to
431545e
Compare
Refactor the type analysis modules in the Erlang compiler to
be able to derive type information from relational operators
in guards.
Consider this function:
f(A) when is_integer(A), 0 =< A, A =< 1000 ->
A + 1.
From the guard, a human can easily figure out that `A` must be
an integer in the range 0 through 1000. The compiler in OTP 25
cannot:
{test,is_integer,{f,1},[{x,0}]}.
{test,is_ge,{f,1},[{tr,{x,0},{t_integer,any}},{integer,0}]}.
{test,is_ge,{f,1},[{integer,1000},{tr,{x,0},{t_integer,any}}]}.
{gc_bif,'+',{f,0},1,[{tr,{x,0},{t_integer,any}},{integer,1}],{x,0}}.
With this commit, the compiler generates the following code:
{test,is_integer,{f,1},[{x,0}]}.
{test,is_ge,{f,1},[{tr,{x,0},{t_integer,any}},{integer,0}]}.
{test,is_ge,{f,1},[{integer,1000},{tr,{x,0},{t_integer,{0,'+inf'}}}]}.
{gc_bif,'+',{f,0},1,[{tr,{x,0},{t_integer,{0,1000}}},{integer,1}],{x,0}}.
The compiler can now also derive better types for the following function:
g(A) when 0 =< A, A =< 1000 ->
A + 1.
Since `A` is sandwiched between two numbers, `A` must be a number:
{test,is_ge,{f,3},[{x,0},{integer,0}]}.
{test,is_ge,
{f,3},
[{integer,1000},
{tr,{x,0},
{t_union,{t_atom,any},
{t_list,any,any},
{t_number,{0,'+inf'}},
{t_tuple,0,false,#{}},
other}}]}.
{gc_bif,'+',{f,0},1,[{tr,{x,0},{t_number,{0,1000}}},{integer,1}],{x,0}}.
The JIT will generate slightly better code for known numeric operands than
for unknown operands.
As part of this commit, the following major changes were made:
* Ranges for integers can now extend to infinity at one endpoint. That
is, a range can go from negative infinity to some integer, or from
some integer to positive infinity. That change allows the compiler to
represent the type for the variable `A` when `A` is known to be an
integer and `A >= 0` is true.
* Changed the number type to also include a (potentially infinite) range.
* Introduced an `other` type as a mean to construct a union type that
is equivalent to the `any` type. That makes it possible to represent
the type for `A` when all we know is that `A >= 0` (see the type in
in the second `is_ge` test in the generated code for `g/1` above).
* The API for the `beam_bounds` module was changed to avoid having to
create functions with the same name as operators and BIFs. Having
functions named `min` and `max` in the module would have been
error-prone and painful.
c412a61 to
92611e5
Compare
Refactor the type analysis modules in the Erlang compiler to
be able to derive type information from relational operators
in guards.
Consider this function:
From the guard, a human can easily figure out that
Amust bean integer in the range 0 through 1000. The compiler in OTP 25
cannot:
With this pull request, the compiler generates the following code:
The compiler can now also derive better types for the following function:
Since
Ais sandwiched between two numbers,Amust be a number:The JIT will generate slightly better code for known numeric operands than
for unknown operands.
As part of this commit, the following major changes were made:
Ranges for integers can now extend to infinity at one endpoint. That
is, a range can go from negative infinity to some integer, or from
some integer to positive infinity. That change allows the compiler to
represent the type for the variable
AwhenAis known to be aninteger and
A >= 0is true.Changed the number type to also include a (potentially infinite) range.
Introduced an
othertype as a mean to construct a union type thatis equivalent to the
anytype. That makes it possible to representthe type for
Awhen all we know is thatA >= 0(see the type inin the second
is_getest in the generated code forg/1above).The API for the
beam_boundsmodule was changed to avoid having tocreate functions with the same name as operators and BIFs. Having
functions named
minandmaxin the module would have beenerror-prone and painful.