Age | Commit message (Collapse) | Author |
|
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-22
* john/compiler/fix-fail-path-exceptions-bsm/OTP-15946:
beam_ssa_bsm: Leave ?BADARG_BLOCK alone when cloning fail path
|
|
* john/compiler/fix-unsafe-tuple_size-opt/OTP-15945:
beam_ssa_opt: Do not apply tuple_size optimization outside guards
|
|
This fix is rather ugly and tacked-on, but I'm not comfortable
refactoring the pass in an emergency patch.
|
|
|
|
Rewriting `tuple_size` to `is_tuple` + `tuple_size` will cause it
not to throw an exception, either crashing the compiler or the
emulator when the code runs.
|
|
The compiler would treat the "Unit" of bs_init instructions as
the unit of the result instead of the required unit of the input,
causing is_binary checks to be wrongly optimized away.
|
|
* bjorn/compiler/fix-beam_ssa_dead-patch/OTP-15845:
Fix unsafe optimizations where guard tests could be removed
|
|
'bjorng_ghub/bjorn/compiler/fix-beam_ssa_dead-crash/ERL-956/OTP-15848' into maint-22
* bjorng_ghub/bjorn/compiler/fix-beam_ssa_dead-crash/ERL-956/OTP-15848:
Eliminate crash in the beam_ssa_dead compiler pass
|
|
into maint-22
* bjorn/compiler/fix-unloadable-code-patch/ERL-955/OTP-15846:
Fix loading of Core Erlang code for extracting a map element
|
|
* bjorn/compiler/fix-beam_except/ERL-954/OTP-15839:
Fix compiler crash in beam_except
|
|
* bjorn/compiler/fix-unsafe-type-inference/OTP-15838:
Fix unsafe negative type inference
# Conflicts:
# lib/compiler/src/beam_ssa_type.erl
|
|
* john/compiler/list_append_type/OTP-15841:
compiler: Fix broken type for erlang:'++'/2
|
|
* bjorn/compiler/fix-receive-patch/ERL-950/OTP-15832:
Eliminate compiler crash when compiling complex receive statements
|
|
A repeated test could be optimized away. Example:
bar(A) ->
if is_bitstring(A) ->
if is_binary(A) ->
binary;
true ->
bitstring
end;
true ->
other
end.
In the example, the `is_binary/1` test would be optimized away,
basically turning the example into:
bar(A) ->
if is_bitstring(A) ->
bitstring;
true ->
other
end.
Thanks user Marcus Kruse in the Elixir forum for noticing this bug.
|
|
The compiler could crash in the beam_ssa_dead pass while compiling
complex nested `case` expressions. See the added test case for an
example and explanation.
https://bugs.erlang.org/browse/ERL-956
|
|
The compiler would crash in `beam_except` while compiling this
function:
bar(Req) ->
ok = case Req of
"POST" -> {error, <<"BAD METHOD ", Req/binary>>, Req};
_ -> ok
end.
https://bugs.erlang.org/browse/ERL-954
|
|
|
|
The following Core Erlang code could not be loaded:
'f'/1 = fun (_1) ->
case <_1> of
<~{'foo':='foo'}~> when 'true' ->
_1
end
Loading would fail with the following message:
beam/beam_load.c(2314): Error loading function example:f/1: op i_get_map_element_hash p x a u x:
no specific operation found
https://bugs.erlang.org/browse/ERL-955
|
|
The type optimizer pass (`beam_ssa_type`) could make unsafe
negative inferences. That is, incorrectly infer that a variable
could *not* have a particular type.
This bug was found when adding another optimization. It is not
clear how write a failing test case without that added optimization.
|
|
Certain complex receive statements would result in an internal
compiler failure. That would happen when the compiler would fail
to find the common exit block following a receive. See the added
test case for an example.
https://bugs.erlang.org/browse/ERL-950
|
|
The compiler would not terminate while compiling the following code:
foo(<<N:32>>, Tuple, NewValue) ->
_ = element(N, Tuple),
setelement(N, Tuple, NewValue).
The type analysis pass would attempt to construct a huge list when
attempting analyse the type of `Tuple` after the call to
`setelement/3`.
https://bugs.erlang.org/browse/ERL-948
|
|
* john/compiler/fix-missing-match-reposition/ERL-923:
compiler: Propagate match context position on fail path
|
|
|
|
|
|
`beam_asm` would encode `{literal,[]}`, `{literal,erlang}`, and
`{literal,42}` in a less efficient way than the equivalent values
`nil`, `{atom,erlang}`, and `{integer,42}`. That would increase the
size of BEAM files and could increase the loaded code size. It would
probably not harm performance, because `literal` was only used this
way in code that generates `badmatch` and `case_clause` exceptions.
|
|
|
|
|
|
The core_parse.hrl can be used in applications with the
+warn_untyped_record compiler flag.
|
|
|
|
* bjorn/compiler/cuddle-with-tests:
Verify the highest opcode for the r21 test suites
Add test_lib:highest_opcode/1
sys_core_fold: Simplify case_expand_var/2
beam_validator: Remove uncovered lines in lists_mod_return_type/3
Cover return type determination of lists functions
|
|
Validation could fail when a function that never returned was used
in a try block (see attached test case). It's possible to solve
this without disabling the optimization as the generated code is
sound, but I'm not comfortable making such a large change this
close to the OTP 22 release.
|
|
5239eb0c62a9 stopped storing patterns that a variable has matched.
The only tuples that are stored in the type database are tuples
that have been previously constructed.
Therefore, the code in sys_core_fold:case_expand_var/2 and friends
that converts a tuple pattern to a tuple construction can be simplified
to used the stored tuple directly.
|
|
Don't bother infering the return types for lists function that
beam_ssa_type does not handle.
|
|
* bjorn/hipe-compilation/OTP-15596:
HiPE: Don't fail the compilation for unimplemented instructions
|
|
|
|
|
|
For reasons better explained in the source code, ssa_opt_float
skips optimizing inside guards but it failed to do so
consistently; while the pass never processed guard blocks, it was
still possible to erroneously defer error checking to a guard
block, crashing the compiler once it realized its state was
invalid.
|
|
This ensures that unreachable branches are properly ignored on
repeated checks (although tuple type subtraction isn't complete
yet).
|
|
Type subtraction never resulted in the 'none' type, even when it
was obvious that it should. Once that was fixed it became apparent
that inequality checks also fell into the same subtraction trap
that the type pass warned about in a comment.
This then led to another funny problem with select_val, consider
the following code:
{bif,'>=',{f,0},[{x,0},{integer,1}],{x,0}}.
{select_val,{x,0},{f,70},{list,[{atom,false},{f,69},
{atom,true},{f,68}]}}.
The validator knows that '>=' can only return a boolean, so once it
has subtracted 'false' and 'true' it killed the state because all
all valid branches had been taken, so validation would crash once
it tried to branch off the fail label.
|
|
|
|
|
|
|
|
The current type conflict resolution works well for the example
case in the comment, but doesn't handle branched code properly,
consider the following:
{label,2}.
{test,is_tagged_tuple,{f,ignored},[{x,0},3,{atom,r}]}.
{allocate_zero,2,1}.
{move,{x,0},{y,0}}.
%% {y,0} is known to be {r, _, _} now.
{get_tuple_element,{x,0},2,{x,0}}.
{'try',{y,1},{f,3}}.
%% ... snip ...
{jump,{f,5}}.
{label,3}.
{try_case,{y,1}}.
%% {x,0} is the error class (an atom), {x,1} is the error term.
{test,is_eq_exact,{f,ignored},[{x,0},{y,0}]}.
%% ... since tuples and atoms can't meet, the type of {y,0} is
%% now {atom,[]} because the current code assumes the type
%% we're updating with.
{move,{x,1},{x,0}}.
{jump,{f,5}}.
{label,5}.
%% ... joining tuple (block 2) and atom (block 3) means 'term',
%% so the get_tuple_element instruction fails to validate
%% despite this being unrechable from block 3.
{test_heap,3,1}.
{get_tuple_element,{y,0},1,{x,1}}.
{put_tuple2,{x,0},{list,[{x,1},{x,0}]}}.
{deallocate,2}.
return.
This commit kills the state on type conflicts, making unreachable
instructions truly unreachable.
|
|
While complex_test made certain branching instructions a lot easier
to read, we're still using `branch_state` for many others which is
hard to read and makes it impossible to "abort" branches on type
conflicts.
This commit replaces nearly all uses of `branch_state` with a
general branching mechanism, improving readability and paving the
way for proper type conflict resolution.
|
|
The element type can not be extracted before the tuple type has
been updated.
|
|
|
|
Move size=all binary clause pruning to v3_kernel
|
|
Tune BEAM instructions for the new compiler (part 1)
|
|
Optimize the beam_ssa_dead sub pass
|