aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
AgeCommit message (Collapse)Author
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
2019-02-18compiler: Allow disabling SSA passes in -compile() directivesJohn Högberg
This fixes compiling against older OTP versions with the +r?VSN options, which often expand to disabling certain SSA passes to avoid new instructions.
2019-02-18beam_validator: Infer types from result of all type test BIFsJohn Högberg
The compiler will usually optimize these into test instructions, but they'll nevertheless pop up in some cases.
2019-02-18beam_validator: Infer BIF argument typesJohn Högberg
If we know that a BIF will badarg unless its arguments have certain types, we can infer that we have at least those types on success. Note that we can't do this in the general case as the BIF could fail for reasons other than bad arguments.
2019-02-15inline_SUITE: Make coverage/1 test cheaperBjörn Gustavsson
The sole purpose of inline_SUITE:coverage/1 is to ensure that all lines are covered in sys_core_inline. Do that in a cheaper way.
2019-02-15Remove compile_SUITE:big_file/1Björn Gustavsson
This test case does not test anything unique that is not tested by other test cases.
2019-02-15Add test modules that disable all SSA optimizationsBjörn Gustavsson
This makes sure that the SSA optimizations are not essential and may help to cover more code in beam_ssa_pre_codegen and beam_ssa_codegen.
2019-02-15Cover erl_bifs.erlBjörn Gustavsson
2019-02-15Remove attempt to handle all bs_match_string instructionsBjörn Gustavsson
eb0b8da6e816 started to use a binary instead of a string in bs_match_string instructions. Remove a clause that attempts to handle the old form of bs_match_string from old .S files. This is pointless, because an old .S file is likely to contain a bs_context_to_binary instruction as well. The bs_context_to_binary is no longer recognized by `beam_validator`, so those old .S files will not work anyway.
2019-02-15Cover exception throwing code in beam_ssa_optBjörn Gustavsson
2019-02-15Parallelize test of listing filesBjörn Gustavsson
2019-02-15Don't limit the number of processes when running coverBjörn Gustavsson
With the recent update to cover to use the `counters` modules, there is no longer any reason to limit the number of parallel processes when running `cover`.
2019-02-15Merge branch 'bjorn/compiler/beam_ssa_opt'Björn Gustavsson
* bjorn/compiler/beam_ssa_opt: Make sure that beam_ssa_opt optimizes all functions
2019-02-15Merge branch 'maint'Björn Gustavsson
* maint: Add persistent_term:get(Key, DefaultValue) Make dialyzer faster for left-associative andalso/orelse expressions
2019-02-15Make sure that beam_ssa_opt optimizes all functionsBjörn Gustavsson
The function `get_call_order_po/2` did not always include all functions in a module. The method it used was to first find all leave functions (functions not calling any other function), and then find all others functions that called any of the leave functions either directly or indirectly. Functions that did not call a leave function (directly or indirectly) would not be included in the list of functions to optimize. Reimplement `get_call_order_po/2` to use the standard algorithm for constructing a list of nodes in reverse postorder and then reverse that list.
2019-02-14Merge branch 'bjorn/compiler/improve-move-elimination'Björn Gustavsson
* bjorn/compiler/improve-move-elimination: beam_jump: Improve elimination of redundant moves
2019-02-13Make dialyzer faster for left-associative andalso/orelse expressionsBjörn Gustavsson
https://bugs.erlang.org/browse/ERL-851
2019-02-11beam_jump: Improve elimination of redundant movesBjörn Gustavsson
2019-02-11compiler tests: Restrict cover to run on the local nodeBjörn Gustavsson
This change saves about about a minute when running the cover-compiled compiler tests.
2019-02-11Merge pull request #2134 from bjorng/bjorn/compiler/propagate-noneBjörn Gustavsson
beam_ssa_type: Propagate the 'none' type from calls
2019-02-11beam_ssa_type: Propagate the 'none' type from callsBjörn Gustavsson
Consider this pseudo code: f(...) -> Val = case Expr of ... -> ... ; ... -> ... ; ... -> my_abort(something_went_wrong) end, %% Here follows code that uses Val. . . . my_abort(Reason) -> throw({error,Reason}). The first two clauses in the case will probably provide some information about the type of the variable `Var`, information that would be useful for optimizing the code that follows the case. However, the third clause would ruin everything. The call to `my_abort/1` could return anything, and thus `Val` could also have any type. 294d66a295f6 introduced module-level type analysis, which will in general keep track of the return type of a local function call. However, it does not improve the optimization for this specific function. When a function never returns, that is, when its type is `none`, it does not propagate the `none` type, but instead pretends that the return type is `any`. This commit extends the handling of functions that don't return to properly handle the `none` type. Any instructions that directly follows the function that does not return will be discarded, and the call will be rewritten to a tail-recursive call. For this specific example, it means that the type for `Val` deduced from the first two clauses will be retained and can be used for optimizing the code after the case.
2019-02-08beam_validator: type_test in BIFs that only fail on invalid typesJohn Högberg
2019-02-08beam_validator: Simplify complex branchesJohn Högberg
Branches where the state is altered on both success and failure are hard to follow and require juggling the current state, so this commit adds a helper function to make it easier.
2019-02-08beam_validator: Explain why verify_get_map wipes dst registersJohn Högberg
2019-02-08beam_validator: fconv means we have a numberJohn Högberg
2019-02-08beam_validator: Simplify update_ne/eq_typesJohn Högberg
2019-02-08beam_validator: Remove pointless fragility propagationJohn Högberg
set_aliased_type already preserves fragility when updating the type of a fragile register.
2019-02-08beam_validator: Misc cosmetic refactoringJohn Högberg
2019-02-07Merge pull request #2135 from bjorng/bjorn/compiler/optimize-dominatorsBjörn Gustavsson
Optimize ssa_opt_sink for huge functions
2019-02-06Optimize ssa_opt_sink for huge functionsBjörn Gustavsson
The ssa_opt_sink optimization of beam_ssa_opt could get very slow for certain huge functions. 9a190cae9bd7 partly addressed this issue by terminating the optimization early if there happened to be no get_tuple_element instructions at all in the function. This commit addresses the issue more directly by making the dominator calculation in beam_ssa:dominators/1 more efficient. The same algorithm as before is used, but it is implemented in a more efficient way based on the ideas in "A Simple, Fast Dominance Algorithm" (http://www.hipersoft.rice.edu/grads/publications/dom14.pdf). As well as being more efficient, the new implementation also gives an explicit representation of the dominator tree, which makes it possible to simplify and optimize the ssa_opt_sink optimization.
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-04beam_ssa_opt: Fix function name printing in sub-pass crash dumpJohn Högberg
2019-02-04beam_validator: Remove unreachable case clauseJohn Högberg
2019-02-04Merge pull request #2126 from bjorng/bjorn/compiler/compilation-speedBjörn Gustavsson
Reduce compilation times
2019-02-01inline_SUITE: Don't start a slave nodeBjörn Gustavsson
A long time ago there was a good idea to run compiled code in a slave node. Nowadays, not so much.
2019-02-01Correct test_lib:is_cloned_mod/1Björn Gustavsson
test_lib:is_cloned_mod(inline_SUITE) would return true.
2019-02-01sys_core_fold_lists: Propagate annotations in expansion of lists functionsBjörn Gustavsson
There could be a warning with a `no_file` atom instead of filename and line number.
2019-02-01Parallelize compile_SUITE:bc_options/1Björn Gustavsson
2019-02-01Remove the optimized_guard/1 test caseBjörn Gustavsson
With the new SSA code passes, the optimized_guard/1 test case has become really bad at finding unnecessary `and` and `or` instructions.
2019-02-01Make helper functions tail-recursiveBjörn Gustavsson
Two helper functions in beam_ssa_opt and beam_ssa_dead are body-recursive for no good reason. While at it, add some clarifying comments to the functions.
2019-02-01Optimize beam_ssa:def_used/2Björn Gustavsson
beam_ssa:def_used/2 is used by beam_ssa_pre_codegen when reserving Y registers. Do the following optimizations: * Use an ordset instead of a gb_set. When the only operation performed on a set is union/2, an ordset will usually be faster, especially when the result is an ordset. * Use a cerl_set instead of a gb_set for the set of all possible predecessors. cerl_sets is usually faster than gb_sets.
2019-02-01Prefer map syntax and guard BIFs over the maps modulesBjörn Gustavsson
Avoiding calls usually reduces the size of the stack frame and reduces register shuffling.
2019-02-01beam_ssa_type: Optimize calculation of variables that are only used onceBjörn Gustavsson
2019-02-01Use gb_sets:delete/2 instead of gb_sets:delete_any/2Björn Gustavsson
Save a little time by using gb_sets:delete/2 instead of gb_sets:delete_any/2 when the key is known to be in the set.
2019-02-01Speed up beam_ssa_dead when there are many sequential blocksBjörn Gustavsson
beam_ssa_dead could be very slow if there were many blocks connected with unconditional branches (for example, if a block had contained many `call` instructions and been split by ssa_opt_split_blocks). It turns out that `comb_get_sw/3` does an unnecessary (and perhaps incorrect) recursive call to itself when the terminator for the block is an unconditional branch. Removing the recursive call does not disable any optimizations, but will be much faster if there are many blocks connected with unconditional branches. Reported-by: Michał Muskała
2019-02-01Optimize ssa_opt_sink when nothing can be sunkBjörn Gustavsson
Compilation will be much faster if there are many blocks, but no get_tuple_element instructions. Reported-by: Michał Muskała
2019-02-01Merge pull request #2122 from bjorng/bjorn/compiler/fix-beam_exceptBjörn Gustavsson
Fix internal consistency failure caused by beam_except
2019-01-31Fix internal consistency failure caused by beam_exceptBjörn Gustavsson
Fix a bug where the number of live registers in a `bs_get_tail` instruction was too low. Consider this example: -export([bs_get_tail/2]). bs_get_tail(Bin, Config) -> bs_get_tail_1(Bin, 0, 0, Config). bs_get_tail_1(<<_:32, Rest/binary>>, Z1, Z2, F1) -> {Rest,Z1,Z2,F1}. `beam_validator` would emit the following diagnostics: t: function bs_get_tail_1/4+2: Internal consistency check failed - please report this bug. Instruction: {func_info,{atom,t},{atom,bs_get_tail_1},4} Error: {uninitialized_reg,{x,3}}: Here is the part of the code that generates the `function_clause` exception before the optimization: {test_heap,6,4}. {put_list,{x,3},nil,{x,2}}. {put_list,{integer,0},{x,2},{x,2}}. {put_list,{integer,0},{x,2},{x,2}}. {bs_set_position,{x,1},{x,0}}. {bs_get_tail,{x,1},{x,0},3}. %3 live registers. {test_heap,2,3}. {put_list,{x,0},{x,2},{x,1}}. {move,{atom,function_clause},{x,0}}. {line,[{location,"t.erl",8}]}. {call_ext_only,2,{extfunc,erlang,error,2}}. The `bs_get_tail` instruction expects that 3 registers will be live at this point. `beam_except` rewrites the code like this: {bs_set_position,{x,1},{x,0}}. {bs_get_tail,{x,1},{x,0},3}. %Still 3. Too low. {move,{integer,0},{x,1}}. {move,{integer,0},{x,2}}. {jump,{f,3}}. Now the number of live registers in `bs_get_tail` is too low, because the `{x,3}` register will become undefined. This commit adds code to update the number of live registers in the `bs_get_tail` instruction, producing this code: {bs_set_position,{x,1},{x,0}}. {bs_get_tail,{x,1},{x,0},4}. %Adjusted to 4. {move,{integer,0},{x,1}}. {move,{integer,0},{x,2}}. {jump,{f,3}}.
2019-01-31Merge branch 'maint'Björn Gustavsson
* maint: Eliminate bogus warning when using tuple calls