aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/icode/hipe_icode.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe/icode/hipe_icode.erl')
-rw-r--r--lib/hipe/icode/hipe_icode.erl76
1 files changed, 43 insertions, 33 deletions
diff --git a/lib/hipe/icode/hipe_icode.erl b/lib/hipe/icode/hipe_icode.erl
index 5c7003b0ed..24b7ac4783 100644
--- a/lib/hipe/icode/hipe_icode.erl
+++ b/lib/hipe/icode/hipe_icode.erl
@@ -1,9 +1,5 @@
%% -*- erlang-indent-level: 2 -*-
%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2013. All Rights Reserved.
-%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
@@ -16,8 +12,6 @@
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
-%% %CopyrightEnd%
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% HiPE Intermediate Code
%% ====================================================================
@@ -30,9 +24,6 @@
%% 2003-03-15 ES ([email protected]):
%% Started commenting in Edoc.
%% Moved pretty printer to separate file.
-%%
-%% $Id$
-%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%@doc
@@ -438,6 +429,7 @@
if_true_label/1,
if_false_label/1,
if_args/1,
+ if_args_update/2,
if_pred/1,
%% is_if/1,
@@ -594,6 +586,7 @@
uses/1,
defines/1,
is_safe/1,
+ reduce_unused/1,
strip_comments/1,
subst/2,
subst_uses/2,
@@ -610,7 +603,9 @@
%% Exported types
%%
--export_type([icode/0]).
+-export_type([icode/0, params/0]).
+
+-type params() :: [icode_var()].
%%---------------------------------------------------------------------
%%
@@ -618,7 +613,7 @@
%%
%%---------------------------------------------------------------------
--spec mk_icode(mfa(), [icode_var()], boolean(), boolean(), [icode_instr()],
+-spec mk_icode(mfa(), params(), boolean(), boolean(), [icode_instr()],
{non_neg_integer(),non_neg_integer()},
{icode_lbl(),icode_lbl()}) -> icode().
mk_icode(Fun, Params, IsClosure, IsLeaf, Code, VarRange, LabelRange) ->
@@ -629,61 +624,61 @@ mk_icode(Fun, Params, IsClosure, IsLeaf, Code, VarRange, LabelRange) ->
var_range=VarRange,
label_range=LabelRange}.
--spec mk_icode(mfa(), [icode_var()], boolean(), boolean(), [icode_instr()],
+-spec mk_icode(mfa(), params(), boolean(), boolean(), [icode_instr()],
hipe_consttab(), {non_neg_integer(),non_neg_integer()},
- {icode_lbl(),icode_lbl()}) -> #icode{}.
+ {icode_lbl(),icode_lbl()}) -> icode().
mk_icode(Fun, Params, IsClosure, IsLeaf, Code, Data, VarRange, LabelRange) ->
#icode{'fun'=Fun, params=Params, code=Code,
data=Data, is_closure=IsClosure, is_leaf=IsLeaf,
var_range=VarRange, label_range=LabelRange}.
--spec icode_fun(#icode{}) -> mfa().
+-spec icode_fun(icode()) -> mfa().
icode_fun(#icode{'fun' = MFA}) -> MFA.
--spec icode_params(#icode{}) -> [icode_var()].
+-spec icode_params(icode()) -> params().
icode_params(#icode{params = Params}) -> Params.
--spec icode_params_update(#icode{}, [icode_var()]) -> #icode{}.
-icode_params_update(Icode, Params) ->
+-spec icode_params_update(icode(), params()) -> icode().
+icode_params_update(Icode, Params) ->
Icode#icode{params = Params}.
--spec icode_is_closure(#icode{}) -> boolean().
+-spec icode_is_closure(icode()) -> boolean().
icode_is_closure(#icode{is_closure = Closure}) -> Closure.
--spec icode_is_leaf(#icode{}) -> boolean().
+-spec icode_is_leaf(icode()) -> boolean().
icode_is_leaf(#icode{is_leaf = Leaf}) -> Leaf.
--spec icode_code(#icode{}) -> icode_instrs().
+-spec icode_code(icode()) -> icode_instrs().
icode_code(#icode{code = Code}) -> Code.
--spec icode_code_update(#icode{}, icode_instrs()) -> #icode{}.
+-spec icode_code_update(icode(), icode_instrs()) -> icode().
icode_code_update(Icode, NewCode) ->
Vmax = highest_var(NewCode),
Lmax = highest_label(NewCode),
Icode#icode{code = NewCode, var_range = {0,Vmax}, label_range = {0,Lmax}}.
--spec icode_data(#icode{}) -> hipe_consttab().
+-spec icode_data(icode()) -> hipe_consttab().
icode_data(#icode{data=Data}) -> Data.
-%% %% -spec icode_data_update(#icode{}, hipe_consttab()) -> #icode{}.
+%% %% -spec icode_data_update(icode(), hipe_consttab()) -> icode().
%% icode_data_update(Icode, NewData) -> Icode#icode{data=NewData}.
--spec icode_var_range(#icode{}) -> {non_neg_integer(), non_neg_integer()}.
+-spec icode_var_range(icode()) -> {non_neg_integer(), non_neg_integer()}.
icode_var_range(#icode{var_range = VarRange}) -> VarRange.
--spec icode_label_range(#icode{}) -> {non_neg_integer(), non_neg_integer()}.
+-spec icode_label_range(icode()) -> {non_neg_integer(), non_neg_integer()}.
icode_label_range(#icode{label_range = LabelRange}) -> LabelRange.
--spec icode_info(#icode{}) -> icode_info().
+-spec icode_info(icode()) -> icode_info().
icode_info(#icode{info = Info}) -> Info.
--spec icode_info_update(#icode{}, icode_info()) -> #icode{}.
+-spec icode_info_update(icode(), icode_info()) -> icode().
icode_info_update(Icode, Info) -> Icode#icode{info = Info}.
--spec icode_closure_arity(#icode{}) -> arity().
+-spec icode_closure_arity(icode()) -> arity().
icode_closure_arity(#icode{closure_arity = Arity}) -> Arity.
--spec icode_closure_arity_update(#icode{}, arity()) -> #icode{}.
+-spec icode_closure_arity_update(icode(), arity()) -> icode().
icode_closure_arity_update(Icode, Arity) -> Icode#icode{closure_arity = Arity}.
@@ -711,6 +706,9 @@ if_op_update(IF, NewOp) -> IF#icode_if{op=NewOp}.
-spec if_args(#icode_if{}) -> [icode_term_arg()].
if_args(#icode_if{args=Args}) -> Args.
+-spec if_args_update(#icode_if{}, [icode_term_arg()]) -> #icode_if{}.
+if_args_update(IF, Args) -> IF#icode_if{args=Args}.
+
-spec if_true_label(#icode_if{}) -> icode_lbl().
if_true_label(#icode_if{true_label=TrueLbl}) -> TrueLbl.
@@ -1376,12 +1374,12 @@ remove_constants(L) ->
%% Substitution: replace occurrences of X by Y if {X,Y} is in the
%% Subst_list.
--spec subst([{_,_}], I) -> I when is_subtype(I, icode_instr()).
+-spec subst([{_,_}], I) -> I when I :: icode_instr().
subst(Subst, I) ->
subst_defines(Subst, subst_uses(Subst, I)).
--spec subst_uses([{_,_}], I) -> I when is_subtype(I, icode_instr()).
+-spec subst_uses([{_,_}], I) -> I when I :: icode_instr().
subst_uses(Subst, I) ->
case I of
@@ -1405,7 +1403,7 @@ subst_uses(Subst, I) ->
#icode_label{} -> I
end.
--spec subst_defines([{_,_}], I) -> I when is_subtype(I, icode_instr()).
+-spec subst_defines([{_,_}], I) -> I when I :: icode_instr().
subst_defines(Subst, I) ->
case I of
@@ -1709,7 +1707,7 @@ mk_new_label() ->
%% @doc Removes comments from Icode.
%%
--spec strip_comments(#icode{}) -> #icode{}.
+-spec strip_comments(icode()) -> icode().
strip_comments(ICode) ->
icode_code_update(ICode, no_comments(icode_code(ICode))).
@@ -1763,6 +1761,18 @@ is_safe(Instr) ->
#icode_end_try{} -> false
end.
+%% @doc Produces a simplified instruction sequence that is equivalent to [Instr]
+%% under the assumption that all results of Instr are unused, or 'false' if
+%% there is no such sequence (other than [Instr] itself).
+
+-spec reduce_unused(icode_instr()) -> false | [icode_instr()].
+
+reduce_unused(Instr) ->
+ case is_safe(Instr) of
+ true -> [];
+ false -> false
+ end.
+
%%-----------------------------------------------------------------------
-spec highest_var(icode_instrs()) -> non_neg_integer().