diff options
| author | Frej Drejhammar <frej.drejhammar@gmail.com> | 2023-03-10 08:34:59 +0100 |
|---|---|---|
| committer | Frej Drejhammar <frej.drejhammar@gmail.com> | 2023-03-10 09:54:05 +0100 |
| commit | 0bac830c937c7c39b6aae37a73bd135841dde969 (patch) | |
| tree | 1ad21e5496b2425ebc7f37ad7f9f931dac25aaa0 /lib/compiler/src | |
| parent | 8130d7ff72b9a7344bbf38ae11283eb01aab3ae5 (diff) | |
| download | erlang-0bac830c937c7c39b6aae37a73bd135841dde969.tar.gz | |
compiler: Be stricter when tracking values in private append
Tracking values to patch into writable binaries in the private append
pass doesn't make any attempt to use type information to exclude
execution paths not relevant when tracking an appendable binary. In
order to avoid later failed attempts to rewrite non-bitstring literals
into bs_init_writable-created values during the rewrite phase, we
change the tracking phase to preemptively abort tracking as soon as we
detect that the element we are tracking can't apply to the literal.
Closes #6999
Diffstat (limited to 'lib/compiler/src')
| -rw-r--r-- | lib/compiler/src/beam_ssa_private_append.erl | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/lib/compiler/src/beam_ssa_private_append.erl b/lib/compiler/src/beam_ssa_private_append.erl index aab7d73936..bb68dc12f9 100644 --- a/lib/compiler/src/beam_ssa_private_append.erl +++ b/lib/compiler/src/beam_ssa_private_append.erl @@ -167,16 +167,30 @@ get_results(SSA, Element, Fun, DefSt) -> get_results([{_,#b_blk{last=#b_ret{arg=#b_var{}=V}}}|Rest], Acc, Element, Fun, DefSt) -> get_results(Rest, [{V,Element}|Acc], Element, Fun, DefSt); -get_results([{_,#b_blk{last=#b_ret{arg=#b_literal{val=Lit}}}}|Rest], - Acc, Element=self, Fun, DefSt) when not is_bitstring(Lit) -> - %% As value tracking is done without type information, we can - %% follow def chains which don't terminate in a bitstring. This is - %% harmless, but we should ignore them and not, later on, try to - %% patch them to a bs_writable_binary. - get_results(Rest, Acc, Element, Fun, DefSt); -get_results([{Lbl,#b_blk{last=#b_ret{arg=#b_literal{}}}}|Rest], +get_results([{Lbl,#b_blk{last=#b_ret{arg=#b_literal{val=Lit}}}}|Rest], Acc, Element, Fun, DefSt0) -> - DefSt = add_literal(Fun, {ret,Lbl,Element}, DefSt0), + %% As tracking doesn't make any attempt to use type information to + %% exclude execution paths not relevant when tracking an + %% appendable binary, it can happen that we encounter literals + %% which do not match the type of the element. We can safely stop + %% the tracking in that case. + Continue = case Element of + {tuple_elements,_} -> + is_tuple(Lit); + {tuple_element,_,_} -> + is_tuple(Lit); + Elements when is_list(Elements) -> + is_tuple(Lit); + self -> + is_bitstring(Lit); + {hd,_} -> + is_list(Lit) andalso (Lit =/= []) + end, + DefSt = if Continue -> + add_literal(Fun, {ret,Lbl,Element}, DefSt0); + true -> + DefSt0 + end, get_results(Rest, Acc, Element, Fun, DefSt); get_results([_|Rest], Acc, Element, Fun, DefSt) -> get_results(Rest, Acc, Element, Fun, DefSt); |
