aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
AgeCommit message (Collapse)Author
2019-02-28beam_ssa_opt: Use is_tagged_tuple moreBjörn Gustavsson
Consider this code: foo(X) -> case X of {ok,A} -> A; error -> X end. The `is_tagged_tuple` instruction would not be used because not all instructions in the tuple matching sequence had the same failure label: function t:foo(_0) { 0: @ssa_bool:7 = bif:is_tuple _0 br @ssa_bool:7, label 8, label 4 8: @ssa_arity = bif:tuple_size _0 @ssa_bool:9 = bif:'=:=' @ssa_arity, literal 2 br @ssa_bool:9, label 6, label 3 6: _4 = get_tuple_element _0, literal 0 @ssa_bool = bif:'=:=' _4, literal ok br @ssa_bool, label 5, label 3 5: _3 = get_tuple_element _0, literal 1 ret _3 4: @ssa_bool:11 = bif:'=:=' _0, literal error br @ssa_bool:11, label 10, label 3 10: ret _0 3: _2 = put_tuple literal case_clause, _0 %% t.erl:5 @ssa_ret:12 = call remote (literal erlang):(literal error)/1, _2 ret @ssa_ret:12 } Enhance the ssa_opt_record optimization to use `is_tagged_tuple` even if all failure labels are not the same: function t:foo(_0) { 0: @ssa_bool:7 = bif:is_tuple _0 br @ssa_bool:7, label 8, label 4 8: @ssa_bool:9 = is_tagged_tuple _0, literal 2, literal ok br @ssa_bool:9, label 6, label 3 6: _3 = get_tuple_element _0, literal 1 ret _3 4: @ssa_bool:11 = bif:'=:=' _0, literal error br @ssa_bool:11, label 10, label 3 10: ret _0 3: _2 = put_tuple literal case_clause, _0 %% t.erl:5 @ssa_ret:12 = call remote (literal erlang):(literal error)/1, _2 ret @ssa_ret:12 } The tuple test will be repeated, but since four instructions are replaced by two instructions, the code will still be faster and smaller.
2019-02-28beam_ssa_opt: Order consecutive get_tuple_element instructionsBjörn Gustavsson
2019-02-27beam_validator: Clarify a commentJohn Högberg
2019-02-27beam_validator: Make call argument validation stricterJohn Högberg
We used to cheat by checking if it were possible to meet the Given and Required types, which caught the most common problems but potentially let tuple element conflicts pass through. This was a compromise to let the thing "work" while we were refactoring the validator, but we can be a lot stricter now that its type tracking capabilities approach those of the type optimization pass.
2019-02-27beam_validator: Don't explode when building terms in receiveJohn Högberg
Building terms with fragile contents is okay because the GC is disabled during loop_rec, and the resulting term won't be reachable from the root set afterwards. ERL-862
2019-02-27beam_validator: Improve 'binary' type trackingJohn Högberg
2019-02-27beam_validator: Infer tuple element typesJohn Högberg
This is possible now that we track types on a per-value basis, and no longer need to care whether the source tuple's register has been clobbered by the time we infer the type.
2019-02-27beam_validator: Tolerate the 'receive' hack in prim_evalJohn Högberg
2019-02-27beam_validator: Track types by value rather than by registerJohn Högberg
This is a rather subtle but important distinction. While tracking types on a per-register basis is fairly effective, it forces us to track which registers alias each other, and makes it tricky to infer types over large blocks of code as instruction arguments may have been clobbered between definition and inference. Tracking types on a per-value basis makes us immune to these problems.
2019-02-27beam_validator: Disregard 'none' on joinJohn Högberg
2019-02-27beam_validator: Handle is_number, and join(float,int) -> numberJohn Högberg
I have no idea how this escaped us for so long...
2019-02-27beam_validator: Treat is_nil as is_eq_exact with nilJohn Högberg
2019-02-27beam_validator: Simplify get_element_typeJohn Högberg
2019-02-27beam_validator: Fix literal handling in meet/2John Högberg
2019-02-27beam_validator: Use literals as keys in container (tuple) elementsJohn Högberg
2019-02-27beam_validator: Refactor try/catch handling, againJohn Högberg
2019-02-27beam_validator: Refactor register initializationJohn Högberg
2019-02-27beam_validator: Refactor stack allocationJohn Högberg
2019-02-26beam_validator: Handle argument/return types for more functionsJohn Högberg
2019-02-26beam_validator: Don't forget last element when using put_tupleJohn Högberg
2019-02-26beam_jump: Fail label of select_val is unsafe for move eliminationJohn Högberg
Consider the following code: bme(Int) -> TagInt = Int band 2#111, Tag = case TagInt of 0 -> a; 1 -> b; 2 -> c; 3 -> d; 4 -> e; 5 -> f; 6 -> g; 7 -> h end, case Tag of g -> expects_g(TagInt, Tag); h -> expects_h(TagInt, Tag); _ -> Tag = id(Tag), ok end. expects_g(6, Atom) -> Atom = id(g), ok. expects_h(7, Atom) -> Atom = id(h), ok. The type optimization pass would recognize that TagInt can only be [0 .. 7], so the first 'case' would select_val over [0 .. 6] and swap out the fail label with the block for 7. A later optimization would merge this block with 'expects_h' in the second case, as the latter is only reachable from the former. ... but this broke down when the move elimination optimization didn't take the fail label of the first select_val into account. This caused it believe that the only way to reach 'expects_h' was through the second case when 'Tag' =:= 'h', which made it remove the move instruction added in the first case, passing garbage to expects_h/2.
2019-02-25cerl_sets: Use maps:filter/2 in filter/2John Högberg
This should be slightly more efficient than converting to/from lists for large sets.
2019-02-22Merge branch 'bjorn/compiler/use-lists-types'Björn Gustavsson
* bjorn/compiler/use-lists-types: beam_ssa_type: Use types from some 'lists' functions
2019-02-21beam_ssa_type: Use types from some 'lists' functionsBjörn Gustavsson
This commit lets the compiler know about the return type of some of the functions in the `lists` module. Knowing about the return will allow the compiler to emit fewer type test instructions, and also fewer instructions for throwing `case_clause` or `badmatch` exceptions, thus producing slightly faster and more compact code. This change makes the `lists` module a part of the language, but it could be argued that it already is because several functions (e.g. `member/2` and `keymember/3`) are implemented in as BIFs in the runtime system. Therefore, a user cannot simply change the `lists` module and expect everything to continue working as before. The compiler will now know the return types for the following functions: all/2 any/2 keymember/3 member/2 prefix/2 suffix/2 dropwhile/2 duplicate/2 filter/2 flatten/1 map/2 mapfoldl/3 mapfoldr/3 partition/2 reverse/1 sort/1 splitwith/1 takewhile/1 unzip/1 usort/1 zip/2 zipwith/3
2019-02-21sys_core_fold: Remove an unsafe optimizationBjörn Gustavsson
`sys_core_fold` has an optimization of repeated pattern matching. For example, when a record is matched the first time, the pattern is remembered. When the same record is matched again, the matching does not need to be repeated, but the variables bound in the first matching can be re-used. It turns out that that there is a name capture problem when the old inliner is used. The old inliner is used when explicitly inling certain functions, and by the compiler test suites for testing the compiler. The name capture problem could be eliminated by more aggressive variable renaming when inlining. But, fortunately, given the new SSA passes, this optimization is no longer as essential as it used to be. Removing the optimization turns out to be mostly benefical, leading to a smaller stack frame in many cases. Also remove the optimizations of `element/2`, `is_record/3`, and `setelement/3` from `sys_core_fold`. Because matched patterns are no longer remembered, those optimizations can very rarely be applied any more. (Those same optimizations are already done in `beam_ssa_type`.)
2019-02-21beam_ssa_type: Optimize setelement with partially constant argumentsBjörn Gustavsson
2019-02-21beam_ssa_opt: Do local CSE of get_tuple_element instructionsBjörn Gustavsson
For some reason, a `get_tuple_element` instruction was not deemed suitble for local common sub expression elimination. It turns out that enabling CSE for `get_tuple_element` is benefical. It will also be even more benefical in a future commit where some of the optimizations in `sys_core_fold` are removed.
2019-02-21Merge branch 'john/compiler/more-validator-cuddling'John Högberg
* john/compiler/more-validator-cuddling: beam_validator: Refactor call argument validation beam_validator: Refactor liveness/stack initialization checks beam_validator: Refactor try/catch handling beam_validator: Remember definitions on assignment beam_validator: Refactor stack trimming beam_validator: Track definitions of all terms beam_validator: Remove special handling of map_get/is_map_key beam_validator: Refactor select_tuple_arity beam_validator: Treat select_val as a series of '=:=' beam_validator: Treat all bs_get instructions as extractions beam_validator: Separate BIF/call types more clearly beam_validator: Assert that no tuple elements are out of bounds beam_validator: Get rid of the last uses of set_aliased_type beam_validator: Minor cosmetic refactoring
2019-02-21beam_validator: Refactor call argument validationJohn Högberg
2019-02-21beam_validator: Refactor liveness/stack initialization checksJohn Högberg
2019-02-21beam_validator: Refactor try/catch handlingJohn Högberg
2019-02-20beam_validator: Remember definitions on assignmentJohn Högberg
2019-02-20beam_validator: Refactor stack trimmingJohn Högberg
2019-02-20beam_validator: Track definitions of all termsJohn Högberg
2019-02-20beam_validator: Remove special handling of map_get/is_map_keyJohn Högberg
Neither can be used for type subtraction, so the default BIF handler suits them just fine.
2019-02-20beam_validator: Refactor select_tuple_arityJohn Högberg
2019-02-20beam_validator: Treat select_val as a series of '=:='John Högberg
2019-02-20beam_validator: Treat all bs_get instructions as extractionsJohn Högberg
While this is strictly only relevant for bs_get_binary2, we should never build anything while matching a message, so it ought to be safe to remove this last raw use of propagate_fragility.
2019-02-20beam_validator: Separate BIF/call types more clearlyJohn Högberg
2019-02-20beam_validator: Assert that no tuple elements are out of boundsJohn Högberg
2019-02-20beam_validator: Get rid of the last uses of set_aliased_typeJohn Högberg
Granted, it's replaced with a thin wrapper, but it'll simplify migration to the new type format.
2019-02-20beam_validator: Minor cosmetic refactoringJohn Högberg
2019-02-20erl_bifs: Add a note to the comment for is_pure/3Björn Gustavsson
2019-02-20Correct confusing comment in beam_ssa_typeBjörn Gustavsson
2019-02-20Improve optimization of switchesBjörn Gustavsson
Part of the switch optimization done by `ssa_opt_sw` can be better done in `beam_ssa_type`.
2019-02-20Evaluate pure BIFs with literal argumentsBjörn Gustavsson
2019-02-20Refactor optimization of Bool =:= trueBjörn Gustavsson
Refactor optimization of `Bool =:= true` to make the code somewhat simpler, as well as potentially apply the optimization in more cases.
2019-02-20Always make andalso/orelse right-associativeBjörn Gustavsson
Always rewriting left-associative andalso/orelse to right-associative will not change the code (except in very rare cases), but it will make sure that the transformation is tested.
2019-02-19Do the destructive setelement optimization in SSABjörn Gustavsson
The expansion of record field updates, when more than one field is updated, but not a majority of the fields, will create a sequence of calls to `erlang:setelement(Index, Value, Tuple)` where Tuple in the first call is the original record tuple, and in the subsequent calls Tuple is the result of the previous call. Furthermore, all Index values are constant positive integers, and the first call to `setelement` will have the greatest index. Thus all the following calls do not actually need to test at run-time whether Tuple has type tuple, nor that the index is within the tuple bounds. Since OTP R7, the `sys_core_dsetel` pass, run as the very last Core Erlang pass, has optimized this sequence of `setelement` calls to use a special destructive version of `setelement` (called `set_tuple_element`) for all but the very first `setelement` in the sequence. It turns out that the presence of the `set_tuple_element` in SSA code is awkward and can prevent or complicate type analysis and aggressive optimizations. Therefore, this commit removes the `sys_core_dsetel` pass and reimplements it for SSA code. The optimization will be done in the `beam_ssa_pre_codegen` pass (that is, just before code generation and after running all other SSA code optimization passes). In most cases, the resulting BEAM code is identical to previous code. For a few modules, the BEAM code is actually slightly better, with smaller stack frames.
2019-02-19Merge branch 'john/compiler/cuddle-validator'John Högberg
* john/compiler/cuddle-validator: compiler: Allow disabling SSA passes in -compile() directives beam_validator: Infer types from result of all type test BIFs beam_validator: Infer BIF argument types beam_validator: type_test in BIFs that only fail on invalid types beam_validator: Simplify complex branches beam_validator: Explain why verify_get_map wipes dst registers beam_validator: fconv means we have a number beam_validator: Simplify update_ne/eq_types beam_validator: Remove pointless fragility propagation beam_validator: Misc cosmetic refactoring