aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2018-01-10 07:02:21 +0100
committerBjörn Gustavsson <[email protected]>2018-01-11 12:05:50 +0100
commit1a029efd1ad47f5736faa7f7be6780b649a8b257 (patch)
tree94a4ad2110f742540796aa9c061585837c23a1ed
parent114f6de068f1cf5b0cf0cf1aacf2ff9a7f1f3650 (diff)
downloadotp-1a029efd1ad47f5736faa7f7be6780b649a8b257.tar.gz
otp-1a029efd1ad47f5736faa7f7be6780b649a8b257.tar.bz2
otp-1a029efd1ad47f5736faa7f7be6780b649a8b257.zip
Run beam_block again after other optimizations have been run
Running beam_block again after the other optimizations have run will give it more opportunities for optimizations. In particular, more allocate_zero/2 instructions can be turned into allocate/2 instructions, and more get_tuple_element/3 instructions can store the retrieved value into the correct register at once. Out of a sample of about 700 modules in OTP, 64 modules were improved by this commit.
-rw-r--r--lib/compiler/src/beam_block.erl16
-rw-r--r--lib/compiler/src/compile.erl6
2 files changed, 17 insertions, 5 deletions
diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl
index 7b3a95e03e..488485c17a 100644
--- a/lib/compiler/src/beam_block.erl
+++ b/lib/compiler/src/beam_block.erl
@@ -28,15 +28,21 @@
-spec module(beam_utils:module_code(), [compile:option()]) ->
{'ok',beam_utils:module_code()}.
-module({Mod,Exp,Attr,Fs0,Lc}, _Opt) ->
- Fs = [function(F) || F <- Fs0],
+module({Mod,Exp,Attr,Fs0,Lc}, Opts) ->
+ Blockify = not member(no_blockify, Opts),
+ Fs = [function(F, Blockify) || F <- Fs0],
{ok,{Mod,Exp,Attr,Fs,Lc}}.
-function({function,Name,Arity,CLabel,Is0}) ->
+function({function,Name,Arity,CLabel,Is0}, Blockify) ->
try
%% Collect basic blocks and optimize them.
- Is1 = blockify(Is0),
- Is2 = embed_lines(Is1),
+ Is2 = case Blockify of
+ true ->
+ Is1 = blockify(Is0),
+ embed_lines(Is1);
+ false ->
+ Is0
+ end,
Is3 = beam_utils:anno_defs(Is2),
Is4 = move_allocates(Is3),
Is5 = beam_utils:live_opt(Is4),
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index 770aa2c6c1..1409c358c2 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -775,6 +775,8 @@ asm_passes() ->
{iff,drecv,{listing,"recv"}},
{unless,no_record_opt,{pass,beam_record}},
{iff,drecord,{listing,"record"}},
+ {unless,no_blk2,?pass(block2)},
+ {iff,dblk2,{listing,"block2"}},
{unless,no_stack_trimming,{pass,beam_trim}},
{iff,dtrim,{listing,"trim"}},
{pass,beam_flatten}]},
@@ -1350,6 +1352,10 @@ v3_kernel(Code0, #compile{options=Opts,warnings=Ws0}=St) ->
{ok,Code,St}
end.
+block2(Code0, #compile{options=Opts}=St) ->
+ {ok,Code} = beam_block:module(Code0, [no_blockify|Opts]),
+ {ok,Code,St}.
+
test_old_inliner(#compile{options=Opts}) ->
%% The point of this test is to avoid loading the old inliner
%% if we know that it will not be used.