aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
AgeCommit message (Collapse)Author
2016-10-26Merge branch 'maint'Björn Gustavsson
* maint: Don't let inline_list_funcs degrade optimizations
2016-10-24Don't let inline_list_funcs degrade optimizationsBjörn Gustavsson
83199af0263 refactored sys_core_fold to break out the code for the inline_lists_funcs option to its own module. Unfortunately, it also accidentally turned off compile-time evaluation of calls to BIFs with wholly or partial constant arguments. For example, the code for the following funtion gets much worse when inline_list_funcs is used: b() -> R0 = #r{}, R1 = setelement(1+2, R0, "deux"), R2 = setelement(1+3, R1, "trois"), R3 = setelement(1+5, R2, "cinq"), R4 = setelement(1+2, R3, "DEUX"), R4. ERL-285
2016-10-07Merge branch 'maint'Björn Gustavsson
* maint: beam_bsm: Eliminate unsafe optimization
2016-10-06beam_bsm: Eliminate unsafe optimizationBjörn Gustavsson
The following code causes a compiler failure: first_after(Data, Offset) -> case byte_size(Data) > Offset of false -> {First, Rest} = {ok, ok}, ok; true -> <<_:Offset/binary, Rest/binary>> = Data, %% 'Rest' saved in y(0) before the call. {First, _} = match_first(Data, Rest), %% When beam_bsm sees the code, the following line %% which uses y(0) has been optimized away. {First, Rest} = {First, Rest}, First end. match_first(_, <<First:1/binary, Rest/binary>>) -> {First, Rest}. Here is the error message from beam_validator: t: function first_after/2+15: Internal consistency check failed - please report this bug. Instruction: {call,2,{f,7}} Error: {multiple_match_contexts,[{x,1},0]}: Basically, what happens is that at time of code generation, the variable 'Rest' is needed after the call to match_first/2 and is therefore saved in y(0). When beam_bsm (a late optimization pass) sees the code, the use of y(0) following the call to match_first/2 has been optimized away. beam_bsm therefore assumes that the delayed sub-binary creation is safe. (Actually, it is safe, but beam_validator does not realize it.) The bug was caused by two separate commits: e199e2471a reduced the number of special cases to handle in BEAM optimization passed by breaking apart the tail-recursive call instructions (call_only and call_last) into separate instructions. Unfortunately, the special handling for tail calls was lost, which resulted in worse code (i.e. the delayed sub-binary creation optimization could not be applied). e1aa422290 tried to compensate, but did so in a way that was not always safe. Teaching beam_validator that this kind of code is safe would be expensive. Instead, we will undo the damage caused by the two commits. Re-introduce the special handling of tail-recursive calls in beam_bsm that was lost in the first commit. (Effectively) revert the change in the second commit. ERL-268
2016-10-05Merge branch 'maint'Björn Gustavsson
* maint: Update primary bootstrap beam_block: Avoid unsafe inclusion of get_map_elements in blocks
2016-10-05beam_block: Avoid unsafe inclusion of get_map_elements in blocksBjörn Gustavsson
c2035ebb8b restricted the get_map_elements instruction so that it could only occur at the beginning of a block. It turns out that including it anywhere in a block is unsafe. Therefore, never put get_map_elements instruction in blocks. (Also remove the beam_utils:join_even/2 function since it is no longer used.) ERL-266
2016-09-29Merge branch 'rickard/time-unit/OTP-13831'Rickard Green
* rickard/time-unit/OTP-13831: Replace usage of deprecated time units
2016-09-29Merge branch 'josevalim/compiler/at-var/PR-1081/OTP-13924'Björn Gustavsson
* josevalim/compiler/at-var/PR-1081/OTP-13924: Use @ in variable names generated by core and kernel
2016-09-26sys_core_fold: Run optimizations to a fixpointBjörn Gustavsson
Run the optimizations until a fixpoint is reached, or until the maximum iteration count is reached. The hope is that in the future we can many small optimizations instead of optimizations that try to do everything in one pass. This change allows us to remove the ad-hoc calls to expr/2 to run more optimizations on a piece of code.
2016-09-26sys_core_fold: Improve case optimizationBjörn Gustavsson
The optimization that avoids building a tuple in a case expression would not work if any clause matched a tuple as in the following example: f(A, B) -> case {A,B} of {<<X>>,Y} -> {X,Y} end. The generated Core Erlang code would look like this (note the tuples in the case expression and the pattern): 'f'/2 = fun (_cor1,_cor0) -> case {_cor1,_cor0} of <{#{#<X>(8,1,'integer',['unsigned'|['big']])}#,Y}> when 'true' -> {X,Y} . . . end It is expected that the code should look like this (note that tuples have been replaced with "values"): 'f'/2 = fun (_cor1,_cor0) -> %% Line 5 case <_cor1,_cor0> of <#{#<X>(8,1,'integer',['unsigned'|['big']])}#,Y> -> {X,Y} . . . end While at it, also fix bugs in the handling of pattern with aliases. The bindings were produced in the wrong order (creating 'let's with referring to free variables), but in most cases the incorrect bindings were discarded later without causing any harm.
2016-09-26sys_core_fold: Correct scope verification codeBjörn Gustavsson
703e8f4490bf broke the scope verification code (by calling ordsets:is_subset/2 with an unsorted second argument). While we are it, also optimize the verification function by avoiding converting the map to a sorted list.
2016-09-26core_pp: Correct printing of map updatesBjörn Gustavsson
2016-09-26Use @ in variable names generated by core and kernelJosé Valim
The previous variable names can be generated by projects like LFE and Elixir, leading to possible conflicts. Our first to choice to solve such conflicts was to use $ but that's not a valid variable name in core. Therefore we picked @ which is currently supported and still reduces the chance of conflicts.
2016-09-21Simplify handling of internal BIFsBjörn Gustavsson
Do a simpler translation of internal BIFs. While we are it, also remove the dummy values of Index and Uniq from the make_fun internal operation.
2016-09-21v3_life: Eliminate special handling of guardsBjörn Gustavsson
Remove the special handling #k_try{} in guards in v3_life. If we introduce a new #k_protected{} record in v3_kernel, v3_life no longer needs to know whether it is processing guards or bodies.
2016-09-21Simplify beam_utilsBjörn Gustavsson
When beam_utils was first written, it did not have the functions for testing whether a register was not used. Those were added later, in sort of a hacky way. Also, is_killed*() and is_not_used*() for Y registers would return the same answer. Fix that to make the API more consistent (an Y register can only be killed by a deallocate/1 instruction). We will need to change beam_trim to call beam_utils:is_not_used/3 instead of beam_utils:is_killed/3.
2016-09-21erl_bifs: Remove error_logger:warning_map/0 as a safe BIFBjörn Gustavsson
There is no need to list every obscure safe BIF in erl_bifs:is_safe/3. The purpose of erl_bifs:is_safe/3 is merely to warn when the return value of one of the safe BIFs is ignored.
2016-09-21beam_validator: Correct reporting of y register numberBjörn Gustavsson
The error would be: {multiple_match_contexts,[{x,0},2]} instead of: {multiple_match_contexts,[{x,0},{y,2}]}
2016-09-21beam_jump: Don't try to handle a label at the very endBjörn Gustavsson
Since the beam_a pass has always been run and have removed any unused label, there can never be a label as the very last instruction in a function.
2016-09-21beam_jump: Simplify eliminate_fallthroughs/2Björn Gustavsson
eliminate_fallthroughs/2 has special code to handle two labels next to each other, but that does not seem to ever happen and there was one line uncovered in is_label/1. Since inserting an extra jump between two labels would not cause any real problems, remove the extra handling of two consecutive labels.
2016-09-21beam_listing: Remove support for listing sys_pre_expand formatBjörn Gustavsson
The compiler stopped using sys_pre_expand in ae3e177c514c354831.
2016-09-14Merge branch 'maint'Björn Gustavsson
* maint: beam_validator: Handle unreachable instructions Turn off parallel make for start scripts Makefile
2016-09-13beam_validator: Handle unreachable instructionsBjörn Gustavsson
ab03678e introduced an optimization in the beam_z pass that could introduce unreachable code in BEAM files (a 'jump' instruction is removed after a 'raise' instruction, but the code following the target of the 'jump' is not removed). Since this situation happens very rarely, there is no point in adding another pass that can remove unreachable code after beam_z. Instead we will make sure that beam_validator can skip the unreachable code. Skipping unreachable code is already done in valfun_1/2 (for historical reasons), but we will also need to do it in val_dsetel/2.
2016-09-07Merge branch 'maint'Björn Gustavsson
* maint: [snmp] Correct bug when path to mib contains UTF-8 characters [ic] Fix but when UTF-8 character in path to idl spec sys_core_fold: Don't move a fun into a guard
2016-09-05sys_core_fold: Don't move a fun into a guardBjörn Gustavsson
Moving a fun into a guard may cause code that is not accepted by beam_validator.
2016-09-05Merge branch 'bjorn/floor-ceiling/OTP-13692'Björn Gustavsson
* bjorn/floor-ceiling/OTP-13692: Add math:floor/1 and math:ceil/1 Implement the new ceil/1 and floor/1 guard BIFs
2016-09-05Add math:floor/1 and math:ceil/1Björn Gustavsson
Add math:floor/1 and math:ceil/1 to avoid unnecessary conversions in floating point expressions. That is, instead of having to write float(floor(X)) as part of a floating point expressions, we can write simply math:floor(X).
2016-09-05Implement the new ceil/1 and floor/1 guard BIFsBjörn Gustavsson
Implement as ceil/1 and floor/1 as new guard BIFs (essentially part of Erlang language). They are guard BIFs because trunc/1 is a guard BIF. It would be strange to have trunc/1 as a part of the language, but not ceil/1 and floor/1.
2016-09-02Fix overridden BIFsBjörn Gustavsson
The filters in a list comprehension can be guard expressions or an ordinary expressions. If a guard expression is used as a filter, an exception will basically mean the same as 'false': t() -> L = [{some_tag,42},an_atom], [X || X <- L, element(1, X) =:= some_tag] %% Returns [{some_tag,42}] On the other hand, if an ordinary expression is used as a filter, there will be an exception: my_element(N, T) -> element(N, T). t() -> L = [{some_tag,42},an_atom], [X || X <- L, my_element(1, X) =:= some_tag] %% Causes a 'badarg' exception when element(1, an_atom) is evaluated It has been allowed for several releases to override a BIF with a local function. Thus, if we define a function called element/2, it will be called instead of the BIF element/2 within the module. We must use the "erlang:" prefix to call the BIF. Therefore, the following code is expected to work the same way as in our second example above: -compile({no_auto_import,[element/2]}). element(N, T) -> erlang:element(N, T). t() -> L = [{some_tag,42},an_atom], [X || X <- L, element(1, X) =:= some_tag]. %% Causes a 'badarg' exception when element(1, an_atom) is evaluated But the compiler refuses to compile the code with the following diagnostic: call to local/imported function element/2 is illegal in guard
2016-09-01Remove sys_pre_expandBjörn Gustavsson
The previous commits have made sys_pre_expand superfluous. Since sys_pre_expand is undocumented and unsupported it can be removed in a major release without prior deprecation. Also remove code in erl_parse that handles abstract code that has passed through sys_pre_expand. We considered deprecating sys_pre_expand just in case, but decided against it for the following reasons: - Anyone brave and knowledgeable enough to use sys_pre_expand should be able to cope with sys_pre_expand being removed. - If we kept it, but didn't test it anywhere in OTP, it could potentially stop working. So we would probably have to add some test cases.
2016-09-01compiler: Eliminate use of sys_pre_expandBjörn Gustavsson
sys_pre_expand previously did a lot more work, for example, translating records and funs, but now is merely a grab bag of small transformations. Move those transformations to v3_core.
2016-08-25Replace usage of deprecated time unitsRickard Green
2016-08-19Reinstate optimization of binary literal matchingBjörn Gustavsson
105c5b0071 was reverted in dd1162846e because clauses that were supposed to match would not match. (See 8b83bc0b.) Reintroduce the optimization, but make sure that we only shortcut bs_context_to_binary instructions and not bs_start_match2 instructions.
2016-08-12Merge branch 'maint'Björn Gustavsson
* maint: asn1_test_lib: Compile ASN.1 modules in parallel Support 'make -j' when compiling ASN.1 modules [ERL-209] Fix ambiguous_catch_try_state inconsistency error
2016-08-11[ERL-209] Fix ambiguous_catch_try_state inconsistency errorBjörn Gustavsson
It is not safe to share code between 'catch' blocks.
2016-08-10Merge branch 'josevalim/large-binary-strings/PR-1131/OTP-13794'Björn Gustavsson
* josevalim/large-binary-strings/PR-1131/OTP-13794: Move expansion of strings in binaries to v3_core
2016-08-05beam_block: Fix potentially unsafe optimization in move_allocates/1Björn Gustavsson
beam_block has an optimization that only is safe when it is applied immediately after code generation. That is pointed out in a comment: NOTE: Moving allocation instructions is only safe because it is done immediately after code generation so that we KNOW that if {x,X} is initialized, all x registers with lower numbers are also initialized. That assumption may not be true after other optimizations, such as the beam_utils:live_opt/1 optimization. The new beam_reorder pass added in OTP 19 runs before beam_block. Therefore, the optimization is potentially unsafe. The optimization is also unsafe if compilation is started from assembly code in a .S file. Rewrite the optimization to make it safe. See the newly added comment for details. ERL-202
2016-08-04Move expansion of strings in binaries to v3_coreJosé Valim
This speeds up the compilation of binary literals with string values in them. For example, compiling a file with a ~340kB binary would yield the following times by the compiler: Compiling "foo" parse_module : 0.130 s 5327.6 kB transform_module : 0.000 s 5327.6 kB lint_module : 0.011 s 5327.8 kB expand_module : 0.508 s 71881.2 kB v3_core : 0.463 s 11.5 kB Notice the increase in memory and processing time in expand_module and v3_core. This happened because expand_module would expand the string in binaries into chars. For example, the binary <<"foo">>, which is represented as {bin, 1, [ {bin_element, 1, {string, 1, "foo"}, default, default} ]} would be converted to {bin, 1, [ {bin_element, 1, {char, 1, $f}, default, default}, {bin_element, 1, {char, 1, $o}, default, default}, {bin_element, 1, {char, 1, $o}, default, default} ]} However, v3_core would then traverse all of those characters and convert it into an actual binary, as it is a literal value. This patch addresses this issue by moving the expansion of string into chars to v3_core and only if a literal value cannot not be built. This reduces the compilation time of the file mentioned above to the values below: Compiling "bar" parse_module : 0.134 s 5327.6 kB transform_module : 0.000 s 5327.6 kB lint_module : 0.005 s 5327.8 kB expand_module : 0.000 s 5328.7 kB v3_core : 0.013 s 11.2 kB
2016-07-15Merge branch 'maint-19' into maintBjörn-Egil Dahlberg
2016-07-12Revert "beam_dead: Improve optimization of literal binary matching"Björn-Egil Dahlberg
This reverts commit 105c5b0071056dc062797e58772e098d2a3a4627.
2016-06-30Merge branch 'aronisstav/compiler/fix-compile-forms-spec/PR-1109' into maintBjörn Gustavsson
* aronisstav/compiler/fix-compile-forms-spec/PR-1109: Fix spec of compile:(noenv_)forms/2
2016-06-23Fix try-catch when writing makefileMagnus Henoch
Any exceptions at this point would be of class error, not exit.
2016-06-22Show error reason when compiler cannot write fileMagnus Henoch
When the compiler fails to write an output file, it used to just print "error writing file". With this change, it also prints the error reason: $ echo "-module(foo)." > foo.erl $ chmod -w . $ erlc foo.erl /tmp/bar/foo.bea#: error writing file: permission denied
2016-06-20Fix spec of compile:(noenv_)forms/2Stavros Aronis
The input for a call to compile:(noenv_)forms/2 can also be a cerl module (useful e.g. to resume with 'from_core' after a 'to_core' compilation). Internal representations used for 'from_asm' and 'from_beam' compilation can also be valid, but have no relevant types defined.
2016-06-07Compiler: new function env_compiler_options/0alisdair sullivan
retrieve the value of the environment variable ERL_COMPILER_OPTIONS in the same manner as used by file/2, forms/2 and output_generated/2
2016-06-03Merge branch 'bjorn/compiler/misc'Björn Gustavsson
* bjorn/compiler/misc: misc_SUITE: Cover the remaining lines in beam_peep Avoid the dreaded "no_file" in warnings Eliminate crash for map updates in guards beam_block: Eliminate crash in beam_utils
2016-06-03Merge branch 'jv/compiler/mapsify-rec_env/PR-1082/OTP-13646'Björn-Egil Dahlberg
* jv/compiler/mapsify-rec_env/PR-1082/OTP-13646: Convert dict() to map() in rec_env.erl
2016-06-02Avoid the dreaded "no_file" in warningsBjörn Gustavsson
Add more filename/line number annotations while translating to Core Erlang in v3_core, and ensure that sys_core_fold retains existing annotations. The goal is to avoid that sys_core_fold generate warnings with "no_file" instead of a filename.
2016-06-02Eliminate crash for map updates in guardsBjörn Gustavsson
beam_validator would complain that x(1) is uninitialized in a test_heap instruction when attempting to compile the following code with sys_core_fold turned off: foo(M) when not (M#{true := 0}); [M] -> ok. Simplified, the generated BEAM assembly code looked like this: test is_map BadMap x(0) put_map_exact Fail x(0) => x(1) ... jump BooleanStuff BadMap: move ok => x(1) jump Fail BooleanStuff: ... move Boolean => x(2) jump Build Fail: move false => x(2) Build: test_heap 2 3 %% x(0), x(1), x(2) must be live. ... That is, if put_map_exact failed, control would transfer to the label Fail without initializing x(1). Fix that by making sure that x(1) is initilized even if put_map_exact fails: test is_map BadMap x(0) put_map_exact BadLbl x(0) => x(1) ... jump OkLbl BadLbl: move ok => x(1) jump Fail OkLbl: jump BooleanStuff BadMap: move ok => x(1) jump Fail BooleanStuff: ... move Boolean => x(2) jump Build Fail: move false => x(2) Build: test_heap 2 3 %% x(0), x(1), x(2) must be live. ... Note that this situation is rare, and that other optimization passes (beam_dead and beam_jump in particular) will clean up this mess.
2016-06-01Convert dict() to map() in rec_env.erlJosé Valim