diff options
author | Björn Gustavsson <[email protected]> | 2019-01-29 07:34:11 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2019-01-29 07:34:11 +0100 |
commit | 2f296e1a44a8abfd3f5d35aa9c111eecaac3156d (patch) | |
tree | 5f28275abc4086f3d72542b3257e74e36987f7b5 | |
parent | 5a38332a37eecc29a21fa2d83ba0b719f3a721d4 (diff) | |
parent | acf96b6e024864b5dce41ef68725bb0228fe3100 (diff) | |
download | otp-2f296e1a44a8abfd3f5d35aa9c111eecaac3156d.tar.gz otp-2f296e1a44a8abfd3f5d35aa9c111eecaac3156d.tar.bz2 otp-2f296e1a44a8abfd3f5d35aa9c111eecaac3156d.zip |
Merge pull request #2112 from bjorng/bjorn/compiler/compilation-speed
Speed up the compiler when compiling the idna package
-rw-r--r-- | lib/compiler/src/beam_ssa_dead.erl | 47 | ||||
-rw-r--r-- | lib/compiler/src/beam_ssa_opt.erl | 12 |
2 files changed, 47 insertions, 12 deletions
diff --git a/lib/compiler/src/beam_ssa_dead.erl b/lib/compiler/src/beam_ssa_dead.erl index 067d9a6741..09b29025c6 100644 --- a/lib/compiler/src/beam_ssa_dead.erl +++ b/lib/compiler/src/beam_ssa_dead.erl @@ -181,9 +181,9 @@ shortcut_2(L, Bs0, UnsetVars0, St) -> %% We have a potentially suitable br. %% Now update the set of variables that will never %% be set if this block will be skipped. - UnsetVars1 = [V || #b_set{dst=V} <- Is], - UnsetVars = ordsets:union(UnsetVars0, - ordsets:from_list(UnsetVars1)), + SetInThisBlock = [V || #b_set{dst=V} <- Is], + UnsetVars = update_unset_vars(L, Br, SetInThisBlock, + UnsetVars0, St), %% Continue checking whether this br is suitable. shortcut_3(Br, Bs#{from:=L}, UnsetVars, St) @@ -296,6 +296,37 @@ shortcut_3(Br, Bs, UnsetVars, #st{target=Target}=St) -> end end. +update_unset_vars(L, Br, SetInThisBlock, UnsetVars, #st{skippable=Skippable}) -> + case is_map_key(L, Skippable) of + true -> + %% None of the variables used in this block are used in + %% the successors. We can speed up compilation by avoiding + %% adding variables to the UnsetVars if the presence of + %% those variable would not change the outcome of the + %% tests in is_br_safe/2. + case Br of + #b_br{bool=Bool} -> + case member(Bool, SetInThisBlock) of + true -> + %% Bool is a variable defined in this + %% block. It will change the outcome of + %% the `not member(V, UnsetVars)` check in + %% is_br_safe/2. The other variables + %% defined in this block will not. + ordsets:add_element(Bool, UnsetVars); + false -> + %% Bool is either a variable not defined + %% in this block or a literal. Adding it + %% to the UnsetVars set would not change + %% the outcome of the tests in + %% is_br_safe/2. + UnsetVars + end + end; + false -> + ordsets:union(UnsetVars, ordsets:from_list(SetInThisBlock)) + end. + shortcut_two_way(#b_br{succ=Succ,fail=Fail}, Bs0, UnsetVars0, St) -> case shortcut_2(Succ, Bs0, UnsetVars0, St#st{target=Fail}) of {#b_br{bool=#b_literal{},succ=Fail},_,_}=Res -> @@ -919,11 +950,11 @@ used_vars([{L,#b_blk{is=Is}=Blk}|Bs], UsedVars0, Skip0) -> Used = used_vars_blk(Blk, Used0), UsedVars = used_vars_phis(Is, L, Used, UsedVars0), - %% combine_eqs/1 needs different variable usage - %% information than shortcut_opt/1. The Skip - %% map will have an entry for each block that - %% can be skipped (does not bind any variable used - %% in successor). + %% combine_eqs/1 needs different variable usage information than + %% shortcut_opt/1. The Skip map will have an entry for each block + %% that can be skipped (does not bind any variable used in + %% successor). This information is also useful for speeding up + %% shortcut_opt/1. Defined0 = [Def || #b_set{dst=Def} <- Is], Defined = ordsets:from_list(Defined0), diff --git a/lib/compiler/src/beam_ssa_opt.erl b/lib/compiler/src/beam_ssa_opt.erl index f99993522a..e528bb4dfb 100644 --- a/lib/compiler/src/beam_ssa_opt.erl +++ b/lib/compiler/src/beam_ssa_opt.erl @@ -1970,13 +1970,17 @@ verify_merge_is([#b_set{op=Op}|_]) -> verify_merge_is(_) -> ok. -is_merge_allowed(_, _, #b_blk{is=[#b_set{op=peek_message}|_]}) -> +is_merge_allowed(_, #b_blk{}, #b_blk{is=[#b_set{op=peek_message}|_]}) -> false; -is_merge_allowed(L, Blk0, #b_blk{}) -> - case beam_ssa:successors(Blk0) of +is_merge_allowed(L, #b_blk{last=#b_br{}}=Blk, #b_blk{}) -> + %% The predecessor block must have exactly one successor (L) for + %% the merge to be safe. + case beam_ssa:successors(Blk) of [L] -> true; [_|_] -> false - end. + end; +is_merge_allowed(_, #b_blk{last=#b_switch{}}, #b_blk{}) -> + false. %%% %%% When a tuple is matched, the pattern matching compiler generates a |