aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2011-09-23 14:10:53 +0200
committerMicael Karlberg <[email protected]>2011-09-23 14:10:53 +0200
commit524ad34276ef31fc5c306943539e3fe9bd19ad8c (patch)
treeb6d497f9461375b02527bc3d1f10c7a58f3e38e0 /lib/hipe
parent3f9de4601b8539eea14de2d1517f54956e05d03a (diff)
parent92657321ac647f343c6b88985d66a2d611fd982d (diff)
downloadotp-524ad34276ef31fc5c306943539e3fe9bd19ad8c.tar.gz
otp-524ad34276ef31fc5c306943539e3fe9bd19ad8c.tar.bz2
otp-524ad34276ef31fc5c306943539e3fe9bd19ad8c.zip
Merge branch 'major' of super:otp into bmk/inets/inets58_integration
Diffstat (limited to 'lib/hipe')
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl100
-rw-r--r--lib/hipe/cerl/erl_types.erl16
-rw-r--r--lib/hipe/icode/hipe_beam_to_icode.erl2
-rw-r--r--lib/hipe/regalloc/hipe_node_sets.erl2
-rw-r--r--lib/hipe/rtl/hipe_rtl_lcm.erl2
5 files changed, 91 insertions, 31 deletions
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index 43c2ac2615..1483b2aee1 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -366,7 +366,7 @@ type(erlang, '>', 2, Xs = [Lhs, Rhs]) ->
is_integer(LhsMax), is_integer(RhsMin), RhsMin >= LhsMax -> F;
true -> t_boolean()
end;
- false -> t_boolean()
+ false -> compare('>', Lhs, Rhs)
end,
strict(Xs, Ans);
type(erlang, '>=', 2, Xs = [Lhs, Rhs]) ->
@@ -384,7 +384,7 @@ type(erlang, '>=', 2, Xs = [Lhs, Rhs]) ->
is_integer(LhsMax), is_integer(RhsMin), RhsMin > LhsMax -> F;
true -> t_boolean()
end;
- false -> t_boolean()
+ false -> compare('>=', Lhs, Rhs)
end,
strict(Xs, Ans);
type(erlang, '<', 2, Xs = [Lhs, Rhs]) ->
@@ -402,7 +402,7 @@ type(erlang, '<', 2, Xs = [Lhs, Rhs]) ->
is_integer(LhsMin), is_integer(RhsMax), RhsMax =< LhsMin -> F;
true -> t_boolean()
end;
- false -> t_boolean()
+ false -> compare('<', Lhs, Rhs)
end,
strict(Xs, Ans);
type(erlang, '=<', 2, Xs = [Lhs, Rhs]) ->
@@ -420,7 +420,7 @@ type(erlang, '=<', 2, Xs = [Lhs, Rhs]) ->
is_integer(LhsMin), is_integer(RhsMax), RhsMax < LhsMin -> F;
true -> t_boolean()
end;
- false -> t_boolean()
+ false -> compare('=<', Lhs, Rhs)
end,
strict(Xs, Ans);
type(erlang, '+', 1, Xs) ->
@@ -737,6 +737,7 @@ type(erlang, element, 2, Xs) ->
type(erlang, erase, 0, _) -> t_any();
type(erlang, erase, 1, _) -> t_any();
type(erlang, external_size, 1, _) -> t_integer();
+type(erlang, external_size, 2, _) -> t_integer();
type(erlang, finish_after_on_load, 2, Xs) ->
%% Internal BIF used by on_load.
strict(arg_types(erlang, finish_after_on_load, 2), Xs,
@@ -1201,6 +1202,7 @@ type(erlang, process_flag, 2, Xs) ->
case t_atom_vals(Flag) of
['error_handler'] -> t_atom();
['min_heap_size'] -> t_non_neg_integer();
+ ['scheduler'] -> t_non_neg_integer();
['monitor_nodes'] -> t_boolean();
['priority'] -> t_process_priority_level();
['save_calls'] -> t_non_neg_integer();
@@ -1901,7 +1903,7 @@ type(prim_file, internal_native2name, 1, Xs) ->
fun (_) -> t_prim_file_name() end);
type(prim_file, internal_normalize_utf8, 1, Xs) ->
strict(arg_types(prim_file, internal_normalize_utf8, 1), Xs,
- fun (_) -> t_binary() end);
+ fun (_) -> t_unicode_string() end);
%%-- gen_tcp ------------------------------------------------------------------
%% NOTE: All type information for this module added to avoid loss of precision
type(gen_tcp, accept, 1, Xs) ->
@@ -2326,10 +2328,7 @@ type(lists, keyfind, 3, Xs) ->
case t_tuple_subtypes(Tuple) of
unknown -> Ret;
List ->
- Keys = [type(erlang, element, 2, [Y, S])
- || S <- List],
- Infs = [t_inf(Key, X) || Key <- Keys],
- case all_is_none(Infs) of
+ case key_comparisons_fail(X, Y, List) of
true -> t_atom('false');
false -> Ret
end
@@ -2359,9 +2358,7 @@ type(lists, keymember, 3, Xs) ->
case t_tuple_subtypes(Tuple) of
unknown -> t_boolean();
List ->
- Keys = [type(erlang, element, 2, [Y,S]) || S <- List],
- Infs = [t_inf(Key, X) || Key <- Keys],
- case all_is_none(Infs) of
+ case key_comparisons_fail(X, Y, List) of
true -> t_atom('false');
false -> t_boolean()
end
@@ -2391,10 +2388,7 @@ type(lists, keysearch, 3, Xs) ->
case t_tuple_subtypes(Tuple) of
unknown -> Ret;
List ->
- Keys = [type(erlang, element, 2, [Y, S])
- || S <- List],
- Infs = [t_inf(Key, X) || Key <- Keys],
- case all_is_none(Infs) of
+ case key_comparisons_fail(X, Y, List) of
true -> t_atom('false');
false -> Ret
end
@@ -2822,9 +2816,6 @@ list_replace(1, E, [_X | Xs]) ->
any_is_none_or_unit(Ts) ->
lists:any(fun erl_types:t_is_none_or_unit/1, Ts).
-all_is_none(Ts) ->
- lists:all(fun erl_types:t_is_none/1, Ts).
-
check_guard([X], Test, Type) ->
check_guard_single(X, Test, Type).
@@ -3177,6 +3168,59 @@ arith(Op, X1, X2) ->
end.
%%=============================================================================
+%% Comparison of terms
+%%=============================================================================
+
+compare(Op, Lhs, Rhs) ->
+ case t_is_none(t_inf(Lhs, Rhs)) of
+ false -> t_boolean();
+ true ->
+ case Op of
+ '<' -> always_smaller(Lhs, Rhs);
+ '>' -> always_smaller(Rhs, Lhs);
+ '=<' -> always_smaller(Lhs, Rhs);
+ '>=' -> always_smaller(Rhs, Lhs)
+ end
+ end.
+
+always_smaller(Type1, Type2) ->
+ {Min1, Max1} = type_ranks(Type1),
+ {Min2, Max2} = type_ranks(Type2),
+ if Max1 < Min2 -> t_atom('true');
+ Min1 > Max2 -> t_atom('false');
+ true -> t_boolean()
+ end.
+
+type_ranks(Type) ->
+ type_ranks(Type, 1, 0, 0, type_order()).
+
+type_ranks(_Type, _I, Min, Max, []) -> {Min, Max};
+type_ranks(Type, I, Min, Max, [TypeClass|Rest]) ->
+ {NewMin, NewMax} =
+ case t_is_none(t_inf(Type, TypeClass)) of
+ true -> {Min, Max};
+ false -> case Min of
+ 0 -> {I, I};
+ _ -> {Min, I}
+ end
+ end,
+ type_ranks(Type, I+1, NewMin, NewMax, Rest).
+
+type_order() ->
+ [t_number(), t_atom(), t_reference(), t_fun(), t_port(), t_pid(), t_tuple(),
+ t_list(), t_binary()].
+
+key_comparisons_fail(X0, KeyPos, TupleList) ->
+ X = case t_is_number(t_inf(X0, t_number())) of
+ false -> X0;
+ true -> t_number()
+ end,
+ lists:all(fun(Tuple) ->
+ Key = type(erlang, element, 2, [KeyPos, Tuple]),
+ t_is_none(t_inf(Key, X))
+ end, TupleList).
+
+%%=============================================================================
-spec arg_types(atom(), atom(), arity()) -> [erl_types:erl_type()] | 'unknown'.
@@ -3443,6 +3487,8 @@ arg_types(erlang, exit, 2) ->
[t_sup(t_pid(), t_port()), t_any()];
arg_types(erlang, external_size, 1) ->
[t_any()]; % takes any term as input
+arg_types(erlang, external_size, 2) ->
+ [t_any(), t_list()]; % takes any term as input and a list of options
arg_types(erlang, finish_after_on_load, 2) ->
[t_atom(), t_boolean()];
arg_types(erlang, float, 1) ->
@@ -3697,6 +3743,7 @@ arg_types(erlang, process_display, 2) ->
arg_types(erlang, process_flag, 2) ->
[t_sup([t_atom('trap_exit'), t_atom('error_handler'),
t_atom('min_heap_size'), t_atom('priority'), t_atom('save_calls'),
+ t_atom('scheduler'), % undocumented
t_atom('monitor_nodes'), % undocumented
t_tuple([t_atom('monitor_nodes'), t_list()])]), % undocumented
t_sup([t_boolean(), t_atom(), t_non_neg_integer()])];
@@ -3738,7 +3785,7 @@ arg_types(erlang, send, 3) ->
arg_types(erlang, send_after, 3) ->
[t_non_neg_integer(), t_sup(t_pid(), t_atom()), t_any()];
arg_types(erlang, seq_trace, 2) ->
- [t_atom(), t_sup([t_boolean(), t_tuple([t_fixnum(), t_fixnum()]), t_nil()])];
+ [t_atom(), t_sup([t_boolean(), t_tuple([t_fixnum(), t_fixnum()]), t_fixnum(), t_nil()])];
arg_types(erlang, seq_trace_info, 1) ->
[t_seq_trace_info()];
arg_types(erlang, seq_trace_print, 1) ->
@@ -3987,7 +4034,7 @@ arg_types(ets, match_object, 3) ->
arg_types(ets, match_spec_compile, 1) ->
[t_matchspecs()];
arg_types(ets, match_spec_run_r, 3) ->
- [t_matchspecs(), t_any(), t_list()];
+ [t_list(t_tuple()),t_matchspecs(), t_list()];
arg_types(ets, member, 2) ->
[t_tab(), t_any()];
arg_types(ets, new, 2) ->
@@ -4019,8 +4066,12 @@ arg_types(ets, select_reverse, 3) ->
arg_types(ets, slot, 2) ->
[t_tab(), t_non_neg_fixnum()]; % 2nd arg can be 0
arg_types(ets, setopts, 2) ->
- Opt = t_sup(t_tuple([t_atom('heir'), t_pid(), t_any()]),
- t_tuple([t_atom('heir'), t_atom('none')])),
+ Opt = t_sup([t_tuple([t_atom('heir'), t_pid(), t_any()]),
+ t_tuple([t_atom('heir'), t_atom('none')]),
+ t_tuple([t_atom('protection'),
+ t_sup([t_atom('protected'),
+ t_atom('private'),
+ t_atom('public')])])]),
[t_tab(), t_sup(Opt, t_list(Opt))];
arg_types(ets, update_counter, 3) ->
Int = t_integer(),
@@ -4812,6 +4863,9 @@ t_ets_info_items() ->
t_atom('owner'),
t_atom('protection'),
t_atom('size'),
+ t_atom('compressed'),
+ t_atom('heir'),
+ t_atom('stats'),
t_atom('type')]).
%% =====================================================================
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index 1748c1cc16..7ff170776e 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -211,7 +211,8 @@
record_field_diffs_to_string/2,
subst_all_vars_to_any/1,
lift_list_to_pos_empty/1,
- is_erl_type/1
+ is_erl_type/1,
+ atom_to_string/1
]).
%%-define(DO_ERL_TYPES_TEST, true).
@@ -3360,14 +3361,14 @@ t_to_string(?var(Id), _RecDict) when is_integer(Id) ->
record_to_string(Tag, [_|Fields], FieldNames, RecDict) ->
FieldStrings = record_fields_to_string(Fields, FieldNames, RecDict, []),
- "#" ++ atom_to_list(Tag) ++ "{" ++ string:join(FieldStrings, ",") ++ "}".
+ "#" ++ atom_to_string(Tag) ++ "{" ++ string:join(FieldStrings, ",") ++ "}".
record_fields_to_string([F|Fs], [{FName, _DefType}|FDefs], RecDict, Acc) ->
NewAcc =
case t_is_any(F) orelse t_is_atom('undefined', F) of
true -> Acc;
false ->
- StrFV = atom_to_list(FName) ++ "::" ++ t_to_string(F, RecDict),
+ StrFV = atom_to_string(FName) ++ "::" ++ t_to_string(F, RecDict),
%% ActualDefType = t_subtract(DefType, t_atom('undefined')),
%% Str = case t_is_any(ActualDefType) of
%% true -> StrFV;
@@ -3393,7 +3394,7 @@ field_diffs([F|Fs], [{FName, DefType}|FDefs], RecDict, Acc) ->
case t_is_subtype(F, DefType) of
true -> Acc;
false ->
- Str = atom_to_list(FName) ++ "::" ++ t_to_string(DefType, RecDict),
+ Str = atom_to_string(FName) ++ "::" ++ t_to_string(DefType, RecDict),
[Str|Acc]
end,
field_diffs(Fs, FDefs, RecDict, NewAcc);
@@ -3906,7 +3907,7 @@ t_form_to_string({type, _L, union, Args}) ->
string:join(t_form_to_string_list(Args), " | ");
t_form_to_string({type, _L, Name, []} = T) ->
try t_to_string(t_from_form(T))
- catch throw:{error, _} -> atom_to_list(Name) ++ "()"
+ catch throw:{error, _} -> atom_to_string(Name) ++ "()"
end;
t_form_to_string({type, _L, Name, List}) ->
io_lib:format("~w(~s)",
@@ -3920,6 +3921,11 @@ t_form_to_string_list([H|T], Acc) ->
t_form_to_string_list([], Acc) ->
lists:reverse(Acc).
+-spec atom_to_string(atom()) -> string().
+
+atom_to_string(Atom) ->
+ lists:flatten(io_lib:format("~w", [Atom])).
+
%%=============================================================================
%%
%% Utilities
diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl
index f557d3419e..45b390acbd 100644
--- a/lib/hipe/icode/hipe_beam_to_icode.erl
+++ b/lib/hipe/icode/hipe_beam_to_icode.erl
@@ -724,7 +724,7 @@ trans_fun([{test,bs_get_float2,{f,Lbl},[Ms,_Live,Size,Unit,{field_flags,Flags0},
?EXIT({bad_bs_size_constant,Size});
BitReg ->
Bits = mk_var(BitReg),
- {{bs_get_float,Unit,Flags}, [Bits,MsVar]}
+ {{bs_get_float,Unit,Flags}, [MsVar,Bits]}
end,
trans_op_call({hipe_bs_primop,Name}, Lbl, Args, [Dst,MsVar], Env, Instructions);
trans_fun([{test,bs_get_integer2,{f,Lbl},[Ms,_Live,Size,Unit,{field_flags,Flags0},X]}|
diff --git a/lib/hipe/regalloc/hipe_node_sets.erl b/lib/hipe/regalloc/hipe_node_sets.erl
index b5e2971c4d..0bb21d7506 100644
--- a/lib/hipe/regalloc/hipe_node_sets.erl
+++ b/lib/hipe/regalloc/hipe_node_sets.erl
@@ -29,7 +29,7 @@
-record(node_sets,
{spilled, % Nodes marked for spilling
- colored % Nodes succesfully colored
+ colored % Nodes successfully colored
}).
spilled(Node_sets) -> Node_sets#node_sets.spilled.
diff --git a/lib/hipe/rtl/hipe_rtl_lcm.erl b/lib/hipe/rtl/hipe_rtl_lcm.erl
index 5d65389d48..d45ab4ed46 100644
--- a/lib/hipe/rtl/hipe_rtl_lcm.erl
+++ b/lib/hipe/rtl/hipe_rtl_lcm.erl
@@ -269,7 +269,7 @@ insert_expr_last(CFG0, Label, Instr) ->
%% is a branch operation).
insert_expr_last_work(_, Instr, []) ->
%% This case should not happen since this means that block was completely
- %% empty when the function was called. For compability we insert it last.
+ %% empty when the function was called. For compatibility we insert it last.
[Instr];
insert_expr_last_work(_, Instr, [Code1]) ->
%% We insert the code next to last.