aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
AgeCommit message (Collapse)Author
2019-01-25Merge branch 'john/compiler/trim-ignore-annos'John Högberg
* john/compiler/trim-ignore-annos: beam_trim: Ignore type annotations
2019-01-25Merge branch 'john/compiler/misc-validator-fixes/ERL-832'John Högberg
* john/compiler/misc-validator-fixes/ERL-832: Make the beam_validator smarter again, again
2019-01-25Merge pull request #2106 from bjorng/bjorn/compiler/fewer-movesBjörn Gustavsson
Reduce redundant moves and register shuffling
2019-01-24Make the beam_validator smarter again, againJohn Högberg
The fix in f9ea85611faca82c7494449ddb8bcb1ef1d194cb didn't consider that the tested register could be aliased.
2019-01-24beam_trim: Ignore type annotationsJohn Högberg
The type annotations inserted by beam_ssa_type and beam_ssa_bsm would inadvertently disable stack trimming, as unknown instructions are considered unsafe.
2019-01-24Introduce optimizations of tail phisBjörn Gustavsson
Try to eliminate short blocks that starts with a phi node and end in a return. For example: Result = phi { Res1, 4 }, { literal true, 5 } Ret = put_tuple literal ok, Result ret Ret The code in this block can be inserted at the end blocks 4 and 5. Thus, the following code can be inserted into block 4: Ret:1 = put_tuple literal ok, Res1 ret Ret:1 And the following code into block 5: Ret:2 = put_tuple literal ok, literal true ret Ret:2 Which can be further simplified to: ret literal {ok, true} This transformation may lead to more code improvements, for example: * Stack trimming * Fewer test_heap instructions * Smaller stack frames
2019-01-24Merge pull request #2100 from jhogberg/john/compiler/module-type-optimizationJohn Högberg
Apply type optimizations across local function calls
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-24beam_ssa_opt: Add a scaffold for module-level optimizationsJohn Högberg
This serves as a base for the upcoming module-level type optimization, but may come in handy for other passes like beam_ssa_funs and beam_ssa_bsm that have their own ad-hoc implementations.
2019-01-24Reduce redundant moves and register shufflingBjörn Gustavsson
Consider this function and its corresponding BEAM code: foo(Map, Key) -> Val = case Map of #{Key:=Val0} -> Val0; _ -> default end, bar(1, 2, Val). {label,2}. {test,is_map,{f,3},[{x,0}]}. {get_map_elements,{f,3},{x,0},{list,[{x,1},{x,0}]}}. ^^^^^ {jump,{f,4}}. {label,3}. {move,{atom,default},{x,0}}. ^^^^^ {label,4}. {move,{integer,2},{x,1}}. {move,{x,0},{x,2}}. ^^^^^ {move,{integer,1},{x,0}}. {call_only,3,{f,6}}. Note that the value of the variable `Val` will first be placed in `{x,0}` and then moved to `{x,2}` where it needs to be when calling the `bar/3` function. The reason for the extra `move` instruction is that the register allocator picks the lowest numbered available register when choosing a register to put a variable in. In this case, `{x,0}` will be chosen. If we only could give a hint to the register allocator that it would be better to put `Val` in `{x,2}`, the extra `move` would disappear: {label,2}. {test,is_map,{f,3},[{x,0}]}. {get_map_elements,{f,3},{x,0},{list,[{x,1},{x,2}]}}. {jump,{f,4}}. {label,3}. {move,{atom,default},{x,2}}. {label,4}. {move,{integer,2},{x,1}}. {move,{integer,1},{x,0}}. {call_only,3,{f,6}}. There already is an existing sub pass (`reserve_regs`) in `beam_ssa_pre_codegen` that among things tries to give the register allocator hints that some variables should be placed in specific registers, if possible. However, the existing hinting mechanism is limited, essentially only working within a single SSA block. This commit extends the hinting mechanism, allowing hints to be passed across SSA blocks, eliminating `move` instructions and register shuffling in many places. (494 modules out of a sample of 1236 modules were changed by this commit.)
2019-01-23beam_ssa_pre_codegen: Use lists:splitwith/2 for separating phi nodesBjörn Gustavsson
Use lists:splitwith/2 instead of lists:partition/2 for splitting out phi nodes. Since phi nodes are always the first instructions in a block, the result will be the same, but splitwith/2 is faster.
2019-01-21beam_ssa_opt: Don't ruin arguments of bs_match/skipJohn Högberg
If the match instruction was already marked as a skip, we'd ruin its argument list.
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-21beam_validator: Validate types on local function callsJohn Högberg
2019-01-21beam_validator: Add a stable interface for type annotationsJohn Högberg
2019-01-21beam_validator: Handle aliased registers during type inferenceJohn Högberg
2019-01-18Merge branch 'bjorn/compiler/misc'Björn Gustavsson
* bjorn/compiler/misc: beam_ssa_type: Simplify is_singleton_type/1 beam_ssa_opt: Run ssa_opt_tuple_size early beam_ssa_codegen: Remove forgotten and unreachable clause beam_ssa_opt: Run the type optimization pass twice beam_ssa_type: Eliminate redundant 'succeeded' instructions
2019-01-18Merge branch 'bjorn/compiler/fix-inlined-funs'Björn Gustavsson
* bjorn/compiler/fix-inlined-funs: sys_core_inline: Kill *all* fun annotations when inlining
2019-01-18Merge branch 'bjorn/compiler/beam_validator/ERL-832'Björn Gustavsson
* bjorn/compiler/beam_validator/ERL-832: Make the beam_validator smarter (again)
2019-01-18beam_ssa_type: Simplify is_singleton_type/1Björn Gustavsson
2019-01-18beam_ssa_opt: Run ssa_opt_tuple_size earlyBjörn Gustavsson
Running ssa_opt_tuple_size early will give more opportunities for optimizations.
2019-01-18beam_ssa_codegen: Remove forgotten and unreachable clauseBjörn Gustavsson
fd682dd3b1dc corrected label generation for 'or', but forgot to remove the old incorrect clause (that can no longer be reached).
2019-01-18beam_ssa_opt: Run the type optimization pass twiceBjörn Gustavsson
The code will be significantly improved by running the type optimization pass twice. The ssa_opt_misc pass can be eliminated because everything it does is also done by the type optimization pass.
2019-01-17Make the beam_validator smarter (again)Björn Gustavsson
Needed because of the optimizations in 48f20bd589fa69. https://bugs.erlang.org/browse/ERL-832
2019-01-17sys_core_inline: Kill *all* fun annotations when inliningBjörn Gustavsson
sys_core_inline didn't kill fun annotations in variables, which could lead to duplicated wrapper functions for funs. That was basically harmless because the duplicated functions were eventually discarded.
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-16Move optimizations of bs_put* instruction to beam_ssa_optBjörn Gustavsson
Do the optimizations of bs_put* instructions in beam_ssa_opt and remove the beam_bs pass. This can lead to a slight improvement of compilation times.
2019-01-16Refactor string operandsBjörn Gustavsson
There are two instructions that take string operands: {bs_put_string,Fail,NumberOfBytes,{string,String}} {bs_match_string,Fail,Register,NumberOfBits,{string,String}} In the canonical BEAM code that is passed to beam_asm, string String is currently represented as a list. (The string in bs_match_string is a bitstring before the beam_z compiler pass.) That is wasteful, because there will be unnecessary conversions between lists and binaries. Change the representation of String to be a binary. Furthermore, bs_put_string is an optimization of a bs_put_binary instruction with a literal binary operand. Currently, the bs_put_string instruction is introduced in beam_bs. Delay the introduction of bs_put_string to the beam_z pass. That will simplify optimizations and allow us to do the optimization currently done in beam_bs in a SSA pass in a future commit.
2019-01-16Move coalescing of bs_skip to beam_ssa_optBjörn Gustavsson
The optimization can be applied in a few more places if done before ssa_opt_bsm_shortcut (for example, in unicode:cbv/2).
2019-01-16Merge branch 'maint'Björn Gustavsson
* maint: beam_type: Eliminate compiler crash when arithmetic expression fails Conflicts: lib/compiler/src/beam_type.erl
2019-01-16Merge branch 'bjorn/compiler/beam_type/ERL_829/OTP-15518' into maintBjörn Gustavsson
* bjorn/compiler/beam_type/ERL_829/OTP-15518: beam_type: Eliminate compiler crash when arithmetic expression fails
2019-01-16Merge branch 'maint'Rickard Green
* maint: Updated OTP version Prepare release
2019-01-16Merge branch 'maint-21' into maintRickard Green
* maint-21: Updated OTP version Prepare release
2019-01-16Merge pull request #2091 from bjorng/bjorn/compiler/beam_ssa_typeBjörn Gustavsson
Improve type optimizations
2019-01-15Prepare releaseErlang/OTP
2019-01-14beam_type: Eliminate compiler crash when arithmetic expression failsBjörn Gustavsson
The compiler would crash when compiling code such as: (A / B) band 16#ff The type for the expression would be 'none', but beam_type:verified_type/1 did not handle 'none'. https://bugs.erlang.org/browse/ERL-829
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_codegen: Correct label generation for 'or'Björn Gustavsson
Code generation for 'or' with {z,0} destination could generate duplicate new labels. The bug was introduced in eb571f8951bd.
2019-01-11beam_ssa_pre_codegen: Don't use z registers for 'xor' and 'is_record'Björn Gustavsson
There is no easy way to convert xor or is_record/2 to test operations.
2019-01-11beam_ssa_pre_codegen: Correct short-lived optimizationBjö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.
2019-01-11erl_bif: Mark is_map/1 as safeBjörn Gustavsson
2019-01-11beam_validator: Infer types from '=:='Björn Gustavsson
As beam_ssa_type is about to get smarter, beam_validator must be smarter too.
2019-01-07Merge branch 'maint'Björn Gustavsson
* maint: Remove unsafe optimization for delaying creation of stackframe Conflicts: lib/compiler/src/v3_codegen.erl
2019-01-07Merge branch 'bjorn/compiler/interim-tuple-bug/OTP-15501/ERL-807' into maintBjörn Gustavsson
* bjorn/compiler/interim-tuple-bug/OTP-15501/ERL-807: Remove unsafe optimization for delaying creation of stackframe
2019-01-07Remove unsafe optimization for delaying creation of stackframeBjörn Gustavsson
b89044a800c4 introduced an optimization that tries to delay creation of stack frames. It turns out that this optimization is not always safe. (See the new test case for an example.) Since the code generator is completely rewritten in the `master` branch for the upcoming OTP 22 release, it does not make sense trying to mend this optimization. It is better to remove it. Out of a sample of about 1000 modules in OTP, about 50 of them are changed as a result of removing this optimization. The compiler in OTP 22 will do the same optimization in a cleaner, safer, and more effective way. https://bugs.erlang.org/browse/ERL-807
2018-12-18Make all compiler options work in the option listBjörn Gustavsson
Before OTP 22, the option `{nowarn_deprecated_function,MFAs}` was only recognized when given in the file with the attribute `-compile()`. (The option `{nowarn_unused_function,FAs}` was incorrectly documented to only work in a file, but it also worked when given in the option list.) Starting from OTP 22, all options that can be given in the file can also be given in the option list.
2018-12-13Merge branch 'maint'Sverker Eriksson