Age | Commit message (Collapse) | Author |
|
Compiling programs with very many uses of the "dot notation"
for extracting a record element could be very slow. The reason
is that each extraction of a record element (R#r.a) would first be
transformed to code like this:
case R of
{r,rec0,_,_} -> rec0;
_ -> error({badrecord,r})
end
In Core Erlang, each '_' would be become a new variable. The
resulting code would be optimized by sys_core_fold, but the
optimization process could be very slow.
Profiling shows that sub_del_var/2 was the worst bottleneck, and the
sub_is_val/2 the second worst bottleneck. In both cases, the culprit
is the linear traversal of a very long list (the list of variable
substitutions). Fortunately, there already is a gb_set (the scope)
which contains all variables that are currently live. If a variable is
not known to be live, it is no point in doing the linear operation on
the list.
|
|
erlc is wired to treat *.S files as assembler and build them as
compile:file(File, [from_asm]), but this is not documented. There's also
a documented compile:file/2 option called 'asm' (mapping to 'from_asm'),
but the wording discourages its use. All of this has been in place and
in use for a long time. Therefore, it should be supported officially.
To fix that, make the following changes:
* document erlc handling of *.core files
* un-document 'asm' and document 'from_asm' instead
* deprecate 'asm'
While at it, fix a minor typo in the test suite.
|
|
This makes applying the pass a second time a no-op.
|
|
|
|
Any init instruction following an allocate is put in the Inits list of the
corresponding alloc tuple.
|
|
If an allocate_zero instruction is fed to beam_block and the beam_type
pass is not used afterwards (e.g. with erlc +no_topt), the 'no_opt' atom
will be rejected by beam_flatten.
|
|
The compiler shouldn't crash when fed an already-optimised BEAM assembly file.
|
|
This adds optional names to fun expressions. A named fun expression
is parsed as a tuple `{named_fun,Loc,Name,Clauses}` in erl_parse.
If a fun expression has a name, it must be present and be the same in
every of its clauses. The function name shadows the environment of the
expression shadowing the environment and it is shadowed by the
environment of the clauses' arguments. An unused function name triggers
a warning unless it is prefixed by _, just as every variable.
Variable _ is allowed as a function name.
It is not an error to put a named function in a record field default
value.
When transforming to Core Erlang, the named fun Fun is changed into
the following expression:
letrec 'Fun'/Arity =
fun (Args) ->
let <Fun> = 'Fun'/Arity
in Case
in 'Fun'/Arity
where Args is the list of arguments of 'Fun'/Arity and Case the
Core Erlang expression corresponding to the clauses of Fun.
This transformation allows us to entirely skip any k_var to k_local
transformation in the fun's clauses bodies.
|
|
|
|
|
|
|
|
* nox/lift-after/OTP-11267:
Lift 'after' blocks to zeroary functions
|
|
files as delimiters.
While working on a tool that processes Erlang code and testing it against this repo,
I found out about those little sneaky 0xff. I thought it may be of help to other
people build such tools to remove non-conforming-to-standard characters.
|
|
* maint:
core_lint: Correct the type error() to conform to the code
|
|
Commit 60984ade updated the code, but not the type spec.
Noticed-by: Kostis Sagonas
|
|
* maint:
compiler: Conform returned errors to the documented format
|
|
ErrorInfo is documented to be:
{ErrorLine,Module,ErrorDescriptor}
but for some errors with line numbers it would look like:
{Module,ErrorDescriptor}
Ensure that all ErrorInfo tuples have three elements. Use 'none'
instead of a line number:
{none,Module,ErrorDescriptor}
There already are errors that return 'none' when no line number is
available, but that convention was not documented. Mention it in the
documentation.
Also make sure that the compiler will not print 'none' as a line
number in error messages (if the 'report_errors' option is given) as
that looks stupid. That is, when attempting to compile a non-existing
module, the error message should be:
non-existing.erl: no such file or directory
and not:
non-existing.erl:none: no such file or directory
|
|
* maint: (26 commits)
genop.tab: Add documentation for many BEAM instructions
asn1ct_constucted_per: Directly call asn1ct_gen_per
Clean up handling of .asn1db files
PER, UPER: Fix encoding/decoding of open types greater than 16K
PER, UPER: Optimize table constraints
PER, UPER: Optimize encoding using an intermediate format
Refactor decoding of components of SEQUENCE OF / SET OF
PER,UPER: Get rid of unused 'telltype' argument in decoding functions
Optimize the generated encode/2 function
UPER: Optimize complete/1
Clean up checking of objects
Improve tests of deep table constraints
BER: Handle multiple optional SEQUENCE fields with table constraints
Test OPTIONAL and DEFAULT for open types
PER/UPER: Fix encoding of an object set with multiple inlined constructs
Remove broken support for multiple UNIQUE
Extend the test for parameterized information objects
asn1_SUITE: Remove off-topic (and slow) smp/1 test case
SeqOf: Add more tricky SEQUENCE OF tests
Clean up handling of extension addition groups
...
|
|
By Erik Stenman (happi) with corrections by me.
|
|
|
|
* nox/match-context-return/OTP-11247:
Added primary bootstrap
Forbid returning a match context in beam_validator
|
|
* maint:
Fix compiler crash for 'B and B' guard
|
|
|
|
If a match context is returned from a function without being converted
back to a plain old binary, the whole VM will crash.
|
|
Conflicts:
bootstrap/lib/compiler/ebin/v3_core.beam
|
|
* nox/fix-comp-warnings/OTP-11212:
Bootstrap
Silence a misleading warning with some comprehensions
|
|
Conflicts:
bootstrap/lib/compiler/ebin/cerl_inline.beam
|
|
If 'after' blocks are not lifted, the ids of functions in their bodies
must be killed and it can make stacktraces more confusing than they
should. We lift them to zeroary functions to avoid unnecessary killings
and duplication of code.
|
|
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
|
|
|
|
|
|
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 ].
|
|
Now that unsized binary segments are forbidden in patterns of bit string
generators, v3_core:append_tail_segment/2 does not need to check for an
existing unsized tail segment and can thus be changed to a simple '++'/2
call.
|
|
* maint:
compiler: Correct liveness optimization for wait/1
|
|
* bjorn/compiler/fix-compiler-crash/OTP-11119:
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
|
|
The clause was formerly commented-out because at this point in the code,
no bs_put_string instruction has been generated yet when compiling from
Erlang.
If an Erlang module is compiled to BEAM assembly and the result contains
a bs_put_string instruction, the output can't be compiled to binary
anymore and the compiler crashes with the following error:
$ erlc prs.S
Function: compress/1
prs.S:none: internal error in beam_block;
crash reason: {{case_clause,
{'EXIT',
{function_clause,
[{beam_utils,live_opt,
[[{bs_put_string,1,{string,[0]}},
{bs_init,
{f,0},
{bs_append,0,8,{field_flags,[]}},
0,
[{integer,8},{x,0}],
{x,1}},
{label,2}],
2,
{1,{1,1,nil,nil}},
[{block,
[{'%live',2},
{set,[{x,0}],[{x,1}],move},
{'%live',1}]},
return]],
[{file,"beam_utils.erl"},{line,639}]},
{beam_utils,live_opt,1,
[{file,"beam_utils.erl"},{line,205}]},
{beam_block,function,2,
[{file,"beam_block.erl"},{line,38}]},
{lists,mapfoldl,3,
[{file,"lists.erl"},{line,1329}]},
{beam_block,module,2,
[{file,"beam_block.erl"},{line,29}]},
{compile,'-select_passes/2-anonymous-2-',2,
[{file,"compile.erl"},{line,476}]},
{compile,'-internal_comp/4-anonymous-1-',2,
[{file,"compile.erl"},{line,276}]},
{compile,fold_comp,3,
[{file,"compile.erl"},{line,294}]}]}}},
[{compile,'-select_passes/2-anonymous-2-',2,
[{file,"compile.erl"},{line,476}]},
{compile,'-internal_comp/4-anonymous-1-',2,
[{file,"compile.erl"},{line,276}]},
{compile,fold_comp,3,[{file,"compile.erl"},{line,294}]},
{compile,internal_comp,4,[{file,"compile.erl"},{line,278}]},
{compile,'-do_compile/2-anonymous-0-',2,
[{file,"compile.erl"},{line,152}]}]}
|
|
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).
|
|
|
|
* hb/unicode/OTP-10907:
otp_SUITE: Add test cases to ensure that OTP conventions are obeyed
Convert XML files to UTF-8
Convert XML files to UTF-8, where needed
Remove the "coding: utf-8" comment from all Erlang source files
Update primary bootstrap
Change the default encoding of Erlang files to UTF-8
|
|
|
|
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.
|
|
The Core Erlang compiler simplifies let expressions by moving them
into their argument when it is another let or a case expression.
It can then perform other optimizations such as removing the let
expressions altogether, sometimes saving BEAM registers later in
the process.
This commit teaches sys_core_fold how to move let expressions into
sequence arguments.
|
|
* nox/fix-bc-optim/OTP-11005:
Add a new option +clint0 to the compiler
Fix optimization of some binary comprehensions
|
|
This option makes the compiler run the Core Erlang linting pass before
any optimization pass, which can crash if the given code has unbound
variables, something that is detected by core_lint.
|
|
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
|