aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/v3_kernel.erl
AgeCommit message (Collapse)Author
2012-10-09v3_kernel: Fix match code for matched out segment size in multiple clausesBjörn Gustavsson
When matched variable is used as a size field in multiple clauses, as in: foo(<<L:8,A:L>>) -> A; foo(<<L:8,A:L,B:8>>) -> {A,B}. the match tree would branch out before the segment that used the matched-out variable (in this example, the tree would branch out before the matching of A:L). That happens because the pattern matching compilator did not take variable substitutions into account when grouping clauses that match the same value. That is, the generated code would work similarly to this code: foo(<<L:8,T/binary>>) -> case T of <<A:L>> -> A; _ -> case T of <<A:L,B:8>> -> %% A matched out again! {A,B} end end. We would like the matching to work more like: foo(<<L,A:L,T/binary>>) -> case T of <<>> -> A; <<B:8>> -> {A,B} end. Fix the problem by taking the substitutions into account when grouping clauses that match out the same value.
2012-10-09Improve binary matching of literalsBjörn Gustavsson
The bs_match_string instruction is used to speed up matching of binary literals. For example, given this source code: foo1(<<1,2,3>>) -> ok. The matching part of the code will look like: {test,bs_start_match2,{f,1},1,[{x,0},0],{x,0}}. {test,bs_match_string,{f,3},[{x,0},24,{string,[1,2,3]}]}. {test,bs_test_tail2,{f,3},[{x,0},0]}. Nice. However, if we do a simple change to the source code: foo2(<<1,2,3>>) -> ok; foo2(<<>>) -> error. the resulting matching code will look like (sligthly simplified): {test,bs_start_match2,{f,4},1,[{x,0},0],{x,0}}. {test,bs_get_integer2,{f,7},1,[{x,0},{integer,8},1,Flags],{x,1}}. {test,is_eq_exact,{f,8},[{x,1},{integer,1}]}. {test,bs_match_string,{f,6},[{x,0},16,{string,[2,3]}]}. {test,bs_test_tail2,{f,6},[{x,0},0]}. {move,{atom,ok},{x,0}}. return. {label,6}. {bs_restore2,{x,0},{atom,start}}. {label,7}. {test,bs_test_tail2,{f,8},[{x,0},0]}. That is, matching of the first byte is not combined into the bs_match_string instruction that follows. Fix this problem by allowing a bs_match_string instruction to be used if all clauses will match either the same integer literal or the empty binary.
2012-08-22compiler: Warn if the size of a binary segment is invalidBjörn Gustavsson
The compiler would silently accept and Dialyzer would crash on code like: <<X:(2.5)>> It is never acceptable for Dialyzer to crash. The compiler should at least generate a warning for such code. It is tempting to let the compiler generate an error, but that would mean that code like: Sz = 42.0, <<X:Sz>>. would be possible to compile with optimizations disabled, but not with optimizations enabled. Dialyzer crashes because it calls cerl:bitstr_bitsize/1, which crashes if the type of size for the segment is invalid. The easiest way to avoid that crash is to extend the sanity checks in v3_core to also include the size field of binary segments. That will cause the compiler to issue a warning and to replace the bad binary construction with a call to erlang:error/1. (It also means that Dialyzer will not issue a warning for bad size fields.)
2012-03-30Update copyright yearsBjörn-Egil Dahlberg
2012-03-14v3_core: Don't put negative line numbers in annotationsBjörn Gustavsson
In Core Erlang and later passes, compiler-generated code can be indicated in two different ways: by negative line numbers and by a 'compiler_generated' annotation. Simplify the code and improve coverage by turning negative line numbers positive and adding a 'compiler_generated' annotation in the v3_core pass. That means that Core Erlang and latter passes do not have deal with negative line numbers.
2012-03-14v3_kernel: Dig out the line number only when generating a warningBjörn Gustavsson
2012-03-14v3_kernel: Clean up handling of guardsBjörn Gustavsson
Handling of guards become a mess when andalso/orelse in guards were introduced. Clean it up by using common code for most constructs, regardless of where they occur, and when needed use is_in_guard/1 to handle guard constructs differently.
2012-01-11v3_kernel: Introduce is_in_guard/1Björn Gustavsson
2012-01-11v3_kernel: Removed unreached clause for #k_bin_int{} in sub_size_var/1Björn Gustavsson
The size field of a #k_bin_int{} is always a literal integer (#k_int{}); thus there is no way this clause can match. While we are at it, remove a duplicated call to select_assert_match_possible/3 in select_bin_int/1.
2012-01-11v3_kernel: Remove unreached handling of #k_bin_int{} in arg_con/1Björn Gustavsson
arg_con/1 will never be called with #k_bin_int{} argument, since a #k_bin_int{} is constructed out of #k_bin_seg{} only after arg_con/1 has been called with a #k_bin_seg{} argument.
2012-01-11v3_codegen: Eliminate the special case of 'put' without destinationBjörn Gustavsson
If we let v3_kernel make sure that a 'put' operation always has a destination register, the special case in v3_codegen is not needed.
2012-01-11v3_kernel: Don't attempt to share identical literalsBjörn Gustavsson
It is unlikely that sharing literals will actually save any time. Literals that can be shared are usually small. It is more likely that maintaining the dictionary of literals will waste time.
2012-01-11v3_kernel: Handle sequences in guardsBjörn Gustavsson
A guard with a sequence will cause a crash in v3_codegen. Currently, it seems that a sequence in a guard will never happen when compiling from Erlang code, but there are several reasons to fix this problem anyway: * There are other compilers that generate Core Erlang code. * Changes to sys_core_fold (perhaps additional optimizations) may cause sequences to be generated in guards. * A previously uncovered line in sys_core_fold:opt_guard_try/1 will now be covered.
2012-01-11v3_kernel: Remove clauses that are never executed in arg_val/1Björn Gustavsson
arg_val/1 will never be called for single-valued types, so there is no need handle these types.
2012-01-11v3_kernel.hrl: Remove unused record #k_string{}Björn Gustavsson
2012-01-11v3_kernel.erl: Remove unused define of EXPENSIVE_BINARY_LIMITBjörn Gustavsson
2012-01-04Eliminate the match_fail primop in v3_kernel and later passesBjörn Gustavsson
In the v3_life pass, it is assumed that a 'match_fail' primop only occur at the top-level and at the end of a function. But this code: do_split_cases(A) -> case A of x -> Z = dummy1; _ -> Z = dummy2, a=b end, Z. will be optimized by sys_core_fold to the following code: 'split_cases'/1 = fun (_cor0) -> let <_cor7,Z> = case _cor0 of <'x'> when 'true' -> < 'dummy1','dummy1' > <_cor6> when 'true' -> %% Here follows a 'match_fail' primop inside %% multiple return values: < primop 'match_fail'({'badmatch','b'}),'dummy2' > end in Z moving the 'match_fail' primop into a "values" construction. In the future, we would like to get rid of the v3_life pass (it is there for historical reasons), so in the mean-time we prefer to not add more code to it by generalizing the handling of 'match_fail'. Since the 'match_fail' primop can be simulated by erlang:error/{1,2}, the simplest solution is to translate 'match_fail' to a call to erlang:error/{1,2} in v3_kernel and remove the handling of 'match_fail' in v3_life and v3_codegen. It is tempting to get rid of 'match_fail' also in the Core Erlang format, but there are two issues: - Removing the support for 'match_fail' completely may break tools that generate Core Erlang code. We should not do that in a minor release. - There is no easy way to generate a 'function_clause' exception that will remain correct if it will be inlined into another function. (Calling "erlang:error(function_clause, Args)" is fine only if it is not inlined into another function.) A good solution probably involves introducing new instructions, which is better done in a major release. Noticed-by: Håkan Matsson Minimized-test-case-by: Erik Søe Sørensen
2011-12-09Update copyright yearsBjörn-Egil Dahlberg
2011-11-07compiler: Eliminate use of deprecated erlang:hash/2Björn Gustavsson
Now that beam_asm computes the Index and Uniq values for funs, there is no need to compute those values in the sys_pre_expand and v3_kernel modules, thus eliminating the calls to the deprecated erlang:hash/2 function. It would be tempting to stop generating the name for the fun in sys_pre_expand so that we did not have to add the Info field to a tuple. But: * The debugger depends on the name being there. (Simple solution: Let the debugger generate the name itself.) * When a fun has been inlined into another function, the fun name in 'id' annotation will be used to notice the inlining and change the final clause of the top-level case from generating a 'function_clause' exception to a case_clause exception. (Possible workaround: Have the inliner set an inlined attribute on functions that have been inlined, or have the inliner rewrite 'function_clause' exceptions itself.)
2011-08-16v3_kernel: Make sure that line number annotations are passed throughBjörn Gustavsson
2011-08-16Fix binary matching in the debuggerBjörn Gustavsson
'eval_bits' is a common utility module used for evaluting binary construction and matching. The functions that do matching (match_bits/{6,7} and bin_gen/6) are supposed to treat the bindings as an abstract data type, but they assume that the bindings have the same representation as in the erl_eval module. That may cause binary matching to fail in the debugger, because the debugger represents the bindings as an unordered list of two-tuples, while the erl_eval modules uses an ordered list of two-tuple (an ordset). One way to fix the problem would be to let the debugger to use ordered lists to represent the bindings. Unfortunately, that would also change how the bindings are presented in the user interface. Currently, the variable have most been recently assigned is shown first, which is convenient. Fix the matching problem by mending the leaky abstraction in eval_bits. The matching functions needs to be passed two additional operations: one for looking up a variable in the bindings and one for adding a binding. Those operations could be passed as two more funs (in addition to the evaluation and match fun already passed), but the functions already have too many arguments. Therefore, change the meaning of the match fun, so that the first argument is the operation to perform ('match', 'binding', or 'add_binding') and second argument is a tuple with arguments for the operation.
2010-12-21compiler: Don't include -export_type as attributes in BEAM filesBjörn Gustavsson
Similar to -spec and -type, -export_type should be not be included as attributes (and therefore loaded) in BEAM files, but only in the abstract code chunk.
2010-05-12Remove opaque declarations from the attributesBjörn Gustavsson
-opaque declarations should not be retained in the attributes (because they will be loaded along with the code and are not useful). While at it, filter away those Dialyzer attributes as early as possible - in v3_kernel.
2010-03-26Consistently rewrite an inlined function_clause exception to case_clauseBjörn Gustavsson
A function_clause exception is generated by jumping to a func_info/3 instruction at the beginning of the function. The x registers are assumed to contain the arguments for the function. That means that a func_info/3 instruction copied from another function (or even from the same function if not at the top level) will not work, so it must be replaced with an instruction that generates a case_clause exception. In Core Erlang, a func_info/3 instruction is represented as a the primop match_fail({function_clause,Arg1,...ArgN}). The current mechanism that is supposed to replace the primop match_fail(function_clause) with match_fail(case_clause) will fail to do that in the following circumstances: 1. If the inliner has inlined a function into itself. Fix that by having the inliner clear the function_name annotations on all match_fail primops in functions that are inlined. (To simplify doing that, the annotation is now on the primop node itself and not on the 'function_clause' atom inside it.) 2. If the inliner has rewritten the tuple node in the primop node to a literal (when inlining a function call with literal arguments), v3_kernel would not recognize the match_fail(function_clause) primop and would not rewrite it. Fix it by making v3_kernel smarter. Also simplify the "old" inliner (sys_core_inline) to only clear the function_name annotations instead of rewriting function_clause execptions to case_clause execptions itself.
2010-03-25Merge branch 'bg/compiler-remove-r11-support' into devErlang/OTP
* bg/compiler-remove-r11-support: compiler: Don't support the no_binaries option erts: Don't support the put_string/3 instruction compiler: Don't support the no_constant_pool option compiler: Don't support the r11 option test_server: Don't support communication with R11 nodes binary_SUITE: Don't test bit-level binary roundtrips with R11 nodes erts: Test compatibility of funs with R12 instead of R11 OTP-8531 bg/compiler-remove-r11-support
2010-03-22compiler: Don't support the no_constant_pool optionBjörn Gustavsson
The no_constant_pool option was implied by the r11 option. It turns off the usage of the constant (literal) pool, so that BEAM instructions that use constants can be loaded in an R11 system. Since the r11 option has been removed, there is no need to retain the no_constant_pool option.
2009-11-20The R13B03 release.OTP_R13B03Erlang/OTP