aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2018-08-24 14:14:09 +0200
committerBjörn Gustavsson <[email protected]>2018-09-12 14:19:05 +0200
commit52abce861178bbce0dc3acb22cc8935f9a434981 (patch)
tree3e6be6f21ffc06783f8dada3bc5bb6e50ca04ca7 /lib/compiler
parentecbe1327a5da4ecc02cdbc636bd54d901b92c215 (diff)
downloadotp-52abce861178bbce0dc3acb22cc8935f9a434981.tar.gz
otp-52abce861178bbce0dc3acb22cc8935f9a434981.tar.bz2
otp-52abce861178bbce0dc3acb22cc8935f9a434981.zip
Move two optimizations from beam_dead to beam_a
The 'move' instruction can be eliminated in code such as: {test,is_eq_exact,{f,42},[{x,0},{atom,value}]}. {move,{atom,value},{x,0}}. Move that optimization from beam_dead to beam_a. The optimization will be simpler because the 'move' instruction has not yet been moved into a block. Getting rid of 'move' earlier will also save work for later passes. Also move the optimization that eliminates instructions such as from beam_dead to beam_a: {test_is_eq_exact,{f,42},[{x,0},{x,0}]}.
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/beam_a.erl7
-rw-r--r--lib/compiler/src/beam_dead.erl15
2 files changed, 7 insertions, 15 deletions
diff --git a/lib/compiler/src/beam_a.erl b/lib/compiler/src/beam_a.erl
index 266e8f46c8..0abc845310 100644
--- a/lib/compiler/src/beam_a.erl
+++ b/lib/compiler/src/beam_a.erl
@@ -52,6 +52,13 @@ function({function,Name,Arity,CLabel,Is0}) ->
erlang:raise(Class, Error, Stack)
end.
+rename_instrs([{test,is_eq_exact,_,[Dst,Src]}=Test,
+ {move,Src,Dst}|Is]) ->
+ %% The move instruction is not needed.
+ rename_instrs([Test|Is]);
+rename_instrs([{test,is_eq_exact,_,[Same,Same]}|Is]) ->
+ %% Same literal or same register. Will always succeed.
+ rename_instrs(Is);
rename_instrs([{apply_last,A,N}|Is]) ->
[{apply,A},{deallocate,N},return|rename_instrs(Is)];
rename_instrs([{call_last,A,F,N}|Is]) ->
diff --git a/lib/compiler/src/beam_dead.erl b/lib/compiler/src/beam_dead.erl
index 546f0461b9..f57bed0658 100644
--- a/lib/compiler/src/beam_dead.erl
+++ b/lib/compiler/src/beam_dead.erl
@@ -80,11 +80,6 @@ move_move_into_block([], Acc) -> reverse(Acc).
%%% the register already contains the value being assigned, as in the
%%% following code:
%%%
-%%% test is_eq_exact SomeLabel Src Dst
-%%% move Src Dst
-%%%
-%%% or in:
-%%%
%%% select_val Register FailLabel [... Literal => L1...]
%%% .
%%% .
@@ -103,9 +98,6 @@ forward([{move,_,_}=Move|[{label,L}|_]=Is], D, Lc, Acc) ->
forward([{bif,_,_,_,_}=Bif|[{label,L}|_]=Is], D, Lc, Acc) ->
%% bif/4 followed by jump/1 is optimized by backward/3.
forward([Bif,{jump,{f,L}}|Is], D, Lc, Acc);
-forward([{block,[]}|Is], D, Lc, Acc) ->
- %% Empty blocks can prevent optimizations.
- forward(Is, D, Lc, Acc);
forward([{select,select_val,Reg,_,List}=I|Is], D0, Lc, Acc) ->
D = update_value_dict(List, Reg, D0),
forward(Is, D, Lc, [I|Acc]);
@@ -130,13 +122,6 @@ forward([{label,Lbl}=LblI|[{move,Lit,Dst}|Is1]=Is0], D, Lc, Acc) ->
_ -> Is0 %Keep move instruction.
end,
forward(Is, D, Lc, [LblI|Acc]);
-forward([{test,is_eq_exact,_,[Same,Same]}|Is], D, Lc, Acc) ->
- forward(Is, D, Lc, Acc);
-forward([{test,is_eq_exact,_,[Dst,Src]}=I,
- {block,[{set,[Dst],[Src],move}|Bl]}|Is], D, Lc, Acc) ->
- forward([I,{block,Bl}|Is], D, Lc, Acc);
-forward([{test,is_eq_exact,_,[Dst,Src]}=I,{move,Src,Dst}|Is], D, Lc, Acc) ->
- forward([I|Is], D, Lc, Acc);
forward([{test,_,_,_}=I|Is]=Is0, D, Lc, Acc) ->
%% Help the second, backward pass to by inserting labels after
%% relational operators so that they can be skipped if they are