diff options
author | Björn Gustavsson <[email protected]> | 2019-01-31 08:08:09 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2019-02-01 12:47:07 +0100 |
commit | 8c5edfebf22bb1e235989f4890cb729e82d9a885 (patch) | |
tree | b227a9aaf59c19ad8cce9b516352ef672cb460e4 /lib/compiler/src/beam_ssa_opt.erl | |
parent | 939b7da053408682de888bd6423ff7e9cc6ea448 (diff) | |
download | otp-8c5edfebf22bb1e235989f4890cb729e82d9a885.tar.gz otp-8c5edfebf22bb1e235989f4890cb729e82d9a885.tar.bz2 otp-8c5edfebf22bb1e235989f4890cb729e82d9a885.zip |
Make helper functions tail-recursive
Two helper functions in beam_ssa_opt and beam_ssa_dead
are body-recursive for no good reason.
While at it, add some clarifying comments to the functions.
Diffstat (limited to 'lib/compiler/src/beam_ssa_opt.erl')
-rw-r--r-- | lib/compiler/src/beam_ssa_opt.erl | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/lib/compiler/src/beam_ssa_opt.erl b/lib/compiler/src/beam_ssa_opt.erl index c83bd446d3..ca5eefe4fc 100644 --- a/lib/compiler/src/beam_ssa_opt.erl +++ b/lib/compiler/src/beam_ssa_opt.erl @@ -1149,25 +1149,28 @@ ssa_opt_live({#st{ssa=Linear0}=St, FuncDb}) -> live_opt([{L,Blk0}|Bs], LiveMap0, Blocks) -> Blk1 = beam_ssa_share:block(Blk0, Blocks), Successors = beam_ssa:successors(Blk1), - Live0 = live_opt_succ(Successors, L, LiveMap0), + Live0 = live_opt_succ(Successors, L, LiveMap0, gb_sets:empty()), {Blk,Live} = live_opt_blk(Blk1, Live0), LiveMap = live_opt_phis(Blk#b_blk.is, L, Live, LiveMap0), live_opt(Bs, LiveMap, Blocks#{L:=Blk}); live_opt([], _, Acc) -> Acc. -live_opt_succ([S|Ss], L, LiveMap) -> - Live0 = live_opt_succ(Ss, L, LiveMap), +live_opt_succ([S|Ss], L, LiveMap, Live0) -> Key = {S,L}, case LiveMap of #{Key:=Live} -> - gb_sets:union(Live, Live0); + %% The successor has a phi node, and the value for + %% this block in the phi node is a variable. + live_opt_succ(Ss, L, LiveMap, gb_sets:union(Live, Live0)); #{S:=Live} -> - gb_sets:union(Live, Live0); + %% No phi node in the successor, or the value for + %% this block in the phi node is a literal. + live_opt_succ(Ss, L, LiveMap, gb_sets:union(Live, Live0)); #{} -> - Live0 + %% A peek_message block which has not been processed yet. + live_opt_succ(Ss, L, LiveMap, Live0) end; -live_opt_succ([], _, _) -> - gb_sets:empty(). +live_opt_succ([], _, _, Acc) -> Acc. live_opt_phis(Is, L, Live0, LiveMap0) -> LiveMap = LiveMap0#{L=>Live0}, |