aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
AgeCommit message (Collapse)Author
2018-09-12Merge branch 'maint-21' into maintRickard Green
* maint-21: 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
2018-09-11Update release notesErlang/OTP
2018-09-11Update version numbersErlang/OTP
2018-09-10Fix include-path regression caused by dd0a39cJohn Högberg
Include paths don't actually affect code generation in any way, but it's reasonable for a build tool like rebar3 to recompile when the include paths change. This commit restores the old behavior without the +deterministic flag.
2018-08-31Merge branch 'hasse/dialyzer/improve_guards/OTP-15268/ERL-680' into maintHans Bolinder
* hasse/dialyzer/improve_guards/OTP-15268/ERL-680: dialyzer: Improve handling of complex guards
2018-08-28dialyzer: Improve handling of complex guardsHans Bolinder
See also https://bugs.erlang.org/browse/ERL-680. The right associative short circuit expressions 'andalso' and 'orelse' are expanded by the Compiler (see v3_core) into 'case' expressions. If parentheses are used to enforce left associativeness, variables are introduced, and the time needed by Dialyzer increases exponentially. Rather than trying to fix Dialyzer itself, v3_core now rewrites repeated use of 'andalso' ('orelse') into right associative expressions before creating the 'case' expressions.
2018-08-22map_SUITE: Test is_map_key/2 followed by a map updateBjörn Gustavsson
2018-08-22beam_validator: Infer the type of the map argument for is_map_key/2Björn Gustavsson
Make sure that beam_validator considers a call to is_map_key/2 followed by an update of the same map without an is_map/1 test safe. (This situation will probably not be encountered when using the compiler in OTP 21, but better safe than sorry.)
2018-08-22map_SUITE: Cover map_get optimizations in beam_deadBjörn Gustavsson
2018-08-14Fix compiler crash when compiling double receivesBjörn Gustavsson
The compiler would crash when compiling a function with two receive statements. https://bugs.erlang.org/browse/ERL-703
2018-08-13Merge pull request #1919 from bjorng/bjorn/compiler/fix-is_map_key/OTP-15227Björn Gustavsson
Correct error behavior of is_map_key/2 in guards
2018-08-13Correct error behavior of is_map_key/2 in guardsBjörn Gustavsson
Consider the following functions: foo() -> bar(not_a_map). bar(M) when not is_map_key(a, M) -> ok; bar(_) -> error. What will `foo/0` return? It depends. If the module is compiled with the default compiler options, the return value will be `ok`. If the module is compiled with the `inline` option, the return value will be `error`. The correct value is `error`, because the call to `is_map_key/2` when the second argument is not a map should fail the entire guard. That is the way other failing guards BIFs are handled. For example: foo() -> bar(not_a_tuple). bar(T) when not element(1, T) -> ok; bar(_) -> error. `foo/0` always returns `error` (whether the code is inlined or not). This bug can be fixed by changing the classification of `is_map_key/2` in the `erl_internal` module. It is now classified as a type test, which is incorrect because type tests should not fail. Reclassifying it as a plain guard BIF corrects the bug. This correction also fixes the internal consistency check failure which was reported in: https://bugs.erlang.org/browse/ERL-699
2018-08-11Merge branch 'maint-21' into maintRickard Green
* maint-21: Updated OTP version Update release notes Update version numbers
2018-08-10Update release notesErlang/OTP
2018-08-10Update version numbersErlang/OTP
2018-08-10Merge branch ↵Erlang/OTP
'john/compiler/fix-deterministic-include-paths/OTP-15204/ERL-679' into maint-21 * john/compiler/fix-deterministic-include-paths/OTP-15204/ERL-679: Omit include path debug info for +deterministic builds # Conflicts: # lib/compiler/test/compile_SUITE.erl
2018-08-10Merge branch 'maint-20' into maintRickard Green
* maint-20: Updated OTP version Update release notes Update version numbers crypto: Fix crash in compute_key(ecdh, ...) on badarg Relax add_table_copy restriction Fixed #Ref ordering bug Test #Ref ordering in lists and ets Do NOT disc_load from ram_copies when master_node is set ssl: Make sure that a correct cipher suite is selected ssl: Correct handling of empty server SNI extension
2018-08-10Merge pull request #1911 from ↵Björn Gustavsson
bjorng/bjorn/compiler/binary-syntax/ERL-689/OTP-15219 Fix bug in binary matching
2018-08-09Update release notesErlang/OTP
2018-08-09Update version numbersErlang/OTP
2018-08-09Merge branch ↵Rickard Green
'john/compiler/fix-deterministic-include-paths/OTP-15204/ERL-679' into maint * john/compiler/fix-deterministic-include-paths/OTP-15204/ERL-679: Omit include path debug info for +deterministic builds
2018-08-09Omit include path debug info for +deterministic buildsJohn Högberg
Compiling the same file with different include paths resulted in different files with the `+deterministic` flag even if everything but the paths were identical. This was caused by the absolute path of each include directory being unconditionally included in a debug information chunk. This commit fixes this by only including this information in non-deterministic builds.
2018-08-09Merge pull request #1910 from ↵Björn Gustavsson
bjorng/bjorn/compiler/letrec-side-effect-fix/ERL-658/OTP-15188 Fix side-effect optimization when compiling from Core Erlang
2018-08-08Fix bug in binary matchingBjörn Gustavsson
The compiler generates incorrect code for the following example: decode_binary(_, <<Length, Data/binary>>) -> case {Length, Data} of {0, _} -> %% When converting the match context back to a binary, %% Data will be set to the entire original binary, %% that is, to <<0>> instead of <<>>. {{0, 0, 0}, Data}; {4, <<Y:16/little, M, D, Rest/binary>>} -> {{Y, M, D}, Rest} end. The problem is the delayed sub binary creation optimization, which is not safe to do in this case. This commit introduces a heuristic that will disable the delayed sub binary creation optimization for this example. Unfortunately, the heuristic may turn off the optimization when it would actually be safe. In the OTP codebase, the optimization is turned off in two instances, once in string.erl and once in dets_v9.erl. https://bugs.erlang.org/browse/ERL-689
2018-08-08Merge pull request #1903 from michalmuskala/mm/useless-callBjörn Gustavsson
Eliminate double computation of next var
2018-08-08Fix side-effect optimization when compiling from Core ErlangJohn Högberg
When an expression is only used for its side effects, we try to remove everything that doesn't tie into a side-effect, but we went a bit too far when we applied the optimization to funs defined in such a context. Consider the following: do letrec 'f'/0 = fun () -> ... whatever ... in call 'side':'effect'(apply 'f'/0()) 'ok' When f/0 is optimized under the assumption that its return value is unused, side:effect/1 will be fed the result of the last side-effecting expression in f/0 instead of its actual result. https://bugs.erlang.org/browse/ERL-658 Co-authored-by: Björn Gustavsson <[email protected]>
2018-08-07Eliminate double computation of next varMichał Muskała
My compiler benchmarks on modules with huge functions, show the next_free_variable_name call to be expensive. It turns out one of the 3 calls to the function was completely ignored.
2018-08-06beam_validator: Fix false diagnostic for a receive nested in a tryBjörn Gustavsson
When nesting a receive in a try/catch, there could be a false diagnostic that a fragile term is used. https://bugs.erlang.org/browse/ERL-684
2018-07-18Merge pull request #1875 from ↵John Högberg
jhogberg/john/compiler/fix-varsize-binary-comprehension/OTP-15186/ERL-665 Fix a crash when compiling variable-sized binary comprehensions
2018-07-16Abort size calculation when a matched-out variable is usedJohn Högberg
Referencing a matched-out variable in a size expression makes it impossible to calculate the size of the result based on the size of the matched binary. The compiler would still generate code to do this however, which would crash since the variable isn't defined at the size calculation.
2018-07-13docs: make clean all XMLDIRLukas Larsson
2018-07-06Call test_lib:recompile/1 from init_per_suite/1Björn Gustavsson
Call test_lib:recompile/1 from init_per_suite/1 instead of from all/0. That makes it easy to find the log from the compilation in the log file for the init_per_suite/1 test case.
2018-06-29Update release notesErlang/OTP
2018-06-29Update version numbersErlang/OTP
2018-06-29Merge branch 'bjorn/compiler/fix-beam_jump-crash/ERL-660/OTP-15166' into ↵Erlang/OTP
maint-21 * bjorn/compiler/fix-beam_jump-crash/ERL-660/OTP-15166: Eliminate a crash in the beam_jump pass
2018-06-29Merge branch 'bjorn/compiler/fix-map_get/OTP-15157' into maint-21Erlang/OTP
* bjorn/compiler/fix-map_get/OTP-15157: Fix internal compiler error for map_get/2
2018-06-29Merge branch 'bjorn/compiler/fix-skipped-matching/ERL-655/OTP-15156' into ↵Erlang/OTP
maint-21 * bjorn/compiler/fix-skipped-matching/ERL-655/OTP-15156: beam_type: Fix unsafe optimization
2018-06-29Eliminate a crash in the beam_jump passBjörn Gustavsson
https://bugs.erlang.org/browse/ERL-660
2018-06-27Fix internal compiler error for map_get/2Björn Gustavsson
Code such as that the following: Val = map_get(a, Map), Map#{a:=z} %Could be any map update would incorrectly cause an internal consistency check failure: Internal consistency check failed - please report this bug. Instruction: {put_map_exact,{f,0},{x,0},{x,0},1,{list,[{atom,a},{atom,z}]}} Error: {bad_type,{needed,map},{actual,term}}: Update beam_validator so that it understands that the second argument for map_get/2 is a map.
2018-06-27beam_type: Fix unsafe optimizationBjörn Gustavsson
beam_type assumed that the operand for the bs_context_to_binary instruction must be a binary. That is not correct; bs_context_to_binary accepts anything. Based on the incorrect assumption, beam_type would remove other test instructions. The bug was introduced in eee8655788d2, which was supposed to be just a refactoring commit. https://bugs.erlang.org/browse/ERL-655
2018-06-25Prepare releaseErlang/OTP
2018-06-25Fix unsafe optimization when running beam_block the second timeBjörn Gustavsson
The compiler would crash when compiling code such as: serialize(#{tag := value, id := Id, domain := Domain}) -> [case Id of nil -> error(id({required, id})); _ -> <<10, 1:16/signed, Id:16/signed>> end, case Domain of nil -> error(id({required, domain})); _ -> <<8, 2:16/signed, Domain:32/signed>> end]. The crash would look like this: Function: serialize/1 t.erl: internal error in block2; crash reason: {badmatch,false} in function beam_utils:live_opt/4 (beam_utils.erl, line 861) in call from beam_utils:live_opt/1 (beam_utils.erl, line 285) in call from beam_block:function/2 (beam_block.erl, line 47) in call from beam_block:'-module/2-lc$^0/1-0-'/2 (beam_block.erl, line 33) in call from beam_block:'-module/2-lc$^0/1-0-'/2 (beam_block.erl, line 33) in call from beam_block:module/2 (beam_block.erl, line 33) in call from compile:block2/2 (compile.erl, line 1358) in call from compile:'-internal_comp/5-anonymous-1-'/3 (compile.erl, line 349) The reason for the crash is an assertion failure caused by a previous unsafe optimization. Here is the code before the unsafe optimization: . . . {bs_init2,{f,0},7,0,0,{field_flags,[]},{x,1}}. {bs_put_string,3,{string,[8,0,2]}}. {bs_put_integer,{f,0},{integer,32},1,{field_flags,[signed,big]},{y,1}}. {move,{x,1},{x,0}}. {test_heap,4,1}. . . . beam_block:move_allocate/1 moved up the test_heap/2 instruction past the move/2 instruction, adjusting the number of live registers at the same time: . . . {bs_init2,{f,0},7,0,0,{field_flags,[]},{x,1}}. %% Only x1 is live now. {bs_put_string,3,{string,[8,0,2]}}. {bs_put_integer,{f,0},{integer,32},1,{field_flags,[signed,big]},{y,1}}. {test_heap,4,2}. %Unsafe. x0 is dead. {move,{x,1},{x,0}}. . . . This optimization is unsafe because the bs_init2 instruction killed x0. The bug is in beam_utils:anno_defs/1, which adds annotations indicating the registers that are defined at the beginning of each block. The annotation before the move/2 instruction incorrectly indicated that x0 was live. https://bugs.erlang.org/browse/ERL-650 https://github.com/elixir-lang/elixir/issues/7782
2018-06-19Prepare releaseErlang/OTP
2018-06-18Update copyright yearHenrik Nord
2018-06-07Merge pull request #1832 from josevalim/jv-revert-beam-jumpBjörn Gustavsson
Revert "Run the sharing optimisation in beam_jump until fixpoint"
2018-06-07Merge pull request #1831 from bjorng/bjorn/compiler/fix-name-captureBjörn Gustavsson
Fix name capture problem in sys_core_fold OTP-15115
2018-06-04Revert "Run the sharing optimisation in beam_jump until fixpoint"José Valim
We have found cases where compilation drastically slows down due to this commit. We are working on a minimal cases and plan to bring this patch back once we can work our the performance issues. This reverts commit f7c9383f4c3d4b6819b5ba4d54c7093df806fe4a.
2018-06-04sys_core_fold: Fix name capture problemBjörn Gustavsson
sys_core_fold could do unsafe transformations on the code from the old inliner (invoked using the compiler option `{inline,[{F/A}]}` to request inlining of specific functions). To explain the bug, let's first look at an example that sys_core_fold handles correctly. Consider this code: 'foo'/2 = fun (Arg1,Arg2) -> let <B> = Arg2 in let <A,B> = <B,Arg1> in {A,B} In this example, the lets can be completely eliminated, since the arguments for the lets are variables (as opposed to expressions). Since the variable B is rebound in the inner let, `sys_core_fold` must take special care when doing the substitutions. Here is the correct result: 'foo'/2 = fun (Arg1, Arg2) -> {Arg2,Arg1} Consider a slight modifictation of the example: 'bar'/2 = fun (Arg1,Arg2) -> let <B> = [Arg2] in let <A,B> = <B,[Arg1]> in {A,B} Here some of the arguments for the lets are expressions, so the lets must be kept. sys_core_fold does not handle this example correctly: 'bar'/2 = fun (Arg1,Arg2) -> let <B> = [Arg2] in let <B> = [Arg1] in {B,B} In the inner let, the variable A has been eliminated and replaced with the variable B in the body (the first B in the tuple). Since the B in the outer let is never used, the outer let will be eliminated, giving: 'bar'/2 = fun (Arg1,Arg2) -> let <B> = [Arg1] in {B,B} To handle this example correctly, sys_core_fold must rename the variable B in the inner let like this to avoid capturing B: 'bar'/2 = fun (Arg1,Arg2) -> let <B> = [Arg2] in let <NewName> = [Arg1] in {B,NewName} (Note: The `v3_kernel` pass alreday handles those examples correctly in case `sys_core_fold` has been disabled.)
2018-06-04sys_core_inline: Avoid spurious warningsBjörn Gustavsson
Add more `compiler_generated` attributes to avoid spurious compiler warnings triggered by the bug fix in the next commit.
2018-05-29Revert "Prepare release"Henrik
This reverts commit fd8e49b5bddceaae803670121b603b5eee8c5c08.