aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe')
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl398
-rw-r--r--lib/hipe/cerl/erl_types.erl53
-rw-r--r--lib/hipe/doc/src/notes.xml127
-rw-r--r--lib/hipe/doc/src/ref_man.xml2
-rw-r--r--lib/hipe/icode/hipe_beam_to_icode.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_callgraph.erl8
-rw-r--r--lib/hipe/icode/hipe_icode_exceptions.erl2
-rw-r--r--lib/hipe/icode/hipe_icode_primops.erl13
-rw-r--r--lib/hipe/icode/hipe_icode_range.erl366
-rw-r--r--lib/hipe/main/hipe.erl27
-rw-r--r--lib/hipe/main/hipe_main.erl12
-rw-r--r--lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl2
-rw-r--r--lib/hipe/rtl/hipe_rtl.erl7
-rw-r--r--lib/hipe/rtl/hipe_rtl_arith.inc9
-rw-r--r--lib/hipe/rtl/hipe_rtl_primops.erl2
-rw-r--r--lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl45
-rw-r--r--lib/hipe/rtl/hipe_tagscheme.erl2
-rw-r--r--lib/hipe/tools/hipe_tool.erl40
-rw-r--r--lib/hipe/vsn.mk2
19 files changed, 530 insertions, 593 deletions
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index 835f9a205a..30b911c41b 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -48,6 +48,7 @@
t_boolean/0,
t_byte/0,
t_char/0,
+ t_charlist/0,
t_cons/0,
t_cons/2,
t_cons_hd/1,
@@ -124,7 +125,8 @@
t_tuple/1,
t_tuple_args/1,
t_tuple_size/1,
- t_tuple_subtypes/1
+ t_tuple_subtypes/1,
+ t_unicode_string/0
]).
-ifdef(DO_ERL_BIF_TYPES_TEST).
@@ -189,127 +191,19 @@ type(binary, referenced_byte_size, 1, Xs) ->
strict(arg_types(binary, referenced_byte_size, 1), Xs,
fun(_) -> t_non_neg_integer() end);
%%-- code ---------------------------------------------------------------------
-type(code, add_path, 1, Xs) ->
- strict(arg_types(code, add_path, 1), Xs,
- fun (_) ->
- t_sup(t_boolean(),
- t_tuple([t_atom('error'), t_atom('bad_directory')]))
- end);
-type(code, add_patha, 1, Xs) ->
- type(code, add_path, 1, Xs);
-type(code, add_paths, 1, Xs) ->
- strict(arg_types(code, add_paths, 1), Xs, fun(_) -> t_atom('ok') end);
-type(code, add_pathsa, 1, Xs) ->
- type(code, add_paths, 1, Xs);
-type(code, add_pathsz, 1, Xs) ->
- type(code, add_paths, 1, Xs);
-type(code, add_pathz, 1, Xs) ->
- type(code, add_path, 1, Xs);
-type(code, all_loaded, 0, _) ->
- t_list(t_tuple([t_atom(), t_code_loaded_fname_or_status()]));
-type(code, compiler_dir, 0, _) ->
- t_string();
-type(code, del_path, 1, Xs) ->
- strict(arg_types(code, del_path, 1), Xs,
- fun (_) ->
- t_sup(t_boolean(),
- t_tuple([t_atom('error'), t_atom('bad_name')]))
- end);
-type(code, delete, 1, Xs) ->
- strict(arg_types(code, delete, 1), Xs, fun (_) -> t_boolean() end);
-type(code, ensure_loaded, 1, Xs) ->
- type(code, load_file, 1, Xs);
type(code, get_chunk, 2, Xs) ->
strict(arg_types(code, get_chunk, 2), Xs,
fun (_) -> t_sup(t_binary(), t_atom('undefined')) end);
-type(code, get_object_code, 1, Xs) ->
- strict(arg_types(code, get_object_code, 1), Xs,
- fun (_) ->
- t_sup(t_tuple([t_atom(), t_binary(), t_string()]),
- t_atom('error'))
- end);
-type(code, get_path, 0, _) ->
- t_list(t_string());
-type(code, is_loaded, 1, Xs) ->
- strict(arg_types(code, is_loaded, 1), Xs,
- fun (_) ->
- t_sup([t_tuple([t_atom('file'), t_code_loaded_fname_or_status()]),
- t_atom('false')])
- end);
-type(code, is_sticky, 1, Xs) ->
- strict(arg_types(code, is_sticky, 1), Xs, fun (_) -> t_boolean() end);
type(code, is_module_native, 1, Xs) ->
strict(arg_types(code, is_module_native, 1), Xs,
fun (_) -> t_sup(t_boolean(), t_atom('undefined')) end);
-type(code, lib_dir, 0, _) ->
- t_string();
-type(code, lib_dir, 1, Xs) ->
- strict(arg_types(code, lib_dir, 1), Xs,
- fun (_) ->
- t_sup(t_string(),
- t_tuple([t_atom('error'), t_atom('bad_name')]))
- end);
-type(code, load_abs, 1, Xs) ->
- strict(arg_types(code, load_abs, 1), Xs,
- fun ([_File]) -> t_code_load_return(t_atom()) end); % XXX: cheating
-type(code, load_abs, 2, Xs) ->
- strict(arg_types(code, load_abs, 2), Xs,
- fun ([_File,Mod]) -> t_code_load_return(Mod) end);
-type(code, load_binary, 3, Xs) ->
- strict(arg_types(code, load_binary, 3), Xs,
- fun ([Mod,_File,_Bin]) -> t_code_load_return(Mod) end);
-type(code, load_file, 1, Xs) ->
- strict(arg_types(code, load_file, 1), Xs,
- fun ([Mod]) -> t_code_load_return(Mod) end);
-type(code, load_native_partial, 2, Xs) ->
- strict(arg_types(code, load_native_partial, 2), Xs,
- fun ([Mod,_Bin]) -> t_code_load_return(Mod) end);
-type(code, load_native_sticky, 3, Xs) ->
- strict(arg_types(code, load_native_sticky, 3), Xs,
- fun ([Mod,_Bin,_]) -> t_code_load_return(Mod) end);
type(code, module_md5, 1, Xs) ->
strict(arg_types(code, module_md5, 1), Xs,
fun (_) -> t_sup(t_binary(), t_atom('undefined')) end);
type(code, make_stub_module, 3, Xs) ->
strict(arg_types(code, make_stub_module, 3), Xs, fun ([Mod,_,_]) -> Mod end);
-type(code, priv_dir, 1, Xs) ->
- strict(arg_types(code, priv_dir, 1), Xs,
- fun (_) ->
- t_sup(t_string(), t_tuple([t_atom('error'), t_atom('bad_name')]))
- end);
-type(code, purge, 1, Xs) ->
- type(code, delete, 1, Xs);
-type(code, rehash, 0, _) -> t_atom('ok');
-type(code, replace_path, 2, Xs) ->
- strict(arg_types(code, replace_path, 2), Xs,
- fun (_) ->
- t_sup([t_atom('true'),
- t_tuple([t_atom('error'), t_atom('bad_name')]),
- t_tuple([t_atom('error'), t_atom('bad_directory')]),
- t_tuple([t_atom('error'),
- t_tuple([t_atom('badarg'), t_any()])])])
- end);
-type(code, root_dir, 0, _) ->
- t_string();
-type(code, set_path, 1, Xs) ->
- strict(arg_types(code, set_path, 1), Xs,
- fun (_) ->
- t_sup([t_atom('true'),
- t_tuple([t_atom('error'), t_atom('bad_path')]),
- t_tuple([t_atom('error'), t_atom('bad_directory')])])
- end);
-type(code, soft_purge, 1, Xs) ->
- type(code, delete, 1, Xs);
-type(code, stick_mod, 1, Xs) ->
- strict(arg_types(code, stick_mod, 1), Xs, fun (_) -> t_atom('true') end);
-type(code, unstick_mod, 1, Xs) ->
- type(code, stick_mod, 1, Xs);
-type(code, which, 1, Xs) ->
- strict(arg_types(code, which, 1), Xs,
- fun (_) ->
- t_sup([t_code_loaded_fname_or_status(),
- t_atom('non_existing')])
- end);
+type(code, rehash, 0, _) ->
+ t_atom('ok');
%%-- erl_ddll -----------------------------------------------------------------
type(erl_ddll, demonitor, 1, Xs) ->
type(erlang, demonitor, 1, Xs);
@@ -1865,6 +1759,8 @@ type(erts_debug, flat_size, 1, Xs) ->
strict(arg_types(erts_debug, flat_size, 1), Xs, fun (_) -> t_integer() end);
type(erts_debug, get_internal_state, 1, _) ->
t_any();
+type(erts_debug, instructions, 0, _) ->
+ t_list(t_list(t_byte()));
type(erts_debug, lock_counters, 1, Xs) ->
strict(arg_types(erts_debug, lock_counters, 1), Xs,
fun ([Arg]) ->
@@ -1992,34 +1888,18 @@ type(ets, update_counter, 3, Xs) ->
type(ets, update_element, 3, Xs) ->
strict(arg_types(ets, update_element, 3), Xs, fun (_) -> t_boolean() end);
%%-- file ---------------------------------------------------------------------
-type(file, close, 1, Xs) ->
- strict(arg_types(file, close, 1), Xs, fun (_) -> t_file_return() end);
-type(file, delete, 1, Xs) ->
- strict(arg_types(file, delete, 1), Xs, fun (_) -> t_file_return() end);
-type(file, get_cwd, 0, _) ->
- t_sup(t_tuple([t_atom('ok'), t_string()]),
- t_tuple([t_atom('error'), t_file_posix_error()]));
-type(file, make_dir, 1, Xs) ->
- strict(arg_types(file, make_dir, 1), Xs, fun (_) -> t_file_return() end);
-type(file, open, 2, Xs) ->
- strict(arg_types(file, open, 2), Xs,
- fun (_) ->
- t_sup([t_tuple([t_atom('ok'), t_file_io_device()]),
- t_tuple([t_atom('error'), t_file_posix_error()])])
- end);
-type(file, read_file, 1, Xs) ->
- strict(arg_types(file, read_file, 1), Xs,
- fun (_) ->
- t_sup([t_tuple([t_atom('ok'), t_binary()]),
- t_tuple([t_atom('error'), t_file_posix_error()])])
- end);
-type(file, set_cwd, 1, Xs) ->
- strict(arg_types(file, set_cwd, 1), Xs,
- fun (_) -> t_sup(t_atom('ok'),
- t_tuple([t_atom('error'), t_file_posix_error()]))
- end);
-type(file, write_file, 2, Xs) ->
- strict(arg_types(file, write_file, 2), Xs, fun (_) -> t_file_return() end);
+type(file, native_name_encoding, 0, _) ->
+ t_file_encoding();
+%%-- prim_file ----------------------------------------------------------------
+type(prim_file, internal_name2native, 1, Xs) ->
+ strict(arg_types(prim_file, internal_name2native, 1), Xs,
+ fun (_) -> t_binary() end);
+type(prim_file, internal_native2name, 1, Xs) ->
+ strict(arg_types(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);
%%-- gen_tcp ------------------------------------------------------------------
%% NOTE: All type information for this module added to avoid loss of precision
type(gen_tcp, accept, 1, Xs) ->
@@ -3346,80 +3226,16 @@ arg_types(binary, part, 3) ->
arg_types(binary, referenced_byte_size, 1) ->
[t_binary()];
%%------- code ----------------------------------------------------------------
-arg_types(code, add_path, 1) ->
- [t_string()];
-arg_types(code, add_patha, 1) ->
- arg_types(code, add_path, 1);
-arg_types(code, add_paths, 1) ->
- [t_list(t_string())];
-arg_types(code, add_pathsa, 1) ->
- arg_types(code, add_paths, 1);
-arg_types(code, add_pathsz, 1) ->
- arg_types(code, add_paths, 1);
-arg_types(code, add_pathz, 1) ->
- arg_types(code, add_path, 1);
-arg_types(code, all_loaded, 0) ->
- [];
-arg_types(code, compiler_dir, 0) ->
- [];
-arg_types(code, del_path, 1) ->
- [t_sup(t_string(), t_atom())]; % OBS: doc differs from add_path/1 - why?
-arg_types(code, delete, 1) ->
- [t_atom()];
-arg_types(code, ensure_loaded, 1) ->
- arg_types(code, load_file, 1);
arg_types(code, get_chunk, 2) ->
[t_binary(), t_string()];
-arg_types(code, get_object_code, 1) ->
- [t_atom()];
-arg_types(code, get_path, 0) ->
- [];
-arg_types(code, is_loaded, 1) ->
- [t_atom()];
-arg_types(code, is_sticky, 1) ->
- [t_atom()];
arg_types(code, is_module_native, 1) ->
[t_atom()];
-arg_types(code, lib_dir, 0) ->
- [];
-arg_types(code, lib_dir, 1) ->
- [t_atom()];
-arg_types(code, load_abs, 1) ->
- [t_string()];
-arg_types(code, load_abs, 2) ->
- [t_code_loaded_fname_or_status(), t_atom()];
-arg_types(code, load_binary, 3) ->
- [t_atom(), t_code_loaded_fname_or_status(), t_binary()];
-arg_types(code, load_file, 1) ->
- [t_atom()];
-arg_types(code, load_native_partial, 2) ->
- [t_atom(), t_binary()];
-arg_types(code, load_native_sticky, 3) ->
- [t_atom(), t_binary(), t_sup(t_binary(), t_atom('false'))];
arg_types(code, module_md5, 1) ->
[t_binary()];
arg_types(code, make_stub_module, 3) ->
[t_atom(), t_binary(), t_tuple([t_list(), t_list()])];
-arg_types(code, priv_dir, 1) ->
- [t_atom()];
-arg_types(code, purge, 1) ->
- arg_types(code, delete, 1);
arg_types(code, rehash, 0) ->
[];
-arg_types(code, replace_path, 2) ->
- [t_atom(), t_string()];
-arg_types(code, root_dir, 0) ->
- [];
-arg_types(code, set_path, 1) ->
- [t_string()];
-arg_types(code, soft_purge, 1) ->
- arg_types(code, delete, 1);
-arg_types(code, stick_mod, 1) ->
- [t_atom()];
-arg_types(code, unstick_mod, 1) ->
- arg_types(code, stick_mod, 1);
-arg_types(code, which, 1) ->
- [t_atom()];
%%------- erl_ddll ------------------------------------------------------------
arg_types(erl_ddll, demonitor, 1) ->
arg_types(erlang, demonitor, 1);
@@ -3548,9 +3364,9 @@ arg_types(erlang, atom_to_binary, 2) ->
arg_types(erlang, atom_to_list, 1) ->
[t_atom()];
arg_types(erlang, binary_part, 2) ->
- [t_binary(), t_tuple([t_integer(),t_integer()])];
+ [t_binary(), t_tuple([t_non_neg_integer(), t_integer()])];
arg_types(erlang, binary_part, 3) ->
- [t_binary(), t_integer(), t_integer()];
+ [t_binary(), t_non_neg_integer(), t_integer()];
arg_types(erlang, binary_to_atom, 2) ->
[t_binary(), t_encoding_a2b()];
arg_types(erlang, binary_to_existing_atom, 2) ->
@@ -3813,9 +3629,10 @@ arg_types(erlang, nodes, 1) ->
arg_types(erlang, now, 0) ->
[];
arg_types(erlang, open_port, 2) ->
+ ArgT = t_sup(t_unicode_string(), t_binary()),
[t_sup(t_atom(), t_sup([t_tuple([t_atom('spawn'), t_string()]),
t_tuple([t_atom('spawn_driver'), t_string()]),
- t_tuple([t_atom('spawn_executable'), t_string()]),
+ t_tuple([t_atom('spawn_executable'), ArgT]),
t_tuple([t_atom('fd'), t_integer(), t_integer()])])),
t_list(t_sup(t_sup([t_atom('stream'),
t_atom('exit_status'),
@@ -3831,8 +3648,8 @@ arg_types(erlang, open_port, 2) ->
t_tuple([t_atom('line'), t_integer()]),
t_tuple([t_atom('cd'), t_string()]),
t_tuple([t_atom('env'), t_list(t_tuple(2))]), % XXX: More
- t_tuple([t_atom('args'), t_list(t_string())]),
- t_tuple([t_atom('arg0'), t_string()])])))];
+ t_tuple([t_atom('args'), t_list(ArgT)]),
+ t_tuple([t_atom('arg0'), ArgT])])))];
arg_types(erlang, phash, 2) ->
[t_any(), t_pos_integer()];
arg_types(erlang, phash2, 1) ->
@@ -4107,6 +3924,8 @@ arg_types(erts_debug, flat_size, 1) ->
[t_any()];
arg_types(erts_debug, get_internal_state, 1) ->
[t_any()];
+arg_types(erts_debug, instructions, 0) ->
+ [];
arg_types(erts_debug, lock_counters, 1) ->
[t_sup([t_atom(enabled),
t_atom(info),
@@ -4206,24 +4025,15 @@ arg_types(ets, update_element, 3) ->
PosValue = t_tuple([t_integer(), t_any()]),
[t_tab(), t_any(), t_sup(PosValue, t_list(PosValue))];
%%------- file ----------------------------------------------------------------
-arg_types(file, close, 1) ->
- [t_file_io_device()];
-arg_types(file, delete, 1) ->
- [t_file_name()];
-arg_types(file, get_cwd, 0) ->
+arg_types(file, native_name_encoding, 0) ->
[];
-arg_types(file, make_dir, 1) ->
- [t_file_name()];
-arg_types(file, open, 2) ->
- [t_file_name(), t_list(t_file_open_option())];
-arg_types(file, read_file, 1) ->
- [t_file_name()];
-arg_types(file, set_cwd, 1) ->
- [t_file_name()];
-arg_types(file, write, 2) ->
- [t_file_io_device(), t_iodata()];
-arg_types(file, write_file, 2) ->
- [t_file_name(), t_sup(t_binary(), t_list())];
+%%-- prim_file ----------------------------------------------------------------
+arg_types(prim_file, internal_name2native, 1) ->
+ [t_prim_file_name()];
+arg_types(prim_file, internal_native2name, 1) ->
+ [t_binary()];
+arg_types(prim_file, internal_normalize_utf8, 1) ->
+ [t_binary()];
%%------- gen_tcp -------------------------------------------------------------
arg_types(gen_tcp, accept, 1) ->
[t_socket()];
@@ -4542,11 +4352,11 @@ arg_types(os, timestamp, 0) ->
arg_types(re, compile, 1) ->
[t_iodata()];
arg_types(re, compile, 2) ->
- [t_iodata(), t_list(t_re_compile_option())];
+ [t_sup(t_iodata(), t_charlist()), t_list(t_re_compile_option())];
arg_types(re, run, 2) ->
- [t_iodata(), t_re_RE()];
+ [t_sup(t_iodata(), t_charlist()), t_re_RE()];
arg_types(re, run, 3) ->
- [t_iodata(), t_re_RE(), t_list(t_re_run_option())];
+ [t_sup(t_iodata(), t_charlist()), t_re_RE(), t_list(t_re_run_option())];
%%------- string --------------------------------------------------------------
arg_types(string, chars, 2) ->
[t_char(), t_non_neg_integer()];
@@ -4655,17 +4465,17 @@ t_httppacket() ->
t_HttpHeader(), t_atom('http_eoh'), t_HttpError()]).
t_endian() ->
- t_sup([t_atom('big'), t_atom('little')]).
+ t_sup(t_atom('big'), t_atom('little')).
%% =====================================================================
%% Types for the binary module
%% =====================================================================
t_binary_part() ->
- t_tuple([t_non_neg_integer(),t_integer()]).
+ t_tuple([t_non_neg_integer(), t_integer()]).
t_binary_canonical_part() ->
- t_tuple([t_non_neg_integer(),t_non_neg_integer()]).
+ t_tuple([t_non_neg_integer(), t_non_neg_integer()]).
t_binary_pattern() ->
t_sup([t_binary(),
@@ -4673,10 +4483,10 @@ t_binary_pattern() ->
t_binary_compiled_pattern()]).
t_binary_compiled_pattern() ->
- t_tuple([t_atom('cp'),t_binary()]).
+ t_tuple([t_atom('cp'), t_binary()]).
t_binary_options() ->
- t_list(t_tuple([t_atom('scope'),t_binary_part()])).
+ t_list(t_tuple([t_atom('scope'), t_binary_part()])).
%% =====================================================================
%% HTTP types documented in R12B-4
@@ -4686,16 +4496,16 @@ t_HttpRequest() ->
t_tuple([t_atom('http_request'), t_HttpMethod(), t_HttpUri(), t_HttpVersion()]).
t_HttpResponse() ->
- t_tuple([t_atom('http_response'), t_HttpVersion(), t_integer(), t_string()]).
+ t_tuple([t_atom('http_response'), t_HttpVersion(), t_integer(), t_HttpString()]).
t_HttpHeader() ->
- t_tuple([t_atom('http_header'), t_integer(), t_HttpField(), t_any(), t_string()]).
+ t_tuple([t_atom('http_header'), t_integer(), t_HttpField(), t_any(), t_HttpString()]).
t_HttpError() ->
- t_tuple([t_atom('http_error'), t_string()]).
+ t_tuple([t_atom('http_error'), t_HttpString()]).
t_HttpMethod() ->
- t_sup(t_HttpMethodAtom(), t_string()).
+ t_sup(t_HttpMethodAtom(), t_HttpString()).
t_HttpMethodAtom() ->
t_atoms(['OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE']).
@@ -4704,18 +4514,18 @@ t_HttpUri() ->
t_sup([t_atom('*'),
t_tuple([t_atom('absoluteURI'),
t_sup(t_atom('http'), t_atom('https')),
- t_string(),
+ t_HttpString(),
t_sup(t_non_neg_integer(), t_atom('undefined')),
- t_string()]),
- t_tuple([t_atom('scheme'), t_string(), t_string()]),
- t_tuple([t_atom('abs_path'), t_string()]),
- t_string()]).
+ t_HttpString()]),
+ t_tuple([t_atom('scheme'), t_HttpString(), t_HttpString()]),
+ t_tuple([t_atom('abs_path'), t_HttpString()]),
+ t_HttpString()]).
t_HttpVersion() ->
t_tuple([t_non_neg_integer(), t_non_neg_integer()]).
t_HttpField() ->
- t_sup(t_HttpFieldAtom(), t_string()).
+ t_sup(t_HttpFieldAtom(), t_HttpString()).
t_HttpFieldAtom() ->
t_atoms(['Cache-Control', 'Connection', 'Date', 'Pragma', 'Transfer-Encoding',
@@ -4732,6 +4542,9 @@ t_HttpFieldAtom() ->
'Set-Cookie', 'Set-Cookie2', 'X-Forwarded-For', 'Cookie',
'Keep-Alive', 'Proxy-Connection']).
+t_HttpString() ->
+ t_sup(t_string(),t_binary()).
+
%% =====================================================================
%% These are used for the built-in functions of 'code'
%% =====================================================================
@@ -4823,7 +4636,8 @@ t_process_priority_level() ->
t_sup([t_atom('max'), t_atom('high'), t_atom('normal'), t_atom('low')]).
t_process_status() ->
- t_sup([t_atom('runnable'), t_atom('running'),
+ t_sup([t_atom('exiting'), t_atom('garbage_collecting'),
+ t_atom('runnable'), t_atom('running'),
t_atom('suspended'), t_atom('waiting')]).
t_raise_errorclass() ->
@@ -4962,10 +4776,11 @@ t_matchres() ->
%% From the 'ets' documentation
%%-----------------------------
%% Option = Type | Access | named_table | {keypos,Pos}
-%% | {heir,pid(),HeirData} | {heir,none}
-%% | {write_concurrency,boolean()}
+%% | {heir,pid(),HeirData} | {heir,none} | Tweaks
%% Type = set | ordered_set | bag | duplicate_bag
%% Access = public | protected | private
+%% Tweaks = {write_concurrency,boolean()}
+%% | {read_concurrency,boolean()} | compressed
%% Pos = integer()
%% HeirData = term()
t_ets_new_options() ->
@@ -4977,10 +4792,12 @@ t_ets_new_options() ->
t_atom('protected'),
t_atom('private'),
t_atom('named_table'),
+ t_tuple([t_atom('keypos'), t_integer()]),
t_tuple([t_atom('heir'), t_pid(), t_any()]),
t_tuple([t_atom('heir'), t_atom('none')]),
- t_tuple([t_atom('keypos'), t_integer()]),
- t_tuple([t_atom('write_concurrency'), t_boolean()])])).
+ t_tuple([t_atom('write_concurrency'), t_boolean()]),
+ t_tuple([t_atom('read_concurrency'), t_boolean()]),
+ t_atom('compressed')])).
t_ets_info_items() ->
t_sup([t_atom('fixed'),
@@ -4996,68 +4813,11 @@ t_ets_info_items() ->
t_atom('type')]).
%% =====================================================================
-%% These are used for the built-in functions of 'file'
+%% These are used for the built-in functions of 'prim_file'
%% =====================================================================
-t_file_io_device() ->
- t_sup(t_pid(), t_tuple([t_atom('file_descriptor'), t_atom(), t_any()])).
-
-t_file_name() ->
- t_sup([t_atom(),
- t_string(),
- %% DeepList = [char() | atom() | DeepList] -- approximation below
- t_list(t_sup([t_atom(), t_string(), t_list()]))]).
-
-t_file_open_option() ->
- t_sup([t_atom('read'),
- t_atom('write'),
- t_atom('append'),
- t_atom('raw'),
- t_atom('binary'),
- t_atom('delayed_write'),
- t_atom('read_ahead'),
- t_atom('compressed'),
- t_tuple([t_atom('delayed_write'),
- t_pos_integer(), t_non_neg_integer()]),
- t_tuple([t_atom('read_ahead'), t_pos_integer()])]).
-
-%% This lists all Posix errors that can occur in file:*/* functions
-t_file_posix_error() ->
- t_sup([t_atom('eacces'),
- t_atom('eagain'),
- t_atom('ebadf'),
- t_atom('ebusy'),
- t_atom('edquot'),
- t_atom('eexist'),
- t_atom('efault'),
- t_atom('efbig'),
- t_atom('eintr'),
- t_atom('einval'),
- t_atom('eio'),
- t_atom('eisdir'),
- t_atom('eloop'),
- t_atom('emfile'),
- t_atom('emlink'),
- t_atom('enametoolong'),
- t_atom('enfile'),
- t_atom('enodev'),
- t_atom('enoent'),
- t_atom('enomem'),
- t_atom('enospc'),
- t_atom('enotblk'),
- t_atom('enotdir'),
- t_atom('enotsup'),
- t_atom('enxio'),
- t_atom('eperm'),
- t_atom('epipe'),
- t_atom('erofs'),
- t_atom('espipe'),
- t_atom('esrch'),
- t_atom('estale'),
- t_atom('exdev')]).
-
-t_file_return() ->
- t_sup(t_atom('ok'), t_tuple([t_atom('error'), t_file_posix_error()])).
+t_prim_file_name() ->
+ t_sup(t_unicode_string(), t_binary()).
%% =====================================================================
%% These are used for the built-in functions of 'gen_tcp'
@@ -5214,13 +4974,14 @@ t_re_MP() -> %% it's supposed to be an opaque data type
t_tuple([t_atom('re_pattern'), t_integer(), t_integer(), t_binary()]).
t_re_RE() ->
- t_sup(t_re_MP(), t_iodata()).
+ t_sup([t_re_MP(), t_iodata(), t_charlist()]).
t_re_compile_option() ->
- t_sup([t_atoms(['anchored', 'caseless', 'dollar_endonly', 'dotall',
- 'extended', 'firstline', 'multiline', 'no_auto_capture',
- 'dupnames', 'ungreedy']),
- t_tuple([t_atom('newline'), t_re_NLSpec()])]).
+ t_sup([t_atoms(['unicode', 'anchored', 'caseless', 'dollar_endonly',
+ 'dotall', 'extended', 'firstline', 'multiline',
+ 'no_auto_capture', 'dupnames', 'ungreedy']),
+ t_tuple([t_atom('newline'), t_re_NLSpec()]),
+ t_atoms(['bsr_anycrlf', 'bsr_unicode'])]).
t_re_run_option() ->
t_sup([t_atoms(['anchored', 'global', 'notbol', 'noteol', 'notempty']),
@@ -5237,7 +4998,7 @@ t_re_Type() ->
t_atoms(['index', 'list', 'binary']).
t_re_NLSpec() ->
- t_atoms(['cr', 'crlf', 'lf', 'anycrlf']).
+ t_atoms(['cr', 'crlf', 'lf', 'anycrlf', 'any']).
t_re_ValueSpec() ->
t_sup(t_atoms(['all', 'all_but_first', 'first', 'none']), t_re_ValueList()).
@@ -5259,7 +5020,12 @@ t_ML() -> % a binary or a possibly deep list of integers or binaries
t_sup(t_list(t_sup([t_integer(), t_binary(), t_list()])), t_binary()).
t_encoding() ->
- t_atoms(['latin1', 'unicode', 'utf8', 'utf16', 'utf32']).
+ t_sup([t_atoms(['latin1', 'unicode', 'utf8', 'utf16', 'utf32']),
+ t_tuple([t_atom('utf16'), t_endian()]),
+ t_tuple([t_atom('utf32'), t_endian()])]).
+
+t_file_encoding() ->
+ t_atoms(['latin1', 'utf8']).
t_encoding_a2b() -> % for the 2nd arg of atom_to_binary/2 and binary_to_atom/2
t_atoms(['latin1', 'unicode', 'utf8']).
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index 4dd124a457..080d6936b2 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -62,6 +62,7 @@
t_boolean/0,
t_byte/0,
t_char/0,
+ t_charlist/0,
t_collect_vars/1,
t_cons/0,
t_cons/2,
@@ -195,6 +196,7 @@
t_tuple_size/1,
t_tuple_sizes/1,
t_tuple_subtypes/1,
+ t_unicode_string/0,
t_unify/2,
t_unify/3,
t_unit/0,
@@ -1455,6 +1457,26 @@ t_is_tuple(_) -> false.
%% Non-primitive types, including some handy syntactic sugar types
%%
+-spec t_unicode_string() -> erl_type().
+
+t_unicode_string() ->
+ t_list(t_unicode_char()).
+
+-spec t_charlist() -> erl_type().
+
+t_charlist() ->
+ t_charlist(1).
+
+-spec t_charlist(non_neg_integer()) -> erl_type().
+
+t_charlist(N) when N > 0 ->
+ t_maybe_improper_list(t_sup([t_unicode_char(),
+ t_unicode_binary(),
+ t_charlist(N-1)]),
+ t_sup(t_unicode_binary(), t_nil()));
+t_charlist(0) ->
+ t_maybe_improper_list(t_any(), t_sup(t_unicode_binary(), t_nil())).
+
-spec t_constant() -> erl_type().
t_constant() ->
@@ -1549,6 +1571,16 @@ t_parameterized_module() ->
t_timeout() ->
t_sup(t_non_neg_integer(), t_atom('infinity')).
+-spec t_unicode_binary() -> erl_type().
+
+t_unicode_binary() ->
+ t_binary(). % with characters encoded in UTF-8 coding standard
+
+-spec t_unicode_char() -> erl_type().
+
+t_unicode_char() ->
+ t_integer(). % representing a valid unicode codepoint
+
%%-----------------------------------------------------------------------------
%% Some built-in opaque types
%%
@@ -2127,7 +2159,8 @@ t_elements(?identifier(IDs)) ->
t_elements(?list(_, _, _) = T) -> [T];
t_elements(?number(_, _) = T) ->
case T of
- ?number(?any, ?unknown_qual) -> [T];
+ ?number(?any, ?unknown_qual) ->
+ [?float, ?integer(?any)];
?float -> [T];
?integer(?any) -> [T];
?int_range(_, _) -> [T];
@@ -2174,10 +2207,10 @@ t_inf(?var(_), T, _Mode) -> subst_all_vars_to_any(T);
t_inf(T, ?var(_), _Mode) -> subst_all_vars_to_any(T);
t_inf(?any, T, _Mode) -> subst_all_vars_to_any(T);
t_inf(T, ?any, _Mode) -> subst_all_vars_to_any(T);
-t_inf(?unit, _, _Mode) -> ?unit;
-t_inf(_, ?unit, _Mode) -> ?unit;
t_inf(?none, _, _Mode) -> ?none;
t_inf(_, ?none, _Mode) -> ?none;
+t_inf(?unit, _, _Mode) -> ?unit; % ?unit cases should appear below ?none
+t_inf(_, ?unit, _Mode) -> ?unit;
t_inf(T, T, _Mode) -> subst_all_vars_to_any(T);
t_inf(?atom(Set1), ?atom(Set2), _) ->
case set_intersection(Set1, Set2) of
@@ -2386,10 +2419,12 @@ inf_tuple_sets(L1, L2, Mode) ->
List -> ?tuple_set(List)
end.
-inf_tuple_sets([{Arity, Tuples1}|Left1], [{Arity, Tuples2}|Left2], Acc, Mode) ->
+inf_tuple_sets([{Arity, Tuples1}|Ts1], [{Arity, Tuples2}|Ts2], Acc, Mode) ->
case inf_tuples_in_sets(Tuples1, Tuples2, Mode) of
- [] -> inf_tuple_sets(Left1, Left2, Acc, Mode);
- NewTuples -> inf_tuple_sets(Left1, Left2, [{Arity, NewTuples}|Acc], Mode)
+ [] -> inf_tuple_sets(Ts1, Ts2, Acc, Mode);
+ [?tuple_set([{Arity, NewTuples}])] ->
+ inf_tuple_sets(Ts1, Ts2, [{Arity, NewTuples}|Acc], Mode);
+ NewTuples -> inf_tuple_sets(Ts1, Ts2, [{Arity, NewTuples}|Acc], Mode)
end;
inf_tuple_sets([{Arity1, _}|Ts1] = L1, [{Arity2, _}|Ts2] = L2, Acc, Mode) ->
if Arity1 < Arity2 -> inf_tuple_sets(Ts1, L2, Acc, Mode);
@@ -2766,7 +2801,9 @@ t_subtract_list(T, []) ->
-spec t_subtract(erl_type(), erl_type()) -> erl_type().
t_subtract(_, ?any) -> ?none;
+t_subtract(_, ?var(_)) -> ?none;
t_subtract(?any, _) -> ?any;
+t_subtract(?var(_) = T, _) -> T;
t_subtract(T, ?unit) -> T;
t_subtract(?unit, _) -> ?unit;
t_subtract(?none, _) -> ?none;
@@ -2820,7 +2857,7 @@ t_subtract(?list(Contents1, Termination1, Size1) = T,
true ->
case {Size1, Size2} of
{?nonempty_qual, ?unknown_qual} -> ?none;
- {?unknown_qual, ?nonempty_qual} -> Termination1;
+ {?unknown_qual, ?nonempty_qual} -> ?nil;
{S, S} -> ?none
end;
false ->
@@ -2922,7 +2959,7 @@ t_subtract(T, ?product(_)) ->
T;
t_subtract(?union(U1), ?union(U2)) ->
subtract_union(U1, U2);
-t_subtract(T1, T2) ->
+t_subtract(T1, T2) ->
?union(U1) = force_union(T1),
?union(U2) = force_union(T2),
subtract_union(U1, U2).
diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml
index cf30db0482..434bfac64c 100644
--- a/lib/hipe/doc/src/notes.xml
+++ b/lib/hipe/doc/src/notes.xml
@@ -30,6 +30,133 @@
</header>
<p>This document describes the changes made to HiPE.</p>
+<section><title>Hipe 3.7.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix erroneous fail info of a hipe_bs_primop</p>
+ <p>
+ Own Id: OTP-9036</p>
+ </item>
+ <item>
+ <p>
+ The change fixes a bug in the translation of 'bs_add'
+ BEAM instruction to HiPE's Icode representation. When
+ these instructions appeared in a guard context the
+ previous translation was obviously buggy.</p>
+ <p>
+ Own Id: OTP-9044</p>
+ </item>
+ <item>
+ <p>
+ Sanitize the specs of the code module</p>
+ <p>
+ After the addition of unicode_binary() to the
+ file:filename() type, dialyzer started complaining about
+ erroneous or incomplete specs in some functions of the
+ 'code' module. The culprit was hard-coded information in
+ erl_bif_types for functions of this module, which were
+ not updated. Since these functions have proper specs
+ these days and code duplication (pun intended) is never a
+ good idea, their type information was removed from
+ erl_bif_types.</p>
+ <p>
+ While doing this, some erroneous comments were fixed in
+ the code module and also made sure that the code now runs
+ without dialyzer warnings even when the
+ -Wunmatched_returns option is used.</p>
+ <p>
+ Some cleanups were applied to erl_bif_types too.</p>
+ <p>
+ Own Id: OTP-9100</p>
+ </item>
+ <item>
+ <p>
+ Fix bug in the simplification of inexact comparisons</p>
+ <p>
+ On 31/1/2011 Paul Guyot reported a bug in the native code
+ compilation of inexact equality/inequality tests between
+ floats and integers. The relevant test was:</p>
+ <p>
+ f(X) -&gt; Y = X / 2, Y == 0.</p>
+ <p>
+ and hipe erroneously evaluated the calls f(0) and f(0.0)
+ to 'false'.</p>
+ <p>
+ The culprit was in the simplification code of the Icode
+ range analysis which used an erroneous test (lists:any/1
+ instead of lists:all/1).</p>
+ <p>
+ Own Id: OTP-9101</p>
+ </item>
+ <item>
+ <p>
+ Document exiting and garbage_collecting process statuses</p>
+ <p>
+ Own Id: OTP-9102</p>
+ </item>
+ <item>
+ <p>
+ Remove hipe constants pool</p>
+ <p>
+ Hipe constants used to be allocated within a single,
+ fixed-size pool for interaction with the garbage
+ collector. However, the garbage collector no longer
+ depends on constants being allocated within a single
+ pool, and the fixed size of the pool both meant
+ unnecessary allocations on most deployments and crashes
+ on deployments requiring more constants.</p>
+ <p>
+ The code was simplified to directly invoke erts_alloc.
+ Debugging and undocumented function
+ hipe_bifs:show_literals/0 was removed (it returned true
+ and output text to the console), and debugging and
+ undocumented function hipe_bifs:constants_size/0 was
+ rewritten with a global to count the size of allocated
+ constants.</p>
+ <p>
+ Own Id: OTP-9128</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Hipe 3.7.8.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Several type specifications for standard libraries were
+ wrong in the R14B01 release. This is now corrected. The
+ corrections concern types in re,io,filename and the
+ module erlang itself.</p>
+ <p>
+ Own Id: OTP-9008</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Hipe 3.7.8</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Compiler warnings were eliminated.</p>
+ <p>
+ Own Id: OTP-8855</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Hipe 3.7.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/hipe/doc/src/ref_man.xml b/lib/hipe/doc/src/ref_man.xml
index 09d10147ee..bdafb61d08 100644
--- a/lib/hipe/doc/src/ref_man.xml
+++ b/lib/hipe/doc/src/ref_man.xml
@@ -4,7 +4,7 @@
<application xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl
index 920c94d85c..d7eb035551 100644
--- a/lib/hipe/icode/hipe_beam_to_icode.erl
+++ b/lib/hipe/icode/hipe_beam_to_icode.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -918,7 +918,7 @@ trans_fun([{bs_add, {f,Lbl}, [Old,New,Unit], Res}|Instructions], Env) ->
Succ = mk_label(new),
[hipe_icode:mk_primop([Temp], '*',
[NewVar, hipe_icode:mk_const(Unit)],
- hipe_icode:label_name(Succ), Lbl),
+ hipe_icode:label_name(Succ), map_label(Lbl)),
Succ]
end
end,
@@ -930,7 +930,7 @@ trans_fun([{bs_add, {f,Lbl}, [Old,New,Unit], Res}|Instructions], Env) ->
[FailLbl,
hipe_icode:mk_fail([hipe_icode:mk_const(badarg)], error)]};
true ->
- {Lbl, []}
+ {map_label(Lbl), []}
end,
IsPos =
[hipe_icode:mk_if('>=', [Temp, hipe_icode:mk_const(0)],
diff --git a/lib/hipe/icode/hipe_icode_callgraph.erl b/lib/hipe/icode/hipe_icode_callgraph.erl
index 95182fc002..ae4b5785c4 100644
--- a/lib/hipe/icode/hipe_icode_callgraph.erl
+++ b/lib/hipe/icode/hipe_icode_callgraph.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -25,8 +25,6 @@
%% in hipe_icode_type.erl.
%%
%% Created : 7 Jun 2004 by Tobias Lindahl <[email protected]>
-%%
-%% $Id$
%%-----------------------------------------------------------------------
-module(hipe_icode_callgraph).
@@ -48,7 +46,7 @@
-type mfa_icode() :: {mfa(), #icode{}}.
--record(icode_callgraph, {codedict :: dict(), ordered_sccs :: [[atom()]]}).
+-record(icode_callgraph, {codedict :: dict(), ordered_sccs :: [[mfa()]]}).
%%------------------------------------------------------------------------
%% Exported functions
@@ -78,7 +76,7 @@ construct_callgraph(List) ->
to_list(#icode_callgraph{codedict = Dict, ordered_sccs = SCCs}) ->
FlatList = lists:flatten(SCCs),
- [{Mod, dict:fetch(Mod, Dict)} || Mod <- FlatList].
+ [{MFA, dict:fetch(MFA, Dict)} || MFA <- FlatList].
%%------------------------------------------------------------------------
diff --git a/lib/hipe/icode/hipe_icode_exceptions.erl b/lib/hipe/icode/hipe_icode_exceptions.erl
index 3c8f7b5712..00caffb24b 100644
--- a/lib/hipe/icode/hipe_icode_exceptions.erl
+++ b/lib/hipe/icode/hipe_icode_exceptions.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/hipe/icode/hipe_icode_primops.erl b/lib/hipe/icode/hipe_icode_primops.erl
index b0fe7eb708..a413531c07 100644
--- a/lib/hipe/icode/hipe_icode_primops.erl
+++ b/lib/hipe/icode/hipe_icode_primops.erl
@@ -2,19 +2,19 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -26,9 +26,6 @@
%% Notes :
%% History : * 2001-06-13 Erik Johansson ([email protected]):
%% Created.
-%%
-%% $Id$
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-module(hipe_icode_primops).
@@ -197,7 +194,7 @@ fails(#element{}) -> true;
%% fails(#gc_test{}) -> ???
fails({hipe_bs_primop, {bs_start_match, _}}) -> true;
fails({hipe_bs_primop, {{bs_start_match, bitstr}, _}}) -> true;
-fails({hipe_bs_primop, {{bs_start_match, ok_matchstate}, _}}) -> false;
+fails({hipe_bs_primop, {{bs_start_match, ok_matchstate}, _}}) -> true;
fails({hipe_bs_primop, {bs_get_binary, _, _}}) -> true;
fails({hipe_bs_primop, {bs_get_binary_all, _, _}}) -> true;
fails({hipe_bs_primop, {bs_get_binary_all_2, _, _}}) -> true;
diff --git a/lib/hipe/icode/hipe_icode_range.erl b/lib/hipe/icode/hipe_icode_range.erl
index bcc857acf4..c222e8a5d5 100644
--- a/lib/hipe/icode/hipe_icode_range.erl
+++ b/lib/hipe/icode/hipe_icode_range.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-2011. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%%-------------------------------------------------------------------
@@ -59,15 +59,17 @@
-record(range, {range :: range_rep(),
other :: boolean()}).
+-type range() :: #range{}.
--record(ann, {range :: #range{},
+-record(ann, {range :: range(),
type :: erl_types:erl_type(),
count :: integer()}).
+-type ann() :: #ann{}.
--type range_anno() :: {range_anno, #ann{}, fun((#ann{}) -> string())}.
--type args_fun() :: fun((mfa(),cfg()) -> [#range{}]).
--type call_fun() :: fun((mfa(),[#range{}]) -> #range{}).
--type final_fun() :: fun((mfa(),[#range{}]) -> ok).
+-type range_anno() :: {'range_anno', ann(), fun((ann()) -> string())}.
+-type args_fun() :: fun((mfa(), cfg()) -> [range()]).
+-type call_fun() :: fun((mfa(), [range()]) -> range()).
+-type final_fun() :: fun((mfa(), [range()]) -> 'ok').
-type data() :: {mfa(), args_fun(), call_fun(), final_fun()}.
-type label() :: non_neg_integer().
-type info() :: gb_tree().
@@ -75,15 +77,15 @@
-type variable() :: #icode_variable{}.
-type annotated_variable() :: #icode_variable{}.
-type argument() :: #icode_const{} | variable().
--type three_range_fun() :: fun((#range{},#range{},#range{}) -> #range{}).
+-type three_range_fun() :: fun((range(),range(),range()) -> range()).
-type instr_split_info() :: {icode_instr(), [{label(),info()}]}.
--type last_instr_return() :: {instr_split_info(), #range{}}.
+-type last_instr_return() :: {instr_split_info(), range()}.
-record(state, {info_map = gb_trees:empty() :: info(),
counter = dict:new() :: dict(),
cfg :: cfg(),
liveness = gb_trees:empty() :: gb_tree(),
- ret_type :: #range{},
+ ret_type :: range(),
lookup_fun :: call_fun(),
result_action :: final_fun()}).
@@ -108,8 +110,8 @@ cfg(Cfg, MFA, Options, Servers) ->
-spec concurrent_cfg(cfg(), mfa(), pid()) -> cfg().
concurrent_cfg(Cfg, MFA, CompServer) ->
- CompServer ! {ready, {MFA,self()}},
- {ArgsFun,CallFun,FinalFun} = do_analysis(Cfg, MFA),
+ CompServer ! {ready, {MFA, self()}},
+ {ArgsFun, CallFun, FinalFun} = do_analysis(Cfg, MFA),
Ans = do_rewrite(Cfg, MFA, ArgsFun, CallFun, FinalFun),
CompServer ! {done_rewrite, MFA},
Ans.
@@ -227,7 +229,7 @@ analyse_block(Label, Info, State, Rewrite) ->
state__update_info(State2, InfoList, Rewrite).
-spec analyse_BB([icode_instr()], info(), [icode_instr()], boolean(), call_fun()) ->
- {[icode_instr()], [{label(),info()}], #range{}}.
+ {[icode_instr()], [{label(),info()}], range()}.
analyse_BB([Last], Info, Code, Rewrite, LookupFun) ->
{{NewI, LabelInfoList}, RetType} =
@@ -266,9 +268,9 @@ handle_args(I, Info, WidenFun) ->
%% io:format("Uses: ~p~nRanges: ~p~n", [Uses, PresentRanges]),
JoinFun = fun(Var, Range) -> update_info(Var, Range, WidenFun) end,
NewUses = lists:zipwith(JoinFun, Uses, PresentRanges),
- hipe_icode:subst_uses(lists:zip(Uses, NewUses),I).
+ hipe_icode:subst_uses(lists:zip(Uses, NewUses), I).
--spec join_info(#ann{}, #range{}, three_range_fun()) -> #ann{}.
+-spec join_info(ann(), range(), three_range_fun()) -> ann().
join_info(Ann = #ann{range = R1, type = Type, count = ?WIDEN}, R2, Fun) ->
Ann#ann{range = Fun(R1, R2, range_from_simple_type(Type))};
@@ -278,17 +280,17 @@ join_info(Ann = #ann{range = R1, type = Type, count = C}, R2, _Fun) when C < ?WI
NewR -> Ann#ann{range = NewR, count = C+1}
end.
--spec join_three(#range{}, #range{}, #range{}) -> #range{}.
+-spec join_three(range(), range(), range()) -> range().
join_three(R1, R2, R3) ->
inf(sup(R1, R2), R3).
--spec update_info(variable(), #range{}) -> annotated_variable().
+-spec update_info(variable(), range()) -> annotated_variable().
update_info(Var, Range) ->
update_info(Var, Range, fun update_three/3).
--spec update_info(variable(), #range{}, three_range_fun()) -> annotated_variable().
+-spec update_info(variable(), range(), three_range_fun()) -> annotated_variable().
update_info(Arg, R, Fun) ->
case hipe_icode:is_annotated_variable(Arg) of
@@ -299,7 +301,7 @@ update_info(Arg, R, Fun) ->
Arg
end.
--spec update_info1(any(), #range{}, three_range_fun()) -> range_anno().
+-spec update_info1(any(), range(), three_range_fun()) -> range_anno().
update_info1({range_anno, Ann, _}, R2, Fun) ->
make_range_anno(update_ann(Ann,R2,Fun));
@@ -314,71 +316,71 @@ update_ann(Ann = #ann{range = R1, type = Type, count = C}, R2, _Fun) ->
NewR -> Ann#ann{range = NewR, count = C+1}
end.
--spec type_to_ann(erl_types:erl_type()) -> #ann{}.
+-spec type_to_ann(erl_types:erl_type()) -> ann().
type_to_ann(Type) ->
- #ann{range = range_from_simple_type(Type), type = t_limit(Type,1), count=1}.
+ #ann{range = range_from_simple_type(Type), type = t_limit(Type,1), count = 1}.
--spec make_range_anno(#ann{}) -> range_anno().
+-spec make_range_anno(ann()) -> range_anno().
make_range_anno(Ann) ->
{range_anno, Ann, fun pp_ann/1}.
--spec update_three(#range{}, #range{}, #range{}) -> #range{}.
+-spec update_three(range(), range(), range()) -> range().
update_three(_R1, R2, R3) ->
inf(R2, R3).
--spec safe_widen(#range{}, #range{}, #range{}) -> #range{}.
+-spec safe_widen(range(), range(), range()) -> range().
safe_widen(#range{range=Old}, #range{range=New}, T = #range{range=Wide}) ->
ResRange =
- case {Old,New,Wide} of
- {{Min,Max1},{Min,Max2},{_,Max}} ->
- case inf_geq(OMax = next_up_limit(inf_max([Max1,Max2])),Max) of
+ case {Old, New, Wide} of
+ {{Min,Max1}, {Min,Max2}, {_,Max}} ->
+ case inf_geq(OMax = next_up_limit(inf_max([Max1, Max2])), Max) of
true -> {Min,Max};
false -> {Min,OMax}
end;
- {{Min1,Max},{Min2,Max},{Min,_}} ->
- case inf_geq(Min, OMin = next_down_limit(inf_min([Min1,Min2]))) of
+ {{Min1,Max}, {Min2,Max}, {Min,_}} ->
+ case inf_geq(Min, OMin = next_down_limit(inf_min([Min1, Min2]))) of
true -> {Min,Max};
false -> {OMin,Max}
end;
- {{Min1,Max1},{Min2,Max2},{Min,Max}} ->
+ {{Min1,Max1}, {Min2,Max2}, {Min,Max}} ->
RealMax =
- case inf_geq(OMax = next_up_limit(inf_max([Max1,Max2])),Max) of
+ case inf_geq(OMax = next_up_limit(inf_max([Max1, Max2])), Max) of
true -> Max;
false -> OMax
end,
RealMin =
- case inf_geq(Min, OMin = next_down_limit(inf_min([Min1,Min2]))) of
+ case inf_geq(Min, OMin = next_down_limit(inf_min([Min1, Min2]))) of
true -> Min;
false -> OMin
end,
- {RealMin,RealMax};
+ {RealMin, RealMax};
_ ->
Wide
end,
- T#range{range=ResRange}.
+ T#range{range = ResRange}.
--spec widen(#range{}, #range{}, #range{}) -> #range{}.
+-spec widen(range(), range(), range()) -> range().
widen(#range{range=Old}, #range{range=New}, T = #range{range=Wide}) ->
ResRange =
- case {Old,New,Wide} of
- {{Min,_},{Min,Max2},{_,Max}} ->
- case inf_geq(OMax = next_up_limit(Max2),Max) of
+ case {Old, New, Wide} of
+ {{Min,_}, {Min,Max2}, {_,Max}} ->
+ case inf_geq(OMax = next_up_limit(Max2), Max) of
true -> {Min,Max};
false -> {Min,OMax}
end;
- {{_,Max},{Min2,Max},{Min,_}} ->
+ {{_,Max}, {Min2,Max}, {Min,_}} ->
case inf_geq(Min, OMin = next_down_limit(Min2)) of
true -> {Min,Max};
false -> {OMin,Max}
end;
- {_,{Min2,Max2},{Min,Max}} ->
+ {_, {Min2,Max2}, {Min,Max}} ->
RealMax =
- case inf_geq(OMax = next_up_limit(Max2),Max) of
+ case inf_geq(OMax = next_up_limit(Max2), Max) of
true -> Max;
false -> OMax
end,
@@ -387,11 +389,11 @@ widen(#range{range=Old}, #range{range=New}, T = #range{range=Wide}) ->
true -> Min;
false -> OMin
end,
- {RealMin,RealMax};
+ {RealMin, RealMax};
_ ->
Wide
end,
- T#range{range=ResRange}.
+ T#range{range = ResRange}.
-spec analyse_call(#icode_call{}, call_fun()) -> #icode_call{}.
@@ -421,7 +423,7 @@ analyse_move(Move) ->
analyse_begin_handler(Handler) ->
SubstList =
- [{Dst,update_info(Dst,any_type())} ||
+ [{Dst, update_info(Dst, any_type())} ||
Dst <- hipe_icode:begin_handler_dstlist(Handler)],
hipe_icode:subst_defines(SubstList, Handler).
@@ -494,14 +496,14 @@ analyse_switch_val(Switch, Info, Rewrite) ->
end
end.
--spec update_infos(argument(), info(), [{#range{},label()}]) -> [{label(),info()}].
+-spec update_infos(argument(), info(), [{range(),label()}]) -> [{label(),info()}].
update_infos(Arg, Info, [{Range, Label}|Rest]) ->
- [{Label,enter_define({Arg,Range},Info)} | update_infos(Arg,Info,Rest)];
+ [{Label,enter_define({Arg,Range},Info)} | update_infos(Arg, Info, Rest)];
update_infos(_, _, []) -> [].
--spec get_range_label_list([{argument(),label()}], #range{}, [{#range{},label()}]) ->
- {#range{},[{#range{},label()}]}.
+-spec get_range_label_list([{argument(),label()}], range(), [{range(),label()}]) ->
+ {range(),[{range(),label()}]}.
get_range_label_list([{Val,Label}|Cases], SRange, Acc) ->
VRange = get_range_from_arg(Val),
@@ -516,7 +518,7 @@ get_range_label_list([], SRange, Acc) ->
{PointTypes, _} = lists:unzip(Acc),
{remove_point_types(SRange, PointTypes), Acc}.
--spec update_switch(#icode_switch_val{}, [{#range{},label()}], boolean()) ->
+-spec update_switch(#icode_switch_val{}, [{range(),label()}], boolean()) ->
#icode_switch_val{}.
update_switch(Switch, LabelRangeList, KeepFail) ->
@@ -524,14 +526,14 @@ update_switch(Switch, LabelRangeList, KeepFail) ->
case label_range_list_to_cases(LabelRangeList, []) of
no_update ->
Switch;
- Cases ->
+ Cases ->
hipe_icode:switch_val_cases_update(Switch, Cases)
end,
if KeepFail -> S2;
true -> S2
end.
--spec label_range_list_to_cases([{#range{},label()}], [{#icode_const{},label()}]) ->
+-spec label_range_list_to_cases([{range(),label()}], [{#icode_const{},label()}]) ->
'no_update' | [{#icode_const{},label()}].
label_range_list_to_cases([{#range{range={C,C},other=false},Label}|Rest],
@@ -586,9 +588,9 @@ analyse_last_call(Call, Info, LookupFun) ->
NewInfo = enter_vals(NewI, Info),
case hipe_icode:call_fail_label(Call) of
[] ->
- {NewI, [{Continuation,NewInfo}]};
+ {NewI, [{Continuation, NewInfo}]};
Fail ->
- {NewI, [{Continuation,NewInfo}, {Fail,Info}]}
+ {NewI, [{Continuation, NewInfo}, {Fail, Info}]}
end.
-spec analyse_if(#icode_if{}, info(), boolean()) ->
@@ -596,16 +598,16 @@ analyse_last_call(Call, Info, LookupFun) ->
analyse_if(If, Info, Rewrite) ->
case hipe_icode:if_args(If) of
- Args = [_,_] ->
+ [_, _] = Args ->
analyse_sane_if(If, Info, Args, get_range_from_args(Args), Rewrite);
_ ->
TrueLabel = hipe_icode:if_true_label(If),
FalseLabel = hipe_icode:if_false_label(If),
- {If, [{TrueLabel,Info},{FalseLabel,Info}]}
+ {If, [{TrueLabel, Info}, {FalseLabel, Info}]}
end.
-spec analyse_sane_if(#icode_if{}, info(), [argument(),...],
- [#range{},...], boolean()) ->
+ [range(),...], boolean()) ->
{#icode_goto{} | #icode_if{}, [{label(), info()}]}.
analyse_sane_if(If, Info, [Arg1, Arg2], [Range1, Range2], Rewrite) ->
@@ -613,59 +615,61 @@ analyse_sane_if(If, Info, [Arg1, Arg2], [Range1, Range2], Rewrite) ->
'>' ->
{TrueRange2, TrueRange1, FalseRange2, FalseRange1} =
range_inequality_propagation(Range2, Range1);
- '==' ->
- {TempTrueRange1, TempTrueRange2, FalseRange1, FalseRange2}=
- range_equality_propagation(Range1, Range2),
- TrueRange1 = set_other(TempTrueRange1,other(Range1)),
- TrueRange2 = set_other(TempTrueRange2,other(Range2));
'<' ->
- {TrueRange1, TrueRange2, FalseRange1, FalseRange2} =
+ {TrueRange1, TrueRange2, FalseRange1, FalseRange2} =
range_inequality_propagation(Range1, Range2);
'>=' ->
{FalseRange1, FalseRange2, TrueRange1, TrueRange2} =
range_inequality_propagation(Range1, Range2);
'=<' ->
- {FalseRange2, FalseRange1, TrueRange2, TrueRange1} =
+ {FalseRange2, FalseRange1, TrueRange2, TrueRange1} =
range_inequality_propagation(Range2, Range1);
'=:=' ->
- {TrueRange1, TrueRange2, FalseRange1, FalseRange2}=
+ {TrueRange1, TrueRange2, FalseRange1, FalseRange2} =
range_equality_propagation(Range1, Range2);
'=/=' ->
{FalseRange1, FalseRange2, TrueRange1, TrueRange2} =
range_equality_propagation(Range1, Range2);
+ '==' ->
+ {TempTrueRange1, TempTrueRange2, FalseRange1, FalseRange2} =
+ range_equality_propagation(Range1, Range2),
+ TrueRange1 = set_other(TempTrueRange1, other(Range1)),
+ TrueRange2 = set_other(TempTrueRange2, other(Range2));
'/=' ->
- {TempFalseRange1, TempFalseRange2, TrueRange1, TrueRange2}=
+ {TempFalseRange1, TempFalseRange2, TrueRange1, TrueRange2} =
range_equality_propagation(Range1, Range2),
- FalseRange1 = set_other(TempFalseRange1,other(Range1)),
- FalseRange2 = set_other(TempFalseRange2,other(Range2))
+ FalseRange1 = set_other(TempFalseRange1, other(Range1)),
+ FalseRange2 = set_other(TempFalseRange2, other(Range2))
end,
- TrueLabel = hipe_icode:if_true_label(If),
- FalseLabel = hipe_icode:if_false_label(If),
- TrueInfo =
- enter_defines([{Arg1,TrueRange1}, {Arg2,TrueRange2}],Info),
- FalseInfo =
- enter_defines([{Arg1,FalseRange1}, {Arg2,FalseRange2}],Info),
- True =
- case lists:any(fun range__is_none/1,[TrueRange1,TrueRange2]) of
+ %% io:format("TR1 = ~w\nTR2 = ~w\n", [TrueRange1, TrueRange2]),
+ True =
+ case lists:all(fun range__is_none/1, [TrueRange1, TrueRange2]) of
true -> [];
- false -> [{TrueLabel,TrueInfo}]
+ false ->
+ TrueLabel = hipe_icode:if_true_label(If),
+ TrueArgRanges = [{Arg1, TrueRange1}, {Arg2, TrueRange2}],
+ TrueInfo = enter_defines(TrueArgRanges, Info),
+ [{TrueLabel, TrueInfo}]
end,
- False =
- case lists:any(fun range__is_none/1, [FalseRange1,FalseRange2]) of
+ %% io:format("FR1 = ~w\nFR2 = ~w\n", [FalseRange1, FalseRange2]),
+ False =
+ case lists:all(fun range__is_none/1, [FalseRange1, FalseRange2]) of
true -> [];
- false -> [{FalseLabel,FalseInfo}]
+ false ->
+ FalseLabel = hipe_icode:if_false_label(If),
+ FalseArgRanges = [{Arg1, FalseRange1}, {Arg2, FalseRange2}],
+ FalseInfo = enter_defines(FalseArgRanges, Info),
+ [{FalseLabel, FalseInfo}]
end,
- UpdateInfo = True++False,
+ UpdateInfo = True ++ False,
NewIF =
if Rewrite ->
- %%io:format("~w~n~w~n", [{Arg1,FalseRange1},{Arg2,FalseRange2}]),
- %%io:format("Any none: ~w~n", [lists:any(fun range__is_none/1,[FalseRange1,FalseRange2])]),
case UpdateInfo of
- [] -> %%This is weird
+ [] -> %% This is weird
If;
- [{Label,_Info}] ->
+ [{Label, _Info}] ->
hipe_icode:mk_goto(Label);
- [_,_] ->
+ [_, _] ->
If
end;
true ->
@@ -686,13 +690,13 @@ normalize_name(Name) ->
Name -> Name
end.
--spec range_equality_propagation(#range{}, #range{}) ->
- {#range{}, #range{}, #range{}, #range{}}.
+-spec range_equality_propagation(range(), range()) ->
+ {range(), range(), range(), range()}.
range_equality_propagation(Range_1, Range_2) ->
True_range = inf(Range_1, Range_2),
case {range(Range_1), range(Range_2)} of
- {{N,N},{ N,N}} ->
+ {{N,N}, {N,N}} ->
False_range_1 = none_range(),
False_range_2 = none_range();
{{N1,N1}, {N2,N2}} ->
@@ -710,8 +714,8 @@ range_equality_propagation(Range_1, Range_2) ->
end,
{True_range, True_range, False_range_1, False_range_2}.
--spec range_inequality_propagation(#range{}, #range{}) ->
- {#range{}, #range{}, #range{}, #range{}}.
+-spec range_inequality_propagation(range(), range()) ->
+ {range(), range(), range(), range()}.
%% Range1 < Range2
range_inequality_propagation(Range1, Range2) ->
@@ -781,26 +785,24 @@ analyse_type(Type, Info, Rewrite) ->
TrueRange = inf(any_range(), OldVarRange),
FalseRange = inf(none_range(), OldVarRange);
_ ->
- TrueRange = inf(none_range(),OldVarRange),
+ TrueRange = inf(none_range(), OldVarRange),
FalseRange = OldVarRange
end,
TrueLabel = hipe_icode:type_true_label(Type),
FalseLabel = hipe_icode:type_false_label(Type),
- TrueInfo =
- enter_define({Arg,TrueRange},Info),
- FalseInfo =
- enter_define({Arg,FalseRange},Info),
- True =
+ TrueInfo = enter_define({Arg, TrueRange}, Info),
+ FalseInfo = enter_define({Arg, FalseRange}, Info),
+ True =
case range__is_none(TrueRange) of
true -> [];
- false -> [{TrueLabel,TrueInfo}]
+ false -> [{TrueLabel, TrueInfo}]
end,
- False =
+ False =
case range__is_none(FalseRange) of
true -> [];
- false -> [{FalseLabel,FalseInfo}]
+ false -> [{FalseLabel, FalseInfo}]
end,
- UpdateInfo = True++False,
+ UpdateInfo = True ++ False,
NewType =
if Rewrite ->
case UpdateInfo of
@@ -808,15 +810,15 @@ analyse_type(Type, Info, Rewrite) ->
Type;
[{Label,_Info}] ->
hipe_icode:mk_goto(Label);
- [_,_] ->
+ [_, _] ->
Type
end;
true ->
Type
end,
- {NewType,True ++ False}.
+ {NewType, True ++ False}.
--spec compare_with_integer(integer(), #range{}) -> {#range{}, #range{}}.
+-spec compare_with_integer(integer(), range()) -> {range(), range()}.
compare_with_integer(N, OldVarRange) ->
TestRange = range_init({N, N}, false),
@@ -843,13 +845,13 @@ compare_with_integer(N, OldVarRange) ->
%%== Ranges ==================================================================
--spec pp_ann(#ann{} | erl_types:erl_type()) -> [string()].
+-spec pp_ann(ann() | erl_types:erl_type()) -> string().
-pp_ann(#ann{range=#range{range=R, other=false}}) ->
+pp_ann(#ann{range = #range{range = R, other = false}}) ->
pp_range(R);
-pp_ann(#ann{range=#range{range=empty, other=true}, type=Type}) ->
+pp_ann(#ann{range = #range{range = empty, other = true}, type = Type}) ->
t_to_string(Type);
-pp_ann(#ann{range=#range{range=R, other=true}, type=Type}) ->
+pp_ann(#ann{range = #range{range = R, other = true}, type = Type}) ->
pp_range(R) ++ " | " ++ t_to_string(Type);
pp_ann(Type) ->
t_to_string(Type).
@@ -867,12 +869,12 @@ val_to_string(pos_inf) -> "inf";
val_to_string(neg_inf) -> "-inf";
val_to_string(X) when is_integer(X) -> integer_to_list(X).
--spec range_from_type(erl_types:erl_type()) -> [#range{}].
+-spec range_from_type(erl_types:erl_type()) -> [range()].
range_from_type(Type) ->
[range_from_simple_type(T) || T <- t_to_tlist(Type)].
--spec range_from_simple_type(erl_types:erl_type()) -> #range{}.
+-spec range_from_simple_type(erl_types:erl_type()) -> range().
range_from_simple_type(Type) ->
None = t_none(),
@@ -887,7 +889,7 @@ range_from_simple_type(Type) ->
#range{range = Range, other = true}
end.
--spec range_init(range_rep(), boolean()) -> #range{}.
+-spec range_init(range_rep(), boolean()) -> range().
range_init({Min, Max} = Range, Other) ->
case inf_geq(Max, Min) of
@@ -899,39 +901,39 @@ range_init({Min, Max} = Range, Other) ->
range_init(empty, Other) ->
#range{range = empty, other = Other}.
--spec range(#range{}) -> range_rep().
+-spec range(range()) -> range_rep().
range(#range{range = R}) -> R.
--spec other(#range{}) -> boolean().
+-spec other(range()) -> boolean().
other(#range{other = O}) -> O.
--spec set_other(#range{}, boolean()) -> #range{}.
+-spec set_other(range(), boolean()) -> range().
set_other(R, O) -> R#range{other = O}.
--spec range__min(#range{}) -> 'empty' | 'neg_inf' | integer().
+-spec range__min(range()) -> 'empty' | 'neg_inf' | integer().
-range__min(#range{range=empty}) -> empty;
-range__min(#range{range={Min,_}}) -> Min.
+range__min(#range{range = empty}) -> empty;
+range__min(#range{range = {Min,_}}) -> Min.
--spec range__max(#range{}) -> 'empty' | 'pos_inf' | integer().
+-spec range__max(range()) -> 'empty' | 'pos_inf' | integer().
-range__max(#range{range=empty}) -> empty;
-range__max(#range{range={_,Max}}) -> Max.
+range__max(#range{range = empty}) -> empty;
+range__max(#range{range = {_,Max}}) -> Max.
--spec range__is_none(#range{}) -> boolean().
+-spec range__is_none(range()) -> boolean().
-range__is_none(#range{range=empty, other=false}) -> true;
+range__is_none(#range{range = empty, other = false}) -> true;
range__is_none(#range{}) -> false.
--spec range__is_empty(#range{}) -> boolean().
+-spec range__is_empty(range()) -> boolean().
-range__is_empty(#range{range=empty}) -> true;
-range__is_empty(#range{range={_,_}}) -> false.
+range__is_empty(#range{range = empty}) -> true;
+range__is_empty(#range{range = {_,_}}) -> false.
--spec remove_point_types(#range{}, [#range{}]) -> #range{}.
+-spec remove_point_types(range(), [range()]) -> range().
remove_point_types(Range, Ranges) ->
Sorted = lists:sort(Ranges),
@@ -939,35 +941,35 @@ remove_point_types(Range, Ranges) ->
Range1 = lists:foldl(FoldFun, Range, Sorted),
lists:foldl(FoldFun, Range1, lists:reverse(Sorted)).
--spec range__remove_constant(#range{}, #range{}) -> #range{}.
+-spec range__remove_constant(range(), range()) -> range().
-range__remove_constant(R = #range{range={C,C}}, #range{range={C,C}}) ->
- R#range{range=empty};
-range__remove_constant(R = #range{range={C,H}}, #range{range={C,C}}) ->
- R#range{range={C+1,H}};
-range__remove_constant(R = #range{range={L,C}}, #range{range={C,C}}) ->
- R#range{range={L,C-1}};
-range__remove_constant(R = #range{}, #range{range={C,C}}) ->
+range__remove_constant(#range{range = {C, C}} = R, #range{range = {C, C}}) ->
+ R#range{range = empty};
+range__remove_constant(#range{range = {C, H}} = R, #range{range = {C, C}}) ->
+ R#range{range = {C+1, H}};
+range__remove_constant(#range{range = {L, C}} = R, #range{range = {C, C}}) ->
+ R#range{range = {L, C-1}};
+range__remove_constant(#range{} = R, #range{range = {C,C}}) ->
R;
-range__remove_constant(R = #range{}, _) ->
+range__remove_constant(#range{} = R, _) ->
R.
--spec any_type() -> #range{}.
+-spec any_type() -> range().
any_type() ->
- #range{range=any_r(), other=true}.
+ #range{range = any_r(), other = true}.
--spec any_range() -> #range{}.
+-spec any_range() -> range().
any_range() ->
- #range{range=any_r(), other=false}.
+ #range{range = any_r(), other = false}.
--spec none_range() -> #range{}.
+-spec none_range() -> range().
none_range() ->
- #range{range=empty, other=true}.
+ #range{range = empty, other = true}.
--spec none_type() -> #range{}.
+-spec none_type() -> range().
none_type() ->
#range{range = empty, other = false}.
@@ -976,12 +978,12 @@ none_type() ->
any_r() -> {neg_inf, pos_inf}.
--spec get_range_from_args([argument()]) -> [#range{}].
+-spec get_range_from_args([argument()]) -> [range()].
get_range_from_args(Args) ->
[get_range_from_arg(Arg) || Arg <- Args].
--spec get_range_from_arg(argument()) -> #range{}.
+-spec get_range_from_arg(argument()) -> range().
get_range_from_arg(Arg) ->
case hipe_icode:is_const(Arg) of
@@ -989,15 +991,15 @@ get_range_from_arg(Arg) ->
Value = hipe_icode:const_value(Arg),
case is_integer(Value) of
true ->
- #range{range={Value,Value}, other=false};
+ #range{range = {Value, Value}, other = false};
false ->
- #range{range=empty, other=true}
+ #range{range = empty, other = true}
end;
false ->
case hipe_icode:is_annotated_variable(Arg) of
true ->
case hipe_icode:variable_annotation(Arg) of
- {range_anno, #ann{range=Range}, _} ->
+ {range_anno, #ann{range = Range}, _} ->
Range;
{type_anno, Type, _} ->
range_from_simple_type(Type)
@@ -1012,7 +1014,7 @@ get_range_from_arg(Arg) ->
%% inf([R1,R2|Rest]) ->
%% inf([inf(R1,R2)|Rest]).
--spec inf(#range{}, #range{}) -> #range{}.
+-spec inf(range(), range()) -> range().
inf(#range{range=R1, other=O1}, #range{range=R2, other=O2}) ->
#range{range=range_inf(R1,R2), other=other_inf(O1,O2)}.
@@ -1022,8 +1024,8 @@ inf(#range{range=R1, other=O1}, #range{range=R2, other=O2}) ->
range_inf(empty, _) -> empty;
range_inf(_, empty) -> empty;
range_inf({Min1,Max1}, {Min2,Max2}) ->
- NewMin = inf_max([Min1,Min2]),
- NewMax = inf_min([Max1,Max2]),
+ NewMin = inf_max([Min1, Min2]),
+ NewMax = inf_min([Max1, Max2]),
case inf_geq(NewMax, NewMin) of
true ->
{NewMin, NewMax};
@@ -1035,14 +1037,14 @@ range_inf({Min1,Max1}, {Min2,Max2}) ->
other_inf(O1, O2) -> O1 and O2.
--spec sup([#range{},...]) -> #range{}.
+-spec sup([range(),...]) -> range().
sup([R]) ->
R;
sup([R1,R2|Rest]) ->
sup([sup(R1, R2)|Rest]).
--spec sup(#range{}, #range{}) -> #range{}.
+-spec sup(range(), range()) -> range().
sup(#range{range=R1,other=O1}, #range{range=R2,other=O2}) ->
#range{range=range_sup(R1,R2), other=other_sup(O1,O2)}.
@@ -1063,7 +1065,7 @@ other_sup(O1, O2) -> O1 or O2.
%%== Call Support =============================================================
-spec analyse_call_or_enter_fun(fun_name(), [argument()],
- icode_call_type(), call_fun()) -> [#range{}].
+ icode_call_type(), call_fun()) -> [range()].
analyse_call_or_enter_fun(Fun, Args, CallType, LookupFun) ->
%%io:format("Fun: ~p~n Args: ~p~n CT: ~p~n LF: ~p~n", [Fun, Args, CallType, LookupFun]),
@@ -1105,19 +1107,19 @@ analyse_call_or_enter_fun(Fun, Args, CallType, LookupFun) ->
[any_type()];
{hipe_bs_primop, {bs_get_integer, Size, Flags}} ->
{Min, Max} = analyse_bs_get_integer(Size, Flags, length(Args) =:= 1),
- [#range{range={Min, Max}, other=false}, any_type()];
+ [#range{range = {Min, Max}, other = false}, any_type()];
{hipe_bs_primop, _} = Primop ->
Type = hipe_icode_primops:type(Primop),
range_from_type(Type)
end.
--type bin_operation() :: fun((#range{},#range{}) -> #range{}).
--type unary_operation() :: fun((#range{}) -> #range{}).
+-type bin_operation() :: fun((range(), range()) -> range()).
+-type unary_operation() :: fun((range()) -> range()).
-spec basic_type(fun_name()) -> 'not_int' | 'not_analysed'
- | {bin, bin_operation()}
- | {unary, unary_operation()}
- | {fcall, mfa()} | {hipe_bs_primop, _}.
+ | {'bin', bin_operation()}
+ | {'unary', unary_operation()}
+ | {'fcall', mfa()} | {'hipe_bs_primop', _}.
%% Arithmetic operations
basic_type('+') -> {bin, fun(R1, R2) -> range_add(R1, R2) end};
@@ -1214,7 +1216,7 @@ analyse_bs_get_integer(Size, Flags, false) when is_integer(Size),
%% Arithmetic
--spec range_add(#range{}, #range{}) -> #range{}.
+-spec range_add(range(), range()) -> range().
range_add(Range1, Range2) ->
NewMin = inf_add(range__min(Range1), range__min(Range2)),
@@ -1222,7 +1224,7 @@ range_add(Range1, Range2) ->
Other = other(Range1) orelse other(Range2),
range_init({NewMin, NewMax}, Other).
--spec range_sub(#range{}, #range{}) -> #range{}.
+-spec range_sub(range(), range()) -> range().
range_sub(Range1, Range2) ->
Min_sub = inf_min([inf_inv(range__max(Range2)),
@@ -1234,7 +1236,7 @@ range_sub(Range1, Range2) ->
Other = other(Range1) orelse other(Range2),
range_init({NewMin, NewMax}, Other).
--spec range_mult(#range{}, #range{}) -> #range{}.
+-spec range_mult(range(), range()) -> range().
range_mult(#range{range=empty, other=true}, _Range2) ->
range_init(empty, true);
@@ -1274,7 +1276,7 @@ range_mult(Range1, Range2) ->
Other = other(Range1) orelse other(Range2),
range_init(Range, Other).
--spec extreme_divisors(#range{}) -> range_tuple().
+-spec extreme_divisors(range()) -> range_tuple().
extreme_divisors(#range{range={0,0}}) -> {0,0};
extreme_divisors(#range{range={0,Max}}) -> {1,Max};
@@ -1289,7 +1291,7 @@ extreme_divisors(#range{range={Min,Max}}) ->
end
end.
--spec range_div(#range{}, #range{}) -> #range{}.
+-spec range_div(range(), range()) -> range().
%% this is div, not /.
range_div(_, #range{range={0,0}}) ->
@@ -1306,7 +1308,7 @@ range_div(Range1, Den) ->
inf_div(Max1, Min2), inf_div(Max1, Max2)],
range_init({inf_min(Min_max_list), inf_max(Min_max_list)}, false).
--spec range_rem(#range{}, #range{}) -> #range{}.
+-spec range_rem(range(), range()) -> range().
range_rem(Range1, Range2) ->
%% Range1 desides the sign of the answer.
@@ -1332,7 +1334,7 @@ range_rem(Range1, Range2) ->
%%--- Bit operations ----------------------------
--spec range_bsr(#range{}, #range{}) -> #range{}.
+-spec range_bsr(range(), range()) -> range().
range_bsr(Range1, Range2=#range{range={Min, Max}}) ->
New_Range2 = range_init({inf_inv(Max), inf_inv(Min)}, other(Range2)),
@@ -1340,7 +1342,7 @@ range_bsr(Range1, Range2=#range{range={Min, Max}}) ->
%% io:format("bsr res:~w~nInput:= ~w~n", [Ans, {Range1,Range2}]),
Ans.
--spec range_bsl(#range{}, #range{}) -> #range{}.
+-spec range_bsl(range(), range()) -> range().
range_bsl(Range1, Range2) ->
Min1 = range__min(Range1),
@@ -1359,13 +1361,13 @@ range_bsl(Range1, Range2) ->
end,
range_init(MinMax, false).
--spec range_bnot(#range{}) -> #range{}.
+-spec range_bnot(range()) -> range().
range_bnot(Range) ->
Minus_one = range_init({-1,-1}, false),
range_add(range_mult(Range, Minus_one), Minus_one).
--spec width(range_rep() | integer()) -> 'pos_inf' | non_neg_integer().
+-spec width(range_rep() | inf_integer()) -> 'pos_inf' | non_neg_integer().
width({Min, Max}) -> inf_max([width(Min), width(Max)]);
width(pos_inf) -> pos_inf;
@@ -1389,7 +1391,7 @@ negwidth(X, N) ->
false -> negwidth(X, N+1)
end.
--spec range_band(#range{}, #range{}) -> #range{}.
+-spec range_band(range(), range()) -> range().
range_band(R1, R2) ->
{_Min1, Max1} = MM1 = range(R1),
@@ -1423,7 +1425,7 @@ range_band(R1, R2) ->
end,
range_init(Range, false).
--spec range_bor(#range{}, #range{}) -> #range{}.
+-spec range_bor(range(), range()) -> range().
range_bor(R1, R2) ->
{Min1, _Max1} = MM1 = range(R1),
@@ -1457,7 +1459,7 @@ range_bor(R1, R2) ->
end,
range_init(Range, false).
--spec classify_range(#range{}) -> 'minus_minus' | 'minus_plus' | 'plus_plus'.
+-spec classify_range(range()) -> 'minus_minus' | 'minus_plus' | 'plus_plus'.
classify_range(Range) ->
case range(Range) of
@@ -1480,7 +1482,7 @@ classify_int_range(_Number1, Number2) when Number2 < 0 ->
classify_int_range(_Number1, _Number2) ->
minus_plus.
--spec range_bxor(#range{}, #range{}) -> #range{}.
+-spec range_bxor(range(), range()) -> range().
range_bxor(R1, R2) ->
{Min1, Max1} = MM1 = range(R1),
@@ -1895,7 +1897,7 @@ convert_ann_to_types(#ann{range=#range{other=true}, type=Type}) ->
%% Icode Coordinator Callbacks
%%=====================================================================
--spec replace_nones([#range{}]) -> [#range{}].
+-spec replace_nones([range()]) -> [range()].
replace_nones(Args) ->
[replace_none(Arg) || Arg <- Args].
@@ -1905,7 +1907,7 @@ replace_none(Arg) ->
false -> Arg
end.
--spec update__info([#range{}], [#range{}]) -> {boolean(), [#ann{}]}.
+-spec update__info([range()], [range()]) -> {boolean(), [ann()]}.
update__info(NewRanges, OldRanges) ->
SupFun = fun (Ann, Range) ->
join_info(Ann, Range, fun safe_widen/3)
@@ -1915,19 +1917,19 @@ update__info(NewRanges, OldRanges) ->
Change = lists:zipwith(EqFun, ResRanges, OldRanges),
{lists:all(fun (X) -> X end, Change), ResRanges}.
--spec new__info/1 :: ([#range{}]) -> [#ann{}].
+-spec new__info([range()]) -> [ann()].
new__info(NewRanges) ->
[#ann{range=Range,count=1,type=t_any()} || Range <- NewRanges].
--spec return__info/1 :: ([#ann{}]) -> [#range{}].
+-spec return__info([ann()]) -> [range()].
return__info(Ranges) ->
[Range || #ann{range=Range} <- Ranges].
--spec return_none/0 :: () -> [#range{},...].
+-spec return_none() -> [range(),...].
return_none() ->
[none_type()].
--spec return_none_args/2 :: (#cfg{}, mfa()) -> [#range{}].
+-spec return_none_args(cfg(), mfa()) -> [range()].
return_none_args(Cfg, {_M,_F,A}) ->
NoArgs =
case hipe_icode_cfg:is_closure(Cfg) of
@@ -1936,7 +1938,7 @@ return_none_args(Cfg, {_M,_F,A}) ->
end,
lists:duplicate(NoArgs, none_type()).
--spec return_any_args/2 :: (#cfg{}, mfa()) -> [#range{}].
+-spec return_any_args(cfg(), mfa()) -> [range()].
return_any_args(Cfg, {_M,_F,A}) ->
NoArgs =
case hipe_icode_cfg:is_closure(Cfg) of
diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl
index c80fb6a0a2..570e4d9d17 100644
--- a/lib/hipe/main/hipe.erl
+++ b/lib/hipe/main/hipe.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% ====================================================================
@@ -25,7 +25,6 @@
%% Purpose :
%% Notes :
%% History : * 1998-01-28 Erik Johansson ([email protected]): Created.
-%% CVS : $Id$
%% ====================================================================
%% @doc This is the direct interface to the HiPE compiler.
%%
@@ -506,7 +505,7 @@ compile(Name, File, Opts0) ->
run_compiler(Name, DisasmFun, IcodeFun, NewOpts)
end.
--spec compile_core(mod(), _, compile_file(), comp_options()) ->
+-spec compile_core(mod(), cerl:c_module(), compile_file(), comp_options()) ->
{'ok', compile_ret()} | {'error', term()}.
compile_core(Name, Core0, File, Opts) ->
@@ -535,7 +534,7 @@ compile_core(Name, Core0, File, Opts) ->
%%
%% @see compile/3
--spec compile(mod(), _, compile_file(), comp_options()) ->
+-spec compile(mod(), cerl:c_module() | [], compile_file(), comp_options()) ->
{'ok', compile_ret()} | {'error', term()}.
compile(Name, [], File, Opts) ->
@@ -790,7 +789,7 @@ finalize_fun(MfaIcodeList, Exports, Opts) ->
FalseVal when (FalseVal =:= undefined) orelse (FalseVal =:= false) ->
[finalize_fun_sequential(MFAIcode, Opts, #comp_servers{})
|| {_MFA, _Icode} = MFAIcode <- MfaIcodeList];
- TrueVal when (TrueVal =:= true) or (TrueVal =:= debug) ->
+ TrueVal when (TrueVal =:= true) orelse (TrueVal =:= debug) ->
finalize_fun_concurrent(MfaIcodeList, Exports, Opts)
end.
@@ -939,6 +938,8 @@ assemble(CompiledCode, Closures, Exports, Options) ->
hipe_sparc_assemble:assemble(CompiledCode, Closures, Exports, Options);
powerpc ->
hipe_ppc_assemble:assemble(CompiledCode, Closures, Exports, Options);
+ ppc64 ->
+ hipe_ppc_assemble:assemble(CompiledCode, Closures, Exports, Options);
arm ->
hipe_arm_assemble:assemble(CompiledCode, Closures, Exports, Options);
x86 ->
@@ -1048,7 +1049,7 @@ post(Res, Icode, Options) ->
%% --------------------------------------------------------------------
%% @doc Returns the current HiPE version as a string().
--spec version() -> string().
+-spec version() -> nonempty_string().
version() ->
?VERSION_STRING().
@@ -1390,6 +1391,8 @@ o1_opts() ->
Common;
powerpc ->
Common;
+ ppc64 ->
+ Common;
arm ->
Common -- [inline_fp]; % Pointless optimising for absent hardware
x86 ->
@@ -1411,6 +1414,8 @@ o2_opts() ->
Common;
powerpc ->
Common;
+ ppc64 ->
+ Common;
arm ->
Common;
x86 ->
@@ -1429,6 +1434,8 @@ o3_opts() ->
Common;
powerpc ->
Common;
+ ppc64 ->
+ Common;
arm ->
Common;
x86 ->
diff --git a/lib/hipe/main/hipe_main.erl b/lib/hipe/main/hipe_main.erl
index fe9bc83fd2..e81642fb33 100644
--- a/lib/hipe/main/hipe_main.erl
+++ b/lib/hipe/main/hipe_main.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% @doc This is the HiPE compiler's main "loop".
@@ -102,7 +102,7 @@ compile_icode(MFA, LinearIcode0, Options, Servers, DebugState) ->
?opt_start_timer("Icode"),
LinearIcode1 = icode_no_comment(LinearIcode0, Options),
IcodeCfg0 = icode_linear_to_cfg(LinearIcode1, Options),
- %%hipe_icode_cfg:pp(IcodeCfg1),
+ %% hipe_icode_cfg:pp(IcodeCfg0),
IcodeCfg1 = icode_handle_exceptions(IcodeCfg0, MFA, Options),
IcodeCfg3 = icode_inline_bifs(IcodeCfg1, Options),
pp(IcodeCfg3, MFA, icode, pp_icode, Options, Servers),
diff --git a/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl b/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
index ce33af453a..6ba4ac814e 100644
--- a/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
+++ b/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/hipe/rtl/hipe_rtl.erl b/lib/hipe/rtl/hipe_rtl.erl
index ef06b2abf8..29e9c8c8fe 100644
--- a/lib/hipe/rtl/hipe_rtl.erl
+++ b/lib/hipe/rtl/hipe_rtl.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -354,6 +354,8 @@
phi_arglist_update/2,
phi_redirect_pred/3]).
+-export_type([alub_cond/0]).
+
%%
%% RTL
%%
@@ -590,6 +592,9 @@ branch_pred(#branch{p=P}) -> P.
%% alub
%%
+-type alub_cond() :: 'eq' | 'ne' | 'ge' | 'geu' | 'gt' | 'gtu' | 'le'
+ | 'leu' | 'lt' | 'ltu' | 'overflow' | 'not_overflow'.
+
mk_alub(Dst, Src1, Op, Src2, Cond, True, False) ->
mk_alub(Dst, Src1, Op, Src2, Cond, True, False, 0.5).
mk_alub(Dst, Src1, Op, Src2, Cond, True, False, P) ->
diff --git a/lib/hipe/rtl/hipe_rtl_arith.inc b/lib/hipe/rtl/hipe_rtl_arith.inc
index 31fedd927e..e608506234 100644
--- a/lib/hipe/rtl/hipe_rtl_arith.inc
+++ b/lib/hipe/rtl/hipe_rtl_arith.inc
@@ -3,7 +3,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -119,7 +119,8 @@ eval_alu(Op, Arg1, Arg2) ->
%% there are cases where we can evaluate a subset of the bits, but can
%% not do a full eval-alub call (eg. a + 0 gives no carry)
%%
--spec eval_cond_bits(atom(), boolean(), boolean(), boolean(), boolean()) -> boolean().
+-spec eval_cond_bits(hipe_rtl:alub_cond(), boolean(),
+ boolean(), boolean(), boolean()) -> boolean().
eval_cond_bits(Cond, N, Z, V, C) ->
case Cond of
@@ -146,9 +147,7 @@ eval_cond_bits(Cond, N, Z, V, C) ->
'overflow' ->
V;
'not_overflow' ->
- not V;
- _ ->
- ?EXIT({'condition code not handled',Cond})
+ not V
end.
eval_alub(Op, Cond, Arg1, Arg2) ->
diff --git a/lib/hipe/rtl/hipe_rtl_primops.erl b/lib/hipe/rtl/hipe_rtl_primops.erl
index 0361053676..5f273d8251 100644
--- a/lib/hipe/rtl/hipe_rtl_primops.erl
+++ b/lib/hipe/rtl/hipe_rtl_primops.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl b/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl
index 76c0a88933..194cf29b64 100644
--- a/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl
+++ b/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -93,8 +93,6 @@
-include("../ssa/hipe_ssa_const_prop.inc").
-type bool_lattice() :: 'true' | 'false' | 'top' | 'bottom'.
--type conditional() :: 'eq' | 'ne' | 'ge' | 'geu' | 'gt' | 'gtu' | 'le'
- | 'leu' | 'lt' | 'ltu' | 'overflow' | 'not_overflow'.
%%-----------------------------------------------------------------------------
%% Procedure : visit_expression/2
@@ -400,7 +398,7 @@ maybe_top_or_bottom([top | Rest], _) -> maybe_top_or_bottom(Rest, top);
maybe_top_or_bottom([bottom | _], _) -> bottom;
maybe_top_or_bottom([_ | Rest], TB) -> maybe_top_or_bottom(Rest, TB).
--spec partial_eval_branch(conditional(), bool_lattice(), bool_lattice(),
+-spec partial_eval_branch(hipe_rtl:alub_cond(), bool_lattice(), bool_lattice(),
bool_lattice() | 0, bool_lattice() | 0) ->
bool_lattice().
partial_eval_branch(Cond, N0, Z0, V0, C0) ->
@@ -441,14 +439,14 @@ visit_alub(Inst, Env) ->
hipe_rtl:alub_false_label(Inst)];
top -> [];
_ ->
- %if the partial branch cannot be evaluated we must execute the
- % instruction at runtime.
+ %% if the partial branch cannot be evaluated we must execute the
+ %% instruction at runtime.
case partial_eval_branch(hipe_rtl:alub_cond(Inst), N, Z, C, V) of
bottom -> [hipe_rtl:alub_true_label(Inst),
hipe_rtl:alub_false_label(Inst)];
top -> [];
- true -> [hipe_rtl:alub_true_label(Inst) ];
- false -> [hipe_rtl:alub_false_label(Inst) ]
+ true -> [hipe_rtl:alub_true_label(Inst)];
+ false -> [hipe_rtl:alub_false_label(Inst)]
end
end,
{[], NewSSA, NewEnv} = set_to(hipe_rtl:alub_dst(Inst), NewVal, Env),
@@ -944,8 +942,8 @@ update_branch(Inst, Env) ->
%% some small helpers.
alub_to_move(Inst, Res, Lab) ->
- [ hipe_rtl:mk_move(hipe_rtl:alub_dst(Inst), Res),
- hipe_rtl:mk_goto(Lab) ].
+ [hipe_rtl:mk_move(hipe_rtl:alub_dst(Inst), Res),
+ hipe_rtl:mk_goto(Lab)].
make_alub_subst_list(bottom, _, Tail) -> Tail;
make_alub_subst_list(top, Src, _) ->
@@ -970,13 +968,13 @@ update_alub(Inst, Env) ->
%% move and the branch. We can however replace variable with constants:
S1 = make_alub_subst_list(Val1, Src1, []),
S2 = make_alub_subst_list(Val2, Src2, S1),
- [ hipe_rtl:subst_uses(S2, Inst) ];
- _ -> % we know where we will be going, let's find out what Dst should be.
- % knowing where we are going means that at most one of the values is
- % bottom, hence we can replace the alu-instr with a move.
- % remember, a = b + 0 can give us enough info to know what jump to
- % do without knowing the value of a. (I wonder if this will ever
- % actualy happen ;)
+ [hipe_rtl:subst_uses(S2, Inst)];
+ _ -> %% we know where we will be going, let's find out what Dst should be.
+ %% knowing where we are going means that at most one of the values is
+ %% bottom, hence we can replace the alu-instr with a move.
+ %% remember, a = b + 0 can give us enough info to know what jump to
+ %% do without knowing the value of a. (I wonder if this will ever
+ %% actualy happen ;)
Res = case ResVal of
bottom -> % something nonconstant.
if (Val1 =:= bottom) -> Src1;
@@ -985,11 +983,12 @@ update_alub(Inst, Env) ->
_ -> hipe_rtl:mk_imm(ResVal)
end,
case CondRes of
- top -> io:format("oops. something VERY bad: ~w ~w V1 & 2 ~w ~w\n",
- [Inst, {ResVal, N, Z, C, V} , Val1, Val2]),
- [Inst ];
- true -> alub_to_move(Inst, Res, hipe_rtl:alub_true_label(Inst));
- false -> alub_to_move(Inst, Res, hipe_rtl:alub_false_label(Inst))
+ top ->
+ io:format("oops. something VERY bad: ~w ~w V1 & 2 ~w ~w\n",
+ [Inst, {ResVal, N, Z, C, V} , Val1, Val2]),
+ [Inst];
+ true -> alub_to_move(Inst, Res, hipe_rtl:alub_true_label(Inst));
+ false -> alub_to_move(Inst, Res, hipe_rtl:alub_false_label(Inst))
end
end.
@@ -1050,7 +1049,7 @@ update_phi(Instruction, Environment) ->
%%-----------------------------------------------------------------------------
-%% make sure that all precoloured rgisters are taken out of the equation.
+%% make sure that all precoloured registers are taken out of the equation.
lookup_lattice_value(X, Environment) ->
case hipe_rtl_arch:is_precoloured(X) or hipe_rtl:is_const_label(X) of
true ->
diff --git a/lib/hipe/rtl/hipe_tagscheme.erl b/lib/hipe/rtl/hipe_tagscheme.erl
index c0b6dfad8a..5859c345d0 100644
--- a/lib/hipe/rtl/hipe_tagscheme.erl
+++ b/lib/hipe/rtl/hipe_tagscheme.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
diff --git a/lib/hipe/tools/hipe_tool.erl b/lib/hipe/tools/hipe_tool.erl
index a1bd79895d..990805ceca 100644
--- a/lib/hipe/tools/hipe_tool.erl
+++ b/lib/hipe/tools/hipe_tool.erl
@@ -56,9 +56,9 @@
-record(state, {win_created = false :: boolean(),
mindex = 0 :: integer(),
- mod :: module(),
+ mod :: atom(),
funs = [] :: [fa()],
- mods = [] :: [module()],
+ mods = [] :: [atom()],
options = [o2] :: comp_options(),
compiling = false :: 'false' | pid()
}).
@@ -291,8 +291,7 @@ update_code_listbox(State) ->
integer_to_list(length(Mods))++")"),
catch gs:config(code_listbox, [{data, Mods},
{items, Mods},
- {selection, 0}
- ]),
+ {selection, 0}]),
update_module_box(State#state{mods = Mods}, 0, Mods, "")
end
end.
@@ -367,7 +366,7 @@ update_text(Lab, Text) ->
%% @doc Returns a list of all loaded modules.
%%---------------------------------------------------------------------
--spec mods() -> [module()].
+-spec mods() -> [atom()].
mods() ->
[Mod || {Mod,_File} <- code:all_loaded()].
@@ -382,25 +381,26 @@ funs(Mod) ->
native_code(Mod) ->
Mod:module_info(native_addresses).
--spec mfas(module(), [fa()]) -> [mfa()].
+-spec mfas(atom(), [fa()]) -> [mfa()].
mfas(Mod, Funs) ->
[{Mod,F,A} || {F,A} <- Funs].
--spec fun_names(module(), [fa()], [fa_address()], boolean()) -> string().
+-spec fun_names(atom(), [fa()], [fa_address()], boolean()) -> [string()].
fun_names(M, Funs, NativeCode, Prof) ->
- [list_to_atom(atom_to_list(F) ++ "/" ++ integer_to_list(A) ++
- (case in_native(F, A, NativeCode) of
- true -> " [native] ";
- false -> ""
- end)
- ++
- if Prof ->
- (catch integer_to_list(hipe_bifs:call_count_get({M,F,A})));
- true -> ""
- end) ||
- {F,A} <- Funs].
+ [atom_to_list(F) ++ "/" ++ integer_to_list(A)
+ ++
+ (case in_native(F, A, NativeCode) of
+ true -> " [native] ";
+ false -> ""
+ end)
+ ++
+ if Prof ->
+ (catch integer_to_list(hipe_bifs:call_count_get({M,F,A})));
+ true -> ""
+ end
+ || {F,A} <- Funs].
-spec in_native(atom(), arity(), [fa_address()]) -> boolean().
@@ -461,7 +461,7 @@ get_compile(Info) ->
false -> []
end.
--spec is_profiled(module()) -> boolean().
+-spec is_profiled(atom()) -> boolean().
is_profiled(Mod) ->
case hipe_bifs:call_count_get({Mod,module_info,0}) of
@@ -478,7 +478,7 @@ compile(State) ->
P = spawn(fun() -> c(Parent, State#state.mod, State#state.options) end),
State#state{compiling = P}.
--spec c(pid(), module(), comp_options()) -> 'ok'.
+-spec c(pid(), atom(), comp_options()) -> 'ok'.
c(Parent, Mod, Options) ->
Res = hipe:c(Mod, Options),
diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk
index 8e421ce9b2..6ba9009a24 100644
--- a/lib/hipe/vsn.mk
+++ b/lib/hipe/vsn.mk
@@ -1 +1 @@
-HIPE_VSN = 3.7.7
+HIPE_VSN = 3.7.9