summaryrefslogtreecommitdiff
path: root/lib/compiler/src
diff options
context:
space:
mode:
authorFrej Drejhammar <frej.drejhammar@gmail.com>2023-03-10 08:34:59 +0100
committerFrej Drejhammar <frej.drejhammar@gmail.com>2023-03-10 09:54:05 +0100
commit0bac830c937c7c39b6aae37a73bd135841dde969 (patch)
tree1ad21e5496b2425ebc7f37ad7f9f931dac25aaa0 /lib/compiler/src
parent8130d7ff72b9a7344bbf38ae11283eb01aab3ae5 (diff)
downloaderlang-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.erl32
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);