Age | Commit message (Collapse) | Author |
|
beam_bool would make the following code unsafe (which would be
reported by beam_validator):
scotland(Echo) ->
found(case Echo of
Echo when true; Echo, Echo, Echo ->
Echo;
echo ->
[]
end,
Echo = placed).
found(_, _) -> million.
Basically, beam_bool would see that the 'case' would always return
the value of Echo. Thus:
scotland(Echo) ->
found(Echo, Echo = placed).
The only problem is that beam_bool would also remove a 'move'
instruction that would save Echo to the stack. Here is the
assembly code for part of the function:
{allocate_zero,1,1}.
{move,{x,0},{y,0}}. %% Save Echo on stack.
{bif,'=:=',{f,7},[{x,0},{atom,true}],{x,1}}.
{bif,'=:=',{f,7},[{x,0},{atom,true}],{x,2}}.
{bif,'=:=',{f,7},[{x,0},{atom,true}],{x,3}}.
{bif,'and',{f,7},[{x,2},{x,3}],{x,2}}.
{bif,'and',{f,7},[{x,1},{x,2}],{x,1}}.
{jump,{f,8}}.
{label,7}.
{move,{atom,false},{x,1}}.
{label,8}.
{bif,'or',{f,6},[{atom,true},{x,1}],{x,1}}.
{test,is_eq_exact,{f,6},[{x,1},{atom,true}]}. %% Jump never taken.
{jump,{f,5}}.
{label,6}.
{test,is_eq_exact,{f,9},[{x,0},{atom,echo}]}.
{move,nil,{x,0}}.
{jump,{f,5}}.
{label,9}.
{test_heap,3,0}.
{put_tuple,2,{x,0}}.
{put,{atom,case_clause}}.
{put,{y,0}}.
{line,[{location,"t.erl",5}]}.
{call_ext,1,{extfunc,erlang,error,1}}.
{jump,{f,5}}.
{label,5}.
{test,is_eq_exact,{f,12},[{atom,placed},{y,0}]}.
beam_bool would see that the is_eq_exact test at label 8 would
always succeed. It could therefore remove most of the code before
the jump to label 5. Unfortunately it also removed the essential
move of Echo to the stack:
{allocate_zero,1,1}.
%% Instruction incorrectly removed: {move,{x,0},{y,0}}.
{jump,{f,5}}.
{label,5}.
{test,is_eq_exact,{f,12},[{atom,placed},{y,0}]}.
The root cause of the problem is that the 'move' instruction is
included in the block of 'bif' instructions before label 8.
Normally the 'move' instruction would not have been discarded,
but because the left operand to the 'or' BIF is 'true', the
entire block with 'bif' instructions are dropped.
As far as I can see, there is no gain by including 'move'
instructions in the first place. There is no way that better
code will be produced. In fact, the entire optimization can
be given up if 'move' instructions are found in the block.
Thus we can fix this bug by never including any 'move' instructions
in the block of 'bif' instructions. We can also remove all the
code that deals with 'move' instructions within blocks.
Reported-by: Thomas Arts
|
|
When the 'bin_opt_info' is given, warnings without filenames
and line numbers could sometimes be produced:
no_file: Warning: INFO: matching non-variables after
a previous clause matching a variable will prevent delayed
sub binary optimization
The reason for the missing information is that #c_alias{} records lack
location information. There are several ways to fix the problem. The
easiest seems to be to get the location information from the
code).
Noticed-by: José Valim
|
|
|
|
* c-rack/fix-typo3:
Fix typo in call_last/3 spec
Fix typo
Fix typo: message to send is in x(1) not x(0)
Fix another small typo
Fix typo
|
|
Instruction get_map_elements might destroy target registers when the fail-label is taken.
Only seen for patterns with two, and only two, target registers.
Specifically: we copy one register, and then jump.
foo(A,#{a := V1, b := V2}) -> ...
foo(A,#{b := V}) -> ...
call foo(value, #{a=>whops, c=>42}).
corresponding assembler:
{test,is_map,{f,5},[{x,1}]}.
{get_map_elements,{f,7},{x,1},{list,[{atom,a},{x,1},{atom,b},{x,2}]}}.
%% if 'a' exists but not 'b' {x,1} is overwritten, jump {f,7}
{move,{integer,1},{x,0}}.
{call_only,3,{f,10}}.
{label,7}.
{get_map_elements,{f,8},{x,1},{list,[{atom,b},{x,2}]}}.
%% {x,1} (src) is read with a corrupt value
{move,{x,0},{x,1}}.
{move,{integer,2},{x,0}}.
{call_only,3,{f,10}}.
The fix is to remove 'opt_moves' pass for get_map_elements instruction
in the case of two or more destinations.
Reported-by: Valery Tikhonov
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Before beam_split the get_map_elements instruction is still in
blocks and the helper function in beam_jump did not reflect this.
Reported-by: Quviq twitter account
|
|
* bjorn/compiler/spurious-warning:
sys_core_fold: Eliminate warnings for unused terms in effect context
sys_core_fold: Eliminate warnings for unused terms
|
|
* egil/opt-compile-time/OTP-12774:
stdlib: Relax erl_anno_SUITE:is_anno/1 test
Update primary bootstrap
compiler: Use Maps as type information
compiler: Use Maps instead of dict in beam_jump
compiler: Use cerl_sets instead of gb_sets in beam_type
compiler: Use Maps instead of gb_trees in beam_dead
compiler: Use cerl_sets instead of gb_sets in beam_jump
compiler: Use cerl_sets instead of sets in v3_kernel
compiler: Use cerl_sets instead of gb_sets in sys_core_fold
compiler: Add cerl_sets module
compiler: Scope uses gb_sets not gb_trees
beam_dict: Use Maps to map function name indices
beam_dict: Use Maps to map line indices
beam_dict: Use Maps to map atom indices
v3_codegen: Use Maps to map local functions
v3_life: Refactor variable db
compiler: Use lc instead of map/1 in v3_codegen
stdlib: Optimize erl_anno:is_string/1
Conflicts:
bootstrap/lib/kernel/ebin/inet_dns.beam
bootstrap/lib/stdlib/ebin/erl_anno.beam
bootstrap/lib/stdlib/ebin/erl_lint.beam
|
|
The optimization introduced in 0a0d39d351fc could cause spurious
warnings of the type: "a term is constructed, but never used".
That would happen for constructs in effect context.
To avoid those warnings, we will need to apply warning suppression
also in effect context.
|
|
* egil/fix-compiler-beam_bsm/OTP-12758:
compiler: Add tests for beam_bsm get_map_elements
compiler: Teach beam_bsm get_map_elements instruction
|
|
Using Maps as type information container speedups files like cow_http_hd.erl
by ~500ms. Previously spent ~60% of the time in orddict:store/3.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A sets implementation based on maps.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Small speed increase for large files.
|
|
In a5d724cf240a, a debug option for running eprof on a specific
compiler pass was added. That commit added a direct call to the eprof
module in the tools application, and therefore the test case
otp_SUITE:runtime_dependencies/1 would fail because xref would find a
call to the tools application, but tools is not listed as a runtime
dependency in compiler.app.
Since the 'eprof' option is only likely to be used by compiler
maintainers, we don't want a real dependency to the tools application.
Therefore, use c:appcall/4 to hide the call to the eprof module (and
to report the error nicely if the tools application is missing).
|
|
Allows for 'creation of sub binary delayed' optimization if
map instructions are in a clause.
Reported-by: José Valim
|
|
The optimization introduced in 0a0d39d351fc would cause spurious
warnings of the type: "a term is constructed, but never used".
To avoid the warning, we must mark not only tuples and lists as
compiler_generated, but also each element. We must also propagate
compiler_generated annotations in lets. For example, if we have:
let <X -| ['compiler_generated']> = 42 in X + 1
we must propagate the compiler_generated annotation to the literal
when do constant propagation:
42 -| ['compiler_generated'] + 1
|
|
|
|
* nox/compiler/parse_transform-undef/OTP-12723:
Properly report unknown parse transforms
|
|
|
|
* bjorn/compiler/misc:
test_lib: Simplify uniq/0
beam_dict: Correct comparison in opcode/2
beam_utils: Re-use the local helper function drop_labels/1
beam_asm: Speed up encoding of large numbers
compilation_SUITE: Speed up the self_compile test cases
beam_listing: Optimize writing of .S files
v3_core, v3_codegen: Eliminate old-style catches
cerl_inline: Replace old-style 'catch' with 'try'...'catch'
sys_core_fold: Suppress warnings better
beam_utils: Teach check_liveness/3 to understand get_map_elements
Teach beam_trim to handle map instructions
beam_utils: Be less conservative about liveness for exit instructions
beam_validator: Stop validating the 'aligned' flag for binaries
beam_validator: Clean up updating of types for y register
beam_validator: Remove support for removed BIF fault/1,2
beam_validator: Correct merging of states
beam_validator: Correct merging of y registers
sys_pre_expand: Remove unused fields in #expand{} record
|
|
The intention of the comparison is to avoid unnecessary updates of the
">=" instead of ">". With the ">" comparison, typically every line
instruction would cause the #asm{} record to be updated.
|
|
In 8470558, the drop_labels/1 function was added to beam_utils
as a minor optimization. Since the function is already available,
we might as well use it in index_label/3 too.
|
|
The misc_SUITE:integer_encoding/1 test case is annoyingly slow.
Rewrite the encoding of integers in beam_asm to use the
binary:encode_unsigned/1 BIF.
Also tweak the test case itself. Scale the down the maximum
size of the numbers being generated, but also add test of
numbers around boundaries of power of two (which are the numbers
most likely to expose bugs in the encoding).
|
|
The test suites generates listing files, so we can slightly speed
up running of test suites (especially when running 'cover') by
optimizing writing of .S files.
|
|
|
|
Using 'try'...'catch' simplifies the code and improves coverage
because we don't have to re-throw accidentally caught errors.
|
|
86fbd6d76d strengthened type optimization in lets. As a result of
the stronger optimizations, special care had to be taken to
suppress false warnings.
It turns out that false warnings can still slip through. Slapping
on a 'compiler_generated' annotation at the top-level of a
complex term such as #c_tuple{} may not suppress all warnings.
We will need to go deeper into the term to eliminate all warnings.
|
|
Understanding get_map_elements improves the stack trimming done
by beam_trim.
|
|
|
|
beam_utils used to be overly conservative about liveness for
exit instructions such as:
call_ext erlang:exit/1
beam_utils would consider all y registers to be used, to avoid
overwriting a catch or try tag. That does not seem to be a real
risk.
However, we miss opportunities for stack trimming if we consider
y registers used by an exit instruction.
|
|
The run-time system stopped paying attention the 'aligned' flag in bit
syntax construction and matching when bitstrings were introduced in
language.
The beam_asm compiler pass will crash if the 'aligned' flag is given
in bit syntax instructions.
beam_validator still validates the 'aligned' flag. Before
912fea0b712a (which removed the possibility to validate existing
BEAM files), the 'aligned' flag could actually be encountered
when validating a BEAM file.
Since the validation of 'aligned' no longer serves any useful
purpose, remove the validation code.
|