diff options
Diffstat (limited to 'lib/hipe/arm/hipe_arm_cfg.erl')
-rw-r--r-- | lib/hipe/arm/hipe_arm_cfg.erl | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/lib/hipe/arm/hipe_arm_cfg.erl b/lib/hipe/arm/hipe_arm_cfg.erl new file mode 100644 index 0000000000..984a3ccf9e --- /dev/null +++ b/lib/hipe/arm/hipe_arm_cfg.erl @@ -0,0 +1,131 @@ +%% -*- erlang-indent-level: 2 -*- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2005-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_arm_cfg). + +-export([init/1, + labels/1, start_label/1, + succ/2, + bb/2, bb_add/3]). +-export([postorder/1]). +-export([linearise/1]). +-export([params/1, reverse_postorder/1]). +-export([arity/1]). % for linear scan +%%-export([redirect_jmp/3]). + +%%% these tell cfg.inc what to define (ugly as hell) +-define(BREADTH_ORDER,true). % for linear scan +-define(PARAMS_NEEDED,true). +-define(START_LABEL_UPDATE_NEEDED,true). + +-include("hipe_arm.hrl"). +-include("../flow/cfg.hrl"). +-include("../flow/cfg.inc"). + +init(Defun) -> + Code = hipe_arm:defun_code(Defun), + StartLab = hipe_arm:label_label(hd(Code)), + Data = hipe_arm:defun_data(Defun), + IsClosure = hipe_arm:defun_is_closure(Defun), + Name = hipe_arm:defun_mfa(Defun), + IsLeaf = hipe_arm:defun_is_leaf(Defun), + Formals = hipe_arm:defun_formals(Defun), + CFG0 = mk_empty_cfg(Name, StartLab, Data, IsClosure, IsLeaf, Formals), + take_bbs(Code, CFG0). + +is_branch(I) -> + case I of + #b_fun{} -> true; + #b_label{'cond'='al'} -> true; + #pseudo_bc{} -> true; + #pseudo_blr{} -> true; + #pseudo_bx{} -> true; + #pseudo_call{} -> true; + #pseudo_switch{} -> true; + #pseudo_tailcall{} -> true; + _ -> false + end. + +branch_successors(Branch) -> + case Branch of + #b_fun{} -> []; + #b_label{'cond'='al',label=Label} -> [Label]; + #pseudo_bc{true_label=TrueLab,false_label=FalseLab} -> [FalseLab,TrueLab]; + #pseudo_blr{} -> []; + #pseudo_bx{} -> []; + #pseudo_call{contlab=ContLab, sdesc=#arm_sdesc{exnlab=ExnLab}} -> + case ExnLab of + [] -> [ContLab]; + _ -> [ContLab,ExnLab] + end; + #pseudo_switch{labels=Labels} -> Labels; + #pseudo_tailcall{} -> [] + end. + +-ifdef(REMOVE_TRIVIAL_BBS_NEEDED). +fails_to(_Instr) -> []. +-endif. + +-ifdef(notdef). +redirect_jmp(I, Old, New) -> + case I of + #b_label{label=Label} -> + if Old =:= Label -> I#b_label{label=New}; + true -> I + end; + #pseudo_bc{true_label=TrueLab, false_label=FalseLab} -> + I1 = if Old =:= TrueLab -> I#pseudo_bc{true_label=New}; + true -> I + end, + if Old =:= FalseLab -> I1#pseudo_bc{false_label=New}; + true -> I1 + end; + %% handle pseudo_call too? + _ -> I + end. +-endif. + +mk_goto(Label) -> + hipe_arm:mk_b_label(Label). + +is_label(I) -> + hipe_arm:is_label(I). + +label_name(Label) -> + hipe_arm:label_label(Label). + +mk_label(Name) -> + hipe_arm:mk_label(Name). + +linearise(CFG) -> % -> defun, not insn list + MFA = function(CFG), + Formals = params(CFG), + Code = linearize_cfg(CFG), + Data = data(CFG), + VarRange = hipe_gensym:var_range(arm), + LabelRange = hipe_gensym:label_range(arm), + IsClosure = is_closure(CFG), + IsLeaf = is_leaf(CFG), + hipe_arm:mk_defun(MFA, Formals, IsClosure, IsLeaf, + Code, Data, VarRange, LabelRange). + +arity(CFG) -> + {_M, _F, A} = function(CFG), + A. |