aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_validator.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler/src/beam_validator.erl')
-rw-r--r--lib/compiler/src/beam_validator.erl34
1 files changed, 22 insertions, 12 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index ebe9631e09..717ea17475 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -200,7 +200,7 @@ validate_0(Module, [{function,Name,Ar,Entry,Code}|Fs], Ft) ->
numy=none :: none | undecided | index(),
%% Available heap size.
h=0,
- %Available heap size for floats.
+ %%Available heap size for floats.
hf=0,
%% Floating point state.
fls=undefined,
@@ -240,7 +240,7 @@ index_parameter_types([{function,_,_,Entry,Code0}|Fs], Acc0) ->
Acc = index_parameter_types_1(Is, Entry, Acc0),
index_parameter_types(Fs, Acc);
_ ->
- %% Something serious is wrong. Ignore it for now.
+ %% Something is seriously wrong. Ignore it for now.
%% It will be detected and diagnosed later.
index_parameter_types(Fs, Acc0)
end;
@@ -392,6 +392,23 @@ valfun_1(build_stacktrace=I, Vst) ->
call(I, 1, Vst);
valfun_1({move,Src,Dst}, Vst) ->
assign(Src, Dst, Vst);
+valfun_1({swap,RegA,RegB}, Vst0) ->
+ assert_movable(RegA, Vst0),
+ assert_movable(RegB, Vst0),
+
+ %% We don't expect fragile registers to be swapped.
+ %% Therefore, we can conservatively make both registers
+ %% fragile if one of the register is fragile instead of
+ %% swapping the fragility of the registers.
+ Sources = [RegA,RegB],
+ Vst1 = propagate_fragility(RegA, Sources, Vst0),
+ Vst2 = propagate_fragility(RegB, Sources, Vst1),
+
+ %% Swap the value references.
+ VrefA = get_reg_vref(RegA, Vst2),
+ VrefB = get_reg_vref(RegB, Vst2),
+ Vst = set_reg_vref(VrefB, RegA, Vst2),
+ set_reg_vref(VrefA, RegB, Vst);
valfun_1({fmove,Src,{fr,_}=Dst}, Vst) ->
assert_type(float, Src, Vst),
set_freg(Dst, Vst);
@@ -1848,16 +1865,9 @@ get_reg_vref({y,_}=Src, #vst{current=#st{ys=Ys}}) ->
end.
set_type(Type, #value_ref{}=Ref, #vst{current=#st{vs=Vs0}=St}=Vst) ->
- case Vs0 of
- #{ Ref := #value{}=Entry } ->
- Vs = Vs0#{ Ref => Entry#value{type=Type} },
- Vst#vst{current=St#st{vs=Vs}};
- #{} ->
- %% Dead references may happen during type inference and are not an
- %% error in and of themselves. If a problem were to arise from this
- %% it'll explode elsewhere.
- Vst
- end.
+ #{ Ref := #value{}=Entry } = Vs0,
+ Vs = Vs0#{ Ref => Entry#value{type=Type} },
+ Vst#vst{current=St#st{vs=Vs}}.
new_value(Type, Op, Ss, #vst{current=#st{vs=Vs0}=St,ref_ctr=Counter}=Vst) ->
Ref = #value_ref{id=Counter},