diff options
author | Björn Gustavsson <[email protected]> | 2019-01-22 06:50:55 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2019-01-24 07:35:39 +0100 |
commit | c591d4961abef3e61df8bb839d6f4b4a5e626b7b (patch) | |
tree | e31e7e90104bb8ef2fca98f1ebe432924dfe04a5 /erts | |
parent | cacf240d0f722c5c4cb9e4abf3c21a306a48b6c7 (diff) | |
download | otp-c591d4961abef3e61df8bb839d6f4b4a5e626b7b.tar.gz otp-c591d4961abef3e61df8bb839d6f4b4a5e626b7b.tar.bz2 otp-c591d4961abef3e61df8bb839d6f4b4a5e626b7b.zip |
Reduce redundant moves and register shuffling
Consider this function and its corresponding BEAM code:
foo(Map, Key) ->
Val = case Map of
#{Key:=Val0} -> Val0;
_ -> default
end,
bar(1, 2, Val).
{label,2}.
{test,is_map,{f,3},[{x,0}]}.
{get_map_elements,{f,3},{x,0},{list,[{x,1},{x,0}]}}.
^^^^^
{jump,{f,4}}.
{label,3}.
{move,{atom,default},{x,0}}.
^^^^^
{label,4}.
{move,{integer,2},{x,1}}.
{move,{x,0},{x,2}}.
^^^^^
{move,{integer,1},{x,0}}.
{call_only,3,{f,6}}.
Note that the value of the variable `Val` will first be
placed in `{x,0}` and then moved to `{x,2}` where it needs
to be when calling the `bar/3` function.
The reason for the extra `move` instruction is that the
register allocator picks the lowest numbered available register
when choosing a register to put a variable in. In this case,
`{x,0}` will be chosen.
If we only could give a hint to the register allocator that
it would be better to put `Val` in `{x,2}`, the extra `move`
would disappear:
{label,2}.
{test,is_map,{f,3},[{x,0}]}.
{get_map_elements,{f,3},{x,0},{list,[{x,1},{x,2}]}}.
{jump,{f,4}}.
{label,3}.
{move,{atom,default},{x,2}}.
{label,4}.
{move,{integer,2},{x,1}}.
{move,{integer,1},{x,0}}.
{call_only,3,{f,6}}.
There already is an existing sub pass (`reserve_regs`) in
`beam_ssa_pre_codegen` that among things tries to give the register
allocator hints that some variables should be placed in specific
registers, if possible. However, the existing hinting mechanism is
limited, essentially only working within a single SSA block.
This commit extends the hinting mechanism, allowing hints to be passed
across SSA blocks, eliminating `move` instructions and register
shuffling in many places. (494 modules out of a sample of 1236 modules
were changed by this commit.)
Diffstat (limited to 'erts')
0 files changed, 0 insertions, 0 deletions