Age | Commit message (Collapse) | Author |
|
* maint:
Updated OTP version
Update release notes
Update version numbers
erts: Fix "Prevent inconsistent node lists" fix
Fix include-path regression caused by dd0a39c
Restore default SIGTERM behaviour for port programs
|
|
* maint-21:
Updated OTP version
Update release notes
Update version numbers
erts: Fix "Prevent inconsistent node lists" fix
Fix include-path regression caused by dd0a39c
Restore default SIGTERM behaviour for port programs
|
|
|
|
|
|
Include paths don't actually affect code generation in any way, but
it's reasonable for a build tool like rebar3 to recompile when the
include paths change. This commit restores the old behavior without
the +deterministic flag.
|
|
Sometimes when building a tuple, there is no way to avoid an
extra `move` instruction. Consider this code:
make_tuple(A) -> {ok,A}.
The corresponding BEAM code looks like this:
{test_heap,3,1}.
{put_tuple,2,{x,1}}.
{put,{atom,ok}}.
{put,{x,0}}.
{move,{x,1},{x,0}}.
return.
To avoid overwriting the source register `{x,0}`, a `move`
instruction is necessary.
The problem doesn't exist when building a list:
%% build_list(A) -> [A].
{test_heap,2,1}.
{put_list,{x,0},nil,{x,0}}.
return.
Introduce a new `put_tuple2` instruction that builds a tuple in a
single instruction, so that the `move` instruction can be eliminated:
%% make_tuple(A) -> {ok,A}.
{test_heap,3,1}.
{put_tuple2,{x,0},{list,[{atom,ok},{x,0}]}}.
return.
Note that the BEAM loader already combines `put_tuple` and `put`
instructions into an internal instruction similar to `put_tuple2`.
Therefore the introduction of the new instruction will not speed up
execution of tuple building itself, but it will be less work for
the loader to load the new instruction.
|
|
* hasse/dialyzer/improve_guards/OTP-15268/ERL-680:
dialyzer: Improve handling of complex guards
|
|
uabboli/hasse/dialyzer/improve_guards/OTP-15268/ERL-680
dialyzer: Improve handling of complex guards
|
|
See also https://bugs.erlang.org/browse/ERL-680.
The right associative short circuit expressions 'andalso' and 'orelse'
are expanded by the Compiler (see v3_core) into 'case' expressions. If
parentheses are used to enforce left associativeness, variables are
introduced, and the time needed by Dialyzer increases exponentially.
Rather than trying to fix Dialyzer itself, v3_core now rewrites
repeated use of 'andalso' ('orelse') into right associative
expressions before creating the 'case' expressions.
|
|
* bjorn/compiler/ssa:
Travis CI: Run the SSA linter in the Linux64SmokeTest build
Remove retired compiler passes
Introduce a new SSA-based intermediate format
hipe_beam_to_icode: Correct translation of get_map_elements
beam_dead: Remove shortcut of binary matching instruction
beam_bs: Remove optimizations that are easier done on SSA format
Don't run unsafe compiler passes
Simplify optimizations by introducing is_nil late
beam_utils: Make is_tagged_tuple a pure test
beam_except: Enhance recognition of function_clause exceptions
beam_validator: Infer the types of copies in a smarter way
beam_validator: Improve merge of cons and literal list
beam_validator: Strengthen validation of func_info
beam_validator: Allow get_tuple_element before dsetelement
beam_validator: Don't transfer state to labels that can't be reached
beam_validator: Improve type analysis for tuples
beam_validator: Be more careful when updating try/catch state
beam_trim: Handle an empty list of instructions
v3_core: Number argument variables in ascending order
Teach binary instructions to use Y registers as destination
OTP-14894
|
|
|
|
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.)
|
|
* maint:
map_SUITE: Test is_map_key/2 followed by a map update
beam_validator: Infer the type of the map argument for is_map_key/2
map_SUITE: Cover map_get optimizations in beam_dead
|
|
|
|
Make sure that beam_validator considers a call to is_map_key/2
followed by an update of the same map without an is_map/1 test
safe. (This situation will probably not be encountered when
using the compiler in OTP 21, but better safe than sorry.)
|
|
|
|
This optimization can be better done in the SSA format before
code generation.
|
|
The removal of redundant bs_restore2 instructions is done easier
on the SSA format. Keep the rest of the optimizations, because
they are easier to do on the BEAM instructions.
|
|
As a preparation for replacing v3_codegen with a new code generator,
remove unsafe optimization passes. Especially the older compiler
passes have implicit assumptions about how the code is generated.
Remove the optimizations in beam_block (keep the code that creates
blocks) because they are unsafe. beam_block also calls
beam_utils:live_opt/1, which is unsafe.
Remove beam_type because it calls beam_utils:live_opt/1, and also
because it recalculates the number of heaps words and number of live
registers in allocation instructions, thus potentially hiding bugs in
other passes.
Remove beam_receive because it is unsafe.
Remove beam_record because it is the only remaining user
of beam_utils:anno_defs/1.
Remove beam_reorder because it makes much more sense to run it
as an early SSA-based optimization pass.
Remove the now unused functions in beam_utils:
anno_def/1
delete_annos/1
is_killed_block/2
live_opt/1
usage/3
Note that the following test cases will fail because of the
removed optimizations:
compile_SUITE:optimized_guards/1
compile_SUITE:bc_options/1
receive_SUITE:ref_opt/1
|
|
|
|
This will enable more optimizations.
|
|
Don't match exact BEAM instructions when trying to recognize
function_clause exceptions that should be replaced with a jump to the
func_info instruction. Instead, do a symbolic evaluation of the list
building code and see if the result is a list of the argument
registers.
While at it, also teach fix_block_1/2 to completely remove a test_heap
instruction before an exception generation instruction.
|
|
Smarter code generation means that beam_validator must
be smarter too. In the following example, beam_validator
must be able to infer that y0 refers to a map:
move x0 y0
test is_map L1 x0
%% Here the type for y0 must be 'map'.
|
|
|
|
The func_info instruction does not expect a stack frame. There will
be an assertion failure in the debug-compiled runtime system.
|
|
|
|
If we transfer state appropriately to labels that can't be reached,
the state could taint other labels.
|
|
Since the compiler will start optimizing more aggressively, beam_validator
must keep up and improve the recognization of tuples and maps.
|
|
The new code generator will more aggressively reuse registers,
so we must be more careful about updating the state for try/catch.
In particular, an "empty" try/catch that can't throw an
exception must not update the try/catch state.
|
|
|
|
Nicer to read and less confusion.
|
|
* maint:
Fix compiler crash when compiling double receives
erts: Delete fd from poll-set when closing fd_driver port
|
|
remove_message just remove messages without writing to any register.
Compiler is already generating code like:
{get_tuple_element,{x,0},1,{x,0}}.
remove_message.
{jump,{f,6}}
That clearly uses x0 for other purposes.
|
|
The compiler would crash when compiling a function with two
receive statements.
https://bugs.erlang.org/browse/ERL-703
|
|
* maint:
Correct error behavior of is_map_key/2 in guards
|
|
Correct error behavior of is_map_key/2 in guards
|
|
Consider the following functions:
foo() -> bar(not_a_map).
bar(M) when not is_map_key(a, M) -> ok;
bar(_) -> error.
What will `foo/0` return? It depends. If the module is compiled
with the default compiler options, the return value will be
`ok`. If the module is compiled with the `inline` option,
the return value will be `error`.
The correct value is `error`, because the call to `is_map_key/2`
when the second argument is not a map should fail the entire
guard. That is the way other failing guards BIFs are handled.
For example:
foo() -> bar(not_a_tuple).
bar(T) when not element(1, T) -> ok;
bar(_) -> error.
`foo/0` always returns `error` (whether the code is inlined
or not).
This bug can be fixed by changing the classification of `is_map_key/2`
in the `erl_internal` module. It is now classified as a type test,
which is incorrect because type tests should not fail. Reclassifying
it as a plain guard BIF corrects the bug.
This correction also fixes the internal consistency check
failure which was reported in:
https://bugs.erlang.org/browse/ERL-699
|
|
* maint:
Updated OTP version
Update release notes
Update version numbers
|
|
* maint-21:
Updated OTP version
Update release notes
Update version numbers
|
|
|
|
|
|
'john/compiler/fix-deterministic-include-paths/OTP-15204/ERL-679' into maint-21
* john/compiler/fix-deterministic-include-paths/OTP-15204/ERL-679:
Omit include path debug info for +deterministic builds
# Conflicts:
# lib/compiler/test/compile_SUITE.erl
|
|
* maint:
Updated OTP version
Update release notes
Update version numbers
crypto: Fix crash in compute_key(ecdh, ...) on badarg
Relax add_table_copy restriction
Fixed #Ref ordering bug
Test #Ref ordering in lists and ets
Do NOT disc_load from ram_copies when master_node is set
ssl: Make sure that a correct cipher suite is selected
ssl: Correct handling of empty server SNI extension
|
|
* maint-20:
Updated OTP version
Update release notes
Update version numbers
crypto: Fix crash in compute_key(ecdh, ...) on badarg
Relax add_table_copy restriction
Fixed #Ref ordering bug
Test #Ref ordering in lists and ets
Do NOT disc_load from ram_copies when master_node is set
ssl: Make sure that a correct cipher suite is selected
ssl: Correct handling of empty server SNI extension
|
|
* maint:
Fix bug in binary matching
|
|
bjorng/bjorn/compiler/binary-syntax/ERL-689/OTP-15219
Fix bug in binary matching
|
|
|
|
|
|
* maint:
Omit include path debug info for +deterministic builds
|
|
'john/compiler/fix-deterministic-include-paths/OTP-15204/ERL-679' into maint
* john/compiler/fix-deterministic-include-paths/OTP-15204/ERL-679:
Omit include path debug info for +deterministic builds
|