aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
AgeCommit message (Collapse)Author
2017-10-27Eliminate the v3_life passBjörn Gustavsson
The v3_life pass does not do enough to be worth being its own pass. Essentially it does two things: * Calculates life-time information starting from the annotations that v3_kernel provides. That part can be moved into v3_codegen. * Rewrites the Kernel Erlang records to similar plain tuples (for example, #k_cons{hd=Hd,tl=Tl} is rewritten to {cons,Hd,Tl}). That rewriting is not needed and can be eliminated.
2017-10-21Optimize matching of literals for single-valued typesBjörn Gustavsson
If a type only has one clause and if the pattern is literal, the matching can be done more efficiently by directly comparing with the literal. Example: find(String, "") -> String; find(String, <<>>) -> String; find(String, SearchPattern) -> . . . Without this optimization, the relevant part of the code would look this: {test,bs_start_match2,{f,3},2,[{x,1},0],{x,2}}. {test,bs_test_tail2,{f,4},[{x,2},0]}. return. {label,3}. {test,is_nil,{f,4},[{x,1}]}. return. {label,4}. . . . That is, if {x,1} is a binary, a match context will be built to test whether {x,1} is an empty binary. With the optimization, the code will look this: {test,is_eq_exact,{f,3},[{x,1},{literal,<<>>}]}. return. {label,3}. {test,is_nil,{f,4},[{x,1}]}. return. {label,4}. . . .
2017-10-13Merge pull request #1596 from bjorng/bjorn/enhance-try-catchBjörn Gustavsson
(Slightly) optimize catch and try/catch OTP-14683
2017-10-11Optimize a catch whose return value is ignoredBjörn Gustavsson
Rewrite a catch expression like this: catch side_effect(), ... to: try side_effect() catch _:_ -> ok end, ... A try/catch is more efficient since no stack trace will be built when an exception occurs.
2017-10-11Do the receive optimization in the presence of try/catchBjörn Gustavsson
Improve the receive optimization to be able to handle code such as this: Ref = make_ref(), try side_effect() catch _:_ -> ok end, receive %% Clauses that all match Ref. . . . end
2017-10-11Optimize try/catch that ignores the return valueBjörn Gustavsson
If a try/catch is used to ignore the potential exception caused by some expression with a side effect such as: try side_effect() catch _Class:_Reason -> ok end, . . . the generated code will be wasteful: try YReg TryLabel %% call side_effect() here try_end Yreg jump GoodLabel TryLabel: try_case YReg %% try_case has set up registers as follows: %% x(0) -> error | exit | throw %% x(1) -> reason %% x(2) -> raw stack trace data GoodLabel: %% This code does not use any x registers. There will be two code paths that both end up at GoodLabel, and the try_case instruction will set up registers that are never used. We can do better by replacing try_case with try_end to obtain this code: try YReg TryLabel %% call side_effect() here try_end Yreg jump GoodLabel TryLabel: try_end YReg GoodLabel: The jump optimizer (beam_jump) can further optimize this code like this: try YReg TryLabel %% call side_effect() here TryLabel: try_end YReg
2017-10-10Merge branch 'maint'Lars Thorsen
2017-10-10Merge branch 'lars/doc-cleanup/OTP-14475' into maintLars Thorsen
* lars/doc-cleanup/OTP-14475: [edoc] Remove unused module otpsgml_layout.erl Remove unused files from the documentation build
2017-10-05Merge branch 'maint'Rickard Green
* maint: Updated OTP version Update release notes Update version numbers
2017-10-05Merge branch 'maint-19' into maintRickard Green
* maint-19: Updated OTP version Update release notes Update version numbers Conflicts: OTP_VERSION erts/doc/src/notes.xml erts/vsn.mk lib/compiler/doc/src/notes.xml lib/compiler/vsn.mk otp_versions.table
2017-10-05Update release notesErlang/OTP
2017-10-05Update version numbersErlang/OTP
2017-10-03Merge branch 'maint'Hans Nilsson
* maint: Updated OTP version Prepare release Fix zlib merge snafu ssh: fix broken printouts ssh: exclude aes_gcm if peer is OpenSSH 6.2 (known bug) Conflicts: OTP_VERSION
2017-10-02Prepare releaseErlang/OTP
2017-10-02Merge pull request #1546 from michalmuskala/bs-add-optBjörn Gustavsson
Optimise size calculation for binary construction OTP-14654
2017-10-01Merge branch 'maint'Björn Gustavsson
* maint: Fix incorrect internal consistency failure for binary matching code
2017-09-29Fix incorrect internal consistency failure for binary matching codeBjörn Gustavsson
4c31fd0b9665 made the merging of match contexts stricter; in fact, a little bit too strict. Two match contexts with different number of slots would be downgraded to the 'term' type. The correct way is to keep the match context but set the number of slots to the lowest number of slots of the two match contexts. https://bugs.erlang.org/browse/ERL-490
2017-09-28Remove unused files from the documentation buildLars Thorsen
2017-09-26Merge branch 'maint'Henrik Nord
2017-09-22Update release notesErlang/OTP
2017-09-22Update version numbersErlang/OTP
2017-09-15Merge branch 'siri/string-new-api'Siri Hansen
* siri/string-new-api: (28 commits) hipe (test): Do not use deprecated functions in string(3) dialyzer (test): Do not use deprecated functions in string(3) eunit (test): Do not use deprecated functions in string(3) system (test): Do not use deprecated functions in string(3) system (test): Do not use deprecated functions in string(3) mnesia (test): Do not use deprecated functions in string(3) Deprecate old string functions observer: Do not use deprecated functions in string(3) common_test: Do not use deprecated functions in string(3) eldap: Do not use deprecated functions in string(3) et: Do not use deprecated functions in string(3) os_mon: Do not use deprecated functions in string(3) debugger: Do not use deprecated functions in string(3) runtime_tools: Do not use deprecated functions in string(3) asn1: Do not use deprecated functions in string(3) compiler: Do not use deprecated functions in string(3) sasl: Do not use deprecated functions in string(3) reltool: Do not use deprecated functions in string(3) kernel: Do not use deprecated functions in string(3) hipe: Do not use deprecated functions in string(3) ... Conflicts: lib/eunit/src/eunit_lib.erl lib/observer/src/crashdump_viewer.erl lib/reltool/src/reltool_target.erl
2017-09-15compiler: Do not use deprecated functions in string(3)Hans Bolinder
2017-09-15Merge pull request #1558 from josevalim/jv-compile-infoBjörn Gustavsson
Add compile_info option to compile OTP-14615
2017-09-14Add compile_info option to compileJosé Valim
This allows compilers built on top of the compile module to attach external compilation metadata to the compile_info chunk. For example, Erlang uses this chunk to store the compiler version. Elixir and LFE may augment this by also adding their own compiler versions, which can be useful when debugging. The deterministic option does not affect the user supplied compile_info. It is therefore the responsibility of external compilers to guarantee any added information does not violate the determinsitic option, if such option is supported. Finally, this code moves the building of the compile_info options to the compile module instead of beam_asm, moving all of the option mangling code to a single place.
2017-09-13Merge pull request #1544 from michalmuskala/eq-optBjörn Gustavsson
Optimise equality comparisons
2017-09-08Optimise size calculation for binary constructionMichał Muskała
It turns out it was extremely common to have a following sequence: move 0 D1 byte_size _ D2 bs_add D1 D2 D Which is equivalent to just: byte_size _ D Similarly another sequence: move S D1 byte_size _ D2 bs_add D1 D2 D Can be optimised into: byte_size _ D2 bs_add S D2 D Both of those optimisations work with byte_size and bit_size instructions.
2017-09-08Optimise equality comparisonsMichał Muskała
* In both loader and compiler, make sure constants are always the second operand - many passes of the compiler assume that's always the case. * In loader rewrite is_eq_exact with same arguments to skip the instruction and with different constants move one to an x register to maintain the properly outlined above. * The same (but in reverse) is done with the is_ne_exact, where we rewrite to an unconditional jump or add a move to an x register. * All of the above allow to replace is_eq_exact_fss with is_eq_exact_fyy and is_ne_exact_fss with is_ne_exact_fSS as those are the only possibilities left.
2017-08-31Eliminate unnecessary 'move' instructionsBjörn Gustavsson
The compiler could sometimes emit unnecessary 'move' instructions in the code for binary matching, for example for this function: escape(<<Byte, Rest/bits>>, Pos) when Byte >= 127 -> escape(Rest, Pos + 1); escape(<<Byte, Rest/bits>>, Pos) -> escape(Rest, Pos + Byte); escape(<<_Rest/bits>>, Pos) -> Pos. The generated code would look like this: {function, escape, 2, 2}. {label,1}. {line,[{location,"t.erl",17}]}. {func_info,{atom,t},{atom,escape},2}. {label,2}. {test,bs_start_match2,{f,1},2,[{x,0},0],{x,0}}. {test,bs_get_integer2, {f,4}, 2, [{x,0}, {integer,8}, 1, {field_flags,[{anno,[17,{file,"t.erl"}]},unsigned,big]}], {x,2}}. {'%',{bin_opt,[17,{file,"t.erl"}]}}. {move,{x,0},{x,3}}. %% UNECESSARY! {test,is_ge,{f,3},[{x,2},{integer,127}]}. {line,[{location,"t.erl",18}]}. {gc_bif,'+',{f,0},4,[{x,1},{integer,1}],{x,1}}. {move,{x,3},{x,0}}. %% UNECESSARY! {call_only,2,{f,2}}. {label,3}. {line,[{location,"t.erl",20}]}. {gc_bif,'+',{f,0},4,[{x,1},{x,2}],{x,1}}. {move,{x,3},{x,0}}. %% UNECESSARY! {call_only,2,{f,2}}. {label,4}. {move,{x,1},{x,0}}. return. The redundant 'move' instructions have been marked. To avoid the 'move' instructions, we can extend the existing function is_context_unused/1 in v3_codegen. If v3_codegen can know that the match context will not be used again, it can reuse the register for the match context and avoid the extra 'move' instructions. https://bugs.erlang.org/browse/ERL-444
2017-08-31Merge branch 'maint'Björn Gustavsson
* maint: Make handling of match contexts stricter
2017-08-30Merge pull request #1530 from michalmuskala/beam-peep-optBjörn Gustavsson
Enhance optimisations in beam_peep
2017-08-30Make handling of match contexts stricterBjörn Gustavsson
beam_validator could fail issue a diagnostic when a register that was supposed to be a match context was not guaranteed to be a match context. The bug was in merging of types. Merging of a match context with another term would result in a match context. That is wrong. Merging should produce a more general type, not a narrower type. Also, the valid slots in two match contexts should be combined with 'band', not 'bor'.
2017-08-29Merge pull request #1525 from bitnitdit/remove-query-keyword-residuesHans Bolinder
Remove query keyword residues
2017-08-26Enhance optimisations in beam_peepMichał Muskała
When cleaning selects, it might happen we're left with only one pair. In such case convert to a regular test + jump.
2017-08-25Switch query back to be normal atombitnitdit
query was no longer a keyword since the commit 0dc3a29744bed0b7f483ad72e19773dc0982ea50 2012-11-19. So the quotes around query, when it used as atom, no needed.
2017-08-24Merge branch 'maint'Raimo Niskanen
Conflicts: OTP_VERSION
2017-08-24Merge branch 'maint-20' into maintRaimo Niskanen
* maint-20: Updated OTP version Prepare release Accept non-binary options as socket-options Bump version Fix broken handling of default values in extensions for PER compiler: Fix live regs update on allocate in validator Take fail labels into account when determining liveness in block ops Check for overflow when appending binaries, and error out with system_limit
2017-08-23Prepare releaseErlang/OTP
2017-08-23Merge branch ↵Erlang/OTP
'john/compiler/fail-labels-in-blocks-otp-19/ERIERL-48/OTP-14522' into maint-20 * john/compiler/fail-labels-in-blocks-otp-19/ERIERL-48/OTP-14522: compiler: Fix live regs update on allocate in validator Take fail labels into account when determining liveness in block ops
2017-08-22Merge branch 'maint'Lukas Larsson
2017-08-22Merge branch ↵Lukas Larsson
'john/compiler/fail-labels-in-blocks-otp-18/ERIERL-48/OTP-14522' into maint * john/compiler/fail-labels-in-blocks-otp-18/ERIERL-48/OTP-14522: compiler: Fix live regs update on allocate in validator Take fail labels into account when determining liveness in block ops Conflicts: lib/compiler/src/beam_utils.erl
2017-08-16compiler: Fix live regs update on allocate in validatorLukas Larsson
The state without pruned registers was passed on to test_heap causing the validator to belive registers that aren't live actually are live.
2017-08-16compiler: Fix live regs update on allocate in validatorLukas Larsson
The state without pruned registers was passed on to test_heap causing the validator to belive registers that aren't live actually are live.
2017-08-16Take fail labels into account when determining liveness in block opsJohn Högberg
2017-08-16Merge pull request #1528 from ↵Björn Gustavsson
bjorng/bjorn/compiler/improve-case-opt/ERL-452/OTP-14525 Generalize optimization of "one-armed" cases
2017-08-14Apply the redundant test optimisation also in case of fall-throughMichał Muskała
Even though, it's not possible to have fall-throughs when entering the otp pass, it can produce them itself and we're running the pass until fixpoint.
2017-08-14Replace labels instead of inserting duplicates in beam_jumpMichał Muskała
This makes other optimisations more efficient since we have less labels overall.
2017-08-14Enhance elimination of useless tests in beam_jumpMichał Muskała
It can happen we have the following situation: {test,is_tuple,Fail,[R1]} {test,test_arity,Fail,[R1,N1]} {get_tuple_element,R1,N2,R2} {test,is_eq_exaqct,Fail,[R2,Atom]} {jump,Fail} Previously, the optimisation would eliminate the last is_eq_exact test, but we can do more. If the register R2 is not used in Fail, we can eliminate the get_tuple_element instruction as well as all the preceding tests. Ultimately, the whole sequence can be replaced by: {jump,Fail}
2017-08-13Run the sharing optimisation in beam_jump until fixpointMichał Muskała
This is especially useful after inlining a function with a case. Today the compiler would most probably be able to unify all the leafs of the case during the sharing optimisation, but it would fail to unify the pattern matching itself. Naively running the optimisation multiple times wouldn't be able to find the common code either, because it would differ in jump/fail targets of various instructions. To remedy this, after doing each sharing pass we traverse the code backwards when reversing and update all the jump targets with the new targets that were discovered during the unification pass. This allows running the optimisation until fixpoint and makes sure all sharing opportunities will be discovered. This optimisation also helps with the Elixir's `with/else` construct.
2017-08-12Introduce beam_utils:replace_labels/4Michał Muskała