File 2002-Optimise-beam_jump.patch of Package erlang

From 7fed1e036b0c70aaa1e738a403379bab96745e63 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20Muska=C5=82a?= <michal@muskala.eu>
Date: Wed, 6 Jun 2018 19:10:05 +0200
Subject: [PATCH 2/2] Optimise beam_jump

This is an alternative to #1832.

The optimisation relies on special-casing the common pattern of
"renaming" a label by direct jump to another label. The change makes
beam_jump recognise couple more opportunities for optimisation.

The optimisation additionally avoids superfluous list concatenations by
only flattening the accumulator at the very end.
---
 lib/compiler/src/beam_jump.erl | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl
index c33de217bd..19c26d4ef9 100644
--- a/lib/compiler/src/beam_jump.erl
+++ b/lib/compiler/src/beam_jump.erl
@@ -164,17 +164,19 @@ share(Is0) ->
 
 share_1([{label,L}=Lbl|Is], Dict0, Lbls0, [_|_]=Seq, Acc) ->
     case maps:find(Seq, Dict0) of
-	error ->
-	    Dict = maps:put(Seq, L, Dict0),
-	    share_1(Is, Dict, Lbls0, [], [Lbl|Seq ++ Acc]);
-	{ok,Label} ->
+        error ->
+            Dict = maps:put(Seq, L, Dict0),
+            share_1(Is, Dict, Lbls0, [], [[Lbl|Seq]|Acc]);
+        {ok,Label} ->
             Lbls = maps:put(L, Label, Lbls0),
-	    share_1(Is, Dict0, Lbls, [], [Lbl,{jump,{f,Label}}|Acc])
+            share_1(Is, Dict0, Lbls, [], [[Lbl,{jump,{f,Label}}]|Acc])
     end;
-share_1([{func_info,_,_,_}|_]=Is, _, Lbls, [], Acc) when Lbls =/= #{} ->
-    beam_utils:replace_labels(Acc, Is, Lbls, fun(Old) -> Old end);
+share_1([{func_info,_,_,_}|_]=Is0, _, Lbls, [], Acc0) when Lbls =/= #{} ->
+    lists:foldl(fun(Is, Acc) ->
+        beam_utils:replace_labels(Is, Acc, Lbls, fun(Old) -> Old end)
+    end, Is0, Acc0);
 share_1([{func_info,_,_,_}|_]=Is, _, Lbls, [], Acc) when Lbls =:= #{} ->
-    reverse(Acc, Is);
+    lists:foldl(fun lists:reverse/2, Is, Acc);
 share_1([{'catch',_,_}=I|Is], Dict0, Lbls0, Seq, Acc) ->
     {Dict,Lbls} = clean_non_sharable(Dict0, Lbls0),
     share_1(Is, Dict, Lbls, [I|Seq], Acc);
@@ -187,6 +189,9 @@ share_1([{try_case,_}=I|Is], Dict0, Lbls0, Seq, Acc) ->
 share_1([{catch_end,_}=I|Is], Dict0, Lbls0, Seq, Acc) ->
     {Dict,Lbls} = clean_non_sharable(Dict0, Lbls0),
     share_1(Is, Dict, Lbls, [I|Seq], Acc);
+share_1([{jump,{f,To}}=I,{label,L}=Lbl|Is], Dict0, Lbls0, _Seq, Acc) ->
+    Lbls = maps:put(L, To, Lbls0),
+    share_1(Is, Dict0, Lbls, [], [[Lbl,I]|Acc]);
 share_1([I|Is], Dict, Lbls, Seq, Acc) ->
     case is_unreachable_after(I) of
 	false ->
-- 
2.16.4

openSUSE Build Service is sponsored by