aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-11-27 10:18:52 +0100
committerGitHub <[email protected]>2017-11-27 10:18:52 +0100
commit5b0ba5e5f09d65cb15d00f8e089f5d98c5734d1a (patch)
tree318fc28eca569343720f11ab6322d9e13bb4a290 /lib
parent58f3bec6734977e164683854f5ffe11038bd8526 (diff)
parent1cbc6a430d18d80a0b5e6ad0f7f1010d5394056a (diff)
downloadotp-5b0ba5e5f09d65cb15d00f8e089f5d98c5734d1a.tar.gz
otp-5b0ba5e5f09d65cb15d00f8e089f5d98c5734d1a.tar.bz2
otp-5b0ba5e5f09d65cb15d00f8e089f5d98c5734d1a.zip
Merge pull request #1545 from michalmuskala/move-opt
Place move S x0 instructions at the end of blocks
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/src/beam_block.erl11
1 files changed, 10 insertions, 1 deletions
diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl
index 6543e05e20..c640af224d 100644
--- a/lib/compiler/src/beam_block.erl
+++ b/lib/compiler/src/beam_block.erl
@@ -219,11 +219,20 @@ alloc_may_pass({set,_,_,{set_tuple_element,_}}) -> false;
alloc_may_pass({set,_,_,put_list}) -> false;
alloc_may_pass({set,_,_,put}) -> false;
alloc_may_pass({set,_,_,_}) -> true.
-
+
%% opt([Instruction]) -> [Instruction]
%% Optimize the instruction stream inside a basic block.
opt([{set,[X],[X],move}|Is]) -> opt(Is);
+opt([{set,[X],_,move},{set,[X],_,move}=I|Is]) ->
+ opt([I|Is]);
+opt([{set,[{x,0}],[S1],move}=I1,{set,[D2],[{x,0}],move}|Is]) ->
+ opt([I1,{set,[D2],[S1],move}|Is]);
+opt([{set,[{x,0}],[S1],move}=I1,{set,[D2],[S2],move}|Is0]) when S1 =/= D2 ->
+ %% Place move S x0 at the end of move sequences so that
+ %% loader can merge with the following instruction
+ {Ds,Is} = opt_moves([D2], Is0),
+ [{set,Ds,[S2],move}|opt([I1|Is])];
opt([{set,_,_,{line,_}}=Line1,
{set,[D1],[{integer,Idx1},Reg],{bif,element,{f,0}}}=I1,
{set,_,_,{line,_}}=Line2,