aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/icode/hipe_icode_cfg.erl
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/hipe/icode/hipe_icode_cfg.erl
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/hipe/icode/hipe_icode_cfg.erl')
-rw-r--r--lib/hipe/icode/hipe_icode_cfg.erl203
1 files changed, 203 insertions, 0 deletions
diff --git a/lib/hipe/icode/hipe_icode_cfg.erl b/lib/hipe/icode/hipe_icode_cfg.erl
new file mode 100644
index 0000000000..9b4a10e273
--- /dev/null
+++ b/lib/hipe/icode/hipe_icode_cfg.erl
@@ -0,0 +1,203 @@
+%% -*- erlang-indent-level: 2 -*-
+%%======================================================================
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. 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%
+%%
+
+-module(hipe_icode_cfg).
+
+-export([bb/2, bb_add/3,
+ cfg_to_linear/1,
+ is_closure/1,
+ closure_arity/1,
+ linear_to_cfg/1,
+ labels/1, start_label/1,
+ pp/1, pp/2,
+ params/1, params_update/2,
+ pred/2,
+ redirect/4,
+ remove_trivial_bbs/1, remove_unreachable_code/1,
+ succ/2,
+ visit/2, is_visited/2, none_visited/0
+ ]).
+-export([postorder/1, reverse_postorder/1]).
+
+-define(ICODE_CFG, true). % needed by cfg.inc
+%%-define(DO_ASSERT, true).
+
+-include("../main/hipe.hrl").
+-include("hipe_icode.hrl").
+-include("../flow/hipe_bb.hrl").
+-include("../flow/cfg.hrl").
+-include("../flow/cfg.inc").
+
+%%----------------------------------------------------------------------
+%% Prototypes for exported functions which are Icode specific
+%%----------------------------------------------------------------------
+
+-spec labels(cfg()) -> [icode_lbl()].
+-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 bb(cfg(), icode_lbl()) -> 'not_found' | bb().
+-spec bb_add(cfg(), icode_lbl(), bb()) -> cfg().
+-spec pred(cfg(), icode_lbl()) -> [icode_lbl()].
+-spec succ(cfg(), icode_lbl()) -> [icode_lbl()].
+-spec redirect(cfg(), icode_lbl(), icode_lbl(), icode_lbl()) -> cfg().
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Interface to Icode
+%%
+
+-spec linear_to_cfg(#icode{}) -> cfg().
+
+linear_to_cfg(LinearIcode) ->
+ %% hipe_icode_pp:pp(Icode),
+ Code = hipe_icode:icode_code(LinearIcode),
+ IsClosure = hipe_icode:icode_is_closure(LinearIcode),
+ StartLabel = hipe_icode:label_name(hd(Code)),
+ CFG0 = mk_empty_cfg(hipe_icode:icode_fun(LinearIcode),
+ StartLabel,
+ hipe_icode:icode_data(LinearIcode),
+ IsClosure,
+ hipe_icode:icode_is_leaf(LinearIcode),
+ hipe_icode:icode_params(LinearIcode)),
+ CFG1 = info_update(CFG0, hipe_icode:icode_info(LinearIcode)),
+ CFG2 = case IsClosure of
+ true ->
+ closure_arity_update(CFG1,
+ hipe_icode:icode_closure_arity(LinearIcode));
+ false ->
+ CFG1
+ end,
+ ?opt_start_timer("Get BBs icode"),
+ FullCFG = take_bbs(Code, CFG2),
+ ?opt_stop_timer("Get BBs icode"),
+ FullCFG.
+
+%% remove_blocks(CFG, []) ->
+%% CFG;
+%% remove_blocks(CFG, [Lbl|Lbls]) ->
+%% remove_blocks(bb_remove(CFG, Lbl), Lbls).
+
+-spec is_label(icode_instr()) -> boolean().
+is_label(Instr) ->
+ hipe_icode:is_label(Instr).
+
+label_name(Instr) ->
+ hipe_icode:label_name(Instr).
+
+mk_label(Name) ->
+ hipe_icode:mk_label(Name).
+
+mk_goto(Name) ->
+ hipe_icode:mk_goto(Name).
+
+branch_successors(Instr) ->
+ hipe_icode:successors(Instr).
+
+fails_to(Instr) ->
+ hipe_icode:fails_to(Instr).
+
+%% True if instr has no effect.
+-spec is_comment(icode_instr()) -> boolean().
+is_comment(Instr) ->
+ hipe_icode:is_comment(Instr).
+
+%% True if instr is just a jump (no side-effects).
+-spec is_goto(icode_instr()) -> boolean().
+is_goto(Instr) ->
+ hipe_icode:is_goto(Instr).
+
+-spec is_branch(icode_instr()) -> boolean().
+is_branch(Instr) ->
+ hipe_icode:is_branch(Instr).
+
+-spec is_pure_branch(icode_instr()) -> boolean().
+is_pure_branch(Instr) ->
+ case Instr of
+ #icode_if{} -> true;
+ #icode_goto{} -> true;
+ #icode_switch_val{} -> true;
+ #icode_switch_tuple_arity{} -> true;
+ #icode_type{} -> true;
+ %% false cases below -- XXX: are they correct?
+ #icode_label{} -> false;
+ #icode_move{} -> false;
+ #icode_phi{} -> false;
+ #icode_call{} -> false;
+ #icode_enter{} -> false;
+ #icode_return{} -> false;
+ #icode_begin_try{} -> false;
+ #icode_end_try{} -> false;
+ #icode_begin_handler{} -> false;
+ #icode_fail{} -> false;
+ #icode_comment{} -> false
+ end.
+
+-spec is_phi(icode_instr()) -> boolean().
+is_phi(I) ->
+ hipe_icode:is_phi(I).
+
+phi_remove_pred(I, Pred) ->
+ hipe_icode:phi_remove_pred(I, Pred).
+
+%% phi_redirect_pred(I, OldPred, NewPred) ->
+%% hipe_icode:phi_redirect_pred(I, OldPred, NewPred).
+
+redirect_jmp(Jmp, ToOld, ToNew) ->
+ hipe_icode:redirect_jmp(Jmp, ToOld, ToNew).
+
+redirect_ops(_, CFG, _) -> %% We do not refer to labels in Icode ops.
+ CFG.
+
+%%----------------------------------------------------------------------------
+
+-spec pp(cfg()) -> 'ok'.
+
+pp(CFG) ->
+ hipe_icode_pp:pp(cfg_to_linear(CFG)).
+
+-spec pp(io:device(), cfg()) -> 'ok'.
+
+pp(Dev, CFG) ->
+ hipe_icode_pp:pp(Dev, cfg_to_linear(CFG)).
+
+%%----------------------------------------------------------------------------
+
+-spec cfg_to_linear(cfg()) -> #icode{}.
+cfg_to_linear(CFG) ->
+ Code = linearize_cfg(CFG),
+ IsClosure = is_closure(CFG),
+ Icode = hipe_icode:mk_icode(function(CFG),
+ params(CFG),
+ IsClosure,
+ is_leaf(CFG),
+ Code,
+ data(CFG),
+ hipe_gensym:var_range(icode),
+ hipe_gensym:label_range(icode)),
+ Icode1 = hipe_icode:icode_info_update(Icode, info(CFG)),
+ case IsClosure of
+ true -> hipe_icode:icode_closure_arity_update(Icode1, closure_arity(CFG));
+ false -> Icode1
+ end.