aboutsummaryrefslogtreecommitdiffstats
path: root/erts
AgeCommit message (Collapse)Author
2015-07-06Improve unpacking performance on x86_64Björn Gustavsson
When unpacking operands on 64-bit CPUs, use a smarter mask to help the compiler optimize the code. It turns out that on x86_64, if we use the mask 0xFFFFUL (selecting the 16 least significant bits), the compiler can combine a move and a mask operation into the single insruction 'movzwl', which will eliminate one instruction.
2015-07-06Slightly tweak the peformance for get_listBjörn Gustavsson
Fetch the head and tail parts to temporary variables before writing them to their destinations. That should allow the CPU to perform the moves in parallel, which might improve performance.
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 the variable temp_bits at the top scope of process_main()Björn Gustavsson
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-03beam_makeops: Eliminate unnecessary masking when packing 3 operandsBjörn Gustavsson
When packing 3 operands into one word, there would be an unnecessary mask operation when extracting the last operand.
2015-07-03Use a cheaper tag scheme for 'd' operandsBjörn Gustavsson
Since 'd' operands can only either an X register or an Y register, we only need a single bit to distinguish them. Furthermore, we can pre-multiply the register number with the word size to speed up address calculation.
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-03Rewrite the hipe_mode_switch instructionsBjörn Gustavsson
The 'cmd' variable that were shared by several hipe_mode_switch instructions would cause clang to produce sub-optimal code, probably because it considered the instructions as part of of loop that needed to be optimized. What would was that 'cmd' would be assigned to the ESI register (lower 32 bits of the RSI register). It would use ESI for other purposes in instructions, but at the end of every instruction it would set ESI to 1 just in case the next instruction happened to be hipe_trap_return. This can be seen clearly if this commit is omitted and the define HIPE_MODE_SWITCH_CMD_RETURN in hipe/hipe_mode_switch.h is changed from 1 to some other number such as 42. You will see that 42 is assigned to ESI at the end of every instruction. Eliminate this problem by elimininating the shared 'cmd' variable.
2015-07-03Remove the last use of tmp_arg1Björn Gustavsson
2015-07-03Eliminate use of tmp_arg1 and tmp_arg2 in bit syntaxBjö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-07-03Eliminate R_REG_DEFBjörn Gustavsson
2015-07-03Store r(0) and x(0) in the same locationBjörn Gustavsson
As part of improving code generation for clang, we want to eliminate the special variable that stores the content of X register zero most of the time. In a future, that will allow us to eliminate the special case of handling r(0) for most instructions, thus reducing the code size and allow other simplifcations. Therefore, in this commit, eliminate the variable that is used to store r(0) and make r(0) as synonym for x(0). I have chosen to keep the r(0) define to keep the size of the diff managable.
2015-07-03Change the meaning of 'x' in a transformationBjörn Gustavsson
The purpose of this series of commits is to improve code generation for the Clang compiler. As a first step we want to change the meaning of 'x' in a transformation such as: operation Literal=q => move Literal x | operation x Currently, a plain 'x' means reg[0] or x(0), which is the first element in the X register array. That element is distinct from r(0) which is a variable in process_main(). Therefore, since r(0) and x(0) are currently distinct it is fine to use x(0) as a scratch register. However, in the next commit we will eliminate the separate variable for storing the contents of X register zero (thus, x(0) and r(0) will point to the same location in the X register array). Therefore, we must use another scratch register in transformation. Redefine a plain 'x' in a transformation to mean x(1023). Also define SCRATCH_X_REG so that we can refer to the register by name from C code.
2015-07-03beam_emu.c: Remove unused MoveGenDest macroBjörn Gustavsson
2015-07-03beam_makeops: Eliminate crash because of unsafe packingBjörn Gustavsson
Consider an hypothetical instruction: do_something x x c The loader would crash if we tried to load an instance of the instruction with the last operand referencing a literal: {do_something,{x,0},{x,1},{literal,{a,b,c}}} Teach beam_makeops to turn off packing for such unsafe instructions.
2015-07-03Merge branch 'maint'Björn Gustavsson
* maint: Add a smoke test of erts_debug:df/1 Correct disassembly of the i_get_map_elements instruction
2015-07-03Merge branch 'bjorn/erts/beam_debug' into maintBjörn Gustavsson
* bjorn/erts/beam_debug: Add a smoke test of erts_debug:df/1 Correct disassembly of the i_get_map_elements instruction
2015-07-03Merge branch 'maint'Björn-Egil Dahlberg
2015-07-02erts: Fix configure pthread_getnameBjörn-Egil Dahlberg
2015-07-02Add a smoke test of erts_debug:df/1Björn Gustavsson
Run erts_debug:df/1 for all loaded modules. On my reasonably fast, modern computer this test case runs in approximately 10 seconds. To avoid spending many minutes running this test case on older computers, limit the running time to 20 seconds. While we are at it, remove all ?line macros.
2015-07-02Correct disassembly of the i_get_map_elements instructionBjörn Gustavsson
The emulator would crash.
2015-07-01erts: Remove halfword !HEAP_ON_C_STACKBjörn-Egil Dahlberg
2015-07-01Merge branch 'egil/remove-halfword/OTP-12883'Björn-Egil Dahlberg
* egil/remove-halfword/OTP-12883: (21 commits) erts: Remove halfword etp-commands erts: Remove halfword MemKind mseg erts: Remove halfword bases in ETS erts: Remove halfword CHECK_POINTER_MASK erts: Remove halfword relative printf erts: Remove halfword valgrind suppress file erts: Remove halfword specific tests erts: Remove halfword specific allocator types erts: Remove halfword BINARY RELs erts: Remove halfword is_same bases macro erts: Reinstate copy_object over-allocation optimization erts: Remove halfword copy_object_rel erts: Remove halfword object manipulation erts: Remove halfword heap relative comparisions erts: Remove halfword pointer compression erts: Remove halfword basic relative heap operations erts: Remove halfword from configure erts: Remove halfword in lib_src erts: Remove halfword in erl_nif.h erts: Remove halfword in erl_driver.h ...
2015-06-30Merge branch 'maint' to 'master'Sverker Eriksson
2015-06-30Merge branch 'sverk/ets-unfix-delete-race/OTP-12870' into maintSverker Eriksson
* sverk/ets-unfix-delete-race/OTP-12870: erts: Fix ETS race between object deleter and table unfixer
2015-06-30Merge branch 'maint' to 'master'Sverker Eriksson
2015-06-30Merge branch 'sverk/map-merge-trap' into maintSverker Eriksson
* sverk/map-merge-trap: erts: Expand test map_SUITE:t_bif_merge_and_check
2015-06-30Merge branch 'maint'Sverker Eriksson
Conflicts: OTP_VERSION
2015-06-30Prepare releaseErlang/OTP
2015-06-30Merge branch 'sverk/poll-lost-wakeup/OTP-12859' into maint-18Erlang/OTP
* sverk/poll-lost-wakeup/OTP-12859: erts: Fix race in poller thread wake up
2015-06-29Merge branch 'maint-17' into maintSverker Eriksson
Conflicts: OTP_VERSION erts/doc/src/notes.xml erts/vsn.mk otp_versions.table
2015-06-26erts: Fix ETS race between object deleter and table unfixerSverker Eriksson
causing the delete marked object to be left in the table after safe_fixtable(_,false) has returned. This is not super serious as the delete marked object is quite benign and will be deleted at the next unfix operation.
2015-06-25Prepare releaseErlang/OTP
2015-06-25Merge branch 'sverk/poll-lost-wakeup/OTP-12859' into maint-17Erlang/OTP
* sverk/poll-lost-wakeup/OTP-12859: erts: Fix race in poller thread wake up
2015-06-25Merge branch 'egil/fix-purge-literals/OTP-12821' into maint-17Erlang/OTP
* egil/fix-purge-literals/OTP-12821: erts: Fix garbage collect literals in code purge
2015-06-24erts: Remove halfword etp-commandsBjörn-Egil Dahlberg
2015-06-24erts: Remove halfword MemKind msegBjörn-Egil Dahlberg
2015-06-24erts: Remove halfword bases in ETSBjörn-Egil Dahlberg