aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
AgeCommit message (Collapse)Author
2019-08-07beam_ssa_lint: Use #b_var{} instead of variable namesJohn Högberg
2019-08-07Merge branch 'john/compiler/validator-improve-try_case-handling'John Högberg
* john/compiler/validator-improve-try_case-handling: beam_validator: Disallow jumps to try_case handlers
2019-08-07Merge branch 'john/compiler/explicit-call-exceptions'John Högberg
* john/compiler/explicit-call-exceptions: compiler: Simplify set_tuple_element optimization compiler: Make 'succeeded' optimization more general compiler: Simplify call type optimization compiler: All calls may throw, so they all need success checks erts_debug: Turn off unsafe optimizations in test case
2019-08-06Merge branch 'lukas/otp/add-dialyzer-make-target/OTP-15915'Lukas Larsson
* lukas/otp/add-dialyzer-make-target/OTP-15915: otp: Add make dialyzer and make xmllint documentation Add 'make dialyzer' target to top and apps
2019-08-06beam_validator: Disallow jumps to try_case handlersJohn Högberg
By keeping track of the tag types in the exception handler list, we can reject direct jumps to try_case handlers such as those provoked by OTP-15945.
2019-08-06compiler: Simplify set_tuple_element optimizationJohn Högberg
By removing 'succeeded' tests on setelement/3 when we know it succeeds, all sequences that are eligible for set_tuple_element will be nicely bundled in the same block, so we won't need to bother with special try/catch handling. The new version is slightly worse in the case where the first setelement/3 is used to infer the tuple size as that call will remain in its own block, but in practice this only occurs when the user manually spells them out and I couldn't find any examples of this in OTP or Elixir. It's equivalent for record updates.
2019-08-06compiler: Make 'succeeded' optimization more generalJohn Högberg
2019-08-06compiler: Simplify call type optimizationJohn Högberg
2019-08-06compiler: All calls may throw, so they all need success checksJohn Högberg
Only adding them when in try/catch worked, but made the exceptions implicit and forced all later optimization passes to keep them in mind. Making them explicit lets us simplify later passes.
2019-08-05Merge branch 'maint'Björn Gustavsson
* maint: Ensure that the stack slots are initialized when matching maps
2019-08-05Merge branch 'bjorn/compiler/fix-stack-init/ERL-1017/OTP-15968' into maintBjörn Gustavsson
* bjorn/compiler/fix-stack-init/ERL-1017/OTP-15968: Ensure that the stack slots are initialized when matching maps
2019-08-05Ensure that the stack slots are initialized when matching mapsBjörn Gustavsson
When matching a map, the compiler could fail to generate code that would initialize all stack slots (Y registers) properly. Here is a general outline of code that *could* cause this problem: foo(Key, Map) -> Res = case Map of #{Key := Val} -> %% Do something with Val here. . . . #{} -> [] end, %% The stack slot for Val might not have been initialized %% here if the key was not present in the map. . . . %% Use Res. . . . The code generator would wrongly assume that the map matching would always initialize the stack slot, and if nothing else happened to force that stack slot to be initialized, it would remain uninitialized, which would likely crash the runtime system at the next garbage collection. `beam_validator` is supposed to find these kind of problems, but a bug in `beam_validator` prevented it from detecting this problem. https://bugs.erlang.org/browse/ERL-1017
2019-08-05Merge branch 'maint'John Högberg
* maint: beam_validator: Values referenced by other values must be merged
2019-08-05Merge branch 'john/compiler/fix-delayed-type-inference/OTP-15954/ERL-995' ↵John Högberg
into maint * john/compiler/fix-delayed-type-inference/OTP-15954/ERL-995: beam_validator: Values referenced by other values must be merged
2019-08-02Merge pull request #2327 from josevalim/jv-faster-cerl-setsBjörn Gustavsson
Optimize is_subset and is_disjoint in cerl_sets
2019-08-02Merge branch 'maint'Björn Gustavsson
* maint: Avoid extremely long compilation times for huge functions
2019-08-02Merge pull request #2336 from ↵Björn Gustavsson
bjorng/bjorn/compiler/fix-slow-beam_ssa_dead/ERL-1014/OTP-15966 Avoid extremely long compilation times for huge functions
2019-08-02Merge branch 'maint'Björn Gustavsson
* maint: Fix compiler crash when compiling with +no_type_opt Eliminate a crash in the type optimizer pass
2019-08-02Merge branch 'bjorn/compiler/length-misuse/ERL-1013' of ↵Björn Gustavsson
https://github.com/bjorng/otp into maint OTP-15970 * 'bjorn/compiler/length-misuse/ERL-1013' of https://github.com/bjorng/otp: Eliminate a crash in the type optimizer pass
2019-08-02Merge branch 'bjorn/compiler/fix-no_type_opt/ERL-997' of ↵Björn Gustavsson
https://github.com/bjorng/otp into maint OTP-15969 * 'bjorn/compiler/fix-no_type_opt/ERL-997' of https://github.com/bjorng/otp: Fix compiler crash when compiling with +no_type_opt
2019-08-01Avoid extremely long compilation times for huge functionsBjörn Gustavsson
Compiling this example takes less than a second for OTP 21: -define(B, {?A,?A,?A,?A,?A}). -define(C, {?B,?B,?B,?B,?B}). -define(D, {?C,?C,?C,?C,?C}). -define(E, {?D,?D,?D}). f() -> ?E = foo:bar(). The compilation time for OTP 22 is about 10 seconds. Most of the time is spent in `beam_ssa_dead`. This commit introduces several optimizations to bring the compilation time down to about a second. The most important of those optimizations is limiting the effort spent searching forward for a joining point for the success and failure labels for a two-way branch. This change is helped by the change of representation of variable sets from `ordsets` to `cerl_sets`. https://bugs.erlang.org/browse/ERL-1014
2019-08-01Merge branch 'maint'Björn Gustavsson
* maint: Fix unsafe code sharing
2019-08-01Merge branch 'bjorn/compiler/fix-unsafe-sharing/OTP-15963' into maintBjörn Gustavsson
* bjorn/compiler/fix-unsafe-sharing/OTP-15963: Fix unsafe code sharing
2019-07-30Fix compiler crash when compiling with +no_type_optBjörn Gustavsson
If the `no_type_opt` option was given, the compiler would crash when attempting to compile containing with a `try`...`after` construct, such as this code: foo() -> try make_ref() after ok end. To avoid having this bug re-appear, test the `no_type_opt` option in the test suites. https://bugs.erlang.org/browse/ERL-997
2019-07-30Eliminate a crash in the type optimizer passBjörn Gustavsson
https://bugs.erlang.org/browse/ERL-1013
2019-07-29Fix unsafe code sharingBjörn Gustavsson
2019-07-19Optimize is_subset and is_disjoint in cerl_setsJosé Valim
The new implementation use maps iterators and are more perfomant in banchmarks by roughly 10%. More importantly, the iterators approach allow us to short-circuit and abort early. fold and filter have also been changed to use iterators. We could simply delegate to the maps' functions, but inlining the implementation allows us to skip a double anonymous function dispatch.
2019-07-12Merge branch 'john/compiler/improve-validator-type-inference/ERL-998'John Högberg
* john/compiler/improve-validator-type-inference/ERL-998: beam_validator: Improve type inference on inequality beam_validator: Remove redundant calls to infer_types
2019-07-11beam_validator: Values referenced by other values must be mergedJohn Högberg
This is a more proper fix for ERIERL-348. We used to think that we wouldn't need to update the type of a variable that's no longer referenced by a register ("dead value"), but the attached test case pokes a hole in that assumption. To summarize, the result of '=:='/2 is kept alive longer than one of its arguments, which gets pruned in a state merge leaving us with nothing to work on when we finally compare the result. This is fine for most operations since there's no point in (say) updating the size of a tuple we can no longer reach, but '=:='/2 updates the types of both arguments and we risk missing out on important information when either of them is gone. This commit fixes the problem by merging all values that are *reachable* from a register, rather than just those that *exist* in a register, ensuring that all values stay around at least as long as they're needed.
2019-07-11Merge branch 'maint'John Högberg
* maint: Updated OTP version Prepare release # Conflicts: # OTP_VERSION # make/otp_version_tickets_in_merge
2019-07-11Merge branch 'maint-22' into maintJohn Högberg
* maint-22: Updated OTP version Prepare release # Conflicts: # make/otp_version_tickets
2019-07-11beam_validator: Improve type inference on inequalityJohn Högberg
Both sides need to be inferred, and we should infer as if we've made an exact match when we know that LHS is single-valued. This was done for select_val, but we failed to do so for is_ne_exact et al.
2019-07-11beam_validator: Remove redundant calls to infer_typesJohn Högberg
2019-07-11Merge branch 'maint'John Högberg
* maint: compiler: Fix compiler crash introduced by OTP-15952
2019-07-11Merge branch 'john/compiler/fix-bad-try_catch-recv-fix/OTP-15953/ERL-999' ↵John Högberg
into maint * john/compiler/fix-bad-try_catch-recv-fix/OTP-15953/ERL-999: compiler: Fix compiler crash introduced by OTP-15952
2019-07-10Prepare releaseErlang/OTP
2019-07-10compiler: Fix compiler crash introduced by OTP-15952John Högberg
An assertion in code generation would fail when the common exit block was ?BADARG_BLOCK, as some operations expect to always "fail" directly to that block (= throw an exception) and we had inserted a dummy block in between. Other operations could also get funny fail labels, jumping to blocks that immediately jumped to {f,0}, but these were all cleaned up by beam_jump, sweeping the bug under the rug.
2019-07-10Merge branch 'maint'John Högberg
* maint: Updated OTP version Prepare release # Conflicts: # OTP_VERSION # make/otp_version_tickets_in_merge
2019-07-10Merge branch 'maint-22' into maintJohn Högberg
* maint-22: Updated OTP version Prepare release # Conflicts: # make/otp_version_tickets
2019-07-09Prepare releaseErlang/OTP
2019-07-09Merge branch 'john/compiler/fix-fail-path-exceptions-bsm/OTP-15946' into ↵Erlang/OTP
maint-22 * john/compiler/fix-fail-path-exceptions-bsm/OTP-15946: beam_ssa_bsm: Leave ?BADARG_BLOCK alone when cloning fail path
2019-07-09Merge branch 'john/compiler/fix-unsafe-tuple_size-opt/OTP-15945' into maint-22Erlang/OTP
* john/compiler/fix-unsafe-tuple_size-opt/OTP-15945: beam_ssa_opt: Do not apply tuple_size optimization outside guards
2019-07-09Merge branch 'maint'John Högberg
* maint: compiler: Fix broken 'receive' in try/catch blocks
2019-07-09Merge branch 'john/compiler/fix-try_catch-receives/OTP-15952' into maintJohn Högberg
* john/compiler/fix-try_catch-receives/OTP-15952: compiler: Fix broken 'receive' in try/catch blocks
2019-07-09compiler: Fix broken 'receive' in try/catch blocksJohn Högberg
This fix is rather ugly and tacked-on, but I'm not comfortable refactoring the pass in an emergency patch.
2019-07-08Merge pull request #2318 from jhogberg/john/compiler/union-types/OTP-15892John Högberg
Extend the compiler's type representation
2019-07-05beam_ssa_opt: Sink get_tuple_element before type optimizationJohn Högberg
Eagerly extracting elements can be quite problematic now that we have union types. Consider the following: 0: %% _0 is {ok, #record{}} | {error,atom()} _1 = get_tuple_element _0, literal 0 _2 = get_tuple_element _0, literal 1 switch _1, label 0, [ { literal ok, label 1 }, { literal error, label 2 } ] 1: %% _0 is known to be {ok,#record{}} here 2: %% _0 is known to be {error,atom()} here The type pass is clever enough to see that _0 has the types noted above, but because the type of _2 is set in the first block where we didn't have that information yet, it's still #record{} | atom() in both branches. Sinking these instructions to when they are used greatly improves the type information in many cases, but it does have a few limitations and using it in both of the above branches would take us back to square one.
2019-07-05beam_ssa_type: Infer types on switch failureJohn Högberg
If we know that the checked value is a singleton at the fail block, it's safe to infer types as if we've made a direct comparison against that value.
2019-07-05Merge pull request #2314 from josevalim/jv-set-unusedJohn Högberg
Collect unused vars instead of used ones
2019-07-05beam_ssa_type: Subtract more types inferred from '=:='/2John Högberg