aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_clean.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2018-01-31 07:22:24 +0100
committerBjörn Gustavsson <[email protected]>2018-02-14 08:33:25 +0100
commit260d530946fd3eb2e2d7e74465a5095d35822128 (patch)
tree8b1b99aa283e434ad2c56d325d83717230be2381 /lib/compiler/src/beam_clean.erl
parent54b76b437c9008b3aedbf3fd75526ad4719bde7d (diff)
downloadotp-260d530946fd3eb2e2d7e74465a5095d35822128.tar.gz
otp-260d530946fd3eb2e2d7e74465a5095d35822128.tar.bz2
otp-260d530946fd3eb2e2d7e74465a5095d35822128.zip
beam_block: Combine blocks when running beam_block the second time
1a029efd1ad47f started to run the beam_block pass a second time, but it did not attempt to combine adjacent blocks. Combining adjacent blocks leads to many more opportunities for optimizations. After doing some diffing in generated code, it turns out that there is no benefit for beam_split to split out line instructions from blocks. It seems that the only reason it was done was to slightly simplify the implementation of the no_line_info option in beam_clean.
Diffstat (limited to 'lib/compiler/src/beam_clean.erl')
-rw-r--r--lib/compiler/src/beam_clean.erl21
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/compiler/src/beam_clean.erl b/lib/compiler/src/beam_clean.erl
index e094c2c320..7ddf9fa2e2 100644
--- a/lib/compiler/src/beam_clean.erl
+++ b/lib/compiler/src/beam_clean.erl
@@ -24,7 +24,7 @@
-export([module/2]).
-export([bs_clean_saves/1]).
-export([clean_labels/1]).
--import(lists, [foldl/3,reverse/1,filter/2]).
+-import(lists, [foldl/3,reverse/1]).
-spec module(beam_utils:module_code(), [compile:option()]) ->
{'ok',beam_utils:module_code()}.
@@ -303,8 +303,21 @@ maybe_remove_lines(Fs, Opts) ->
end.
remove_lines([{function,N,A,Lbl,Is0}|T]) ->
- Is = filter(fun({line,_}) -> false;
- (_) -> true
- end, Is0),
+ Is = remove_lines_fun(Is0),
[{function,N,A,Lbl,Is}|remove_lines(T)];
remove_lines([]) -> [].
+
+remove_lines_fun([{line,_}|Is]) ->
+ remove_lines_fun(Is);
+remove_lines_fun([{block,Bl0}|Is]) ->
+ Bl = remove_lines_block(Bl0),
+ [{block,Bl}|remove_lines_fun(Is)];
+remove_lines_fun([I|Is]) ->
+ [I|remove_lines_fun(Is)];
+remove_lines_fun([]) -> [].
+
+remove_lines_block([{set,_,_,{line,_}}|Is]) ->
+ remove_lines_block(Is);
+remove_lines_block([I|Is]) ->
+ [I|remove_lines_block(Is)];
+remove_lines_block([]) -> [].