From d6287ba96fddcad782316061a1813bbd627ae6c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20H=C3=B6gberg?= Date: Tue, 28 May 2019 17:22:21 +0200 Subject: beam_validator: Simplify the match context type There's no need to have an id as part of the type, as the value reference (through which the type is reached) uniquely identifies the match context. --- lib/compiler/src/beam_validator.erl | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index c5e3f6ac35..a89295ab72 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -154,8 +154,7 @@ validate_0(Module, [{function,Name,Ar,Entry,Code}|Fs], Ft) -> %% Match context type. -record(ms, - {id=make_ref() :: reference(), %Unique ID. - valid=0 :: non_neg_integer(), %Valid slots + {valid=0 :: non_neg_integer(), %Valid slots slots=0 :: non_neg_integer() %Number of slots }). @@ -487,7 +486,9 @@ valfun_1(remove_message, Vst) -> %% without restrictions. remove_fragility(Vst); valfun_1({'%', {type_info, Reg, match_context}}, Vst) -> - update_type(fun meet/2, #ms{}, Reg, Vst); + %% This is a gross hack, but we'll be rid of it once we have proper union + %% types. + override_type(#ms{}, Reg, Vst); valfun_1({'%', {type_info, Reg, Type}}, Vst) -> %% Explicit type information inserted by optimization passes to indicate %% that Reg has a certain type, so that we can accept cross-function type @@ -1260,21 +1261,22 @@ verify_remote_args_1(X, Vst) -> verify_local_args(-1, _Lbl, _CtxIds, _Vst) -> ok; -verify_local_args(X, Lbl, CtxIds, Vst) -> +verify_local_args(X, Lbl, CtxRefs, Vst) -> Reg = {x, X}, assert_not_fragile(Reg, Vst), case get_movable_term_type(Reg, Vst) of - #ms{id=Id}=Type -> - case CtxIds of - #{ Id := Other } -> + #ms{}=Type -> + VRef = get_reg_vref(Reg, Vst), + case CtxRefs of + #{ VRef := Other } -> error({multiple_match_contexts, [Reg, Other]}); #{} -> verify_arg_type(Lbl, Reg, Type, Vst), - verify_local_args(X - 1, Lbl, CtxIds#{ Id => Reg }, Vst) + verify_local_args(X - 1, Lbl, CtxRefs#{ VRef => Reg }, Vst) end; Type -> verify_arg_type(Lbl, Reg, Type, Vst), - verify_local_args(X - 1, Lbl, CtxIds, Vst) + verify_local_args(X - 1, Lbl, CtxRefs, Vst) end. %% Verifies that the given argument narrows to what the function expects. @@ -2039,13 +2041,9 @@ join({atom,A}, {atom,B}) when is_boolean(A), is_boolean(B) -> bool; join({atom,_}, {atom,_}) -> {atom,[]}; -join(#ms{id=Id1,valid=B1,slots=Slots1}, - #ms{id=Id2,valid=B2,slots=Slots2}) -> - Id = if - Id1 =:= Id2 -> Id1; - true -> make_ref() - end, - #ms{id=Id,valid=B1 band B2,slots=min(Slots1, Slots2)}; +join(#ms{valid=B1,slots=Slots1}, + #ms{valid=B2,slots=Slots2}) -> + #ms{valid=B1 band B2,slots=min(Slots1, Slots2)}; join(T1, T2) when T1 =/= T2 -> %% We've exhaused all other options, so the type must either be a list or %% a 'term'. @@ -2107,10 +2105,6 @@ meet(term, Other) -> Other; meet(Other, term) -> Other; -meet(#ms{}, binary) -> - #ms{}; -meet(binary, #ms{}) -> - #ms{}; meet({literal,_}, {literal,_}) -> none; meet(T1, {literal,_}=T2) -> -- cgit v1.2.3