aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_ssa_type.erl
AgeCommit message (Collapse)Author
2019-02-05beam_ssa_type: Track the types of tuple elementsJohn Högberg
Prior to 294d66a295f6c2101fe3c2da630979ad4e736c08 there wasn't much point to keeping track of tuple element types; they were only known when we had inserted or extracted values from a tuple, and in neither case was it likely that we'd extract the same values again. It makes a lot more sense to do so now that type optimizations are applied across functions; if we return a tuple it's very likely that its elements will be extracted soon after, and knowing their types lets us eliminate more type checks. Co-authored-by: Björn Gustavsson <[email protected]>
2019-02-04beam_ssa_type: Infer types based on the result of #b_switch{}John Högberg
2019-02-01beam_ssa_type: Optimize calculation of variables that are only used onceBjörn Gustavsson
2019-01-28Fix crash in beam_ssa_typeBjörn Gustavsson
To improve compilation times, beam_ssa_type keeps track of variables that are only used once and don't keep types for those variables. As currently implemented, it turns to be unsafe. Change it to only keep track of variables that are only used in the terminator of the block they are defined in. https://bugs.erlang.org/browse/ERL-840
2019-01-24compiler: Introduce module-level type optimizationJohn Högberg
This commit lets the type optimization pass work across functions, tracking return and argument types to eliminate redundant tests.
2019-01-21beam_ssa_type: Fix type subtraction in #b_switch{}John Högberg
A switch is equivalent to a series of '=:=', so we have to subtract each value individually from the type. Subtracting a join risks removing too much type information, and managed to narrow "number" into "float" in the attached test case.
2019-01-21beam_ssa_type: Remove wait_timeout instructions with a timeout of 0John Högberg
2019-01-18beam_ssa_type: Simplify is_singleton_type/1Björn Gustavsson
2019-01-17beam_ssa_type: Eliminate redundant 'succeeded' instructionsBjörn Gustavsson
The beam_ssa_type pass would leave redundant 'succeeded' instructions, and depend on the live optimization pass to remove them. Update beam_ssa_type to remove redundant 'succeeded' instructions. This will not improve the generated code, but will improve compilation times since it eliminates instructions and variables.
2019-01-16Merge pull request #2091 from bjorng/bjorn/compiler/beam_ssa_typeBjörn Gustavsson
Improve type optimizations
2019-01-14Introduce subtraction of typesBjörn Gustavsson
Introduce subtraction of types to allow some redundant tests to be eliminated. Consider this function: foo(L) when is_list(L) -> case L of [_|_] -> non_empty; [] -> empty end. After entering the body of the function, L is known to be either a cons cell or nil (otherwise the is_list/1 guard would have failed). If the L is not a cons cell, it must be nil. Therefore, the test for nil in the second clause of the case can be eliminated. Here is the SSA code with some additonal comments for the function before the optimization: function t:foo(_0) { 0: @ssa_bool = bif:is_list _0 br @ssa_bool, label 4, label 3 4: %% _0 is now a list (cons or nil). @ssa_bool:8 = is_nonempty_list _0 br @ssa_bool:8, label 9, label 7 9: ret literal non_empty 7: %% _0 is not a cons (or we wouldn't be here). %% Subtracting cons from the previously known type list %% gives that _0 must be nil. @ssa_bool:10 = bif:'=:=' _0, literal [] br @ssa_bool:10, label 11, label 6 11: ret literal empty 6: _6 = put_tuple literal case_clause, _0 %% t.erl:5 @ssa_ret:12 = call remote (literal erlang):(literal error)/1, _6 ret @ssa_ret:12 3: _9 = put_list _0, literal [] %% t.erl:4 @ssa_ret:13 = call remote (literal erlang):(literal error)/2, literal function_clause, _9 ret @ssa_ret:13 } Type subtraction gives us that _0 must be nil in block 7, allowing us to remove the comparison of _0 with nil. The code for the function can be simplified to: function t:foo(_0) { 0: @ssa_bool = bif:is_list _0 br @ssa_bool, label 4, label 3 4: @ssa_bool:8 = is_nonempty_list _0 br @ssa_bool:8, label 9, label 11 9: ret literal non_empty 11: ret literal empty 3: _9 = put_list _0, literal [] %% t.erl:4 @ssa_ret:13 = call remote (literal erlang):(literal error)/2, literal function_clause, _9 ret @ssa_ret:13 }
2019-01-14Infer types from more BIFsBjörn Gustavsson
2019-01-11beam_ssa_type: Properly eliminate 'succeeded' instructionsBjörn Gustavsson
When an instruction has been eliminated, the 'succeeded' instruction must be eliminated.
2018-11-15beam_ssa_type: Speed up type analysis for huge functionsBjörn Gustavsson
The type analysis pass (`beam_ssa_type`) keeps the type information for all variables that are in scope. For huge functions, the `join_types/2` function could get really slow when joining two maps with thousands of variables in each. Use a conservative approach to discard type information for variables only used once by a `br` or `switch` in the same block as the variable is defined in. This approach reduces the runtime for the `beam_ssa_type` pass from a few minutes down to few seconds for this module: https://github.com/aggelgian/cuter/blob/master/src/cuter_binlib.erl Rejected approach: Calculate liveness information for all variables and discard type information for any variable that would not be used again. That turned out to not work because some optimizations would invalidate the liveness (in particular, substitutions could lengthen the lifetime for a variable). Trying to update the liveness information when doing the optimizations would be tricky. Noticed-by: Kostis Sagonas
2018-09-28Rewrite BSM optimizations in the new SSA-based intermediate formatJohn Högberg
This commit improves the bit-syntax match optimization pass, leveraging the new SSA intermediate format to perform much more aggressive optimizations. Some highlights: * Watch contexts can be reused even after being passed to a function or being used in a try block. * Sub-binaries are no longer eagerly extracted, making it far easier to keep "happy paths" free from binary creation. * Trivial wrapper functions no longer disable context reuse.
2018-09-20Consistently use #b_var{} instead of var_name()John Högberg
We chose to refer to variables through their var_name() because we anticipated the need to annotate them, but it turned out we didn't really need that, and many things become a lot cleaner if the entire #b_var{} is used to represent variables.
2018-09-17beam_ssa_type: Substitute variables that evaluate to a constantBjörn Gustavsson
In beam_ssa_type, do substitutions similar to what ssa_opt_misc does to get rid of variables that evaluate to constant values. That somewhat simplifies the code of beam_ssa_type, and could improve performance of the compiler since instructions and variables are eliminated, reducing the amount of work for later passes.
2018-09-17beam_ssa_type: Infer types for more instructions and BIFsBjörn Gustavsson
2018-09-17beam_ssa_type: Remove clause in arith_op_types/2 that can't matchBjörn Gustavsson
Remove the following clause from the `fun` clauses in arith_op_types/2 because it cannot possibly match: (_, any) -> number; Here is why it cannot match: The second argument is the accumulator for lists:foldl/3. Its initial value is `unknown`. None of the clauses will update the accumulator to `any`, including the clause that matches `any` in the first argument -- it will set the accumulator to `number`. Thus, the accumulator (second argument) can never be `any` and the clause can never match. QED.
2018-09-12Use beam_ssa:normalize/1 in beam_ssa_typeBjörn Gustavsson
2018-09-12Optimize 'and' and 'or' instructionsBjörn Gustavsson
2018-09-12beam_ssa_type: Remove repeated clauses in meet/2Bjö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.)