From 1a029efd1ad47f5736faa7f7be6780b649a8b257 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Wed, 10 Jan 2018 07:02:21 +0100
Subject: 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.
---
 lib/compiler/src/beam_block.erl | 16 +++++++++++-----
 lib/compiler/src/compile.erl    |  6 ++++++
 2 files changed, 17 insertions(+), 5 deletions(-)

(limited to 'lib')

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.
-- 
cgit v1.2.3