aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/cerl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe/cerl')
-rw-r--r--lib/hipe/cerl/Makefile11
-rw-r--r--lib/hipe/cerl/cerl_to_icode.erl38
-rw-r--r--lib/hipe/cerl/erl_types.erl56
3 files changed, 64 insertions, 41 deletions
diff --git a/lib/hipe/cerl/Makefile b/lib/hipe/cerl/Makefile
index 506e993ff4..d13dfb33c2 100644
--- a/lib/hipe/cerl/Makefile
+++ b/lib/hipe/cerl/Makefile
@@ -42,8 +42,8 @@ RELSYSDIR = $(RELEASE_PATH)/lib/hipe-$(VSN)
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
-MODULES = cerl_cconv cerl_closurean cerl_hipeify \
- cerl_lib cerl_messagean cerl_pmatch cerl_prettypr cerl_to_icode \
+MODULES = cerl_cconv cerl_closurean cerl_hipeify cerl_lib \
+ cerl_messagean cerl_pmatch cerl_prettypr cerl_to_icode \
cerl_typean erl_bif_types erl_types
HRL_FILES= cerl_hipe_primops.hrl
@@ -65,7 +65,7 @@ DOC_FILES= $(MODULES:%=$(DOCS)/%.html)
include ../native.mk
-ERL_COMPILE_FLAGS += +inline +warn_exported_vars +warn_unused_import +warn_missing_spec# +warn_untyped_record
+ERL_COMPILE_FLAGS += -Werror +inline +warn_exported_vars +warn_unused_import +warn_missing_spec #+warn_untyped_record
# ----------------------------------------------------
# Targets
@@ -107,7 +107,6 @@ release_spec: opt
release_docs_spec:
-$(EBIN)/cerl_to_icode.beam: cerl_hipe_primops.hrl ../icode/hipe_icode_primops.hrl
+$(EBIN)/cerl_cconv.beam: cerl_hipe_primops.hrl
$(EBIN)/cerl_hipeify.beam: cerl_hipe_primops.hrl
-$(EBIN)/cerl_lambdalift.beam: cerl_hipe_primops.hrl
-$(EBIN)/erl_bif_types.beam: ../icode/hipe_icode_primops.hrl
+$(EBIN)/cerl_to_icode.beam: cerl_hipe_primops.hrl ../icode/hipe_icode_primops.hrl
diff --git a/lib/hipe/cerl/cerl_to_icode.erl b/lib/hipe/cerl/cerl_to_icode.erl
index 1c1c10d9b0..2645056be1 100644
--- a/lib/hipe/cerl/cerl_to_icode.erl
+++ b/lib/hipe/cerl/cerl_to_icode.erl
@@ -29,9 +29,9 @@
-define(NO_UNUSED, true).
--export([module/2]).
+-export([module/1, module/2]).
-ifndef(NO_UNUSED).
--export([function/3, function/4, module/1]).
+-export([function/3, function/4]).
-endif.
%% Added in an attempt to suppress message by Dialyzer, but I run into
@@ -102,36 +102,32 @@
%% Record definitions
--record(ctxt, {final = false :: boolean(),
- effect = false,
- fail = [], % [] or fail-to label
- class = expr, % expr | guard
- line = 0, % current line number
- 'receive' % undefined | #receive{}
- }).
-
-record('receive', {loop}).
-record(cerl_to_icode__var, {name}).
-record('fun', {label, vars}).
+-record(ctxt, {final = false :: boolean(),
+ effect = false :: boolean(),
+ fail = [], % [] or fail-to label
+ class = expr :: 'expr' | 'guard',
+ line = 0 :: erl_scan:line(), % current line number
+ 'receive' :: 'undefined' | #'receive'{}
+ }).
%% ---------------------------------------------------------------------
%% Code
-
-%% @spec module(Module::cerl()) -> [icode()]
+%% @spec module(Module::cerl()) -> [{mfa(), icode()}]
%% @equiv module(Module, [])
--ifndef(NO_UNUSED).
+-spec module(cerl:c_module()) -> [{mfa(), hipe_icode:icode()}].
+
module(E) ->
module(E, []).
--endif.
-%% @clear
-
-%% @spec module(Module::cerl(), Options::[term()]) -> [icode()]
+%% @spec module(Module::cerl(), Options::[term()]) -> [{mfa(), icode()}]
%%
-%% cerl() = cerl:cerl()
+%% cerl() = cerl:c_module()
%% icode() = hipe_icode:icode()
%%
%% @doc Transforms a Core Erlang module to linear HiPE Icode. The result
@@ -149,7 +145,7 @@ module(E) ->
%% @see function/4
%% @see cerl_hipeify:transform/1
-%% -spec module(cerl:c_module(), [term()]) -> [{mfa(), hipe_icode:icode()}].
+-spec module(cerl:c_module(), [term()]) -> [{mfa(), hipe_icode:icode()}].
module(E, Options) ->
module_1(cerl_hipeify:transform(E, Options), Options).
@@ -163,8 +159,8 @@ module_1(E, Options) ->
throw(error)
end,
S0 = init(M),
- S1 = s__set_pmatch(proplists:get_value(pmatch, Options), S0),
- S2 = s__set_bitlevel_binaries(proplists:get_value(
+ S1 = s__set_pmatch(proplists:get_value(pmatch, Options), S0),
+ S2 = s__set_bitlevel_binaries(proplists:get_value(
bitlevel_binaries, Options), S1),
{Icode, _} = lists:mapfoldl(fun function_definition/2,
S2, cerl:module_defs(E)),
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index 32390045e3..28281a2fac 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -218,6 +218,10 @@
%%-define(DO_ERL_TYPES_TEST, true).
-compile({no_auto_import,[min/2,max/2]}).
+%% HiPE does not understand Maps
+%% (guard function is_map/1 in t_from_term/1)
+-compile(no_native).
+
-ifdef(DO_ERL_TYPES_TEST).
-export([test/0]).
-else.
@@ -498,9 +502,9 @@ t_contains_opaque(?int_range(_From, _To), _Opaques) -> false;
t_contains_opaque(?int_set(_Set), _Opaques) -> false;
t_contains_opaque(?list(Type, Tail, _), Opaques) ->
t_contains_opaque(Type, Opaques) orelse t_contains_opaque(Tail, Opaques);
-t_contains_opaque(?map(Pairs), Opaques) ->
- list_contains_opaque([V||{_,V}<-Pairs], Opaques) orelse
- list_contains_opaque([K||{K,_}<-Pairs], Opaques);
+t_contains_opaque(?map(_) = Map, Opaques) ->
+ list_contains_opaque(map_values(Map), Opaques) orelse
+ list_contains_opaque(map_keys(Map), Opaques);
t_contains_opaque(?matchstate(_P, _Slots), _Opaques) -> false;
t_contains_opaque(?nil, _Opaques) -> false;
t_contains_opaque(?number(_Set, _Tag), _Opaques) -> false;
@@ -614,7 +618,7 @@ t_decorate_with_opaque(T1, T2, Opaques) ->
end
end.
-decorate(?none=Type, _, _Opaques) -> Type;
+decorate(Type, ?none, _Opaques) -> Type;
decorate(?function(Domain, Range), ?function(D, R), Opaques) ->
?function(decorate(Domain, D, Opaques), decorate(Range, R, Opaques));
decorate(?list(Types, Tail, Size), ?list(Ts, Tl, _Sz), Opaques) ->
@@ -680,6 +684,7 @@ union_decorate(U1, U2, Opaques) ->
List = [A,B,F,I,L,N,T,M,Map],
DecList = [Dec ||
E <- List,
+ not t_is_none(E),
not t_is_none(Dec = decorate(E, Opaque, Opaques))],
t_sup([Union|DecList]).
@@ -2089,6 +2094,8 @@ t_has_var(?tuple(Elements, _, _)) ->
t_has_var_list(Elements);
t_has_var(?tuple_set(_) = T) ->
t_has_var_list(t_tuple_subtypes(T));
+t_has_var(?map(_)= Map) ->
+ t_has_var_list(map_keys(Map)) orelse t_has_var_list(map_values(Map));
t_has_var(?opaque(Set)) ->
%% Assume variables in 'args' are also present i 'struct'
t_has_var_list([O#opaque.struct || O <- set_to_list(Set)]);
@@ -2116,21 +2123,28 @@ t_collect_vars(?function(Domain, Range), Acc) ->
t_collect_vars(?list(Contents, Termination, _), Acc) ->
ordsets:union(t_collect_vars(Contents, Acc), t_collect_vars(Termination, []));
t_collect_vars(?product(Types), Acc) ->
- lists:foldl(fun(T, TmpAcc) -> t_collect_vars(T, TmpAcc) end, Acc, Types);
+ t_collect_vars_list(Types, Acc);
t_collect_vars(?tuple(?any, ?any, ?any), Acc) ->
Acc;
t_collect_vars(?tuple(Types, _, _), Acc) ->
- lists:foldl(fun(T, TmpAcc) -> t_collect_vars(T, TmpAcc) end, Acc, Types);
+ t_collect_vars_list(Types, Acc);
t_collect_vars(?tuple_set(_) = TS, Acc) ->
- lists:foldl(fun(T, TmpAcc) -> t_collect_vars(T, TmpAcc) end, Acc,
- t_tuple_subtypes(TS));
+ t_collect_vars_list(t_tuple_subtypes(TS), Acc);
+t_collect_vars(?map(_) = Map, Acc0) ->
+ Acc = t_collect_vars_list(map_keys(Map), Acc0),
+ t_collect_vars_list(map_values(Map), Acc);
t_collect_vars(?opaque(Set), Acc) ->
%% Assume variables in 'args' are also present i 'struct'
- lists:foldl(fun(T, TmpAcc) -> t_collect_vars(T, TmpAcc) end, Acc,
- [O#opaque.struct || O <- set_to_list(Set)]);
+ t_collect_vars_list([O#opaque.struct || O <- set_to_list(Set)], Acc);
+t_collect_vars(?union(List), Acc) ->
+ t_collect_vars_list(List, Acc);
t_collect_vars(_, Acc) ->
Acc.
+t_collect_vars_list([T|Ts], Acc0) ->
+ Acc = t_collect_vars(T, Acc0),
+ t_collect_vars_list(Ts, Acc);
+t_collect_vars_list([], Acc) -> Acc.
%%=============================================================================
%%
@@ -2156,6 +2170,7 @@ t_from_term(T) when is_integer(T) -> t_integer(T);
t_from_term(T) when is_pid(T) -> t_pid();
t_from_term(T) when is_port(T) -> t_port();
t_from_term(T) when is_reference(T) -> t_reference();
+t_from_term(T) when is_map(T) -> t_map();
t_from_term(T) when is_tuple(T) ->
t_tuple([t_from_term(E) || E <- tuple_to_list(T)]).
@@ -3076,6 +3091,9 @@ t_subst_dict(?tuple(Elements, _Arity, _Tag), Dict) ->
t_tuple([t_subst_dict(E, Dict) || E <- Elements]);
t_subst_dict(?tuple_set(_) = TS, Dict) ->
t_sup([t_subst_dict(T, Dict) || T <- t_tuple_subtypes(TS)]);
+t_subst_dict(?map(Pairs), Dict) ->
+ ?map([{t_subst_dict(K, Dict), t_subst_dict(V, Dict)} ||
+ {K, V} <- Pairs]);
t_subst_dict(?opaque(Es), Dict) ->
List = [Opaque#opaque{args = [t_subst_dict(Arg, Dict) || Arg <- Args],
struct = t_subst_dict(S, Dict)} ||
@@ -3125,6 +3143,9 @@ t_subst_aux(?tuple(Elements, _Arity, _Tag), VarMap) ->
t_tuple([t_subst_aux(E, VarMap) || E <- Elements]);
t_subst_aux(?tuple_set(_) = TS, VarMap) ->
t_sup([t_subst_aux(T, VarMap) || T <- t_tuple_subtypes(TS)]);
+t_subst_aux(?map(Pairs), VarMap) ->
+ ?map([{t_subst_aux(K, VarMap), t_subst_aux(V, VarMap)} ||
+ {K, V} <- Pairs]);
t_subst_aux(?opaque(Es), VarMap) ->
List = [Opaque#opaque{args = [t_subst_aux(Arg, VarMap) || Arg <- Args],
struct = t_subst_aux(S, VarMap)} ||
@@ -3700,7 +3721,7 @@ t_unopaque(T) ->
t_unopaque(?opaque(_) = T, Opaques) ->
case Opaques =:= 'universe' orelse is_opaque_type(T, Opaques) of
true -> t_unopaque(t_opaque_structure(T), Opaques);
- false -> T % XXX: needs revision for parametric opaque data types
+ false -> T
end;
t_unopaque(?list(ElemT, Termination, Sz), Opaques) ->
?list(t_unopaque(ElemT, Opaques), t_unopaque(Termination, Opaques), Sz);
@@ -3720,11 +3741,12 @@ t_unopaque(?union([A,B,F,I,L,N,T,M,O,R,Map]), Opaques) ->
UL = t_unopaque(L, Opaques),
UT = t_unopaque(T, Opaques),
UF = t_unopaque(F, Opaques),
+ UMap = t_unopaque(Map, Opaques),
{OF,UO} = case t_unopaque(O, Opaques) of
?opaque(_) = O1 -> {O1, []};
Type -> {?none, [Type]}
end,
- t_sup([?union([A,B,UF,I,UL,N,UT,M,OF,R,Map])|UO]);
+ t_sup([?union([A,B,UF,I,UL,N,UT,M,OF,R,UMap])|UO]);
t_unopaque(T, _) ->
T.
@@ -4231,8 +4253,8 @@ t_from_form({type, _L, list, []}, _TypeNames, _RecDict, _VarDict) ->
t_from_form({type, _L, list, [Type]}, TypeNames, RecDict, VarDict) ->
{T, R} = t_from_form(Type, TypeNames, RecDict, VarDict),
{t_list(T), R};
-t_from_form({type, _L, map, _}, _TypeNames, _RecDict, _VarDict) ->
- {t_map([]), []};
+t_from_form({type, _L, map, _}, TypeNames, RecDict, VarDict) ->
+ builtin_type(map, t_map([]), TypeNames, RecDict, VarDict);
t_from_form({type, _L, mfa, []}, _TypeNames, _RecDict, _VarDict) ->
{t_mfa(), []};
t_from_form({type, _L, module, []}, _TypeNames, _RecDict, _VarDict) ->
@@ -4695,6 +4717,12 @@ is_same_type_name2(gb_trees, gb_tree, [], gb_trees, tree, [_, _]) -> true;
is_same_type_name2(gb_trees, tree, [_, _], gb_trees, gb_tree, []) -> true;
is_same_type_name2(_, _, _, _, _, _) -> false.
+map_keys(?map(Pairs)) ->
+ [K || {K, _} <- Pairs].
+
+map_values(?map(Pairs)) ->
+ [V || {_, V} <- Pairs].
+
%% -----------------------------------
%% Set
%%