aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
AgeCommit message (Collapse)Author
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-03misc_SUITE: Cover the remaining lines in beam_peepBjörn Gustavsson
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-02Revert "Prepare release"Erlang/OTP
This reverts commit e020f75c10410a6943cd055bfa072a2641eab7da.
2016-06-02Prepare releaseErlang/OTP
2016-06-01Convert dict() to map() in rec_env.erlJosé Valim
2016-06-01beam_block: Eliminate crash in beam_utilsBjörn Gustavsson
Somewhat simplified, beam_block would rewrite the target for the first instruction in this code sequence: move x(0) => y(1) gc_bif '+' 1 x(0) => y(0) move y(1) => x(1) move nil => x(0) call 2 local_function/2 The resulting code would be: move x(0) => x(1) %% Changed target. gc_bif '+' 1 x(0) => y(0) move x(1) => y(1) %% Operands swapped (see 02d6135813). move nil => x(0) call 2 local_function/2 The resulting code is not safe because the x(1) will be killed by the gc_bif instruction. 7a47b20c3a cleaned up move optimizations and would reject the optimization if the target was an X register and an allocating instruction was found. To avoid this bug, the optimization must be rejected even if the target is a Y register.
2016-05-31Add additional coverage and smoke test of beam_validatorBjörn Gustavsson
2016-05-31beam_validator: Strengthen validation of match statesBjörn Gustavsson
We want to find bugs in the compiler during compilation. Validation of match contexts was weak, which could allow serious bugs in the generated code to slip through.
2016-05-31beam_validator: Use a record representing the match contextBjörn Gustavsson
Using a record will make it much easier to add additional information.
2016-05-31Merge branch 'bjorn/compiler/misc'Björn Gustavsson
* bjorn/compiler/misc: Eliminate unsafe use of Y registers beam_validator: Add is_bitstring/1 as a safe BIF beam_validator: Remove uncovered line Teach beam_utils:is_pure_test/1 to handle is_bitstr and is_function2 beam_utils: Simplify handling of 'return' to eliminate uncovered line beam_jump: Clean up handling of labels before func_info beam_expect: Correctly handle blocks with multiple allocs v3_codegen: Don't confuse beam_validator v3_codegen: Correct code generation for an error/1 call in a guard beam_receive: Don't crash when encountering nonsensical code
2016-05-30Eliminate unsafe use of Y registersBjörn Gustavsson
If the Core Erlang optimization were turned off (using no_copt), the optimization passes for Beam assembly could generate unsafe code that did not initialize all Y registers before (for example) a call instruction. To fix this, beam_dead should not attempt to remove stores to Y registers. That is not safe if there is an exception-generating instruction inside a try...catch block.
2016-05-30beam_validator: Add is_bitstring/1 as a safe BIFBjörn Gustavsson
beam_validator wrongly complained that the following was not safe because it didn't know that is_bitstring/1 is safe: food(Curriculum) -> [try is_bitstring(functions) catch _ -> 0 end, Curriculum]. While we are it, also add a new bif_SUITE test suite to cover some more code in beam_validator.
2016-05-30beam_validator: Remove uncovered lineBjörn Gustavsson
The raise/3 instruction is specially handled, thus there is no need for bif_type/3 to handle raise/3 (also, the number of arguments was incorrect, so it could never have matched).
2016-05-30Teach beam_utils:is_pure_test/1 to handle is_bitstr and is_function2Björn Gustavsson
The 'is_bitstr' and 'is_function2' tests are pure. The corresponding BIFs have different names; thus the default call to erl_internal:new_type_test/2 is not sufficient.
2016-05-27Declare the type of function entry pointsKostis Sagonas
This shuts off compiler warnings and will allow to enable stronger compiler checks files that include beam_disasm.hrl in the hipe application. While doing that, also modified a comment in the header file and turned a case statement into effectively an assertion: there should not really be any beam files where functions do not have a label as entry point, right?
2016-05-25beam_utils: Simplify handling of 'return' to eliminate uncovered lineBjörn Gustavsson
Y registers are killed by the deallocate/1 instruction, so there is no need to handle Y register in the return/1 instruction in check_liveness/3. There is also no need to keep check_liveness_live_ret/3 since it is only used in one place.
2016-05-25beam_jump: Clean up handling of labels before func_infoBjörn Gustavsson
In complicated code with many indirect jumps to the func_info label, a label could get lost.
2016-05-25beam_expect: Correctly handle blocks with multiple allocsBjörn Gustavsson
A negative allocation could be calculated if a block had multiple allocations. Make sure to process the block in the right order so that the correct allocation is processed. Also add an assertion. This bug was often not noticed because beam_type usually silently recalculates the allocation amount in test_heap/2 instructions.
2016-05-25v3_codegen: Don't confuse beam_validatorBjörn Gustavsson
Generate code that not only is safe, but can easily be seen by beam_validator to be safe.
2016-05-25v3_codegen: Correct code generation for an error/1 call in a guardBjörn Gustavsson
Sometimes v3_codegen would generate unsafe code when there was a call to error/1 in a guard.
2016-05-25beam_receive: Don't crash when encountering nonsensical codeBjörn Gustavsson
2016-05-25Merge branch 'kostis/compiler/v3_kernel/eta-conversion'Björn Gustavsson
* kostis/compiler/v3_kernel/eta-conversion: v3_kernel: Fix typo in comment
2016-05-23v3_kernel: Fix typo in commentKostis Sagonas
2016-05-23Merge branch 'bjorn/compiler/misc'Björn Gustavsson
* bjorn/compiler/misc: beam_bool_SUITE: Cover one more line beam_utils_SUITE: Cover more lines in beam_utils beam_reorder: Don't confuse beam_validator beam_bool: Reject potentially unsafe optimization v3_core: Don't depend on sys_core_fold for cleaning up beam_type: Eliminate crash beam_type: Correct handling of setelement/3 beam_validator: Handle cons literals better beam_validator: Keep better track of tuple literals
2016-05-23beam_bool_SUITE: Cover one more lineBjörn Gustavsson
2016-05-23beam_utils_SUITE: Cover more lines in beam_utilsBjörn Gustavsson
By first adding a call to error/1 to each uncovered line, QuickCheck could find test cases that would cover the lines.
2016-05-23beam_reorder: Don't confuse beam_validatorBjörn Gustavsson
Make sure we don't optimize code such as: is_tuple Fail Src test_arity Fail Src Arity get_tuple_element Src Pos Dst is_map Fail Src If we would reorder the instructions like this: is_tuple Fail Src test_arity Fail Src Arity is_map Fail Src get_tuple_element Src Pos Dst beam_validator would complain that the type for Src is a map instead of a tuple. Since the code has problems to begin with, there is no need to do the optimization.
2016-05-23beam_bool: Reject potentially unsafe optimizationBjörn Gustavsson
When calculating the sets of registers that must be killed or unused, registers set in a {protected,_,_,_} block were not considered. That could result in a crash in the assertion in beam_utils:live_opt_block/4.
2016-05-23v3_core: Don't depend on sys_core_fold for cleaning upBjörn Gustavsson
a3ec2644f5 attempted to teach v3_core not to generate code with unbound variables. The approach taken in that commit is to discard all expressions following a badmatch. That does not work if the badmatch is nested: {[V] = [] = foo,V}, V That would be rewritten to: {error({badmatch,foo})}, V where V is unbound. If we were to follow the same approach, the tuple construction code would have to look out for a badmatch. As would list construction, begin...end, and so on. Therefore, as it is impractical to discard all expressions that follow a badmatch, the only other solution is to ensure that the variables that the pattern binds will somehow be bound. That can be arranged by rewriting the pattern to a pattern that binds the same variables. Thus: error({badmatch,foo}), E = foo, case E of {[V],[]} -> V; Other -> error({badmatch,Other} end
2016-05-23beam_type: Eliminate crashBjörn Gustavsson
The following code: simple() -> case try 0 after [] end of 0 -> college; 1 -> 0 end. would crash the compiler like this: crash reason: {case_clause, {'EXIT', {function_clause, [{beam_type,simplify_select_val_int, [{select,select_val, {x,0}, {f,7}, [{integer,1},{f,9},{integer,0},{f,8}]}, 0], [{file,"beam_type.erl"},{line,169}]}, {beam_type,simplify_basic_1,3, [{file,"beam_type.erl"},{line,155}]}, {beam_type,opt,3,[{file,"beam_type.erl"},{line,57}]}, {beam_type,function,1,[{file,"beam_type.erl"},{line,36}]}, {beam_type,'-module/2-lc$^0/1-0-',1, [{file,"beam_type.erl"},{line,30}]}, {beam_type,module,2,[{file,"beam_type.erl"},{line,30}]}, {compile,'-select_passes/2-anonymous-2-',2, [{file,"compile.erl"},{line,521}]}, {compile,'-internal_comp/4-anonymous-1-',2, [{file,"compile.erl"},{line,306}]}]}}} The root cause is that the type representation is not well-defined. Integers could be represented in three different ways: integer {integer,{1,10}} {integer,0} However, only the first two forms were handled. To avoid similar problems in the future: * Make the type representation stricter. Make sure that integers are only represented as 'integer' or {integer,{Min,Max}}. * Call verify_type/1 whenever a new type is added (not only when merging types) to ensure that only the supported types are added to the type database). (ERL-150)
2016-05-20beam_type: Correct handling of setelement/3Björn Gustavsson
We must be careful how we treat the type info for the result of: setelement(Index, Tuple, NewValue) If Tuple had type information, the result of setelement/3 (in x(0)) would be assigned the same type information. But that is not safe for: setelement(1, Tuple, NewValue) since the type for the first element will be changed. Therefore, we must take care to remove the type information for the first element of the tuple if might have been modified by setelement/3.
2016-05-20beam_validator: Handle cons literals betterBjörn Gustavsson
As a preparation for better optimizations in beam_type, a list literal must be accepted as a 'cons'.
2016-05-20beam_validator: Keep better track of tuple literalsBjörn Gustavsson
As a preparation for upcoming better optimizations in beam_type, we will need to keep better track of tuple literals so that beam_validator will not falsely reject safe code.
2016-05-18Use arity() consistentlyKostis Sagonas
Specs of various *_arity functions in this module used different types (integer(), non_neg_integer(), byte()) to refer to the type arity().
2016-05-16Merge branch 'bjorn/compiler/beam_bool/ERL-143'Björn Gustavsson
* bjorn/compiler/beam_bool/ERL-143: Eliminate crash in beam_bool Add beam_bool_SUITE Add missing test cases in andor_SUITE and beam_block_SUITE
2016-05-16Eliminate crash in beam_boolBjörn Gustavsson
beam_bool would crash when attempting to optimize BEAM code similar to this code: bif '=:=' Reg1 SomeValue => y(0) bif '=:=' Reg2 {atom,true} => x(2) bif '=:=' Reg3 {atom,true} => x(3) bif 'or' x(2) x(3) => x(2) is_eq_exact Fail x(2) {atom,true} The problem is that the first instruction that assigns a value to a Y register. beam_bool:ssa_assign/2 will not accept a Y register argument. We could change ssa_assign/2 to accept a Y register, but that would only cause the entire optimization to be rejected later because the Y register is alive in the code that follows. Therefore, a better solution is to modify extend_block/3 so that the instruction that assign to Y registers are not added to the block. That is, the optimizer will only operate on the following code: bif '=:=' Reg2 {atom,true} => x(2) bif '=:=' Reg3 {atom,true} => x(3) bif 'or' x(2) x(3) => x(2) is_eq_exact Fail x(2) {atom,true} Usually the optimization will succeed, rewriting the four instructions to a select_val instruction. Assembly code such as the above can be produced by code similar to: Y = Something == SomethingElse, case Y of Condition; OtherCondition -> . . . end, . . ., Y. Reported-by: http://bugs.erlang.org/browse/ERL-143 Reported-by: José Valim
2016-05-16Add beam_bool_SUITEBjörn Gustavsson
It's time that we have a dedicated test suite for beam_bool.
2016-05-16Add missing test cases in andor_SUITE and beam_block_SUITEBjörn Gustavsson
Two test cases were not actually run. Even if their main purpose is to ensure that the compiler doesn't crash, we always try to also run the test case (when practial) to also ensure that the generated code is correct.
2016-05-13beam_utils: Correct break in conventions for split_even/1 and join_even/1Björn Gustavsson
Exported functions in this file should appear at the top of the file. Also add missing spaces after commas.
2016-05-13beam_utils: Remove clause checking for illegal set/4 instructionBjörn Gustavsson
I can't remember that clause ever trigger during development. Remove it to eliminated an uncovered line.
2016-05-13beam_utils: Simplify the return value for check_liveness/3Björn Gustavsson
check_liveness/3 returns {unknown,State} if an instruction is not handled. All callers will handle 'unknown' the same way as 'used'. Therefore, we can simplify the code and improve the coverage if we return {used,State} instead of {unknown,State}.
2016-05-13beam_utils: Remove unused codeBjörn Gustavsson
2016-05-13beam_utils: Let code_at/2 fail if the label does not existBjörn Gustavsson
All callers only calls code_at/2 for existing labels and they don't handle the return value 'none'.
2016-05-13beam_utils: Remove unused handling of try/3 in live_opt/4Björn Gustavsson
30cc5c902d moved try/3 instruction inside blocks, so the clause for handling try/3 in live_opt/4 is never executed.
2016-05-13beam_utils: Correct translation of BIFs to testsBjörn Gustavsson
Two lines were never covered, because '[]' was used instead of 'nil'.
2016-05-13core_pp: Remove uncovered clause in is_simple_term/1Björn Gustavsson
The clause for handling #c_values{} in is_simple_term/1 is never executed. It can be safely removed, since there is a default clause that will return 'false' in the extremly unlikely event that a Without the clause, code such as: let <_v1,_v2> = <1,2> in {_v1,_v2} would be printed with an extra newline: let <_v1,_v2> = <1,2> in {_v1,_v2}
2016-05-13core_pp: Crash on unhandled Core Erlang formsBjörn Gustavsson
Don't try to be nice. Since we now have good test suites for Core Erlang, just let it crash.