aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe')
-rw-r--r--lib/hipe/cerl/erl_types.erl93
-rw-r--r--lib/hipe/doc/src/notes.xml95
-rw-r--r--lib/hipe/vsn.mk2
3 files changed, 144 insertions, 46 deletions
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index ea8cc1677d..0883a69918 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -228,7 +228,7 @@
-export([t_is_identifier/1]).
-endif.
--export_type([erl_type/0, opaques/0, type_table/0, mod_records/0,
+-export_type([erl_type/0, opaques/0, type_table/0,
var_table/0, cache/0]).
%%-define(DEBUG, true).
@@ -366,15 +366,17 @@
-type opaques() :: [erl_type()] | 'universe'.
+-type file_line() :: {file:name(), erl_anno:line()}.
-type record_key() :: {'record', atom()}.
-type type_key() :: {'type' | 'opaque', mfa()}.
--type record_value() :: [{atom(), erl_parse:abstract_expr(), erl_type()}].
--type type_value() :: {{module(), {file:name(), erl_anno:line()},
+-type field() :: {atom(), erl_parse:abstract_expr(), erl_type()}.
+-type record_value() :: {file_line(),
+ [{RecordSize :: non_neg_integer(), [field()]}]}.
+-type type_value() :: {{module(), file_line(),
erl_parse:abstract_type(), ArgNames :: [atom()]},
erl_type()}.
-type type_table() :: #{record_key() | type_key() =>
record_value() | type_value()}.
--type mod_records() :: dict:dict(module(), type_table()).
-opaque var_table() :: #{atom() => erl_type()}.
@@ -528,7 +530,9 @@ list_contains_opaque(List, Opaques) ->
'error' | {'ok', erl_type(), erl_type()}.
t_find_opaque_mismatch(T1, T2, Opaques) ->
- catch t_find_opaque_mismatch(T1, T2, T2, Opaques).
+ try t_find_opaque_mismatch(T1, T2, T2, Opaques)
+ catch throw:error -> error
+ end.
t_find_opaque_mismatch(?any, _Type, _TopType, _Opaques) -> error;
t_find_opaque_mismatch(?none, _Type, _TopType, _Opaques) -> throw(error);
@@ -580,8 +584,9 @@ t_find_opaque_mismatch_ordlists(L1, L2, TopType, Opaques) ->
t_find_opaque_mismatch_list(List).
t_find_opaque_mismatch_lists(L1, L2, _TopType, Opaques) ->
- List = [catch t_find_opaque_mismatch(T1, T2, T2, Opaques) ||
- T1 <- L1, T2 <- L2],
+ List = [try t_find_opaque_mismatch(T1, T2, T2, Opaques)
+ catch throw:error -> error
+ end || T1 <- L1, T2 <- L2],
t_find_opaque_mismatch_list(List).
t_find_opaque_mismatch_list([]) -> throw(error);
@@ -611,7 +616,9 @@ t_find_unknown_opaque(T1, T2, Opaques) ->
%% is assumed to be taken from the contract.
t_decorate_with_opaque(T1, T2, Opaques) ->
- case t_is_equal(T1, T2) orelse not t_contains_opaque(T2) of
+ case
+ Opaques =:= [] orelse t_is_equal(T1, T2) orelse not t_contains_opaque(T2)
+ of
true -> T1;
false ->
T = t_inf(T1, T2),
@@ -4249,8 +4256,8 @@ t_to_string(?opaque(Set), RecDict) ->
<- set_to_list(Set)],
" | ");
t_to_string(?matchstate(Pres, Slots), RecDict) ->
- flat_format("ms(~s,~s)", [t_to_string(Pres, RecDict),
- t_to_string(Slots,RecDict)]);
+ flat_format("ms(~ts,~ts)", [t_to_string(Pres, RecDict),
+ t_to_string(Slots,RecDict)]);
t_to_string(?nil, _RecDict) ->
"[]";
t_to_string(?nonempty_list(Contents, Termination), RecDict) ->
@@ -4428,10 +4435,10 @@ opaque_type(Mod, Name, Args, _S, RecDict) ->
opaque_name(Mod, Name, Extra) ->
S = mod_name(Mod, Name),
- flat_format("~s(~s)", [S, Extra]).
+ flat_format("~ts(~ts)", [S, Extra]).
mod_name(Mod, Name) ->
- flat_format("~w:~w", [Mod, Name]).
+ flat_format("~w:~tw", [Mod, Name]).
%%=============================================================================
%%
@@ -4447,11 +4454,11 @@ mod_name(Mod, Name) ->
-type cache_key() :: {module(), atom(), expand_depth(),
[erl_type()], type_names()}.
-type mod_type_table() :: ets:tid().
+-type mod_records() :: dict:dict(module(), type_table()).
-record(cache,
{
types = maps:new() :: #{cache_key() => {erl_type(), expand_limit()}},
- mod_recs = {mrecs, dict:new()} :: 'undefined'
- | {'mrecs', mod_records()}
+ mod_recs = {mrecs, dict:new()} :: {'mrecs', mod_records()}
}).
-opaque cache() :: #cache{}.
@@ -4800,7 +4807,7 @@ type_from_form1(Name, Args, ArgsLen, R, TypeName, TypeNames, S, D, L, C) ->
{NewType, L3, C4}
end;
error ->
- Msg = io_lib:format("Unable to find type ~w/~w\n",
+ Msg = io_lib:format("Unable to find type ~tw/~w\n",
[Name, ArgsLen]),
throw({error, Msg})
end.
@@ -4872,7 +4879,7 @@ remote_from_form1(RemMod, Name, Args, ArgsLen, RemDict, RemType, TypeNames,
{NewType, L3, C4}
end;
error ->
- Msg = io_lib:format("Unable to find remote type ~w:~w()\n",
+ Msg = io_lib:format("Unable to find remote type ~w:~tw()\n",
[RemMod, Name]),
throw({error, Msg})
end.
@@ -4917,7 +4924,7 @@ record_from_form({atom, _, Name}, ModFields, S, D0, L0, C) ->
case GetModRec of
{error, FieldName} ->
throw({error,
- io_lib:format("Illegal declaration of #~w{~w}\n",
+ io_lib:format("Illegal declaration of #~tw{~tw}\n",
[Name, FieldName])});
{ok, NewFields} ->
S2 = S1#from_form{vtab = var_table__new()},
@@ -4931,7 +4938,7 @@ record_from_form({atom, _, Name}, ModFields, S, D0, L0, C) ->
end,
recur_limit(Fun, D0, L0, RecordType, TypeNames);
error ->
- throw({error, io_lib:format("Unknown record #~w{}\n", [Name])})
+ throw({error, io_lib:format("Unknown record #~tw{}\n", [Name])})
end;
false ->
{t_any(), L0, C}
@@ -5105,8 +5112,8 @@ check_record({atom, _, Name}, ModFields, S, C) ->
{ok, DeclFields} = lookup_record(Name, R),
case check_fields(Name, ModFields, DeclFields, S, C1) of
{error, FieldName} ->
- throw({error, io_lib:format("Illegal declaration of #~w{~w}\n",
- [Name, FieldName])});
+ throw({error, io_lib:format("Illegal declaration of #~tw{~tw}\n",
+ [Name, FieldName])});
C2 -> C2
end.
@@ -5171,9 +5178,9 @@ cache_put(Key, Type, DeltaL, #cache{types = Types} = Cache) ->
NewTypes = maps:put(Key, {Type, DeltaL}, Types),
Cache#cache{types = NewTypes}.
--spec t_var_names([erl_type()]) -> [atom()].
+-spec t_var_names([parse_form()]) -> [atom()].
-t_var_names([{var, _, Name}|L]) when L =/= '_' ->
+t_var_names([{var, _, Name}|L]) when Name =/= '_' ->
[Name|t_var_names(L)];
t_var_names([]) ->
[].
@@ -5199,10 +5206,10 @@ t_form_to_string({op, _L, _Op, _Arg1, _Arg2} = Op) ->
t_form_to_string({ann_type, _L, [Var, Type]}) ->
t_form_to_string(Var) ++ "::" ++ t_form_to_string(Type);
t_form_to_string({paren_type, _L, [Type]}) ->
- flat_format("(~s)", [t_form_to_string(Type)]);
+ flat_format("(~ts)", [t_form_to_string(Type)]);
t_form_to_string({remote_type, _L, [{atom, _, Mod}, {atom, _, Name}, Args]}) ->
ArgString = "(" ++ string:join(t_form_to_string_list(Args), ",") ++ ")",
- flat_format("~w:~w", [Mod, Name]) ++ ArgString;
+ flat_format("~w:~tw", [Mod, Name]) ++ ArgString;
t_form_to_string({type, _L, arity, []}) -> "arity()";
t_form_to_string({type, _L, binary, []}) -> "binary()";
t_form_to_string({type, _L, binary, [Base, Unit]} = Type) ->
@@ -5252,12 +5259,12 @@ t_form_to_string({type, _L, range, [From, To]} = Type) ->
_ -> flat_format("Badly formed type ~w",[Type])
end;
t_form_to_string({type, _L, record, [{atom, _, Name}]}) ->
- flat_format("#~w{}", [Name]);
+ flat_format("#~tw{}", [Name]);
t_form_to_string({type, _L, record, [{atom, _, Name}|Fields]}) ->
FieldString = string:join(t_form_to_string_list(Fields), ","),
- flat_format("#~w{~s}", [Name, FieldString]);
+ flat_format("#~tw{~ts}", [Name, FieldString]);
t_form_to_string({type, _L, field_type, [{atom, _, Name}, Type]}) ->
- flat_format("~w::~s", [Name, t_form_to_string(Type)]);
+ flat_format("~tw::~ts", [Name, t_form_to_string(Type)]);
t_form_to_string({type, _L, term, []}) -> "term()";
t_form_to_string({type, _L, timeout, []}) -> "timeout()";
t_form_to_string({type, _L, tuple, any}) -> "tuple()";
@@ -5281,7 +5288,7 @@ t_form_to_string({type, _L, Name, []} = T) ->
catch throw:{error, _} -> atom_to_string(Name) ++ "()"
end;
t_form_to_string({user_type, _L, Name, List}) ->
- flat_format("~w(~s)",
+ flat_format("~tw(~ts)",
[Name, string:join(t_form_to_string_list(List), ",")]);
t_form_to_string({type, L, Name, List}) ->
%% Compatibility: modules compiled before Erlang/OTP 18.0.
@@ -5298,7 +5305,7 @@ t_form_to_string_list([], Acc) ->
-spec atom_to_string(atom()) -> string().
atom_to_string(Atom) ->
- flat_format("~w", [Atom]).
+ flat_format("~tw", [Atom]).
%%=============================================================================
%%
@@ -5331,21 +5338,17 @@ is_erl_type(_) -> false.
'error' | {type_table(), cache()}.
lookup_module_types(Module, CodeTable, Cache) ->
- #cache{mod_recs = ModRecs} = Cache,
- case ModRecs of
- undefined -> error;
- {mrecs, MRecs} ->
- case dict:find(Module, MRecs) of
- {ok, R} ->
- {R, Cache};
- error ->
- try ets:lookup_element(CodeTable, Module, 2) of
- R ->
- NewMRecs = dict:store(Module, R, MRecs),
- {R, Cache#cache{mod_recs = {mrecs, NewMRecs}}}
- catch
- _:_ -> error
- end
+ #cache{mod_recs = {mrecs, MRecs}} = Cache,
+ case dict:find(Module, MRecs) of
+ {ok, R} ->
+ {R, Cache};
+ error ->
+ try ets:lookup_element(CodeTable, Module, 2) of
+ R ->
+ NewMRecs = dict:store(Module, R, MRecs),
+ {R, Cache#cache{mod_recs = {mrecs, NewMRecs}}}
+ catch
+ _:_ -> error
end
end.
@@ -5551,7 +5554,7 @@ set_size(Set) ->
set_to_string(Set) ->
L = [case is_atom(X) of
true -> io_lib:write_string(atom_to_list(X), $'); % stupid emacs '
- false -> flat_format("~w", [X])
+ false -> flat_format("~tw", [X])
end || X <- set_to_list(Set)],
string:join(L, " | ").
diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml
index 38f8dbfea3..9167d0aaec 100644
--- a/lib/hipe/doc/src/notes.xml
+++ b/lib/hipe/doc/src/notes.xml
@@ -31,6 +31,101 @@
</header>
<p>This document describes the changes made to HiPE.</p>
+<section><title>Hipe 3.16</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix hipe compiler flags <c>o0</c> and <c>o1</c> that have
+ previously been ignored by mistake.</p>
+ <p>
+ Own Id: OTP-13862 Aux Id: PR-1154 </p>
+ </item>
+ <item>
+ <p>
+ Fix LLVM backend to not convert all remote calls to own
+ module, like <c>?MODULE:foo()</c>, into local calls.</p>
+ <p>
+ Own Id: OTP-13983</p>
+ </item>
+ <item>
+ <p>
+ Hipe optional LLVM backend does require LLVM version 3.9
+ or later as older versions forced strong dependencies on
+ erts internals structures.</p>
+ <p>
+ Own Id: OTP-14238</p>
+ </item>
+ <item>
+ <p>
+ Fix a bug that has been seen causing failed loading of
+ hipe compiled modules on NetBSD due to unaligned data
+ pointers.</p>
+ <p>
+ Own Id: OTP-14302 Aux Id: ERL-376, PR-1386 </p>
+ </item>
+ <item>
+ <p>
+ Fix miscompilation bug in hipe that could cause wrong
+ function clause to be called from non-tail calls, where
+ the return value is unused, if the right function clause
+ is only reachable from those non-tail calls.</p>
+ <p>
+ Own Id: OTP-14306 Aux Id: ERL-278, PR-1392 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Improve hipe compilation time for large functions.</p>
+ <p>
+ Own Id: OTP-13810 Aux Id: PR-1124 </p>
+ </item>
+ <item>
+ <p>Replaced usage of deprecated symbolic <seealso
+ marker="erts:erlang#type-time_unit"><c>time
+ unit</c></seealso> representations.</p>
+ <p>
+ Own Id: OTP-13831 Aux Id: OTP-13735 </p>
+ </item>
+ <item>
+ <p>
+ Speed up hipe compile time register allocation for larger
+ function.</p>
+ <p>
+ Own Id: OTP-13879</p>
+ </item>
+ <item>
+ <p>
+ Various code generation improvements.</p>
+ <p>
+ Own Id: OTP-14261 Aux Id: PR-1360 </p>
+ </item>
+ <item>
+ <p>
+ Improve hipe compiler to generate code with better CPU
+ register utilization at runtime by the use of 'Live Range
+ Splitting' techniques.</p>
+ <p>
+ Own Id: OTP-14293 Aux Id: PR-1380 </p>
+ </item>
+ <item>
+ <p>
+ Allow HiPE to run on VM built with
+ <c>--enable-m32-build</c>.</p>
+ <p>
+ Own Id: OTP-14330 Aux Id: PR-1397 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Hipe 3.15.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk
index 172d976931..0ef4aa7f09 100644
--- a/lib/hipe/vsn.mk
+++ b/lib/hipe/vsn.mk
@@ -1 +1 @@
-HIPE_VSN = 3.15.4
+HIPE_VSN = 3.16