Age | Commit message (Collapse) | Author |
|
Conflicts:
bootstrap/lib/compiler/ebin/cerl_inline.beam
|
|
* nox/fix-fname-inlining/OTP-11211:
Added primary bootstrap
Restrict inlining of local fun references
|
|
|
|
* jw/fix-float-middle-endian/OTP-11201:
Fix binary construction on floating point middle-endian machines
Fix binary matching on floating point middle-endian machines
Fix erlang:phash2() on floating point middle-endian machines
Fix external term format BIFs on floating point middle-endian machines
|
|
Local fun references look like plain old variables in the Core Erlang
AST but should not be treated as such. Inlining of such expressions is
now restricted to application contexts as a local fun reference should
never occur in a guard.
This is not perfect as it forbids inlining in some safe situations, but
that is still better than a compiler crash.
|
|
* nox/illegal-bitstring-gen-pattern/OTP-11186:
Bootstrap added
Simplify v3_core's translation of bit string generators
Forbid unsized fields in patterns of binary generators
|
|
This complements 933e701 (OTP-10209). Without this patch the test cases
"in_guard/1" and "coerce_to_float/1" in bs_construct_SUITE fail.
The added lines in bs_construct_SUITE cover all branches that were not
covered before (small and big numbers if BIT_OFFSET(erts_bin_offset) != 0).
|
|
|
|
|
|
When compiling comprehensions with generators which are foldable to
'true', a misleading warning is emitted by sys_core_fold because a
clause resulting from the compilation of the comprehension to Core
Erlang is not marked as generated by the compiler.
An example of such a comprehension is [ true || true ].
|
|
It makes no sense to be able to do `<<...,Rest/binary>> <= ...` in a
comprehension. The related Dialyzer test is removed.
|
|
* maint:
compiler: Correct liveness optimization for wait/1
|
|
The live optimization in beam_utils:live_opt/4 did not take into
account that the wait/1 instruction *never* falls through to
the next instruction (it has the same effect on the control flow
as the jump/1 instruction).
|
|
Conflicts:
bootstrap/lib/stdlib/ebin/beam_lib.beam
lib/public_key/test/erl_make_certs.erl
|
|
Since both the STDLIB and compiler applications turn warnings
into errors, we must stop using the old deprecated crypto functions.
While we are at it, generalize the format of the key tuple returned
by beam_lib:make_crypto_key/2 to facilitate introducing new crypto
methods in the future. Change the format to:
{Type,Key,IV,BlockSize}
where Type, Key, and IV are the first three arguments for either
crypto:block_encrypt4/ or crypto:block_decrypt/4, and BlockSize
is the block size for the crypto algorithm (it is needed to properly
pad the plaintext blocks before encryption).
|
|
|
|
|
|
In some circumstances, as when inlining code, when some optimization
passes are disabled or with hand-written but semantically correct Core
Erlang or BEAM assembly, a fresh reference may be live in more than one
register:
...
{allocate_zero,2,2}.
...
{call_ext,0,{extfunc,erlang,make_ref,0}}. % Ref in [x0]
...
{move,{x,0},{y,0}}. % Ref in [x0,y0]
{move,{y,1},{x,0}}. % Ref in [y0]
...
{move,{y,0},{x,0}}. % Ref in [x0,y0]
{move,{x,0},{y,1}}. % Ref in [x0,y0,y1]
{label,5}.
{loop_rec,{f,6},{x,0}}. % Ref in [y0,y1]
...
{loop_rec_end,{f,5}}.
{label,6}.
{wait,{f,5}}.
...
Pass beam_receive expects a single live register for the ref when it
encounters the loop_rec instruction and crashes with the following
reason:
$ erlc t.S
...
crash reason: {{case_clause,
{'EXIT',
{{case_clause,[{y,1},{y,0}]},
[{beam_receive,opt_recv,5,
[{file,"beam_receive.erl"},{line,154}]},
...]}}},
...}
This commit teaches beam_receive how to use a set of registers instead
of a single one when tracking fresh references, thus avoiding the crash.
|
|
|
|
* nox/fix-bc-optim/OTP-11005:
Add a new option +clint0 to the compiler
Fix optimization of some binary comprehensions
|
|
If a variable bound in a generator is used as the size of a segment
in the comprehension body, v3_core uses this variable in the code
generated to compute the initial size given to the `bs_init_writable`
primop before the variable is actually bound, as in:
<< <<0:S>> || S <- Slist >>
Reported-By: Peer Stritzinger
|
|
beam_utils:is_not_used_at/3 could be very slow for complex guards,
because the cached result for previously encountered labels were
neither used nor updated within blocks.
Reported-by: Magnus Müller
|
|
|
|
Commits 53bd4974a101 and 726f6e4c7afe simplified the handling of
match_fail (used to generated exceptions such as 'function_clause')
by first rewriting them to a call to erlang/error{1,2} and later
rewriting them to specialized BEAM instructions (to reduce the
code size).
There was one flaw, though, which only was exposed when more
aggressive optimizations were added in c3b60f86c622. Here is an
example to explain it:
t(V) ->
fun(get) -> V end.
The following BEAM code will be initially generated for the fun:
{function, '-t/1-fun-0-', 2, 5}.
{label,1}.
{line,[{location,"t.erl",5}]}.
{func_info,{atom,t},{atom,'-t/1-fun-0-'},2}.
{label,2}.
{test,is_eq_exact,{f,2},[{x,0},{atom,get}]}.
{move,{x,1},{x,0}}.
return.
{label,2}.
{test_heap,2,1}.
{put_list,{x,0},nil,{x,1}}.
{move,{atom,function_clause},{x,0}}.
{line,[{location,"t.erl",5}]}.
{call_ext_only,2,{extfunc,erlang,error,2}}.
Translating back to Erlang code, that would be roughly:
'-t/1-fun-0-'(get, V) -> V;
'-t/1-fun-0-'(Arg1, _) -> erlang:error(function_clause, [Arg1]).
Note that the second argument (the free variable V) is not included
in the call to erlang:error/2.
The beam_except pass will simplify the code to:
{function, '-t/1-fun-0-', 2, 8}.
{label,1}.
{line,[{location,"t.erl",5}]}.
{func_info,{atom,t},{atom,'-t/1-fun-0-'},2}.
{label,2}.
{test,is_eq_exact,{f,1},[{x,0},{atom,get}]}.
{move,{x,1},{x,0}}.
return.
The code has been shortened by jumping to the func_info/3 instruction.
Translating back to Erlang:
'-t/1-fun-0-'(get, V) -> V;
'-t/1-fun-0-'(Arg1, Arg2) -> erlang:error(function_clause, [Arg1,Arg2]).
it is clear that both arguments are now included in the
'function_clause' exception, even though the initially generated
code only included the first argument.
That is no problem in this particular case, but for some more complex
funs, optimizing the first version based on variable usage could make
the second version unsafe.
I rejected the following potential solutions:
- Including the free arguments in the call to erlang:error/2:
'-t/1-fun-0-'(get, V) -> V;
'-t/1-fun-0-'(Arg1, Arg2) -> erlang:error(function_clause, [Arg1,Arg2]).
Unfortunately, that is tricky. The free variables are only known
after the second pass in v3_kernel when variable usage has been
calculated. We would need to add a third pass (only for funs) that
would the free arguments to the second argument for erlang:error/2
*and* update the variable usage information.
- Calling beam_except earlier, from within beam_block before any
optimizations based on variable usages are done. But means that the
problem could reappear in some other form in the future when other
updates are done to the code generator and/or optimization passes.
The solution I have chosen is to modify beam_except to only replace
a call to erlang:error(function_class, Args) if the length of Args
is the same as the arity in the func_info/3 instruction. The code
will be slightly larger. Also, the free variables for funs and list
comprehensions will no longer be included in the function_clause
exception (that could be less confusing, but it also means less
information during debugging).
|
|
* nox/fix-seq-opt/OTP-10818:
Add two tests for unused multiple values in effect context
Forbid multiple values in Core Erlang sequence arguments
|
|
|
|
|
|
|
|
|
|
The following code:
check(<<"string">>, a1) ->
one;
check(_, a2) ->
two;
check(undefined, a3) ->
three.
produces an internal consistency failure:
check: function check/2+17:
Internal consistency check failed - please report this bug.
Instruction: {test,is_eq_exact,{f,7},[{x,0},{atom,undefined}]}
Error: {match_context,{x,0}}:
Actually, in the current implementation of the run-time system,
comparing a match context to an atom is safe, so I briefly considered
updating the beam_validator to let this code pass through. I
abandoned that approach because not all terms would be safe to
compare to a match context, and the implementation might change
in the future.
Therefore, fix this problem by not allowing any matching of non-variables
(in the argument position for binary being matched) following binary
matching. That solution is simple and safe, and since this kind of
code seems to be rare in practice, there is no need to pursue any
more compilicated solution.
Reported-by: Viktor Sovietov
|
|
* bjorn/remove-parameterized-modules/OTP-10616:
Remove support for parameterized modules
xref_SUITE: Don't test parameterized modules
shell_SUITE: Don't test parameterized modules
erl_expand_records_SUITE: Don't test parameterized modules
erl_eval: Don't test parameterized modules
|
|
|
|
* nox/promote-inline_list_funcs/OTP-10690:
Raise a function_clause error with the right arguments when inlining
Properly guard against badly-typed arguments when inlining
Make inlined list functions fail with function_clause
Document compiler option 'inline_list_funcs'
Silence some wrong warnings triggered by inline_list_funcs
|
|
The inlined lists functions raised an error with only the list instead
of all their given arguments.
|
|
The inlining code for inline_list_funcs silenced the function_clause
error that should occur when calling lists:map(3.5, []).
|
|
The function_clause errors produced by inline_list_funcs should properly
be annotated with their function names to avoid kernel_v3 making them
into case_clauses errors. See v3_kernel:translate_match_fail_1/4.
|
|
|
|
The handling of bs_start_match2 was both too conservative and too
careless. It was too conservative in that would not do the
optimization if the were copies of the match state in other
registers. It was careless in that it did not consider the
failure branch.
Reorganize the code and fix both these issues. Add a test case
to test that the failure branch is considered.
|
|
|
|
|
|
* maint:
Fix compiler crash for binary matching and a complicated guard
|
|
Commit c4375a62cfaabfd8de757f59714623ba1a8cb915 added a parallel
group, but incorrectly, so no test cases at all were run in
receive_SUITE.
|
|
The compiler would crash when attempting to compile a function
head that did binary matching and had a complex expression using
'andalso' and 'not'.
Noticed-by: José Valim
|
|
It should be beam_except_SUITE, since it tests the beam_except
module (introduced in 726f6e4c7afe8ce37b30eedbebe583e7b9bfc51b).
|
|
Run testcases in parallel will make the test suite run slightly
faster. Another reason for this change is that we want more testing
of parallel testcase support in common_test.
|
|
Introduce the mandary beam_a pass that will be run directly after code
generation, and the mandatory beam_z pass that will be run just before
beam_asm. Since these passes surround the optimizations, beam_a can
(for example) do instruction renaming to simplify the optimization
passes and beam_z can undo those renamings.
|
|
|
|
Don't throw the parse tree in the face of the user.
OTP-8707
|
|
beam_jump moves short code sequences ending in an instruction that causes
an exception to the end of the function, in the hope that a jump around
the moved blocked can be replaced with a fallthrough. Therefore, moving
a block that is entered via a fallthrough defeats the purpose of the
optimization.
Also add two more test cases for the beam_receive module to ensure that
all lines are still covered.
|
|
When matched variable is used as a size field in multiple clauses,
as in:
foo(<<L:8,A:L>>) -> A;
foo(<<L:8,A:L,B:8>>) -> {A,B}.
the match tree would branch out before the segment that used the
matched-out variable (in this example, the tree would branch out before
the matching of A:L). That happens because the pattern matching
compilator did not take variable substitutions into account when
grouping clauses that match the same value.
That is, the generated code would work similarly to this code:
foo(<<L:8,T/binary>>) ->
case T of
<<A:L>> ->
A;
_ ->
case T of
<<A:L,B:8>> -> %% A matched out again!
{A,B}
end
end.
We would like the matching to work more like:
foo(<<L,A:L,T/binary>>) ->
case T of
<<>> -> A;
<<B:8>> -> {A,B}
end.
Fix the problem by taking the substitutions into account when grouping
clauses that match out the same value.
|