Age | Commit message (Collapse) | Author |
|
* maint:
Fix an internal consistency check failure caused by beam_except
|
|
* john/compiler/recv-test-coverage:
compiler: Improve test coverage for recv_crit_edges
|
|
|
|
https://bugs.erlang.org/browse/ERL-1026
|
|
* maint:
Fix compiler crash when compiling some receive statements
|
|
The compiler would crash when compiling the following code:
do(Acc) ->
receive
{Pid, abc} ->
ok;
{Pid, []} ->
ok;
{Pid, _Res} ->
exit(_Res)
end,
do([Pid | Acc]).
The last clause that always raises an exception would confuse the
compiler so that it would think that the `receive` statement was at the
end of the function and it would generate incorrect code for the `do/1`
call following the `receive`.
https://bugs.erlang.org/browse/ERL-1022
|
|
* john/compiler/fix-bs_skip-succeeded-oddity:
compiler: Fix awkward match context substitution
beam_ssa_lint: Use #b_var{} instead of variable names
|
|
* john/compiler/remove-dead-code-beam_ssa_type:
beam_ssa_type: Remove unreachable code
|
|
Expand and squeeze literal integers/utf8 bin segments
|
|
This worked out by accident since codegen never actually looks at
the arguments for 'succeeded'; it just assumes that they reference
the preceding instruction.
|
|
|
|
Now that impossible branches are skipped altogether, it's no
longer possible to encounter get_tuple_element with a 'none'
argument.
|
|
* john/compiler/validator-improve-try_case-handling:
beam_validator: Disallow jumps to try_case handlers
|
|
* john/compiler/explicit-call-exceptions:
compiler: Simplify set_tuple_element optimization
compiler: Make 'succeeded' optimization more general
compiler: Simplify call type optimization
compiler: All calls may throw, so they all need success checks
erts_debug: Turn off unsafe optimizations in test case
|
|
* lukas/otp/add-dialyzer-make-target/OTP-15915:
otp: Add make dialyzer and make xmllint documentation
Add 'make dialyzer' target to top and apps
|
|
By keeping track of the tag types in the exception handler list,
we can reject direct jumps to try_case handlers such as those
provoked by OTP-15945.
|
|
By removing 'succeeded' tests on setelement/3 when we know it
succeeds, all sequences that are eligible for set_tuple_element
will be nicely bundled in the same block, so we won't need to
bother with special try/catch handling.
The new version is slightly worse in the case where the first
setelement/3 is used to infer the tuple size as that call will
remain in its own block, but in practice this only occurs when
the user manually spells them out and I couldn't find any
examples of this in OTP or Elixir. It's equivalent for record
updates.
|
|
|
|
|
|
Only adding them when in try/catch worked, but made the exceptions
implicit and forced all later optimization passes to keep them in
mind. Making them explicit lets us simplify later passes.
|
|
* maint:
Ensure that the stack slots are initialized when matching maps
|
|
* bjorn/compiler/fix-stack-init/ERL-1017/OTP-15968:
Ensure that the stack slots are initialized when matching maps
|
|
When matching a map, the compiler could fail to generate code that
would initialize all stack slots (Y registers) properly. Here is a
general outline of code that *could* cause this problem:
foo(Key, Map) ->
Res = case Map of
#{Key := Val} ->
%% Do something with Val here.
.
.
.
#{} ->
[]
end,
%% The stack slot for Val might not have been initialized
%% here if the key was not present in the map.
.
.
.
%% Use Res.
.
.
.
The code generator would wrongly assume that the map matching would
always initialize the stack slot, and if nothing else happened to
force that stack slot to be initialized, it would remain
uninitialized, which would likely crash the runtime system at the next
garbage collection.
`beam_validator` is supposed to find these kind of problems, but a bug
in `beam_validator` prevented it from detecting this problem.
https://bugs.erlang.org/browse/ERL-1017
|
|
This commit adds two operations when handling literal
integers and literal utf8 segments in the v3_kernel pass.
The first operation is to expand all literal integers with
size more than 8 and literal utf8s into integers with size
of 8 (and potentially an integer with size less than 8 at
the end).
This expansion simplifies the code in other operations
inside v3_kernel and ensure they apply more consistently.
For instance, literal binary matching now applies to both
regular and utf8 strings. Furthermore, we can more
efficiently group clauses.
For instance, the following code:
foo(<<$á/utf8, X/binary>>) -> foo(X);
foo(<<$é/utf8, X/binary>>) -> foo(X);
foo(<<>>) -> ok.
Becomes a bs_get_integer_16 comparing 50089 and 50081,
allowing us to skip the utf8 conversion at runtime.
However, since expanding an integer of size 16 into two of
size 8 can be less efficient when matching at runtime,
later we do another pass, where we squeeze all of those
integers together into an integer with maximum size of 24.
This allows prefix matching, such as:
foo(<<"aaaa", X/binary>>) -> foo(X);
foo(<<"bbbb", X/binary>>) -> foo(X);
foo(<<>>) -> ok.
To run more than 2x faster (as long as all clauses match on
a given prefix).
Compilation times and binary size are roughly the same.
|
|
* maint:
beam_validator: Values referenced by other values must be merged
|
|
into maint
* john/compiler/fix-delayed-type-inference/OTP-15954/ERL-995:
beam_validator: Values referenced by other values must be merged
|
|
Optimize is_subset and is_disjoint in cerl_sets
|
|
* maint:
Avoid extremely long compilation times for huge functions
|
|
bjorng/bjorn/compiler/fix-slow-beam_ssa_dead/ERL-1014/OTP-15966
Avoid extremely long compilation times for huge functions
|
|
* maint:
Fix compiler crash when compiling with +no_type_opt
Eliminate a crash in the type optimizer pass
|
|
https://github.com/bjorng/otp into maint
OTP-15970
* 'bjorn/compiler/length-misuse/ERL-1013' of https://github.com/bjorng/otp:
Eliminate a crash in the type optimizer pass
|
|
https://github.com/bjorng/otp into maint
OTP-15969
* 'bjorn/compiler/fix-no_type_opt/ERL-997' of https://github.com/bjorng/otp:
Fix compiler crash when compiling with +no_type_opt
|
|
Compiling this example takes less than a second for OTP 21:
-define(B, {?A,?A,?A,?A,?A}).
-define(C, {?B,?B,?B,?B,?B}).
-define(D, {?C,?C,?C,?C,?C}).
-define(E, {?D,?D,?D}).
f() -> ?E = foo:bar().
The compilation time for OTP 22 is about 10 seconds. Most of the
time is spent in `beam_ssa_dead`.
This commit introduces several optimizations to bring the compilation
time down to about a second.
The most important of those optimizations is limiting the effort spent
searching forward for a joining point for the success and failure
labels for a two-way branch. This change is helped by the change of
representation of variable sets from `ordsets` to `cerl_sets`.
https://bugs.erlang.org/browse/ERL-1014
|
|
* maint:
Fix unsafe code sharing
|
|
* bjorn/compiler/fix-unsafe-sharing/OTP-15963:
Fix unsafe code sharing
|
|
If the `no_type_opt` option was given, the compiler would crash when
attempting to compile containing with a `try`...`after` construct,
such as this code:
foo() ->
try
make_ref()
after
ok
end.
To avoid having this bug re-appear, test the `no_type_opt` option
in the test suites.
https://bugs.erlang.org/browse/ERL-997
|
|
https://bugs.erlang.org/browse/ERL-1013
|
|
|
|
The new implementation use maps iterators and are more
perfomant in banchmarks by roughly 10%. More importantly,
the iterators approach allow us to short-circuit and abort
early.
fold and filter have also been changed to use iterators.
We could simply delegate to the maps' functions, but
inlining the implementation allows us to skip a double
anonymous function dispatch.
|
|
* john/compiler/improve-validator-type-inference/ERL-998:
beam_validator: Improve type inference on inequality
beam_validator: Remove redundant calls to infer_types
|
|
This is a more proper fix for ERIERL-348. We used to think that
we wouldn't need to update the type of a variable that's no
longer referenced by a register ("dead value"), but the attached
test case pokes a hole in that assumption.
To summarize, the result of '=:='/2 is kept alive longer than one
of its arguments, which gets pruned in a state merge leaving us
with nothing to work on when we finally compare the result. This is
fine for most operations since there's no point in (say) updating
the size of a tuple we can no longer reach, but '=:='/2 updates
the types of both arguments and we risk missing out on important
information when either of them is gone.
This commit fixes the problem by merging all values that are
*reachable* from a register, rather than just those that *exist*
in a register, ensuring that all values stay around at least as
long as they're needed.
|
|
* maint:
Updated OTP version
Prepare release
# Conflicts:
# OTP_VERSION
# make/otp_version_tickets_in_merge
|
|
* maint-22:
Updated OTP version
Prepare release
# Conflicts:
# make/otp_version_tickets
|
|
Both sides need to be inferred, and we should infer as if we've
made an exact match when we know that LHS is single-valued. This
was done for select_val, but we failed to do so for is_ne_exact
et al.
|
|
|
|
* maint:
compiler: Fix compiler crash introduced by OTP-15952
|
|
into maint
* john/compiler/fix-bad-try_catch-recv-fix/OTP-15953/ERL-999:
compiler: Fix compiler crash introduced by OTP-15952
|
|
|
|
An assertion in code generation would fail when the common exit
block was ?BADARG_BLOCK, as some operations expect to always "fail"
directly to that block (= throw an exception) and we had inserted
a dummy block in between.
Other operations could also get funny fail labels, jumping to
blocks that immediately jumped to {f,0}, but these were all cleaned
up by beam_jump, sweeping the bug under the rug.
|
|
* maint:
Updated OTP version
Prepare release
# Conflicts:
# OTP_VERSION
# make/otp_version_tickets_in_merge
|