aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/icode
AgeCommit message (Collapse)Author
2018-01-26Eliminate get_list/3 internally in the compilerBjörn Gustavsson
Instructions that produce more than one result complicate optimizations. get_list/3 is one of two instructions that produce multiple results (get_map_elements/3 is the other). Introduce the get_hd/2 and get_tl/2 instructions that return the head and tail of a cons cell, respectively, and use it internally in all optimization passes. For efficiency, we still want to use get_list/3 if both head and tail are used, so we will translate matching pairs of get_hd and get_tl back to get_list instructions.
2018-01-22Don't build a stacktrace if it's only passed to erlang:raise/3Björn Gustavsson
Consider the following function: function({function,Name,Arity,CLabel,Is0}, Lc0) -> try %% Optimize the code for the function. catch Class:Error:Stack -> io:format("Function: ~w/~w\n", [Name,Arity]), erlang:raise(Class, Error, Stack) end. The stacktrace is retrieved, but it is only used in the call to erlang:raise/3. There is no need to build a stacktrace in this function. We can avoid the building if we introduce an instruction called raw_raise/3 that works exactly like the erlang:raise/3 BIF except that its third argument must be a raw stacktrace.
2017-11-30Add syntax in try/catch to retrieve the stacktrace directlyBjörn Gustavsson
This commit adds a new syntax for retrieving the stacktrace without calling erlang:get_stacktrace/0. That allow us to deprecate erlang:get_stacktrace/0 and ultimately remove it. The problem with erlang:get_stacktrace/0 is that it can keep huge terms in a process for an indefinite time after an exception. The stacktrace can be huge after a 'function_clause' exception or a failed call to a BIF or operator, because the arguments for the call will be included in the stacktrace. For example: 1> catch abs(lists:seq(1, 1000)). {'EXIT',{badarg,[{erlang,abs, [[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20|...]], []}, {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]}, {erl_eval,expr,5,[{file,"erl_eval.erl"},{line,431}]}, {shell,exprs,7,[{file,"shell.erl"},{line,687}]}, {shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]}, {shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}} 2> erlang:get_stacktrace(). [{erlang,abs, [[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22, 23,24|...]], []}, {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]}, {erl_eval,expr,5,[{file,"erl_eval.erl"},{line,431}]}, {shell,exprs,7,[{file,"shell.erl"},{line,687}]}, {shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]}, {shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}] 3> We can extend the syntax for clauses in try/catch to optionally bind the stacktrace to a variable. Here is an example using the current syntax: try Expr catch C:E -> Stk = erlang:get_stacktrace(), . . . In the new syntax, it would look like: try Expr catch C:E:Stk -> . . . Only a variable (not a pattern) is allowed in the stacktrace position, to discourage matching of the stacktrace. (Matching would also be expensive, because the raw format of the stacktrace would have to be converted to the cooked form before matching.) Note that: try Expr catch E -> . . . is a shorthand for: try Expr catch throw:E -> . . . If the stacktrace is to be retrieved for a throw, the 'throw:' prefix must be explicitly included: try Expr catch throw:E:Stk -> . . .
2017-11-16HiPE: Unique ref receive optMagnus Lång
2017-11-05HiPE: Verify GC safety of derived valuesMagnus Lång
HiPE has had metadata for gc safety on it's temporaries for a while, but it has never been enforced or even checked, so naturally several gc-safety violations has slipped through. A new pass, hipe_rtl_verify_gcsafe verifies gcsafety on optimised RTL and is used when running the testsuite, and can be manually enabled with +{hipe,[verify_gcsafe]}.
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-03-28hipe_icode_range: Add comment about side-effectsMagnus Lång
2017-03-27hipe: Fix range analysis of calls with ignored resMagnus Lång
HiPE's range analysis would not update the arguments of a callee when the result of the call was ignored. Fixes ERL-278.
2017-03-27hipe: Fix range analysis of 'rem' operatorMagnus Lång
erl_bif_types contains a fixed and improved copy-paste (obvious from the dead Max_range2_leq_zero if branches) of hipe_icode_range:range_rem/2. For now, delete the dead code and propagate back fixes and improvements to hipe_icode_range.
2017-03-24hipe: Transform is_tagged_tuple instructionBjörn-Egil Dahlberg
2017-03-06hipe: Improve code generation for element/2Magnus Lång
* Omit bounds check in more cases. A test case that needs this change to omit bounds check is added. * Improve code generation by reformulating bounds check to decrease register pressure.
2017-03-06hipe_beam_to_icode: Omit redtest in some closuresMagnus Lång
This is useful to generate shorter code for closures generated by (fun F/A).
2016-11-25Merge branch 'richarl/fix-license-headers/PR-788'Björn Gustavsson
* richarl/fix-license-headers/PR-788: Make use of the Header feature in yecc Remove Emacs timestamp markers Remove obsolete CVS keyword markup Update obsolete author e-mails Replace broken example URL Add missing entries to COPYRIGHT file Correct copyright on stdlib files Add license headers to hipe files in kernel Correct copyright info on typer files Correct copyright and license on dialyzer files Correct copyright on remaining hipe files Correct copyright info on hipe cerl files Correct copyright info on cerl-related files Correct the copyright info in docgen_edoc_xml_cb Update Syntax Tools license headers Remove some obsolete files Update EDoc license headers to dual Apache2/LGPL Update EUnit license headers to dual Apache2/LGPL
2016-11-23Remove obsolete CVS keyword markupRichard Carlsson
2016-11-23Correct copyright on remaining hipe filesRichard Carlsson
2016-11-23Merge branch 'maint'Sverker Eriksson
2016-11-19hipe_icode_call_elim: Fix cf elimination crashMagnus Lång
hipe_icode_call_elim could in some cases replace an #icode_call{} with control flow with a move instruction. This would break the control flow graph invariants and cause a crash.
2016-11-16hipe_icode: Always const-propagate if&call argsMagnus Lång
2016-11-15hipe_rtl: drop alub dest when unusedMagnus Lång
2016-11-07Merge branch 'maint'Sverker Eriksson
2016-11-03Fix the native code translation of bs_match_stringKostis Sagonas
This fixes a HiPE bug reported on erlang-questions on 2/11/2016. The BEAM to ICode tranaslation of the bs_match_string instruction, written long ago for binaries (i.e., with byte-sized strings), tried to do a `clever' translation of even bit-sized strings using a HiPE primop that took a `Size' argument expressed in *bytes*. ICode is not really the place to do such a thing, and moreover there is really no reason for the HiPE primop not to take a Size argument expressed in *bits* instead. This commit changes the `Size' argument to be in bits, postpones the translation of the bs_match_string primop Fixed in a pair-programming/debugging session with @margnus1. until RTL and does a proper translation using bit-sized quantities there.
2016-07-11hipe_ssa_liveness: Use map as liveness ADTMagnus Lång
2016-07-11hipe_icode_range: Use maps over gb_trees,setsMagnus Lång
Also, remove unused field 'counter' from #state{}.
2016-07-11hipe_icode_coordinator: Rewrite concurrentlyMagnus Lång
2016-07-11hipe_icode_{bincomp,range}: Improve complexityMagnus Lång
hipe_icode_bincomp:find_bs_get_integer/3 was quadratic for no good reason. By observing that NewSuccs and Rest are always disjoint, we can see that the worklist does not need to be a set. Furthermore, by replacing the ordset Visited with a map, we reduce complexity to (a very low) O(n lg n). On cuter_binlib, this change reduced the time for hipe_icode_bincomp from 60s to .25s. Using a gb_set for Visited gives .5s, and a sets:set 1s. We apply the same optimisation to hipe_icode_range.
2016-05-31Code rewrites to avoid exported vars warningsKostis Sagonas
2016-05-31Define, export and use a hipe_icode:params() typeKostis Sagonas
2016-05-31Use type name, not record notation, in specsKostis Sagonas
2016-05-27Merge branch 'richcarl/erts/fix-init-stop/PR-911/OTP-13630/OTP-13631'Sverker Eriksson
2016-05-25hipe: Add halt/2 to functions that always failSverker Eriksson
Seems like halt/2 should be a member of this club.
2016-05-23Added elimination of maps:is_key/2 calls to HiPEMagnus Lång
* Implemented removal of maps:is_key/2 calls of which the result is known in a new pass during the typed phase, called hipe_icode_call_elim. * Added the option icode_call_elim that enables the hipe_icode_call_elim pass, and made it default for o2.
2016-04-13Merge branch 'henrik/update-copyrightyear'Henrik Nord
* henrik/update-copyrightyear: update copyright-year
2016-03-21Merge branch 'kostis/hipe-inline-fp-crash/PR-984/OTP-13407'Sverker Eriksson
2016-03-15update copyright-yearHenrik Nord
2016-03-10hipe_icode_fp: simplify match/2Magnus Lång
2016-03-07hipe_icode_fp: Replace helper with lists:allMagnus Lång
2016-03-03hipe_icode_fp: Define types for all records usedMagnus Lång
2016-03-03hipe_icode_fp: Add specs and switch trees to mapsMagnus Lång
2016-03-02hipe: Fix crashing bugs when inlining FP opsMagnus Lång
It was assumed in hipe_icode_fp:filter_map/3 that either all predecessors would have an up-to-date ("assigned") tagged copy, or none of them. This is temporarily false during the fixpoint loop in basic_floats:test_icode_type_crash_2/0, which exercises the all_args_equal(Bindings) =:= true branch, that would previously erroneously end up in the 'false' branch, which is what caused the crash in that case. This is likewise only temporarily false during the fixpoint loop in basic_floats:test_icode_type_crash/0, but that case instead exercises the 'false' branch, justifying the inclusion of both tests.
2016-02-25Merge branch 'maint'Henrik Nord
2016-02-07Fix dialyzer warning and some code refactoringKostis Sagonas
A previous commit introduced a change that exposed dead code in this module and caused dialyzer warnings. This dead code was taken out. While at it, performed some code refactoring in the handling of the bs_get_integer primop.
2016-02-02Merge branch 'maint'Zandra
Conflicts: erts/emulator/beam/beam_emu.c
2015-12-15hipe: Use '::' for constraintsHans Bolinder
2015-11-27hipe: Guard against enormous numbers in rangesMagnus Lång
This allows us to compile bs_match_int_SUITE with HiPE without a system_limit crash.
2015-11-27hipe: Fix binary constructions failing with badarithMagnus Lång
Expressions like <<0:(fun(X)->X end(anka))>> would fail with 'badarith' in HiPE, but 'badarg' in BEAM. hipe_beam_to_icode was attempting to optimise the amount of code generated by letting the arithmetic error propagate instead of catching it. However, since it was emitting a block to throw 'badarg' in that case anyway, we can just reuse it to achieve just as compact code that behaves exactly like BEAM.
2015-11-27hipe: test unit size match in bs_put_binary_allMagnus Lång
The unit size field was previously completely discarded when lowering this instruction from BEAM to Icode. This feature was previously missing and expressions such as <<0, <<1:1>>/binary>> would succeed construction when compiled with HiPE.
2015-10-09Update and cleanup HiPE recordsKostis Sagonas
The bulk of the changes concerns cleanups and code refactorings concerning record constructions that assigned 'undefined' to record fields whose type did not contain this value. See commit 8ce35b2. While at it, some new type definitions were introduced and type names were used instead of record type notation. Minor code cleaups were also done.
2015-06-18Change license text to APLv2Bruce Yinhe
2015-04-15Raise more descriptive error messages for failed map operationsBjörn Gustavsson
According to EEP-43 for maps, a 'badmap' exception should be generated when an attempt is made to update non-map term such as: <<>>#{a=>42} That was not implemented in the OTP 17. José Valim suggested that we should take the opportunity to improve the errors coming from map operations: http://erlang.org/pipermail/erlang-questions/2015-February/083588.html This commit implement better errors from map operations similar to his suggestion. When a map update operation (Map#{...}) or a BIF that expects a map is given a non-map term, the exception will be: {badmap,Term} This kind of exception is similar to the {badfun,Term} exception from operations that expect a fun. When a map operation requires a key that is not present in a map, the following exception will be raised: {badkey,Key} José Valim suggested that the exception should be {badkey,Key,Map}. We decided not to do that because the map could potentially be huge and cause problems if the error propagated through links to other processes. For BIFs, it could be argued that the exceptions could be simply 'badmap' and 'badkey', because the bad map and bad key can be found in the argument list for the BIF in the stack backtrace. However, for the map update operation (Map#{...}), the bad map or bad key will not be included in the stack backtrace, so that information must be included in the exception reason itself. For consistency, the BIFs should raise the same exceptions as update operation. If more than one key is missing, it is undefined which of keys that will be reported in the {badkey,Key} exception.
2014-04-29Translate the put_map_assoc and put_map_exact BEAM instructions to ICodeErik Norgren