aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_ssa_type.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-02-18 14:33:55 +0100
committerBjörn Gustavsson <[email protected]>2019-02-19 10:18:08 +0100
commit26c93c06ebb9b1585418d463142f63bdca071f85 (patch)
tree3dc2f224419bc854c59debac04e15b3fb7901383 /lib/compiler/src/beam_ssa_type.erl
parent6c0c1f69353b14bb9cec8d6d2ae134b54bf3b2d7 (diff)
downloadotp-26c93c06ebb9b1585418d463142f63bdca071f85.tar.gz
otp-26c93c06ebb9b1585418d463142f63bdca071f85.tar.bz2
otp-26c93c06ebb9b1585418d463142f63bdca071f85.zip
Do the destructive setelement optimization in SSA
The expansion of record field updates, when more than one field is updated, but not a majority of the fields, will create a sequence of calls to `erlang:setelement(Index, Value, Tuple)` where Tuple in the first call is the original record tuple, and in the subsequent calls Tuple is the result of the previous call. Furthermore, all Index values are constant positive integers, and the first call to `setelement` will have the greatest index. Thus all the following calls do not actually need to test at run-time whether Tuple has type tuple, nor that the index is within the tuple bounds. Since OTP R7, the `sys_core_dsetel` pass, run as the very last Core Erlang pass, has optimized this sequence of `setelement` calls to use a special destructive version of `setelement` (called `set_tuple_element`) for all but the very first `setelement` in the sequence. It turns out that the presence of the `set_tuple_element` in SSA code is awkward and can prevent or complicate type analysis and aggressive optimizations. Therefore, this commit removes the `sys_core_dsetel` pass and reimplements it for SSA code. The optimization will be done in the `beam_ssa_pre_codegen` pass (that is, just before code generation and after running all other SSA code optimization passes). In most cases, the resulting BEAM code is identical to previous code. For a few modules, the BEAM code is actually slightly better, with smaller stack frames.
Diffstat (limited to 'lib/compiler/src/beam_ssa_type.erl')
-rw-r--r--lib/compiler/src/beam_ssa_type.erl28
1 files changed, 0 insertions, 28 deletions
diff --git a/lib/compiler/src/beam_ssa_type.erl b/lib/compiler/src/beam_ssa_type.erl
index 6fa02da89d..3b5d25efce 100644
--- a/lib/compiler/src/beam_ssa_type.erl
+++ b/lib/compiler/src/beam_ssa_type.erl
@@ -277,12 +277,6 @@ opt_is([#b_set{op=call,args=Args0,dst=Dst}=I0|Is],
_ ->
opt_is(Is, Ts, Ds, Fdb, D, Sub, [I|Acc])
end;
-opt_is([#b_set{op=set_tuple_element}=I0|Is],
- Ts0, Ds0, Fdb, D, Sub, Acc) ->
- %% This instruction lacks a return value and destructively updates its
- %% source, so it needs special handling to update the source type.
- {Ts, Ds, I} = opt_set_tuple_element(I0, Ts0, Ds0, Sub),
- opt_is(Is, Ts, Ds, Fdb, D, Sub, [I|Acc]);
opt_is([#b_set{op=succeeded,args=[Arg],dst=Dst}=I],
Ts0, Ds0, Fdb, D, Sub0, Acc) ->
case Ds0 of
@@ -381,28 +375,6 @@ update_arg_types([Arg | Args], [TypeMap0 | TypeMaps], CallId, Ts) ->
update_arg_types([], [], _CallId, _Ts) ->
[].
-opt_set_tuple_element(#b_set{op=set_tuple_element,args=Args0,dst=Dst}=I0,
- Ts0, Ds0, Sub) ->
- Args = simplify_args(Args0, Sub, Ts0),
- [Val,#b_var{}=Src,#b_literal{val=N}] = Args,
-
- SrcType0 = get_type(Src, Ts0),
- ValType = get_type(Val, Ts0),
- Index = N + 1,
-
- #t_tuple{size=Size,elements=Es0} = SrcType0,
- true = Index =< Size, %Assertion.
-
- Es = set_element_type(Index, ValType, Es0),
- SrcType = SrcType0#t_tuple{elements=Es},
-
- I = beam_ssa:normalize(I0#b_set{args=Args}),
-
- Ts = Ts0#{ Dst => any, Src => SrcType },
- Ds = Ds0#{ Dst => I },
-
- {Ts, Ds, I}.
-
simplify(#b_set{op={bif,'and'},args=Args}=I, Ts) ->
case is_safe_bool_op(Args, Ts) of
true ->