aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
AgeCommit message (Collapse)Author
2018-08-31Merge pull request #1944 from ↵Hans Bolinder
uabboli/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-24Merge branch 'bjorn/compiler/ssa'Björn Gustavsson
* bjorn/compiler/ssa: Travis CI: Run the SSA linter in the Linux64SmokeTest build Remove retired compiler passes Introduce a new SSA-based intermediate format hipe_beam_to_icode: Correct translation of get_map_elements beam_dead: Remove shortcut of binary matching instruction beam_bs: Remove optimizations that are easier done on SSA format Don't run unsafe compiler passes Simplify optimizations by introducing is_nil late beam_utils: Make is_tagged_tuple a pure test beam_except: Enhance recognition of function_clause exceptions beam_validator: Infer the types of copies in a smarter way beam_validator: Improve merge of cons and literal list beam_validator: Strengthen validation of func_info beam_validator: Allow get_tuple_element before dsetelement beam_validator: Don't transfer state to labels that can't be reached beam_validator: Improve type analysis for tuples beam_validator: Be more careful when updating try/catch state beam_trim: Handle an empty list of instructions v3_core: Number argument variables in ascending order Teach binary instructions to use Y registers as destination OTP-14894
2018-08-24Remove retired compiler passesBjörn Gustavsson
2018-08-24Introduce a new SSA-based intermediate formatBjörn Gustavsson
v3_codegen is replaced by three new passes: * beam_kernel_to_ssa which translates the Kernel Erlang format to a new SSA-based intermediate format. * beam_ssa_pre_codegen which prepares the SSA-based format for code generation, including register allocation. Registers are allocated using the linear scan algorithm. * beam_ssa_codegen which generates BEAM assembly code from the SSA-based format. It easier and more effective to optimize the SSA-based format before X and Y registers have been assigned. The current optimization passes constantly have to make sure no "holes" in the X register assignments are created (that is, that no X register becomes undefined that an allocation instruction depends on). This commit also introduces the following optimizations: * Replacing of tuple matching of records with the is_tagged_tuple instruction. (Replacing beam_record.) * Sinking of get_tuple_element instructions to just before the first use of the extracted values. As well as potentially avoiding extracting tuple elements when they are not actually used on all executions paths, this optimization could also reduce the number values that will need to be stored in Y registers. (Similar to beam_reorder, but more effective.) * Live optimizations, removing the definition of a variable that is not subsequently used (provided that the operation has no side effects), as well strength reduction of binary matching by replacing the extraction of value from a binary with a skip instruction. (Used to be done by beam_block, beam_utils, and v3_codegen.) * Removal of redundant bs_restore2 instructions. (Formerly done by beam_bs.) * Type-based optimizations across branches. More effective than the old beam_type pass that only did type-based optimizations in basic blocks. * Optimization of floating point instructions. (Formerly done by beam_type.) * Optimization of receive statements to introduce recv_mark and recv_set instructions. More effective with far fewer restrictions on what instructions are allowed between creating the reference and entering the receive statement. * Common subexpression elimination. (Formerly done by beam_block.)
2018-08-23Merge branch 'maint'Björn Gustavsson
* maint: map_SUITE: Test is_map_key/2 followed by a map update beam_validator: Infer the type of the map argument for is_map_key/2 map_SUITE: Cover map_get optimizations in beam_dead
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-17beam_dead: Remove shortcut of binary matching instructionBjörn Gustavsson
This optimization can be better done in the SSA format before code generation.
2018-08-17beam_bs: Remove optimizations that are easier done on SSA formatBjörn Gustavsson
The removal of redundant bs_restore2 instructions is done easier on the SSA format. Keep the rest of the optimizations, because they are easier to do on the BEAM instructions.
2018-08-17Don't run unsafe compiler passesBjörn Gustavsson
As a preparation for replacing v3_codegen with a new code generator, remove unsafe optimization passes. Especially the older compiler passes have implicit assumptions about how the code is generated. Remove the optimizations in beam_block (keep the code that creates blocks) because they are unsafe. beam_block also calls beam_utils:live_opt/1, which is unsafe. Remove beam_type because it calls beam_utils:live_opt/1, and also because it recalculates the number of heaps words and number of live registers in allocation instructions, thus potentially hiding bugs in other passes. Remove beam_receive because it is unsafe. Remove beam_record because it is the only remaining user of beam_utils:anno_defs/1. Remove beam_reorder because it makes much more sense to run it as an early SSA-based optimization pass. Remove the now unused functions in beam_utils: anno_def/1 delete_annos/1 is_killed_block/2 live_opt/1 usage/3 Note that the following test cases will fail because of the removed optimizations: compile_SUITE:optimized_guards/1 compile_SUITE:bc_options/1 receive_SUITE:ref_opt/1
2018-08-17Simplify optimizations by introducing is_nil lateBjörn Gustavsson
2018-08-17beam_utils: Make is_tagged_tuple a pure testBjörn Gustavsson
This will enable more optimizations.
2018-08-17beam_except: Enhance recognition of function_clause exceptionsBjörn Gustavsson
Don't match exact BEAM instructions when trying to recognize function_clause exceptions that should be replaced with a jump to the func_info instruction. Instead, do a symbolic evaluation of the list building code and see if the result is a list of the argument registers. While at it, also teach fix_block_1/2 to completely remove a test_heap instruction before an exception generation instruction.
2018-08-17beam_validator: Infer the types of copies in a smarter wayBjörn Gustavsson
Smarter code generation means that beam_validator must be smarter too. In the following example, beam_validator must be able to infer that y0 refers to a map: move x0 y0 test is_map L1 x0 %% Here the type for y0 must be 'map'.
2018-08-17beam_validator: Improve merge of cons and literal listBjörn Gustavsson
2018-08-17beam_validator: Strengthen validation of func_infoBjörn Gustavsson
The func_info instruction does not expect a stack frame. There will be an assertion failure in the debug-compiled runtime system.
2018-08-17beam_validator: Allow get_tuple_element before dsetelementBjörn Gustavsson
2018-08-17beam_validator: Don't transfer state to labels that can't be reachedBjörn Gustavsson
If we transfer state appropriately to labels that can't be reached, the state could taint other labels.
2018-08-17beam_validator: Improve type analysis for tuplesBjörn Gustavsson
Since the compiler will start optimizing more aggressively, beam_validator must keep up and improve the recognization of tuples and maps.
2018-08-17beam_validator: Be more careful when updating try/catch stateBjörn Gustavsson
The new code generator will more aggressively reuse registers, so we must be more careful about updating the state for try/catch. In particular, an "empty" try/catch that can't throw an exception must not update the try/catch state.
2018-08-17beam_trim: Handle an empty list of instructionsBjörn Gustavsson
2018-08-17v3_core: Number argument variables in ascending orderBjörn Gustavsson
Nicer to read and less confusion.
2018-08-15Merge branch 'maint'Björn Gustavsson
* maint: Fix compiler crash when compiling double receives erts: Delete fd from poll-set when closing fd_driver port
2018-08-14remove_message does not store any pointer to x0Davide Bettio
remove_message just remove messages without writing to any register. Compiler is already generating code like: {get_tuple_element,{x,0},1,{x,0}}. remove_message. {jump,{f,6}} That clearly uses x0 for other purposes.
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 branch 'maint'Björn Gustavsson
* maint: 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-10Merge branch 'maint'Björn Gustavsson
* maint: Fix bug in binary matching
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-09Merge branch 'maint'Rickard Green
* maint: Omit include path debug info for +deterministic builds
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 branch 'maint'Björn Gustavsson
* maint: Fix side-effect optimization when compiling from Core Erlang Conflicts: lib/compiler/src/sys_core_fold.erl
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 #1904 from michalmuskala/mm/get-stacktrace-to-buildBjörn Gustavsson
Rewrite erlang:get_stacktrace calls to primop when safe
2018-08-08Merge branch 'maint'Björn Gustavsson
* maint: Eliminate double computation of next var beam_validator: Fix false diagnostic for a receive nested in a try
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-08-05Rewrite erlang:get_stacktrace calls to primop when safeMichał Muskała
This allows taking advantage of further optimisations, like the raw_raise instruction for code that can't upgrade (yet) to the new stacktrace syntax for compatibility reasons. The rewrite is only done when it is safe - when the get_stacktrace call is the very first thing the handler does.
2018-07-27Change "can not" into "cannot"Raimo Niskanen
I did not find any legitimate use of "can not", however skipped changing e.g RFCs archived in the source tree.
2018-07-18Merge branch 'maint'John Högberg
* maint: Abort size calculation when a matched-out variable is used
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-04Merge branch 'maint'John Högberg
* maint: Updated OTP version Update release notes Update version numbers Eliminate a crash in the beam_jump pass stdlib: Fix a 'chars_limit' bug Fix a race condition when generating async operation ids Fix internal compiler error for map_get/2 beam_type: Fix unsafe optimization public_key: Remove moduli 5121 and 7167 Thoose were added by 598629aeba9de98e8cdf5637043eb34e5d407751 but are not universaly supported.
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