aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-06-26 10:36:19 +0200
committerBjörn Gustavsson <[email protected]>2019-06-26 11:23:18 +0200
commit48cdb47946c516579e6b46979ab4e6f9378d2e79 (patch)
tree638ceca1fdfd7e68bef2c40e6b2f1feff73911e5 /lib/compiler
parenta92672118b5b80fc7f6d902bf064c6efae2754dc (diff)
downloadotp-48cdb47946c516579e6b46979ab4e6f9378d2e79.tar.gz
otp-48cdb47946c516579e6b46979ab4e6f9378d2e79.tar.bz2
otp-48cdb47946c516579e6b46979ab4e6f9378d2e79.zip
Fix slow compilation of huge functions
Some huge functions would compile very slowly because of a bottleneck in `beam_ssa:def_used/2`. One example is the `cuter_binlib` module in https://github.com/cuter-testing/cuter. On my computer, this commit reduces the compilatation time for `cuter_binlib` to 45 seconds down from more than 4 minutes. Noticed-by: Kostis Sagonas
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/beam_ssa.erl20
1 files changed, 13 insertions, 7 deletions
diff --git a/lib/compiler/src/beam_ssa.erl b/lib/compiler/src/beam_ssa.erl
index afd38dcd08..6492d1e1bf 100644
--- a/lib/compiler/src/beam_ssa.erl
+++ b/lib/compiler/src/beam_ssa.erl
@@ -123,7 +123,7 @@
'copy' | 'put_tuple_arity' | 'put_tuple_element' |
'put_tuple_elements' | 'set_tuple_element'.
--import(lists, [foldl/3,keyfind/3,mapfoldl/3,member/2,reverse/1]).
+-import(lists, [foldl/3,keyfind/3,mapfoldl/3,member/2,reverse/1,umerge/1]).
-spec add_anno(Key, Value, Construct) -> Construct when
Key :: atom(),
@@ -651,12 +651,18 @@ is_commutative('=/=') -> true;
is_commutative('/=') -> true;
is_commutative(_) -> false.
-def_used_1([#b_blk{is=Is,last=Last}|Bs], Preds, Def0, Used0) ->
- {Def,Used1} = def_used_is(Is, Preds, Def0, Used0),
- Used = ordsets:union(used(Last), Used1),
- def_used_1(Bs, Preds, Def, Used);
-def_used_1([], _Preds, Def, Used) ->
- {ordsets:from_list(Def),Used}.
+def_used_1([#b_blk{is=Is,last=Last}|Bs], Preds, Def0, UsedAcc) ->
+ {Def,Used} = def_used_is(Is, Preds, Def0, used(Last)),
+ case Used of
+ [] ->
+ def_used_1(Bs, Preds, Def, UsedAcc);
+ [_|_] ->
+ def_used_1(Bs, Preds, Def, [Used|UsedAcc])
+ end;
+def_used_1([], _Preds, Def0, UsedAcc) ->
+ Def = ordsets:from_list(Def0),
+ Used = umerge(UsedAcc),
+ {Def,Used}.
def_used_is([#b_set{op=phi,dst=Dst,args=Args}|Is],
Preds, Def0, Used0) ->