diff options
Diffstat (limited to 'lib/hipe/x86/hipe_x86_cfg.erl')
-rw-r--r-- | lib/hipe/x86/hipe_x86_cfg.erl | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/lib/hipe/x86/hipe_x86_cfg.erl b/lib/hipe/x86/hipe_x86_cfg.erl new file mode 100644 index 0000000000..d15dcc061a --- /dev/null +++ b/lib/hipe/x86/hipe_x86_cfg.erl @@ -0,0 +1,147 @@ +%% -*- 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_x86_cfg). + +-export([init/1, + labels/1, start_label/1, + succ/2, pred/2, + bb/2, bb_add/3]). +-export([postorder/1, reverse_postorder/1]). +-export([linearise/1, params/1, arity/1, redirect_jmp/3]). + +%%% these tell cfg.inc what to define (ugly as hell) +-define(PRED_NEEDED,true). +-define(BREADTH_ORDER,true). +-define(PARAMS_NEEDED,true). +-define(START_LABEL_UPDATE_NEEDED,true). + +-include("hipe_x86.hrl"). +-include("../flow/cfg.hrl"). +-include("../flow/cfg.inc"). + +init(Defun) -> + %% XXX: this assumes that the code starts with a label insn. + %% Is that guaranteed? + Code = hipe_x86:defun_code(Defun), + StartLab = hipe_x86:label_label(hd(Code)), + Data = hipe_x86:defun_data(Defun), + IsClosure = hipe_x86:defun_is_closure(Defun), + MFA = hipe_x86:defun_mfa(Defun), + IsLeaf = hipe_x86:defun_is_leaf(Defun), + Formals = hipe_x86:defun_formals(Defun), + CFG0 = mk_empty_cfg(MFA, StartLab, Data, IsClosure, IsLeaf, Formals), + take_bbs(Code, CFG0). + +is_branch(I) -> + case I of + #jmp_fun{} -> true; + #jmp_label{} -> true; + #jmp_switch{} -> true; + #pseudo_call{} -> true; + #pseudo_jcc{} -> true; + #pseudo_tailcall{} -> true; + #ret{} -> true; + _ -> false + end. + +branch_successors(Branch) -> + case Branch of + #jmp_fun{} -> []; + #jmp_label{label=Label} -> [Label]; + #jmp_switch{labels=Labels} -> Labels; + #pseudo_call{contlab=ContLab, sdesc=#x86_sdesc{exnlab=ExnLab}} -> + case ExnLab of + [] -> [ContLab]; + _ -> [ContLab,ExnLab] + end; + #pseudo_jcc{true_label=TrueLab,false_label=FalseLab} -> [FalseLab,TrueLab]; + #pseudo_tailcall{} -> []; + #ret{} -> [] + end. + +-ifdef(REMOVE_TRIVIAL_BBS_NEEDED). +fails_to(_Instr) -> []. +-endif. + +redirect_jmp(I, Old, New) -> + case I of + #jmp_label{label=Label} -> + if Old =:= Label -> I#jmp_label{label=New}; + true -> I + end; + #pseudo_jcc{true_label=TrueLab, false_label=FalseLab} -> + J0 = if Old =:= TrueLab -> I#pseudo_jcc{true_label=New}; + true -> I + end, + if Old =:= FalseLab -> J0#pseudo_jcc{false_label=New}; + true -> J0 + end; + %% handle pseudo_call too? + _ -> I + end. + +%%% XXX: fix if labels can occur in operands +%% redirect_ops(_Labels, CFG, _Map) -> +%% CFG. + +mk_goto(Label) -> + hipe_x86:mk_jmp_label(Label). + +is_label(I) -> + hipe_x86:is_label(I). + +label_name(Label) -> + hipe_x86:label_label(Label). + +mk_label(Name) -> + hipe_x86:mk_label(Name). + +%% is_comment(I) -> +%% hipe_x86:is_comment(I). +%% +%% is_goto(I) -> +%% hipe_x86:is_jmp_label(I). + +linearise(CFG) -> % -> defun, not insn list + MFA = function(CFG), + Formals = params(CFG), + Code = linearize_cfg(CFG), + Data = data(CFG), + VarRange = hipe_gensym:var_range(x86), + LabelRange = hipe_gensym:label_range(x86), + IsClosure = is_closure(CFG), + IsLeaf = is_leaf(CFG), + hipe_x86:mk_defun(MFA, Formals, IsClosure, IsLeaf, + Code, Data, VarRange, LabelRange). + +arity(CFG) -> + {_M,_F,A} = function(CFG), + A. + +%% init_gensym(CFG) -> +%% HighestVar = find_highest_var(CFG), +%% HighestLabel = find_highest_label(CFG), +%% hipe_gensym:init(), +%% hipe_gensym:set_var(x86, HighestVar), +%% hipe_gensym:set_label(x86, HighestLabel). +%% +%% highest_var(Code) -> +%% hipe_x86:highest_temp(Code). |