aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-01-29 18:09:26 +0100
committerBjörn Gustavsson <[email protected]>2019-02-01 12:44:31 +0100
commit9a190cae9bd7213ff018e17a909efbab04a14a8c (patch)
treeedac9546b6b5b79fe4367a79baa98b0ebc944758 /lib
parentbc0aef4bb631acbf0b8e8fd8ecc51cb1286ed8c9 (diff)
downloadotp-9a190cae9bd7213ff018e17a909efbab04a14a8c.tar.gz
otp-9a190cae9bd7213ff018e17a909efbab04a14a8c.tar.bz2
otp-9a190cae9bd7213ff018e17a909efbab04a14a8c.zip
Optimize ssa_opt_sink when nothing can be sunk
Compilation will be much faster if there are many blocks, but no get_tuple_element instructions. Reported-by: Michał Muskała
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/src/beam_ssa_opt.erl12
1 files changed, 10 insertions, 2 deletions
diff --git a/lib/compiler/src/beam_ssa_opt.erl b/lib/compiler/src/beam_ssa_opt.erl
index e528bb4dfb..47b9ef28d8 100644
--- a/lib/compiler/src/beam_ssa_opt.erl
+++ b/lib/compiler/src/beam_ssa_opt.erl
@@ -2003,8 +2003,16 @@ ssa_opt_sink({#st{ssa=Blocks0}=St, FuncDb}) ->
%% Create a map with all variables that define get_tuple_element
%% instructions. The variable name map to the block it is defined in.
- Defs = maps:from_list(def_blocks(Linear)),
+ case def_blocks(Linear) of
+ [] ->
+ %% No get_tuple_element instructions, so there is nothing to do.
+ {St, FuncDb};
+ [_|_]=Defs0 ->
+ Defs = maps:from_list(Defs0),
+ {do_ssa_opt_sink(Linear, Defs, St), FuncDb}
+ end.
+do_ssa_opt_sink(Linear, Defs, #st{ssa=Blocks0}=St) ->
%% Now find all the blocks that use variables defined by get_tuple_element
%% instructions.
Used = used_blocks(Linear, Defs, []),
@@ -2039,7 +2047,7 @@ ssa_opt_sink({#st{ssa=Blocks0}=St, FuncDb}) ->
From = maps:get(V, Defs),
move_defs(V, From, To, A)
end, Blocks0, DefLoc),
- {St#st{ssa=Blocks}, FuncDb}.
+ St#st{ssa=Blocks}.
def_blocks([{L,#b_blk{is=Is}}|Bs]) ->
def_blocks_is(Is, L, def_blocks(Bs));