Age | Commit message (Collapse) | Author | |
---|---|---|---|
2017-01-12 | v3_life: Add types and specs | Björn Gustavsson | |
2016-11-18 | v3_kernel: Generate optimized code for guards | Björn Gustavsson | |
The compiler produces poor code for complex guard expressions with andalso/orelse. Here is an example from the filename module: -define(IS_DRIVELETTER(Letter),(((Letter >= $A) andalso (Letter =< $Z)) orelse ((Letter >= $a) andalso (Letter =< $z)))). skip_prefix(Name, false) -> Name; skip_prefix([L, DrvSep|Name], DrvSep) when ?IS_DRIVELETTER(L) -> Name; skip_prefix(Name, _) -> Name. beam_bool fails to simplify the code for the guard, leaving several 'bif' instructions: {function, skip_prefix, 2, 49}. {label,48}. {line,[{location,"filename.erl",187}]}. {func_info,{atom,filename},{atom,skip_prefix},2}. {label,49}. {test,is_ne_exact,{f,52},[{x,1},{atom,false}]}. {test,is_nonempty_list,{f,52},[{x,0}]}. {get_list,{x,0},{x,2},{x,3}}. {test,is_nonempty_list,{f,52},[{x,3}]}. {get_list,{x,3},{x,4},{x,5}}. {bif,'=:=',{f,52},[{x,1},{x,4}],{x,6}}. {test,is_ge,{f,50},[{x,2},{integer,65}]}. {bif,'=<',{f,52},[{x,2},{integer,90}],{x,7}}. {test,is_eq_exact,{f,51},[{x,7},{atom,false}]}. {test,is_ge,{f,50},[{x,2},{integer,97}]}. {bif,'=<',{f,52},[{x,2},{integer,122}],{x,7}}. {jump,{f,51}}. {label,50}. {move,{atom,false},{x,7}}. {label,51}. {bif,'=:=',{f,52},[{x,7},{atom,true}],{x,7}}. {test,is_eq_exact,{f,52},[{x,6},{atom,true}]}. {test,is_eq_exact,{f,52},[{x,7},{atom,true}]}. {move,{x,5},{x,0}}. return. {label,52}. return. We can add optimizations of guard tests to v3_kernel to achive a better result: {function, skip_prefix, 2, 49}. {label,48}. {line,[{location,"filename.erl",187}]}. {func_info,{atom,filename},{atom,skip_prefix},2}. {label,49}. {test,is_ne_exact,{f,51},[{x,1},{atom,false}]}. {test,is_nonempty_list,{f,51},[{x,0}]}. {get_list,{x,0},{x,2},{x,3}}. {test,is_nonempty_list,{f,51},[{x,3}]}. {get_list,{x,3},{x,4},{x,5}}. {test,is_eq_exact,{f,51},[{x,1},{x,4}]}. {test,is_ge,{f,51},[{x,2},{integer,65}]}. {test,is_lt,{f,50},[{integer,90},{x,2}]}. {test,is_ge,{f,51},[{x,2},{integer,97}]}. {test,is_ge,{f,51},[{integer,122},{x,2}]}. {label,50}. {move,{x,5},{x,0}}. return. {label,51}. return. Looking at the STDLIB application, there were 112 lines of BIF calls in guards that beam_bool failed to convert to test instructions. This commit eliminates all those BIF calls. Here is how I counted the instructions: $ PATH=$ERL_TOP/bin:$PATH erlc -I ../include -I ../../kernel/include -S *.erl $ grep "bif,'[=<>]" *.S | grep -v f,0 dets.S: {bif,'=:=',{f,547},[{x,4},{atom,read_write}],{x,4}}. dets.S: {bif,'=:=',{f,547},[{x,5},{atom,saved}],{x,5}}. dets.S: {bif,'=:=',{f,589},[{x,5},{atom,read}],{x,5}}. . . . $ grep "bif,'[=<>]" *.S | grep -v f,0 | wc 112 224 6765 $ | |||
2016-09-21 | Simplify handling of internal BIFs | Bjö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-21 | v3_life: Eliminate special handling of guards | Bjö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-03-15 | update copyright-year | Henrik Nord | |
2015-06-18 | Change license text to APLv2 | Bruce Yinhe | |
2015-05-21 | v3_life: Refactor variable db | Björn-Egil Dahlberg | |
2015-04-22 | v3_life: Optimize updating of the variable data base | Björn Gustavsson | |
Updating of the variable data base takes most of the time. | |||
2015-03-11 | v3_life: Combine literal/2 and literal2/2 | Björn Gustavsson | |
For unclear reasons, there are two functions in v3_life that are almost identical: literal/2 and literal2/2. literal/2 is used for expressions and literal2/2 for patterns. It turns out that literal2/2 can do everything that literal/2 can do, except that it transforms maps differently. If we adjust v3_codegen to accept the same format of maps in expressions and patterns, we can rename literal2/2 to literal/2 and use it for expressions and patterns. | |||
2014-03-25 | compiler: map_pair cannot be a type clause in v3_life | Björn-Egil Dahlberg | |
Map pairs are encapsulated in a map. | |||
2014-02-07 | compiler: Fix codegen multiple updates for Maps | Björn-Egil Dahlberg | |
This fixes an error on multiple updates optimization for map pairs. The error was introduced with moving to term order in Maps. This also fixes an error where register life time was lost for values and could result in erroneuos values being emitted in for map pairs. Simplified v3_codegen by moving multiple update optimizations to v3_kernel. | |||
2014-01-29 | compiler: Squash #k_map_pair_*{} to #k_map_pair{} | Björn-Egil Dahlberg | |
Simplify compiler internals for kernel passes. | |||
2014-01-28 | Pass the map pair operators through to the v3_codegen pass | Björn Gustavsson | |
2014-01-28 | Implement support for maps in the compiler | Björn Gustavsson | |
To make it possible to build the entire OTP system, also define dummys for the instructions in ops.tab. | |||
2012-03-30 | Update copyright years | Björn-Egil Dahlberg | |
2012-03-14 | v3_life: Use common code for guards and bodies | Björn Gustavsson | |
2012-01-11 | v3_kernel.hrl: Remove unused record #k_string{} | Björn Gustavsson | |
2012-01-04 | Eliminate the match_fail primop in v3_kernel and later passes | Bjö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-09 | Update copyright years | Björn-Egil Dahlberg | |
2011-08-16 | compiler: Generate line instructions | Björn Gustavsson | |
2010-05-20 | v3_life: Remove clause that cannot match in match_fail/3 | Björn Gustavsson | |
The clause that attempts to match a #k_literal{} where the value is an atom cannot possibly match, since single atoms are always encoded as #k_atom{}. | |||
2010-03-22 | compiler: Don't support the no_constant_pool option | Bjö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. | |||
2010-03-17 | compiler: Provide more information if the v3_life pass crashes | Björn Gustavsson | |
Print the name and arity of the function being compiled if the v3_life compiler pass crashes to facilitate finding out which part of the source code that triggered the problem. | |||
2009-11-20 | The R13B03 release.OTP_R13B03 | Erlang/OTP | |