Age | Commit message (Collapse) | Author |
|
beam_except: Generalize translation to func_info instructions
|
|
* bjorn/compiler/diffable:
scripts/diffable: Correct the number of modules being compiled
scripts/diffable: Use the diffable compiler option
Add a diffable option for the compiler
scripts/diffable: Refactor option parsing
|
|
The `beam_except` pass replaces some calls to `erlang:error/1` or
`erlang:error/2` with specialized instructions in order to reduce the
size of the BEAM code.
In functions that do binary matching, `beam_except` would fail to
translate the instructions that generate a `function_clause`
exception. Here is an example:
bsum(<<H:16,T/binary>>, Acc) ->
bsum(T, Acc+H);
bsum(<<>>, Acc) ->
Acc.
The BEAM code that generates the `function_clause` exception looks
like this:
{label,4}.
{test_heap,2,3}.
{put_list,{x,1},nil,{x,1}}.
%% The following two instructions prevents the translation.
{bs_set_position,{x,2},{x,0}}.
{bs_get_tail,{x,2},{x,0},3}.
{test_heap,2,2}.
{put_list,{x,0},{x,1},{x,1}}.
{move,{atom,function_clause},{x,0}}.
{line,...}.
{call_ext,2,{extfunc,erlang,error,2}}.
Make the translation of `function_clause` exceptions smarter, so
that the following code will be produced:
{label,4}.
{bs_set_position,{x,2},{x,0}}.
{bs_get_tail,{x,2},{x,0},3}.
{jump,{f,1}}. %Jump to `func_info` instruction.
(This issue was noticed when looking at the code generated by
https://github.com/tomas-abrahamsson/gpb.)
|
|
Add the `diffable` option to produce a more diff-friendly output in
a .S file. In a diffable .S file, label numbers starts from 1 in each
function and local function calls use function names instead of labels.
scripts/diffable produces diff-friendly files but only for a hard-coded
sub set of files in OTP. Having the option directly in the compiler
makes is easier to diff the BEAM code for arbitrary source modules.
|
|
The `beam_jump` pass could eliminate `move` instructions when it was
not safe to do so. See the new test case `unsafe_move_elimination/1`
for an example.
Reported-by: Michał Muskała
|
|
|
|
* maint:
compiler: Forward +source flag to epp and fix bug in +deterministic
epp: Allow user to set source name independently of input file name
|
|
Fixes a crash during code generation of the following code:
call_atom() ->
fun({send = Send}) ->
Send()
end.
|
|
The source file path as given to `erlc` was included in an implicit
file attribute inserted by epp, even when the +source flag was
set to something else which was a bit surprising. It was also
included when +deterministic was specified, breaking the flag's
promise.
This commit forwards the +source flag to epp so it inserts the
right information, and if +deterministic is given it will be shaved
to just the base name of the file, guaranteeing the same result
regardless of how the input is reached.
|
|
* bjorn/compiler/misc-fixes:
beam_ssa: Remove unnecessary beam_ssa: prefixes
beam_ssa_bsm: Fix replacement of variables in a remote call
|
|
|
|
Co-authored-by: John Högberg <[email protected]>
|
|
jhogberg/john/compiler/improve-named-funs/OTP-15273/ERL-639
Optimize named funs and fun-wrapped macros
|
|
Introduce the no_spawn_compiler_process option
|
|
If a fun is defined locally and only used for calls, it can be replaced
with direct calls to the relevant function. This greatly speeds up "named
functions" (which rely on make_fun to recreate themselves) and macros that
wrap their body in a fun.
|
|
By default, all code is compiled in a separate process
which is terminated at the end of compilation. However,
some tools, like Dialyzer or compilers for other BEAM languages,
may already manage their own worker processes and spawning
an extra process may slow the compilation down.
In such scenarios, you can pass this option to stop the
compiler from spawning an additional process.
This generalizes commit 657760e18087b0cdbaecc5e96e46f6f66bc9497a.
|
|
* bjorn/compiler/fix-r21-option:
Fix code generation of binary instructions with the r21 option
|
|
Minor cleanups and bug fixes of the compiler
|
|
OTP 22 extends the binary instructions to support a Y register
destination. When giving an option to compile for an earlier
release, make sure that binary instructions don't use a Y register
destination, by rewriting the binary instructions to use an X
register destination and adding a `move` instruction to move
the value to the Y register.
|
|
Rewrite BSM optimizations in the new SSA-based intermediate format
|
|
This has been superseded by bs_get_tail/3. Note that it is NOT
removed from the emulator or beam_disasm, as old modules are still
legal.
|
|
Remove the variable aliasing support that was needed for the
old beam_bsm pass.
|
|
The beam_ssa_bsm pass welds chained matches together, but the match
expressions themselves are unchanged and if there's a tail
alignment check it will be done each time. This subpass figures out
the checks we've already done and deletes the redundant ones.
|
|
This commit improves the bit-syntax match optimization pass,
leveraging the new SSA intermediate format to perform much more
aggressive optimizations. Some highlights:
* Watch contexts can be reused even after being passed to a
function or being used in a try block.
* Sub-binaries are no longer eagerly extracted, making it far
easier to keep "happy paths" free from binary creation.
* Trivial wrapper functions no longer disable context reuse.
|
|
2e40d8d1c51a attempted fix a bug in binary matching, but it only
fixed the bug for the minimized test case.
This commit removes the previous fix and fixes the bug in a more
effective way. See the comments in the new code in `sys_core_bsm`
for an explanation.
This commit restores the optimizations in string.erl and dets_v9.erl
that the previous fix disabled.
I have not found any code where this commit will disable optimizations
when they are actually safe. There are some changes to the code
in ssl_cipher.erl in that some bs_start_match2 instruction did not
reuse the binary register for the match context, but the delayed
sub binary optimizations was never applied to the code in the first
place.
https://bugs.erlang.org/browse/ERL-689
|
|
Moving away this optimization makes beam_block do one thing
and one thing only -- creating blocks.
|
|
The only caller of bif_to_test/3 is beam_ssa_codegen.
|
|
Disallow a literal map source for get_map_elements. There is currently
runtime support for get_map with a literal map source, but by
forbidding it in OTP 22, the runtime support could be removed in a
future release (perhaps OTP 24).
Also verify that the source arguments for get_list, get_hd, get_tl,
and get_tuple_element are not literals. Literals are not supported for
those instructions in the runtime system; verifying it in
beam_validator is a convenience so that this kind of bug will
be detected already during compilation.
|
|
The source map for `get_map_element` is not supposed to be a literal,
and the sanitization code is supposed to ensure that.
The sanitization incorrectly translated this code:
Map = get_tuple_element literal {ok,#{key=>value}}, literal 1
Var = get_map_element Map, literal {a,key}
To this code:
Var = get_map_element literal #{key=>value}, literal {a,key}
Make sure to substitute the arguments for `get_map_element` before
looking for a literal source map.
|
|
|
|
Using maps and cerl_sets instead of dict and sets will slightly
speed up the beam_clean pass for modules with many functions
and/or calls to local functions.
|
|
It is not necessary to combine get_hd and get_tl instruction to
a get_list instruction. It will be done in beam_z.
After this change, beam_flatten does nothing more than eliminating
the blocks.
|
|
Continuing the simplification of beam_flatten, move the optimization
that eliminates a test_heap instruction following a binary construction
by incorporating the allocation of the heap space into the bs_init*
instruction itself.
This change does not change the generated code in any way.
Also remove beam_utils:combine_heap_needs/2, because beam_flatten
was the last user of it.
|
|
The purpose of beam_flatten is to eliminate the blocks created by
beam_block, but it also does a few optimizations because at the
time the optimizations were added, beam_flatten was the most
convenient place.
Move the optimization that places `{move,Something,{x,0}}` before
`call` instructions from beam_flatten to beam_ssa_codegen.
This change will very slightly improve compilation times, and it
will also apply the optimization in more places. In particular,
a `{move,Literal,{x,0}}` would never be moved passed a `trim`
instruction before this change. Now it will.
|
|
jhogberg/john/compiler/validator-aliased-type-fixes/ERL-735
beam_validator: Use set_aliased_type in more operations
|
|
The following code broke because aliases weren't tracked for hd/1:
bug(Bool) ->
Bug = remote:call(),
if
Bool -> %% Branch of some kind.
_ = hd(Bug),
remote:call(),
hd(Bug)
end.
Related to 1f221b27f1336e747f7409692f260055dd3ddf79
|
|
|
|
get_anno/3: as get_anno but with a default value
definitions/1-2: returns a map of variable definitions (#b_set{})
uses/1-2: returns a map of all uses of a given variable
mapfold_blocks_rpo/4: mapfolds over blocks
|
|
The upcoming beam_ssa_bsm pass makes this redundant.
|
|
Now that variables are represented as #b_var{}, there's no longer
any risk of colliding with anything else.
|
|
We chose to refer to variables through their var_name() because we
anticipated the need to annotate them, but it turned out we didn't
really need that, and many things become a lot cleaner if the
entire #b_var{} is used to represent variables.
|
|
Replace beam_dead with beam_ssa_dead
|
|
Most of the optimizations in beam_dead have been superseded
by the optimizations in beam_ssa_dead.
The forward/1 pass of beam_dead has been moved to beam_jump.
The beam_split pass splits blocks that contain instructions with
non-zero labels. Because there are no optimizations left that optimize
instructions within blocks, beam_block never needs to put such
instructions into blocks in the first place. beam_split also moved
'move' instructions out block to help beam_dead. That is no longer
necessary since beam_dead no longer exists.
|
|
Add beam_ssa_dead to perform the main optimizations done
by beam_dead:
* Shortcut branches that jump to another block with a branch.
If it can be seen that the second branch will always branch
to a specific block, replace the target of the first branch.
* Combined nested sequences of '=:=' tests and switch
instructions operating on the same variable to a single switch.
Diffing the compiler output, it seems that beam_ssa_dead finds
many more opportunities for optimizations than beam_dead,
although it does not find all opportunities that beam_dead does.
In total, beam_ssa_dead is such improvement over beam_dead that
there is no reason to keep beam_dead as well as beam_ssa_dead.
Note that beam_ssa_dead does not attempt to optimize away
redundant bs_context_binary instructions, because that instruction
will be superseded by new instructions in the near future.
|
|
Omitting `kill` instructions before BIFs that throw exceptions
will reduce the code size. This optimization supersedes the same
optimizations in beam_dead.
|
|
In beam_ssa_type, do substitutions similar to what ssa_opt_misc does
to get rid of variables that evaluate to constant values. That
somewhat simplifies the code of beam_ssa_type, and could improve
performance of the compiler since instructions and variables are
eliminated, reducing the amount of work for later passes.
|
|
|
|
Remove the following clause from the `fun` clauses in arith_op_types/2
because it cannot possibly match:
(_, any) -> number;
Here is why it cannot match:
The second argument is the accumulator for lists:foldl/3.
Its initial value is `unknown`.
None of the clauses will update the accumulator to `any`, including
the clause that matches `any` in the first argument -- it will set the
accumulator to `number`.
Thus, the accumulator (second argument) can never be `any` and
the clause can never match. QED.
|
|
The floating point optimization relies on heavily on the block
order in the lineararized representation. A new optimization
could easily break the optimization, for example so that no
`fcheckerror` instructions were emitted.
Rewrite the optimization to avoid dependencies on the linear
block order.
|
|
* 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
|