diff options
author | Björn Gustavsson <[email protected]> | 2019-01-16 19:31:22 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2019-01-18 05:45:59 +0100 |
commit | 9814a205a2cf9e1024261e2eee80e460e78600d0 (patch) | |
tree | a97da08a59b97226280e88fbb0e944cd44917c4b | |
parent | 9c852215c79ed6ec42c223463d4b5a0c221b4bf0 (diff) | |
download | otp-9814a205a2cf9e1024261e2eee80e460e78600d0.tar.gz otp-9814a205a2cf9e1024261e2eee80e460e78600d0.tar.bz2 otp-9814a205a2cf9e1024261e2eee80e460e78600d0.zip |
beam_ssa_opt: Run the type optimization pass twice
The code will be significantly improved by running the
type optimization pass twice.
The ssa_opt_misc pass can be eliminated because everything it does
is also done by the type optimization pass.
-rw-r--r-- | lib/compiler/src/beam_ssa_opt.erl | 102 |
1 files changed, 9 insertions, 93 deletions
diff --git a/lib/compiler/src/beam_ssa_opt.erl b/lib/compiler/src/beam_ssa_opt.erl index e23e62b5ad..df40c918b2 100644 --- a/lib/compiler/src/beam_ssa_opt.erl +++ b/lib/compiler/src/beam_ssa_opt.erl @@ -22,7 +22,7 @@ -export([module/2]). -include("beam_ssa.hrl"). --import(lists, [all/2,append/1,foldl/3,keyfind/3,member/2, +-import(lists, [append/1,foldl/3,keyfind/3,member/2, reverse/1,reverse/2, splitwith/2,takewhile/2,unzip/1]). @@ -55,9 +55,13 @@ passes(Opts0) -> ?PASS(ssa_opt_record), %% Run ssa_opt_cse twice, because it will help ssa_opt_dead, - %% and ssa_opt_dead will help ssa_opt_cse. Run ssa_opt_live - %% twice, because it will help ssa_opt_dead and ssa_opt_dead - %% will help ssa_opt_live. + %% and ssa_opt_dead will help ssa_opt_cse. + %% + %% Run ssa_opt_live twice, because it will help ssa_opt_dead + %% and ssa_opt_dead will help ssa_opt_live. + %% + %% Run beam_ssa_type twice, because there will be more + %% opportunities for optimizations after running beam_ssa_dead. ?PASS(ssa_opt_cse), ?PASS(ssa_opt_type), ?PASS(ssa_opt_live), @@ -65,12 +69,12 @@ passes(Opts0) -> ?PASS(ssa_opt_dead), ?PASS(ssa_opt_cse), %Second time. ?PASS(ssa_opt_float), + ?PASS(ssa_opt_type), %Second time. ?PASS(ssa_opt_live), %Second time. ?PASS(ssa_opt_bsm), ?PASS(ssa_opt_bsm_units), ?PASS(ssa_opt_bsm_shortcut), - ?PASS(ssa_opt_misc), ?PASS(ssa_opt_tuple_size), ?PASS(ssa_opt_sw), ?PASS(ssa_opt_blockify), @@ -1346,94 +1350,6 @@ opt_bs_put_split_int_1(Int, L, R) -> end. %%% -%%% Miscellanous optimizations in execution order. -%%% - -ssa_opt_misc(#st{ssa=Linear}=St) -> - St#st{ssa=misc_opt(Linear, #{})}. - -misc_opt([{L,#b_blk{is=Is0,last=Last0}=Blk0}|Bs], Sub0) -> - {Is,Sub} = misc_opt_is(Is0, Sub0, []), - Last = sub(Last0, Sub), - Blk = Blk0#b_blk{is=Is,last=Last}, - [{L,Blk}|misc_opt(Bs, Sub)]; -misc_opt([], _) -> []. - -misc_opt_is([#b_set{op=phi}=I0|Is], Sub0, Acc) -> - #b_set{dst=Dst,args=Args} = I = sub(I0, Sub0), - case all_same(Args) of - true -> - %% Eliminate the phi node if there is just one source - %% value or if the values are identical. - [{Val,_}|_] = Args, - Sub = Sub0#{Dst=>Val}, - misc_opt_is(Is, Sub, Acc); - false -> - misc_opt_is(Is, Sub0, [I|Acc]) - end; -misc_opt_is([#b_set{op={bif,'and'}}=I0], Sub, Acc) -> - #b_set{dst=Dst,args=Args} = I = sub(I0, Sub), - case eval_and(Args) of - error -> - misc_opt_is([], Sub, [I|Acc]); - Val -> - misc_opt_is([], Sub#{Dst=>Val}, Acc) - end; -misc_opt_is([#b_set{op={bif,'or'}}=I0], Sub, Acc) -> - #b_set{dst=Dst,args=Args} = I = sub(I0, Sub), - case eval_or(Args) of - error -> - misc_opt_is([], Sub, [I|Acc]); - Val -> - misc_opt_is([], Sub#{Dst=>Val}, Acc) - end; -misc_opt_is([#b_set{}=I0|Is], Sub, Acc) -> - #b_set{op=Op,dst=Dst,args=Args} = I = sub(I0, Sub), - case make_literal(Op, Args) of - #b_literal{}=Literal -> - misc_opt_is(Is, Sub#{Dst=>Literal}, Acc); - error -> - misc_opt_is(Is, Sub, [I|Acc]) - end; -misc_opt_is([], Sub, Acc) -> - {reverse(Acc),Sub}. - -all_same([{H,_}|T]) -> - all(fun({E,_}) -> E =:= H end, T). - -make_literal(put_tuple, Args) -> - case make_literal_list(Args, []) of - error -> - error; - List -> - #b_literal{val=list_to_tuple(List)} - end; -make_literal(put_list, [#b_literal{val=H},#b_literal{val=T}]) -> - #b_literal{val=[H|T]}; -make_literal(_, _) -> error. - -make_literal_list([#b_literal{val=H}|T], Acc) -> - make_literal_list(T, [H|Acc]); -make_literal_list([_|_], _) -> - error; -make_literal_list([], Acc) -> - reverse(Acc). - -eval_and(Args) -> - case Args of - [_,#b_literal{val=false}=Res] -> Res; - [Res,#b_literal{val=true}] -> Res; - [_,_] -> error - end. - -eval_or(Args) -> - case Args of - [Res,#b_literal{val=false}] -> Res; - [_,#b_literal{val=true}=Res] -> Res; - [_,_] -> error - end. - -%%% %%% Optimize expressions such as "tuple_size(Var) =:= 2". %%% %%% Consider this code: |