aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-01-29 07:33:51 +0100
committerGitHub <[email protected]>2019-01-29 07:33:51 +0100
commit5a38332a37eecc29a21fa2d83ba0b719f3a721d4 (patch)
treebba3f0170f4114062de9477519bdc107cf1192e3
parent2b603d86dbc8715eda4efc78294ded0770d2149e (diff)
parent9528e7a5de22ffa8ce2557e45fb744d2c3548bf5 (diff)
downloadotp-5a38332a37eecc29a21fa2d83ba0b719f3a721d4.tar.gz
otp-5a38332a37eecc29a21fa2d83ba0b719f3a721d4.tar.bz2
otp-5a38332a37eecc29a21fa2d83ba0b719f3a721d4.zip
Merge pull request #2111 from bjorng/bjorn/compiler/not-problem/ERL-840
Fix problems compiling Scalaris
-rw-r--r--lib/compiler/src/beam_ssa_opt.erl8
-rw-r--r--lib/compiler/src/beam_ssa_type.erl24
-rw-r--r--lib/compiler/test/beam_type_SUITE.erl16
3 files changed, 33 insertions, 15 deletions
diff --git a/lib/compiler/src/beam_ssa_opt.erl b/lib/compiler/src/beam_ssa_opt.erl
index 2c898ba6f8..f99993522a 100644
--- a/lib/compiler/src/beam_ssa_opt.erl
+++ b/lib/compiler/src/beam_ssa_opt.erl
@@ -79,11 +79,9 @@ module(Module, Opts) ->
{ok, finish(Module, StMap)}.
phase([FuncId | Ids], Ps, StMap, FuncDb0) ->
- try
- {St, FuncDb} =
- compile:run_sub_passes(Ps, {map_get(FuncId, StMap), FuncDb0}),
-
- phase(Ids, Ps, StMap#{ FuncId => St }, FuncDb)
+ try compile:run_sub_passes(Ps, {map_get(FuncId, StMap), FuncDb0}) of
+ {St, FuncDb} ->
+ phase(Ids, Ps, StMap#{ FuncId => St }, FuncDb)
catch
Class:Error:Stack ->
#b_local{name=Name,arity=Arity} = FuncId,
diff --git a/lib/compiler/src/beam_ssa_type.erl b/lib/compiler/src/beam_ssa_type.erl
index 38ea5e6914..8bd6772ac5 100644
--- a/lib/compiler/src/beam_ssa_type.erl
+++ b/lib/compiler/src/beam_ssa_type.erl
@@ -1072,15 +1072,23 @@ simplify_not(#b_br{bool=#b_var{}=V,succ=Succ,fail=Fail}=Br0, Ts, Ds) ->
%%%
%%% Calculate the set of variables that are only used once in the
-%%% block that they are defined in. That will allow us to discard type
-%%% information for variables that will never be referenced by the
-%%% successor blocks, potentially improving compilation times.
+%%% terminator of the block that defines them. That will allow us to
+%%% discard type information for variables that will never be
+%%% referenced by the successor blocks, potentially improving
+%%% compilation times.
%%%
used_once(Linear, Args) ->
Map0 = used_once_1(reverse(Linear), #{}),
Map = maps:without(Args, Map0),
- cerl_sets:from_list(maps:keys(Map)).
+ Used0 = cerl_sets:from_list(maps:keys(Map)),
+ Used1 = used_in_terminators(Linear, []),
+ cerl_sets:intersection(Used0, Used1).
+
+used_in_terminators([{_,#b_blk{last=Last}}|Bs], Acc) ->
+ used_in_terminators(Bs, beam_ssa:used(Last) ++ Acc);
+used_in_terminators([], Acc) ->
+ cerl_sets:from_list(Acc).
used_once_1([{L,#b_blk{is=Is,last=Last}}|Bs], Uses0) ->
Uses = used_once_2([Last|reverse(Is)], L, Uses0),
@@ -1177,7 +1185,7 @@ get_type(#b_literal{val=Val}, _Ts) ->
%% failed and that L is not 'cons'. 'cons' can be subtracted from the
%% previously known type for L and the result put in FailTypes.
-infer_types(#b_var{}=V, Ts, #d{ds=Ds,once=Once}) ->
+infer_types(#b_var{}=V, Ts, #d{ds=Ds}) ->
#{V:=#b_set{op=Op,args=Args}} = Ds,
Types0 = infer_type(Op, Args, Ds),
@@ -1195,11 +1203,7 @@ infer_types(#b_var{}=V, Ts, #d{ds=Ds,once=Once}) ->
is_singleton_type(T)
end, EqTypes0),
- %% Don't bother updating the types for variables that
- %% are never used again.
- Types2 = Types1 ++ Types0,
- Types = [P || {InfV,_}=P <- Types2, not cerl_sets:is_element(InfV, Once)],
-
+ Types = Types1 ++ Types0,
{meet_types(EqTypes++Types, Ts),subtract_types(Types, Ts)}.
infer_eq_type({bif,'=:='}, [#b_var{}=Src,#b_literal{}=Lit], Ts, Ds) ->
diff --git a/lib/compiler/test/beam_type_SUITE.erl b/lib/compiler/test/beam_type_SUITE.erl
index 6efa98de44..a7ffc3f60a 100644
--- a/lib/compiler/test/beam_type_SUITE.erl
+++ b/lib/compiler/test/beam_type_SUITE.erl
@@ -222,6 +222,9 @@ coverage(Config) ->
booleans(_Config) ->
{'EXIT',{{case_clause,_},_}} = (catch do_booleans_1(42)),
+ ok = do_booleans_2(42, 41),
+ error = do_booleans_2(42, 42),
+
AnyAtom = id(atom),
true = is_atom(AnyAtom),
false = is_boolean(AnyAtom),
@@ -250,6 +253,19 @@ do_booleans_1(B) ->
no -> no
end.
+do_booleans_2(A, B) ->
+ Not = not do_booleans_cmp(A, B),
+ case Not of
+ true ->
+ case Not of
+ true -> error;
+ false -> ok
+ end;
+ false -> ok
+ end.
+
+do_booleans_cmp(A, B) -> A > B.
+
setelement(_Config) ->
T0 = id({a,42}),
{a,_} = T0,