aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/icode
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe/icode')
-rw-r--r--lib/hipe/icode/hipe_beam_to_icode.erl143
-rw-r--r--lib/hipe/icode/hipe_icode.erl14
-rw-r--r--lib/hipe/icode/hipe_icode.hrl8
-rw-r--r--lib/hipe/icode/hipe_icode_callgraph.erl4
-rw-r--r--lib/hipe/icode/hipe_icode_cfg.erl6
-rw-r--r--lib/hipe/icode/hipe_icode_coordinator.erl8
-rw-r--r--lib/hipe/icode/hipe_icode_exceptions.erl8
-rw-r--r--lib/hipe/icode/hipe_icode_fp.erl8
-rw-r--r--lib/hipe/icode/hipe_icode_instruction_counter.erl5
-rw-r--r--lib/hipe/icode/hipe_icode_mulret.erl20
-rw-r--r--lib/hipe/icode/hipe_icode_range.erl10
-rw-r--r--lib/hipe/icode/hipe_icode_ssa.erl4
-rw-r--r--lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl16
-rw-r--r--lib/hipe/icode/hipe_icode_type.erl53
14 files changed, 230 insertions, 77 deletions
diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl
index 81249c958e..4691662f9f 100644
--- a/lib/hipe/icode/hipe_beam_to_icode.erl
+++ b/lib/hipe/icode/hipe_beam_to_icode.erl
@@ -509,6 +509,10 @@ trans_fun([{test,test_arity,{f,Lbl},[Reg,N]}|Instructions], Env) ->
I = hipe_icode:mk_type([trans_arg(Reg)],{tuple,N},
hipe_icode:label_name(True),map_label(Lbl)),
[I,True | trans_fun(Instructions,Env)];
+%%--- is_map ---
+trans_fun([{test,is_map,{f,Lbl},[Arg]}|Instructions], Env) ->
+ {Code,Env1} = trans_type_test(map,Lbl,Arg,Env),
+ [Code | trans_fun(Instructions,Env1)];
%%--------------------------------------------------------------------
%%--- select_val ---
trans_fun([{select_val,Reg,{f,Lbl},{list,Cases}}|Instructions], Env) ->
@@ -1121,6 +1125,49 @@ trans_fun([{trim,N,NY}|Instructions], Env) ->
trans_fun([{line,_}|Instructions], Env) ->
trans_fun(Instructions,Env);
%%--------------------------------------------------------------------
+%% Map instructions added in Spring 2014 (17.0).
+%%--------------------------------------------------------------------
+trans_fun([{test,has_map_fields,{f,Lbl},Map,{list,Keys}}|Instructions], Env) ->
+ {MapMove, MapVar, Env1} = mk_move_and_var(Map, Env),
+ %% We assume that hipe_icode:mk_call has no side-effects, and reuse
+ %% the help function of get_map_elements below, discarding the value
+ %% assignment instruction list.
+ {TestInstructions, _GetInstructions, Env2} =
+ trans_map_query(MapVar, map_label(Lbl), Env1,
+ lists:flatten([[K, {r, 0}] || K <- Keys])),
+ [MapMove, TestInstructions | trans_fun(Instructions, Env2)];
+trans_fun([{get_map_elements,{f,Lbl},Map,{list,KVPs}}|Instructions], Env) ->
+ {MapMove, MapVar, Env1} = mk_move_and_var(Map, Env),
+ {TestInstructions, GetInstructions, Env2} =
+ trans_map_query(MapVar, map_label(Lbl), Env1, KVPs),
+ [MapMove, TestInstructions, GetInstructions | trans_fun(Instructions, Env2)];
+%%--- put_map_assoc ---
+trans_fun([{put_map_assoc,{f,Lbl},Map,Dst,_N,{list,Pairs}}|Instructions], Env) ->
+ {MapMove, MapVar, Env1} = mk_move_and_var(Map, Env),
+ TempMapVar = mk_var(new),
+ TempMapMove = hipe_icode:mk_move(TempMapVar, MapVar),
+ {PutInstructions, Env2}
+ = case Lbl > 0 of
+ true ->
+ gen_put_map_instrs(exists, assoc, TempMapVar, Dst, Lbl, Pairs, Env1);
+ false ->
+ gen_put_map_instrs(new, assoc, TempMapVar, Dst, new, Pairs, Env1)
+ end,
+ [MapMove, TempMapMove, PutInstructions | trans_fun(Instructions, Env2)];
+%%--- put_map_exact ---
+trans_fun([{put_map_exact,{f,Lbl},Map,Dst,_N,{list,Pairs}}|Instructions], Env) ->
+ {MapMove, MapVar, Env1} = mk_move_and_var(Map, Env),
+ TempMapVar = mk_var(new),
+ TempMapMove = hipe_icode:mk_move(TempMapVar, MapVar),
+ {PutInstructions, Env2}
+ = case Lbl > 0 of
+ true ->
+ gen_put_map_instrs(exists, exact, TempMapVar, Dst, Lbl, Pairs, Env1);
+ false ->
+ gen_put_map_instrs(new, exact, TempMapVar, Dst, new, Pairs, Env1)
+ end,
+ [MapMove, TempMapMove, PutInstructions | trans_fun(Instructions, Env2)];
+%%--------------------------------------------------------------------
%%--- ERROR HANDLING ---
%%--------------------------------------------------------------------
trans_fun([X|_], _) ->
@@ -1500,6 +1547,102 @@ trans_type_test2(function2, Lbl, Arg, Arity, Env) ->
hipe_icode:label_name(True), map_label(Lbl)),
{[Move1,Move2,I,True],Env2}.
+%%
+%% Handles the get_map_elements instruction and the has_map_fields
+%% test instruction.
+%%
+trans_map_query(_MapVar, _FailLabel, Env, []) ->
+ {[], [], Env};
+trans_map_query(MapVar, FailLabel, Env, [Key,Val|KVPs]) ->
+ {Move,KeyVar,Env1} = mk_move_and_var(Key,Env),
+ PassLabel = mk_label(new),
+ BoolVar = hipe_icode:mk_new_var(),
+ ValVar = mk_var(Val),
+ IsKeyCall = hipe_icode:mk_call([BoolVar], maps, is_key, [KeyVar, MapVar],
+ remote),
+ TrueTest = hipe_icode:mk_if('=:=', [BoolVar, hipe_icode:mk_const(true)],
+ hipe_icode:label_name(PassLabel), FailLabel),
+ GetCall = hipe_icode:mk_call([ValVar], maps, get, [KeyVar, MapVar], remote),
+ {TestList, GetList, Env2} = trans_map_query(MapVar, FailLabel, Env1, KVPs),
+ {[Move, IsKeyCall, TrueTest, PassLabel|TestList], [GetCall|GetList], Env2}.
+
+%%
+%% Generates a fail label if necessary when translating put_map_* instructions.
+%%
+gen_put_map_instrs(exists, Op, TempMapVar, Dst, FailLbl, Pairs, Env) ->
+ TrueLabel = mk_label(new),
+ IsMapCode = hipe_icode:mk_type([TempMapVar], map,
+ hipe_icode:label_name(TrueLabel), map_label(FailLbl)),
+ DstMapVar = mk_var(Dst),
+ {ReturnLbl, PutInstructions, Env1}
+ = case Op of
+ assoc ->
+ trans_put_map_assoc(TempMapVar, DstMapVar, Pairs, Env, []);
+ exact ->
+ trans_put_map_exact(TempMapVar, DstMapVar,
+ map_label(FailLbl), Pairs, Env, [])
+ end,
+ {[IsMapCode, TrueLabel, PutInstructions, ReturnLbl], Env1};
+gen_put_map_instrs(new, Op, TempMapVar, Dst, new, Pairs, Env) ->
+ TrueLabel = mk_label(new),
+ FailLbl = mk_label(new),
+ IsMapCode = hipe_icode:mk_type([TempMapVar], map,
+ hipe_icode:label_name(TrueLabel),
+ hipe_icode:label_name(FailLbl)),
+ DstMapVar = mk_var(Dst),
+ {ReturnLbl, PutInstructions, Env1}
+ = case Op of
+ assoc ->
+ trans_put_map_assoc(TempMapVar, DstMapVar, Pairs, Env, []);
+ exact ->
+ trans_put_map_exact(TempMapVar, DstMapVar,
+ hipe_icode:label_name(FailLbl), Pairs, Env, [])
+ end,
+ Fail = hipe_icode:mk_fail([hipe_icode:mk_const(badarg)], error),
+ {[IsMapCode, TrueLabel, PutInstructions, FailLbl, Fail, ReturnLbl], Env1}.
+
+%%-----------------------------------------------------------------------
+%% This function generates the instructions needed to insert several
+%% (Key, Value) pairs into an existing map, each recursive call inserts
+%% one (Key, Value) pair.
+%%-----------------------------------------------------------------------
+trans_put_map_assoc(MapVar, DestMapVar, [], Env, Acc) ->
+ MoveToReturnVar = hipe_icode:mk_move(DestMapVar, MapVar),
+ ReturnLbl = mk_label(new),
+ GotoReturn = hipe_icode:mk_goto(hipe_icode:label_name(ReturnLbl)),
+ {ReturnLbl, lists:reverse([GotoReturn, MoveToReturnVar | Acc]), Env};
+trans_put_map_assoc(MapVar, DestMapVar, [Key, Value | Rest], Env, Acc) ->
+ {MoveKey, KeyVar, Env1} = mk_move_and_var(Key, Env),
+ {MoveVal, ValVar, Env2} = mk_move_and_var(Value, Env1),
+ BifCall = hipe_icode:mk_call([MapVar], maps, put,
+ [KeyVar, ValVar, MapVar], remote),
+ trans_put_map_assoc(MapVar, DestMapVar, Rest, Env2,
+ [BifCall, MoveVal, MoveKey | Acc]).
+
+%%-----------------------------------------------------------------------
+%% This function generates the instructions needed to update several
+%% (Key, Value) pairs in an existing map, each recursive call inserts
+%% one (Key, Value) pair.
+%%-----------------------------------------------------------------------
+trans_put_map_exact(MapVar, DestMapVar, _FLbl, [], Env, Acc) ->
+ MoveToReturnVar = hipe_icode:mk_move(DestMapVar, MapVar),
+ ReturnLbl = mk_label(new),
+ GotoReturn = hipe_icode:mk_goto(hipe_icode:label_name(ReturnLbl)),
+ {ReturnLbl, lists:reverse([GotoReturn, MoveToReturnVar | Acc]), Env};
+trans_put_map_exact(MapVar, DestMapVar, FLbl, [Key, Value | Rest], Env, Acc) ->
+ SuccLbl = mk_label(new),
+ {MoveKey, KeyVar, Env1} = mk_move_and_var(Key, Env),
+ {MoveVal, ValVar, Env2} = mk_move_and_var(Value, Env1),
+ IsKey = hipe_icode:mk_new_var(),
+ BifCallIsKey = hipe_icode:mk_call([IsKey], maps, is_key,
+ [KeyVar, MapVar], remote),
+ IsKeyTest = hipe_icode:mk_if('=:=', [IsKey, hipe_icode:mk_const(true)],
+ hipe_icode:label_name(SuccLbl), FLbl),
+ BifCallPut = hipe_icode:mk_call([MapVar], maps, put,
+ [KeyVar, ValVar, MapVar], remote),
+ Acc1 = [BifCallPut, SuccLbl, IsKeyTest, BifCallIsKey, MoveVal, MoveKey | Acc],
+ trans_put_map_exact(MapVar, DestMapVar, FLbl, Rest, Env2, Acc1).
+
%%-----------------------------------------------------------------------
%% trans_puts(Code, Environment) ->
%% {Movs, Code, Vars, NewEnv}
diff --git a/lib/hipe/icode/hipe_icode.erl b/lib/hipe/icode/hipe_icode.erl
index 6d4758bbf1..7b3d087e2d 100644
--- a/lib/hipe/icode/hipe_icode.erl
+++ b/lib/hipe/icode/hipe_icode.erl
@@ -503,7 +503,6 @@
enter_args_update/2,
enter_type/1,
is_enter/1,
-
mk_return/1, %% mk_return(Vars)
%% mk_fail/1, %% mk_fail(Args) class = exit
@@ -606,6 +605,12 @@
-export([highest_var/1, highest_label/1]).
+%%
+%% Exported types
+%%
+
+-export_type([icode/0]).
+
%%---------------------------------------------------------------------
%%
%% Icode
@@ -614,7 +619,7 @@
-spec mk_icode(mfa(), [icode_var()], boolean(), boolean(), [icode_instr()],
{non_neg_integer(),non_neg_integer()},
- {icode_lbl(),icode_lbl()}) -> #icode{}.
+ {icode_lbl(),icode_lbl()}) -> icode().
mk_icode(Fun, Params, IsClosure, IsLeaf, Code, VarRange, LabelRange) ->
#icode{'fun'=Fun, params=Params, code=Code,
is_closure=IsClosure,
@@ -1434,8 +1439,8 @@ subst1([_|Pairs], I) -> subst1(Pairs, I).
%%
%% @doc Returns the successors of an Icode instruction.
%% In CFG form only branch instructions have successors,
-%% but in linear form other instructions like e.g. moves and
-%% others might be the last instruction of some basic block.
+%% but in linear form other instructions like e.g. moves
+%% might be the last instruction of some basic block.
%%
-spec successors(icode_instr()) -> [icode_lbl()].
@@ -1464,6 +1469,7 @@ successors(I) ->
case fail_label(I) of [] -> []; L when is_integer(L) -> [L] end;
#icode_enter{} -> [];
#icode_return{} -> [];
+ #icode_comment{} -> [];
%% the following are included here for handling linear code
#icode_move{} -> [];
#icode_begin_handler{} -> []
diff --git a/lib/hipe/icode/hipe_icode.hrl b/lib/hipe/icode/hipe_icode.hrl
index 060493e61e..46c04beb40 100644
--- a/lib/hipe/icode/hipe_icode.hrl
+++ b/lib/hipe/icode/hipe_icode.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2014. 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
@@ -61,8 +61,8 @@
| 'op_exact_eqeq_2' | 'suspend_msg_timeout'.
-type icode_type_test() :: 'atom' | 'bignum' | 'binary' | 'bitstr' | 'boolean'
- | 'cons' | 'fixnum' | 'float'
- | 'function' | 'function2' | 'integer' | 'list' | 'nil'
+ | 'cons' | 'fixnum' | 'float' | 'function'
+ | 'function2' | 'integer' | 'list' | 'map' | 'nil'
| 'number' | 'pid' | 'port' | 'reference' | 'tuple'
| {'atom', atom()} | {'integer', integer()}
| {'record', atom(), non_neg_integer()}
@@ -108,7 +108,6 @@
length :: non_neg_integer(),
cases :: [icode_switch_case()]}).
-
-record(icode_type, {test :: icode_type_test(),
args :: [icode_term_arg()],
true_label :: icode_lbl(),
@@ -178,5 +177,6 @@
var_range :: {non_neg_integer(), non_neg_integer()},
label_range :: {icode_lbl(), icode_lbl()},
info = [] :: icode_info()}).
+-type icode() :: #icode{}.
%%---------------------------------------------------------------------
diff --git a/lib/hipe/icode/hipe_icode_callgraph.erl b/lib/hipe/icode/hipe_icode_callgraph.erl
index 5789328f47..ccf97ecc17 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-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2014. 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
@@ -46,7 +46,7 @@
-type mfa_icode() :: {mfa(), #icode{}}.
--record(icode_callgraph, {codedict :: dict(), ordered_sccs :: [[mfa()]]}).
+-record(icode_callgraph, {codedict :: dict:dict(), ordered_sccs :: [[mfa()]]}).
%%------------------------------------------------------------------------
%% Exported functions
diff --git a/lib/hipe/icode/hipe_icode_cfg.erl b/lib/hipe/icode/hipe_icode_cfg.erl
index 9b4a10e273..f6c2b0600b 100644
--- a/lib/hipe/icode/hipe_icode_cfg.erl
+++ b/lib/hipe/icode/hipe_icode_cfg.erl
@@ -3,7 +3,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2014. 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
@@ -54,8 +54,8 @@
-spec postorder(cfg()) -> [icode_lbl()].
-spec reverse_postorder(cfg()) -> [icode_lbl()].
--spec is_visited(icode_lbl(), gb_set()) -> boolean().
--spec visit(icode_lbl(), gb_set()) -> gb_set().
+-spec is_visited(icode_lbl(), gb_sets:set()) -> boolean().
+-spec visit(icode_lbl(), gb_sets:set()) -> gb_sets:set().
-spec bb(cfg(), icode_lbl()) -> 'not_found' | bb().
-spec bb_add(cfg(), icode_lbl(), bb()) -> cfg().
diff --git a/lib/hipe/icode/hipe_icode_coordinator.erl b/lib/hipe/icode/hipe_icode_coordinator.erl
index 79e3304e6f..c69db9afa9 100644
--- a/lib/hipe/icode/hipe_icode_coordinator.erl
+++ b/lib/hipe/icode/hipe_icode_coordinator.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2014. 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
@@ -49,9 +49,9 @@ coordinate(CG, Escaping, NonEscaping, Mod) ->
-type mfalists() :: {[mfa()], [mfa()]}.
--spec coordinate(mfalists(), hipe_digraph:hdg(), gb_tree(),
- fun((mfalists(), gb_tree()) -> mfalists()),
- fun((gb_tree()) -> 'ok'), pid()) -> no_return().
+-spec coordinate(mfalists(), hipe_digraph:hdg(), gb_trees:tree(),
+ fun((mfalists(), gb_trees:tree()) -> mfalists()),
+ fun((gb_trees:tree()) -> 'ok'), pid()) -> no_return().
coordinate(MFALists, CG, PM, Restart, LastAction, ServerPid) ->
case MFALists of
diff --git a/lib/hipe/icode/hipe_icode_exceptions.erl b/lib/hipe/icode/hipe_icode_exceptions.erl
index 00caffb24b..6191c536ad 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-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2014. 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
@@ -397,9 +397,9 @@ get_renaming(C, Map) ->
succ :: #cfg{},
pred :: #cfg{},
start_labels :: [icode_lbl(),...],
- visited = hipe_icode_cfg:none_visited() :: gb_set(),
- out = gb_trees:empty() :: gb_tree(),
- in = gb_trees:empty() :: gb_tree()
+ visited = hipe_icode_cfg:none_visited() :: gb_sets:set(),
+ out = gb_trees:empty() :: gb_trees:tree(),
+ in = gb_trees:empty() :: gb_trees:tree()
}).
init_state(CFG) ->
diff --git a/lib/hipe/icode/hipe_icode_fp.erl b/lib/hipe/icode/hipe_icode_fp.erl
index a2ca6132d1..38b3881a77 100644
--- a/lib/hipe/icode/hipe_icode_fp.erl
+++ b/lib/hipe/icode/hipe_icode_fp.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2014. 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
@@ -33,8 +33,8 @@
-include("hipe_icode.hrl").
-include("../flow/cfg.hrl").
--record(state, {edge_map = gb_trees:empty() :: gb_tree(),
- fp_ebb_map = gb_trees:empty() :: gb_tree(),
+-record(state, {edge_map = gb_trees:empty() :: gb_trees:tree(),
+ fp_ebb_map = gb_trees:empty() :: gb_trees:tree(),
cfg :: #cfg{}}).
%%--------------------------------------------------------------------
@@ -424,7 +424,7 @@ redirect_phis([I|Is] = Code, OldFrom, NewFrom, Acc) ->
NewI = hipe_icode:phi_redirect_pred(I, OldFrom, NewFrom),
redirect_phis(Is, OldFrom, NewFrom, [NewI|Acc]);
_ ->
- lists:reverse(Acc) ++ Code
+ lists:reverse(Acc, Code)
end;
redirect_phis([], _OldFrom, _NewFrom, Acc) ->
lists:reverse(Acc).
diff --git a/lib/hipe/icode/hipe_icode_instruction_counter.erl b/lib/hipe/icode/hipe_icode_instruction_counter.erl
index 92658d294a..f44adfe149 100644
--- a/lib/hipe/icode/hipe_icode_instruction_counter.erl
+++ b/lib/hipe/icode/hipe_icode_instruction_counter.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2014. 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
@@ -64,7 +64,8 @@ walktrough_bb(BB, Info) ->
%% The counter specific functions
%%-------------------------------------------------------------------
--spec compare(gb_tree(), gb_tree(), gb_tree()) -> gb_tree().
+-spec compare(gb_trees:tree(), gb_trees:tree(), gb_trees:tree()) ->
+ gb_trees:tree().
compare(Name, Old, New) ->
NewList = gb_trees:to_list(New),
diff --git a/lib/hipe/icode/hipe_icode_mulret.erl b/lib/hipe/icode/hipe_icode_mulret.erl
index 0bf9f89994..99522f6430 100644
--- a/lib/hipe/icode/hipe_icode_mulret.erl
+++ b/lib/hipe/icode/hipe_icode_mulret.erl
@@ -1,8 +1,8 @@
-%% -*- coding: utf-8; erlang-indent-level: 2 -*-
+%% -*- erlang-indent-level: 2 -*-
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2013. 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
@@ -1166,9 +1166,9 @@ printCallList([]) -> io:format("~n").
%% removeUnElems([#icode_call{'fun'={unsafe_element,_}, args=Var}|List], Var, Res) ->
%% removeUnElems(List, Var, Res);
%% removeUnElems([I=#icode_move{dst=Var}|List], [Var], Res) ->
-%% lists:reverse(Res) ++ [I|List];
+%% lists:reverse(Res, [I|List]);
%% removeUnElems([I=#icode_call{dstlist=Var}|List], Var, Res) ->
-%% lists:reverse(Res) ++ [I|List];
+%% lists:reverse(Res, [I|List]);
%% removeUnElems([I|List], Var, Res) ->
%% removeUnElems(List, Var, [I|Res]);
%% removeUnElems([], _, Res) -> lists:reverse(Res).
@@ -1187,7 +1187,7 @@ printCallList([]) -> io:format("~n").
%% false ->
%% case lists:member(Var, Defs) of
%% true ->
-%% lists:reverse(Res) ++ [I|List];
+%% lists:reverse(Res, [I|List]);
%% false ->
%% removeUnElems(List, Var, [I|Res])
%% end
@@ -1195,7 +1195,7 @@ printCallList([]) -> io:format("~n").
%% false ->
%% case lists:member(Var, Defs) of
%% true ->
-%% lists:reverse(Res) ++ [I|List];
+%% lists:reverse(Res, [I|List]);
%% false ->
%% removeUnElems(List, Var, [I|Res])
%% end
@@ -1203,7 +1203,7 @@ printCallList([]) -> io:format("~n").
%% false ->
%% case lists:member(Var, Defs) of
%% true ->
-%% lists:reverse(Res) ++ [I|List];
+%% lists:reverse(Res, [I|List]);
%% false ->
%% removeUnElems(List, Var, [I|Res])
%% end
@@ -1248,16 +1248,16 @@ printCallList([]) -> io:format("~n").
%% modifyCode([I|Code], Var, Res) ->
%% case scanInstr(I, Var) of
%% {move, Arity, VarLst} ->
-%% Code2 = [#icode_return{vars=VarLst}, I |lists:reverse(Res) ++ Code],
+%% Code2 = [#icode_return{vars=VarLst}, I |lists:reverse(Res, Code)],
%% {Arity, lists:reverse(Code2)};
%% {mktuple, Arity, VarLst} ->
-%% Code2 = [#icode_return{vars=VarLst}|lists:reverse(Res) ++ Code],
+%% Code2 = [#icode_return{vars=VarLst}|lists:reverse(Res, Code)],
%% {Arity, lists:reverse(Code2)};
%% other ->
%% modifyCode(Code, Var, [I|Res])
%% end;
%% modifyCode([], Var, Res) ->
-%% {1, lists:reverse(Res) ++ [#icode_return{vars=Var}]}.
+%% {1, lists:reverse(Res, [#icode_return{vars=Var}]}.
%% scanInstr(#icode_call{dstlist=Var, 'fun'=mktuple, args=Lst}, Var) ->
%% {mktuple, length(Lst), Lst};
diff --git a/lib/hipe/icode/hipe_icode_range.erl b/lib/hipe/icode/hipe_icode_range.erl
index 1a2cbfae31..fbc58f3568 100644
--- a/lib/hipe/icode/hipe_icode_range.erl
+++ b/lib/hipe/icode/hipe_icode_range.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2014. 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
@@ -72,8 +72,8 @@
-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().
--type work_list() :: {[label()], [label()], set()}.
+-type info() :: gb_trees:tree().
+-type work_list() :: {[label()], [label()], sets:set()}.
-type variable() :: #icode_variable{}.
-type annotated_variable() :: #icode_variable{}.
-type argument() :: #icode_const{} | variable().
@@ -82,9 +82,9 @@
-type last_instr_return() :: {instr_split_info(), range()}.
-record(state, {info_map = gb_trees:empty() :: info(),
- counter = dict:new() :: dict(),
+ counter = dict:new() :: dict:dict(),
cfg :: cfg(),
- liveness = gb_trees:empty() :: gb_tree(),
+ liveness = gb_trees:empty() :: gb_trees:tree(),
ret_type :: range(),
lookup_fun :: call_fun(),
result_action :: final_fun()}).
diff --git a/lib/hipe/icode/hipe_icode_ssa.erl b/lib/hipe/icode/hipe_icode_ssa.erl
index 4607a96dda..2c4b6d9409 100644
--- a/lib/hipe/icode/hipe_icode_ssa.erl
+++ b/lib/hipe/icode/hipe_icode_ssa.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2014. 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
@@ -37,7 +37,7 @@
-include("../ssa/hipe_ssa.inc").
%% Declarations for exported functions which are Icode-specific.
--spec ssa_liveness__analyze(#cfg{}) -> gb_tree().
+-spec ssa_liveness__analyze(#cfg{}) -> gb_trees:tree().
-spec ssa_liveness__livein(_, icode_lbl()) -> [#icode_variable{}].
%% -spec ssa_liveness__livein(_, icode_lbl(), _) -> [#icode_var{}].
diff --git a/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl b/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl
index 2337ef9323..772e30eada 100644
--- a/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl
+++ b/lib/hipe/icode/hipe_icode_ssa_struct_reuse.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2014. 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
@@ -70,9 +70,9 @@
%% var - maps variables to expression value numbers. These variables are
%% defined or used by the structure expressions.
--record(maps, {var = gb_trees:empty() :: gb_tree(),
- instr = gb_trees:empty() :: gb_tree(),
- expr = gb_trees:empty() :: gb_tree()}).
+-record(maps, {var = gb_trees:empty() :: gb_trees:tree(),
+ instr = gb_trees:empty() :: gb_trees:tree(),
+ expr = gb_trees:empty() :: gb_trees:tree()}).
maps_var(#maps{var = Out}) -> Out.
maps_instr(#maps{instr = Out}) -> Out.
@@ -211,10 +211,10 @@ varinfo_use_add(#varinfo{use = UseSet} = I, Use) ->
pred = none :: 'none' | [icode_lbl()],
succ = none :: 'none' | [icode_lbl()],
code = [] :: [tuple()], % [illegal_icode_instr()]
- phi = gb_trees:empty() :: gb_tree(),
+ phi = gb_trees:empty() :: gb_trees:tree(),
varmap = [] :: [{icode_var(), icode_var()}],
pre_loop = false :: boolean(),
- non_struct_defs = gb_sets:new() :: gb_set(),
+ non_struct_defs = gb_sets:new() :: gb_sets:set(),
up_expr = none :: 'none' | ?SETS:?SET(_),
killed_expr = none :: 'none' | ?SETS:?SET(_),
sub_inserts = ?SETS:new() :: ?SETS:?SET(_),
@@ -319,7 +319,7 @@ node_create(Label, Pred, Succ) ->
start_label = none :: 'none' | icode_lbl(),
rev_postorder = none :: 'none' | [icode_lbl()],
all_expr = none :: 'none' | [non_neg_integer()],
- tree = gb_trees:empty() :: gb_tree()}).
+ tree = gb_trees:empty() :: gb_trees:tree()}).
nodes_postorder(#nodes{postorder = Out}) -> Out.
nodes_rev_postorder(#nodes{rev_postorder = Out}) -> Out.
@@ -356,7 +356,7 @@ nodes_create() -> #nodes{}.
%% del_red_test - flag that is set to true when the reduction test
%% has been inserted is used to move the reduction test.
--record(update, {inserted = gb_trees:empty() :: gb_tree(),
+-record(update, {inserted = gb_trees:empty() :: gb_trees:tree(),
del_red_test = false :: boolean()}).
update_inserted_lookup(#update{inserted = Inserted}, ExprId) ->
diff --git a/lib/hipe/icode/hipe_icode_type.erl b/lib/hipe/icode/hipe_icode_type.erl
index 046949d2f2..ebeb5e2c10 100644
--- a/lib/hipe/icode/hipe_icode_type.erl
+++ b/lib/hipe/icode/hipe_icode_type.erl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2014. 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
@@ -84,22 +84,22 @@
t_fun/0, t_fun/1, t_fun/2, t_fun_args/1, t_fun_arity/1,
t_inf/2, t_inf_lists/2, t_integer/0,
t_integer/1, t_is_atom/1, t_is_any/1,
- t_is_binary/1, t_is_bitstr/1, t_is_bitwidth/1, t_is_boolean/1,
- t_is_fixnum/1, t_is_cons/1,
+ t_is_binary/1, t_is_bitstr/1, t_is_bitwidth/1,
+ t_is_boolean/1, t_is_fixnum/1, t_is_cons/1, t_is_map/1,
t_is_maybe_improper_list/1, t_is_equal/2, t_is_float/1,
t_is_fun/1, t_is_integer/1, t_is_non_neg_integer/1,
t_is_number/1, t_is_matchstate/1,
- t_is_nil/1, t_is_none/1, t_is_port/1, t_is_pid/1,
+ t_is_none/1, t_is_port/1, t_is_pid/1,
t_is_reference/1, t_is_subtype/2, t_is_tuple/1,
t_limit/2, t_matchstate_present/1, t_matchstate/0,
- t_matchstate_slots/1, t_maybe_improper_list/0,
+ t_matchstate_slots/1, t_maybe_improper_list/0, t_map/0,
t_nil/0, t_none/0, t_number/0, t_number/1, t_number_vals/1,
t_pid/0, t_port/0, t_reference/0, t_subtract/2, t_sup/2,
t_to_tlist/1, t_tuple/0, t_tuple/1, t_tuple_sizes/1]).
--record(state, {info_map = gb_trees:empty() :: gb_tree(),
+-record(state, {info_map = gb_trees:empty() :: gb_trees:tree(),
cfg :: cfg(),
- liveness = gb_trees:empty() :: gb_tree(),
+ liveness = gb_trees:empty() :: gb_trees:tree(),
arg_types :: [erl_types:erl_type()],
ret_type = [t_none()] :: [erl_types:erl_type()],
lookupfun :: call_fun(),
@@ -213,7 +213,7 @@ analyse_blocks(Work, State, MFA) ->
{NewState, NewLabels} =
try analyse_block(Label, Info, State)
catch throw:none_type ->
- %% io:format("received none type at label: ~p~n",[Label]),
+ %% io:format("received none type at label: ~p~n", [Label]),
{State,[]}
end,
NewWork2 = add_work(NewWork, NewLabels),
@@ -265,7 +265,7 @@ analyse_insn(I, Info, LookupFun) ->
do_move(I, Info);
#icode_call{} ->
NewInfo = do_call(I, Info, LookupFun),
- %%io:format("Analysing Call: ~w~n~w~n", [I,NewInfo]),
+ %% io:format("Analysing Call: ~w~n~w~n", [I, NewInfo]),
update_call_arguments(I, NewInfo);
#icode_phi{} ->
Type = t_limit(join_list(hipe_icode:args(I), Info), ?TYPE_DEPTH),
@@ -788,16 +788,16 @@ test_record(Atom, Size, Var, VarInfo, TrueLab, FalseLab, Info) ->
end.
test_type(Test, Type) ->
- %%io:format("Test is: ~w\n", [Test]),
- %%io:format("Type is: ~s\n", [format_type(Type)]),
+ %% io:format("Test is: ~w\n", [Test]),
+ %% io:format("Type is: ~s\n", [format_type(Type)]),
Ans =
case t_is_any(Type) of
true -> maybe;
false ->
TrueTest = true_branch_info(Test),
Inf = t_inf(TrueTest, Type),
- %%io:format("TrueTest is: ~s\n", [format_type(TrueTest)]),
- %%io:format("Inf is: ~s\n", [format_type(Inf)]),
+ %% io:format("TrueTest is: ~s\n", [format_type(TrueTest)]),
+ %% io:format("Inf is: ~s\n", [format_type(Inf)]),
case t_is_equal(Type, Inf) of
true ->
not t_is_none(Type);
@@ -895,11 +895,12 @@ test_type0(boolean, T) ->
t_is_boolean(T);
test_type0(list, T) ->
t_is_maybe_improper_list(T);
-test_type0(cons, T) ->
- t_is_cons(T);
-test_type0(nil, T) ->
- t_is_nil(T).
-
+%% test_type0(cons, T) ->
+%% t_is_cons(T);
+%% test_type0(nil, T) ->
+%% t_is_nil(T).
+test_type0(map, T) ->
+ t_is_map(T).
true_branch_info(integer) ->
t_integer();
@@ -931,22 +932,24 @@ true_branch_info(reference) ->
t_reference();
true_branch_info(function) ->
t_fun();
-true_branch_info(cons) ->
- t_cons();
-true_branch_info(nil) ->
- t_nil();
+%% true_branch_info(cons) ->
+%% t_cons();
+%% true_branch_info(nil) ->
+%% t_nil();
true_branch_info(boolean) ->
t_boolean();
+true_branch_info(map) ->
+ t_map();
true_branch_info(T) ->
- exit({?MODULE,unknown_typetest,T}).
+ exit({?MODULE, unknown_typetest, T}).
%% _________________________________________________________________
%%
%% Remove the redundant type tests. If a test is removed, the trace
-%% that isn't taken is explicitly removed from the CFG to simpilify
+%% that isn't taken is explicitly removed from the CFG to simplify
%% the handling of Phi nodes. If a Phi node is left and at least one
-%% branch into it has disappeared, the SSA propagation pass can't
+%% branch into it has disappeared, the SSA propagation pass cannot
%% handle it.
%%
%% If the CFG has changed at the end of this pass, the analysis is