Age | Commit message (Collapse) | Author |
|
beam_utils:live_opt() is only invoked on code that has been
blockified by beam_block. Therefore the allocate/3 and
allocate_heap/4 instructions only occur in their transformed
form inside a block.
While we are it, correct a comment. 'asm' has been replaced
by 'from_asm'.
|
|
While we are it, also remove ?line macros in ref_opt_1/1 and correct
the indentation in do_ref_opt/2.
|
|
The compiler_bug/1 test case succeeded for the wrong reason. The
'asm' option is no longer supported (was ignored) and the compiler
looked for a .erl file.
Make sure that we don't fall for this trick again by making sure
that the error is reported from beam_validator.
|
|
Commits b44f86b7 and 97953704 introduced translations of instructions
in beam_a and beam_z, but forgot to remove the handling of them in
beam_clean.
|
|
Cover more code in v3_core.
|
|
* maint:
Update primary bootstrap
beam_bool: Correct live calculation for GC BIFs
beam_bool: Correct indentation for try...catch
sys_core_fold: Correct optimization of 'case'
Conflicts:
bootstrap/bin/start.boot
bootstrap/bin/start_clean.boot
bootstrap/lib/compiler/ebin/beam_asm.beam
bootstrap/lib/stdlib/ebin/io_lib_pretty.beam
|
|
* bjorn/compiler/map-in-record-bug/OTP-12402:
sys_core_fold: Correct optimization of 'case'
|
|
When optimizing boolean expressions, it is not always possible
to find a number of live registers for a GC BIF that both preserves
all source registers that will be tested and at the same time
does not include registers that are not initialized.
As currently implemented, we have incomplete information about
the register calculated from the free variables. Some registers
are marked as "reserved". Reserved registers means that we don't
know anything about them; they may or may not be initialized.
As a conservative correction (suitable for a maintenance release), we
will abort the optimization if we find any reserved registers when
calculating the number of live registers. We will not attempt to
improve the information about the registers in this commit.
By examining the coverage when running the existing compiler test
suite we find that the optimization is aborted 15 times (before
adding any new test cases). To put that in perspective, the
optimization is successfully applied 4927 times, and aborted for
other reasons 547 times.
Reported-by: Ulf Norell
Reported-by: Anthony Ramine
|
|
Old versions of the Erlang mode for Emacs used to indent try...catch
strangely - the first clause following the 'catch' would be indented
with one space less than the following clauses.
If we are to use the new Erlang mode when we add more clauses, they
would be indented with one space less than the preceding clauses.
That would look silly.
|
|
The optimization of a 'case' statement could lead to incorrect
code that would cause an exception at run-time.
Here is an example to show how the optimization went wrong. Start
with the following code:
f({r,#{key:=Val},X}=S) ->
case S of
{r,_,_} ->
setelement(3, Val, S)
end.
(The record operations have already been translated to the
corresponding tuple operations.) The first step in case_opt/3 is
to substitute S to obtain:
f({r,#{key:=Val},X}=S) ->
case {r,#{key:=Val},X} of
{r,_,_} ->
setelement(3, Val, S)
end.
After that substitution the 'case' can be simplified to:
f({r,#{key:=Val},_}=S) ->
case #{key:=Val} of
NewVar ->
setelement(3, Val, S)
end.
That is the result from case_opt/3. Now eval_case/2 notices
that since there is only one clause left in the 'case', the
'case' can eliminated:
f({r,#{key:=Val},_}=S) ->
NewVar = #{key:=Val},
setelement(3, Val, S).
Since the map construction may have a side effect, it was not
eliminated, but assigned to a variable that is never used.
The problem is that '#{key:=Val}' is fine as a pattern, but in a
construction of a new map, the '=>' operator must be used. So the
map construction will fail, generating an exception.
As a conservative correction for a maintenance release, we will
abort the 'case' optimization if the substitution into the 'case'
expression is anything but data items (tuples, conses, or
literals) or variables.
Reported-by: Dmitry Aleksandrov
|
|
|
|
|
|
While we are, clean up the comments and rearrange the code for
clarity. Also add a test to cover the last uncovered line in
beam_dead.erl.
|
|
Amend the test suite to call beam_dead as originally intended (and not
beam_block), and modify the input data so that the exception will
occur within the try ... catch block in function/2.
|
|
Better optimizations with less code.
|
|
The BEAM compiler translates code such as:
is_hex_digit(D) when $0 =< D, D =< $9 -> true;
is_hex_digit(D) when $a =< D, D =< $z -> true;
is_hex_digit(D) when $A =< D, D =< $Z -> true;
is_hex_digit(_) -> false.
to something like this:
L0: test is_ge L1 {x,0} 48
test is_ge L1 57 {x,0}
move true {x,0}
return.
L1: test is_ge L2 {x,0} 97
test is_ge L2 122 {x,0}
move true {x,0}
return
L2: test is_ge L3 {x,0} 65
test is_ge L3 90 {x,0}
move true {x,0}
return
L3: move false {x,0}
return
We can see that tests will be repeated even if they cannot possibly
succeed. For instance, if we pass in {x,0} equal to 32, the first
test that {x,0} is greater than or equal to 48 at L0 will fail.
The control will transfer to L1, where it will be tested whether
{x,0} is greater than 97. That test will fail and control
will pass to L2, where again the test will fail.
The compiler can do better by short-circuiting repeating tests:
L0: test is_ge L3 {x,0} 48
test is_ge L1 57 {x,0}
move true {x,0}
return.
L1: test is_ge L2 {x,0} 97
test is_ge L3 122 {x,0}
move true {x,0}
return
L2: test is_ge L3 {x,0} 65
test is_ge L3 90 {x,0}
move true {x,0}
return
L3: move false {x,0}
return
|
|
=== OTP-17.4 ===
Changed Applications:
- asn1-3.0.3
- common_test-1.9
- compiler-5.0.3
- crypto-3.4.2
- debugger-4.0.2
- dialyzer-2.7.3
- diameter-1.8
- edoc-0.7.16
- eldap-1.1
- erl_docgen-0.3.7
- erl_interface-3.7.20
- erts-6.3
- eunit-2.2.9
- hipe-3.11.2
- inets-5.10.4
- jinterface-1.5.12
- kernel-3.1
- megaco-3.17.3
- mnesia-4.12.4
- observer-2.0.3
- odbc-2.10.22
- otp_mibs-1.0.10
- parsetools-2.0.12
- percept-0.8.10
- runtime_tools-1.8.15
- snmp-5.1.1
- ssh-3.1
- ssl-5.3.8
- stdlib-2.3
- syntax_tools-1.6.17
- test_server-3.7.2
- tools-2.7.1
- wx-1.3.2
Unchanged Applications:
- cosEvent-2.1.15
- cosEventDomain-1.1.14
- cosFileTransfer-1.1.16
- cosNotification-1.1.21
- cosProperty-1.1.17
- cosTime-1.1.14
- cosTransactions-1.2.14
- et-1.5
- gs-1.5.16
- ic-4.3.6
- orber-3.7.1
- os_mon-2.3
- ose-1.0.2
- public_key-0.22.1
- reltool-0.6.6
- sasl-2.4.1
- typer-0.9.8
- webtool-0.8.10
- xmerl-1.3.7
Conflicts:
OTP_VERSION
erts/vsn.mk
|
|
|
|
This fixes a regression introduced in commit 805f9c89fc01220bc1bb0f27e1b68fd4eca688ba
The problem occured with map keys compiled with dialyzer option turned on.
In OTP 17, map keys needs to be literals.
|
|
* maint:
Fix miscompilation when module contains multiple named funs
Fix locations of shadowing warnings in ms_transform
|
|
Commit 78ce8917d started to use get_anno/1 to extract the line
annotation from filter qualifiers in comprehensions, but this does not
respect the spec of this function and resuls in a dialyzer warning.
To make the code more type-friendly, introduce a get_qual_anno/1
function.
Kostis Sagonas suggested that the function should be implemented
similar to this to also ensure that the qualifiers are of the
appropriate form:
get_qual_anno({call,Line,_,_}) -> Line;
get_qual_anno({op,Line,_,_,_}) -> Line;
.
.
.
get_qual_anno({var,Line,_}) -> Line.
The problem is that it is difficult to know exacly which forms
that may occur and the function will need to be updated if new
abstract forms are added. Thus this implementation would complicate
maintanance without any real payoff.
Reported-by: Kostis Sagonas
|
|
A module containing two named funs bearing the same name and arity could be
miscompiled.
Reported-by: Sam Chapin
|
|
* egil/map-type-opt/OTP-12253:
compiler: Type is_nonempty_list optimization
compiler: Type map optimization
|
|
* tuncer/compiler/finalize-asm-deprecation/OTP-12100:
compiler: finalize 18.x 'asm' deprecation
|
|
|
|
|
|
* egil/maps/variable-keys/OTP-12218: (22 commits)
compiler: Update test for Maps aliasing
compiler: Properly support Map aliasing
compiler: Refactor Map pairs aliasing
compiler: Fix harmless need_heap error for Maps
stdlib: Update Map tests
stdlib: Use environment bindings for Maps keys in erl_eval matching
debugger: Update Map tests
compiler: Update Map tests
compiler: Fix v3_core Maps pair chains
compiler: Use expressions in core patterns
compiler: Use variables in Map cerl inliner
compiler: Reintroduce binary limit for Map keys
compiler: Shameless v3_core hack for variables
compiler: Use variables in Map beam assmebler
compiler: Use variables in Map kernel pass
compiler: Use variables in Map core pass
compiler: Normalize unary ops on Maps key literals
stdlib: Update Map tests
stdlib: erl_lint Map key variables
compiler: Maps are always patterns never values in matching
...
|
|
|
|
Matching of type:
#{K := V1} = #{K := V2} = M,
Will alias (coalesce) to
#{K := V1 = V2} = M.
|
|
|
|
Need heap for maps is zero and fall through is also zero.
|
|
=== OTP-17.3 ===
Changed Applications:
- asn1-3.0.2
- common_test-1.8.2
- compiler-5.0.2
- crypto-3.4.1
- dialyzer-2.7.2
- diameter-1.7.1
- edoc-0.7.15
- erl_docgen-0.3.6
- erl_interface-3.7.18
- erts-6.2
- eunit-2.2.8
- hipe-3.11.1
- ic-4.3.6
- inets-5.10.3
- jinterface-1.5.10
- kernel-3.0.3
- megaco-3.17.2
- mnesia-4.12.3
- observer-2.0.2
- odbc-2.10.21
- os_mon-2.3
- ose-1.0.1
- public_key-0.22.1
- sasl-2.4.1
- snmp-5.1
- ssh-3.0.5
- ssl-5.3.6
- stdlib-2.2
- tools-2.7
- wx-1.3.1
Unchanged Applications:
- cosEvent-2.1.15
- cosEventDomain-1.1.14
- cosFileTransfer-1.1.16
- cosNotification-1.1.21
- cosProperty-1.1.17
- cosTime-1.1.14
- cosTransactions-1.2.14
- debugger-4.0.1
- eldap-1.0.3
- et-1.5
- gs-1.5.16
- orber-3.7
- otp_mibs-1.0.9
- parsetools-2.0.11
- percept-0.8.9
- reltool-0.6.6
- runtime_tools-1.8.14
- syntax_tools-1.6.16
- test_server-3.7.1
- typer-0.9.8
- webtool-0.8.10
- xmerl-1.3.7
Conflicts:
OTP_VERSION
erts/vsn.mk
|
|
|
|
|
|
|
|
The scope is supposed to contain all variables that are currently
live. We need this information for certain optimizations to
avoid capturing a name (a name that is in the scope must be renamed;
for an example, see move_let_into_expr/2 or any function that calls
sub_subst_scope/1). We also use the scope to optimize sub_del_var/2
and sub_is_val/2.
When optimizing case expressions, the scope could be reset to an
empty list (because sub_new/0 was called instead of sub_new/1).
That could cause name capture if inlining was turned on.
As simple way to force this bug is to uncomment the
"-define(DEBUG, 1)." near the beginning of the file. Without this
correction, most files in the test suite fail to compile.
|
|
|
|
Check for literals instead of variables when constructing chains.
|
|
Two patterns, binary_segment size and map_pair key, are expressions
even in matching. If only bound variables are used we are fine but
some expressions which appears as literals needs to be lifted.
Currently only Map key binaries will use this.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Unary ops are normalized before core transformation, i.e. handle
negative integers as map keys.
Strictly speaking, map keys are expressions but by handling them as
patterns we can normalize negative integers.
|
|
'asm' was deprecated in 18315c16, to be removed in 18.x.
|
|
* nox/compiler/improve-core-lint:
Remove obsolete comment in core_lint
Handle return mismatches for calls and primops
Check for more return mismatches
Use +clint0 in compiler's test suites
|
|
|
|
Only exit BIFs and the match_fail primop are allowed to run where more than one
value is expected.
|