diff options
author | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
commit | 84adefa331c4159d432d22840663c38f155cd4c1 (patch) | |
tree | bff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/hipe/icode/hipe_icode_cfg.erl | |
download | otp-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.erl | 203 |
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. |