aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/ops.tab
AgeCommit message (Collapse)Author
2016-04-18Merge branch 'bjorn/compiler/misc-opt'Björn Gustavsson
* bjorn/compiler/misc-opt: v3_kernel: Construct literal lists properly Use the register map in %live in beam_utils:is_killed_block/2 Teach beam_utils to check liveness for put_map instructions beam_peep: Help out beam_jump
2016-04-18Merge branch 'bjorn/erts/beam_load'Björn Gustavsson
* bjorn/erts/beam_load: Optimize get_tuple_element instructions that target Y registers Mend beam_SUITE:packed_registers/1 Correct unpacking of 3 operands on 32-bit archictectures Eliminate misleading #ifdef ARCH_64 in beam_opcodes.h beam_debug: Correct masking when unpacking packed operands
2016-04-14v3_kernel: Construct literal lists properlyBjörn Gustavsson
Use cerl:make_list/1 instead of a home-made make_list/1 to ensure that literal lists are constructed as literals. In a future release, we would like to forbid in the loader construction of literal lists using instructions like: put_list {atom,a} [] Dst The proper way is: move {literal,[a]} {x,0} Also update the comment about "put_list Const [] Dst" in ops.tab.
2016-04-14Optimize get_tuple_element instructions that target Y registersBjörn Gustavsson
Several improvements in the compiler (e.g. c288ab87fd6) has lead to an Y register being the target for get_tuple_element instructions. Therefore, introduce i_get_tuple_element2y that combines two consecutive get_tuple_element instructions that target Y registers.
2016-04-13Merge branch 'henrik/update-copyrightyear'Henrik Nord
* henrik/update-copyrightyear: update copyright-year
2016-04-08Simplify the raise instruction to reduce code sizeBjörn Gustavsson
The raise/2 instruction is almost always used like this: raise x(2) x(1) Therefore, we can translate it to an internal i_raise/0 instruction that uses x(2) x(1) as its implicit operands. We will also remove the backward compatibility with R10-0. It is unlikely that anyone still is using BEAM files compiled with the R10-0 compiler, especially since most of those modules cannot be loaded. The loader will refuse to load any module that uses the old non-GCIng arithmetic instructions or the non-GCing versions of length/1 or size/1. Doing these changes will reduce both the size of the loaded BEAM code and size of the code in process_main().
2016-04-07Eliminate unnecessary renaming of bs_put_utf16/3Björn Gustavsson
There is no reason to rename bs_put_utf16/3. (We rename instructions if we'll need to change the operands or if we will need to avoid an endless transformation loop. Neither of these reasons apply to bs_put_utf16/3.)
2016-04-07Don't let the loader do the compiler's jobBjörn Gustavsson
Optimizations that are possible to do by the compiler should be done by the compiler and not by the loader. If the compiler has done its job correctly, attempting to do the two transformations only wastes time.
2016-04-06ops.tab: Remove useless transformationBjörn Gustavsson
The transformation on the following line will do the job.
2016-03-31Fix unsafe transformation of apply/3 with fixed argumentsBjörn Gustavsson
62473daf introduced an unsafe optimization in the loader. See the comments in the test case for an explanation of the problem.
2016-03-15update copyright-yearHenrik Nord
2016-02-02erts, kernel: Add os:perf_counter functionLukas Larsson
The perf_counter is a very very cheap and high resolution timer that can be used to timestamp system events. It does not have monoticity guarantees, but should on most OS's expose a monotonous time. A special instruction has been created for this counter to further speed up fetching it. OTP-12908
2015-12-09Merge branch 'egil/pd-opt-get/OTP-13167'Björn-Egil Dahlberg
* egil/pd-opt-get/OTP-13167: erts: Add i_get_hash instruction erts: Use internal hash for process dictionaries
2015-12-07erts: Add i_get_hash instructionBjörn-Egil Dahlberg
Calculate hashvalue in load-time for constant process dictionary gets.
2015-07-06Speed up list matchingBjörn Gustavsson
The combination is_non_empty_list followed by get_list is extremly common (but not in estone_SUITE, which is why it has not been noticed before). Therefore it is worthwile to introduce a combined instruction.
2015-07-06Eliminate prefetch for conditional instructionsBjörn Gustavsson
Not pre-fetching in conditional instructions (instructions that use -fail_action) seems to improve performance slightly. The reason for that is that conditional instructions may jump to the failure label, wasting the pre-fetched instruction. Another reason is that that many conditional instructions do a function call, and the register pressure is therefore high. Avoiding the pre-fetch may reduce the register pressure and pontentially result in more efficient code.
2015-07-03Teach beam_makeops to pack operands for move3 and move_windowBjörn Gustavsson
It is currently only possible to pack up to 4 operands. However, the move_window4 instrucion has 5 operands and move_window5 and move3 instrucations have 6 operands. Teach beam_makeops to pack instructions with 5 or 6 operands. Also rewrite the move_window instructions in beam_emu.c to macros to allow their operands to get packed.
2015-07-03Ensure that the move_call_ext_{last,only} instructions are usedBjörn Gustavsson
Update transformations to ensure that the move_call_ext_last and move_call_ext_last are used.
2015-07-03Introduce swap_temp/3 and swap/2Björn Gustavsson
Sequences of three move instructionst that effectively swap the contents of two registers are fairly common. We can replace them with a swap_temp/3 instruction. The third operand is the temporary register to be used for swapping, since the temporary register may actually be used. If swap_temp/3 instruction is followed by a call, the temporary register will often (but not always) be killed by the call. If it is killed, we can replace the swap_temp/3 instruction with a slightly cheaper swap/2 instruction.
2015-07-03Introduce specialized versions of move2Björn Gustavsson
Currently, move2/2 does the two moves sequentially to ensure that the instruction will always work correctly. We can do better than that. If the two move instructions have any registers in common, we can introduce simpler and slightly more efficient instructions to handle those cases: move_shift/3 move_dup/3 For the remaining cases when the the move instructions have no common registers, the move2/4 instruction can perform the moves in parallel which is probably slightly more efficient. For clarity's sake, we will remain the instruction to move2_par/4.
2015-07-03Add back frequently used x(0) instructionsBjörn Gustavsson
2015-07-03Remove the last use of tmp_arg1Björn Gustavsson
2015-07-03Remove the i_fetch instructionBjörn Gustavsson
2015-07-03Eliminate use of i_fetch for bit syntax instructionsBjörn Gustavsson
2015-07-03Eliminate the use of i_fetch for BIF instructionsBjörn Gustavsson
2015-07-03Eliminate the use of i_fetch for relational operatorsBjörn Gustavsson
2015-07-03Eliminate the use of i_fetch in arithmetic instructionsBjörn Gustavsson
The i_fetch instruction fetches two operands and places them in the tmp_arg1 and tmp_arg2 variables. The next instruction (such as i_plus) does not have to handle different types of operands, but can get get them simply from the tmp_arg* variables. Thus, i_fetch was introduced as a way to temper a potentail combinatorial explosion. Unfortunately, clang will generate terrible code because of the tmp_arg1 and tmp_arg2 variables being live across multiple instructions. Note that Clang has no way to predict the control flow from one instruction to another. Clang must assume that any instruction can jump to any other instruction. Somehow GCC manages to cope with this situation much better. Therefore, to improve the quality of the code generated by clang, we must eliminate all uses of the tmp_arg1 and tmp_arg2 variables. This commit eliminates the use of i_fetch in combination with the arithmetic and logical instructions. While we are touching the code for the bsr and bsl instructions, also move the tmp_big[] array from top scope of process main into the block that encloses the bsr and bsl instructions.
2015-07-03Make the 'r' operand type optionalBjörn Gustavsson
The 'r' type is now mandatory. That means in order to handle both of the following instructions: move x(0) y(7) move x(1) y(7) we would need to define two specific operations in ops.tab: move r y move x y We want to make 'r' operands optional. That is, if we have only this specific instruction: move x y it will match both of the following instructions: move x(0) y(7) move x(1) y(7) Make 'r' optional allows us to save code space when we don't want to make handling of x(0) a special case, but we can still use 'r' to optimize commonly used instructions.
2015-07-03Allow X and Y registers to be overloaded with any literalBjörn Gustavsson
Consider the try_case_end instruction: try_case_end s The 's' operand type means that the operand can either be a literal of one of the types atom, integer, or empty list, or a register. That worked well before R12. In R12 additional types of literals where introduced. Because of way the overloading was done, an 's' operand cannot handle the new types of literals. Therefore, code such as the following is necessary in ops.tab to avoid giving an 's' operand a literal: try_case_end Literal=q => move Literal x | try_case_end x While this work, it is error-prone in that it is easy to forget to add that kind of rule. It would also be complicated in case we wanted to introduce a new kind of addition operator such as: i_plus jssd Since there are two 's' operands, two scratch registers and two 'move' instructions would be needed. Therefore, we'll need to find a smarter way to find tag register operands. We will overload the pid and port tags for X and Y register, respectively. That works because pids and port are immediate values (fit in one word), and there are no literals for pids and ports.
2015-06-18Change license text to APLv2Bruce Yinhe
2015-04-27erts: Specialize minus and plus instructionBjörn-Egil Dahlberg
Seen on SSL application where substraction with x registers were prevalent: * i_minus specialization on x registers * i_plus specialization on x registers
2015-04-27erts: Add move2 specialization for common move patternsBjörn-Egil Dahlberg
Common pattern seen in SSL: move y x | move r x -> move2 move r x | move y x -> move2 Common pattern seen in SSL and Compiler: move x r | move x x -> move2
2015-04-24erts: Specialize rem instruction for common caseBjörn-Egil Dahlberg
* i_rem specialization on x registers
2015-04-24erts: Specialize band instruction for common caseBjörn-Egil Dahlberg
* i_band specialization on x registers and constants
2015-04-23erts: Add move window instructionBjörn-Egil Dahlberg
Move an entire region of x registers to the stack. This reduces the dispatch pressure of move instructions. Also introduce a move2 specialization for some common move patterns: move r y | move x y -> move2 : As above, moving regions to the stack move x r | move x y -> move2 : A seemingly common pattern
2015-04-23erts: Add instruction move3 for xy and xxBjörn-Egil Dahlberg
2015-04-23erts: Specialize compare instructionsBjörn-Egil Dahlberg
* i_is_lt for r, x registers and constants * i_is_ge for x registers and constants * i_is_exact_eq for r and x registers
2015-04-13Pre-compute hash values for the general get_map_elements instructionBjörn Gustavsson
See the previous commit for justification and use cases.
2015-04-13Teach the loader to pre-compute the hash value for single-key lookupsBjörn Gustavsson
Let the loader pre-compute the hash value when a single, literal key is matched as in: #{<<"some_key">>:=V} = Map In my measurements, this optimization resulted in a 30 percent speedup for short binary keys. Unfortunately, this optimizization makes no difference for small maps with less than 32 keys, since the hash value is not used. Still, there are the following use cases: * A map used instead of a record with more than 32 entries. I have seen some applications with huge records. * Lookup in JSON dictionaries represented as maps. The hash value will only be used when the map is a hash map (currently, that means at least 32 entries).
2015-04-13Optimize use of i_get_map_element/4Björn Gustavsson
In the i_get_map_element/4 instruction, for literal keys other than atoms, the key would be put into x[0] instead of used directly in the instruction. The reason is that the original implementation of maps only supported atom keys.
2015-04-13Sort maps keys in the loaderBjörn Gustavsson
The map instructions require that the keys in the instructions are sorted (for flatmaps). But that is an implementation detail that should not exposed outside of the BEAM virtual machine. Therefore, make the sorting of the keys the responsibility of the loader and not the compiler. Also note that the sort order for maps with numeric keys or keys with numeric components has changed in OTP 18. That means that code compiled for OTP 17 that operated on maps with map keys might not work in OTP 18 without the sorting in the loader (although it is unlikely to be an issue in practice).
2015-04-13De-optimize the has_map_fields instructionsBjörn Gustavsson
The has_map_fields instruction is infrequently used. Thus there is no need to have the fastest possible implementation; it is better to have an implementation that reduces the code size in the already big process_main() function. We can transform has_map_fields to a get_map_elements instruction, targeting the same unused x[0] register for all keys. That instruction will only be marginally slower than existing implementation.
2015-04-13Fully evaluate is_map/1 for literals at load-timeBjörn Gustavsson
The compiler will only emit is_map/1 instructions with literal argument if optimization is turned off. Therefore, the only reason for this commit is cleanliness.
2015-04-13Remove the fail label operand of the new_map instructionBjörn Gustavsson
The new_map instruction cannot fail, and thus needs no fail label.
2015-04-13Correct transformation of put_map_assoc to new_mapBjörn Gustavsson
A put_map_assoc instruction with an empty source map should be converted to a simpler new_map instruction. The transformation didn't happen because an empty source map is no longer represented as a NIL term (as it was in the beginning before map literals were implemented).
2015-04-13Remove support for put_map_exact without a source mapBjörn Gustavsson
Using the exact operator (':=') is only allowed when an existing map is being updated. Thus the following causes a compilation error: #{k:=v} Therefore there is no need to support the put_map_exact instruction without a source map.
2014-12-05erts: Use linear search for small select_val arraysBjörn-Egil Dahlberg
For searching a key in an array we use linear search in arrays up to 10 elements. Selecting on tuple arity will always use linear search. Instead of using two different instructions we assume selecting on different tuple arities are always few in numbers.
2014-03-17erts: Handle literals in is_map/1Björn-Egil Dahlberg
2014-02-21erts: Maps src instructions can't be literalsBjörn-Egil Dahlberg
Move src to a register if it is a literal.
2014-02-19erts: Introduce new instructions for combined key fetchesBjörn-Egil Dahlberg