diff options
Diffstat (limited to 'lib/hipe/rtl/hipe_rtl_liveness.erl')
-rw-r--r-- | lib/hipe/rtl/hipe_rtl_liveness.erl | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/lib/hipe/rtl/hipe_rtl_liveness.erl b/lib/hipe/rtl/hipe_rtl_liveness.erl new file mode 100644 index 0000000000..3cfada9d6c --- /dev/null +++ b/lib/hipe/rtl/hipe_rtl_liveness.erl @@ -0,0 +1,145 @@ +%% $Id$ +%% +%% %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% +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% LIVENESS ANALYSIS +%% +%% Exports: +%% ~~~~~~~ +%% analyze(CFG) - returns a liveness analysis of CFG. +%% liveout(Liveness, Label) - returns a set of variables that are live on +%% exit from basic block named Label. +%% livein(Liveness, Label) - returns a set of variables that are live on +%% entry to the basic block named Label. +%% list(Instructions, LiveOut) - Given a list of instructions and a liveout +%% set, returns a set of variables live at the first instruction. +%% + +-module(hipe_rtl_liveness). + +%% -define(LIVEOUT_NEEDED,true). % needed for liveness.inc below. +-define(PRETTY_PRINT,false). + +-include("hipe_rtl.hrl"). +-include("../flow/liveness.inc"). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% Interface to CFG and RTL. +%% + +cfg_bb(CFG, L) -> + hipe_rtl_cfg:bb(CFG, L). + +cfg_postorder(CFG) -> + hipe_rtl_cfg:postorder(CFG). + +cfg_succ(CFG, L) -> + hipe_rtl_cfg:succ(CFG, L). + +uses(Instr) -> + hipe_rtl:uses(Instr). + +defines(Instr) -> + hipe_rtl:defines(Instr). + +%% +%% This is the list of registers that are live at exit from a function +%% + +liveout_no_succ() -> + hipe_rtl_arch:live_at_return(). + +%% +%% The following are used only if annotation of the code is requested. +%% + +cfg_labels(CFG) -> + hipe_rtl_cfg:reverse_postorder(CFG). + +pp_block(Label, CFG) -> + BB=hipe_rtl_cfg:bb(CFG, Label), + Code=hipe_bb:code(BB), + hipe_rtl:pp_block(Code). + +pp_liveness_info(LiveList) -> + NewList=remove_precoloured(LiveList), + print_live_list(NewList). + +print_live_list([]) -> + io:format(" none~n", []); +print_live_list([Last]) -> + io:format(" ", []), + print_var(Last), + io:format("~n", []); +print_live_list([Var|Rest]) -> + io:format(" ", []), + print_var(Var), + io:format(",", []), + print_live_list(Rest). + +print_var(A) -> + case hipe_rtl:is_var(A) of + true -> + pp_var(A); + false -> + case hipe_rtl:is_reg(A) of + true -> + pp_reg(A); + false -> + case hipe_rtl:is_fpreg(A) of + true -> + io:format("f~w", [hipe_rtl:fpreg_index(A)]); + false -> + io:format("unknown:~w", [A]) + end + end + end. + +pp_hard_reg(N) -> + io:format("~s", [hipe_rtl_arch:reg_name(N)]). + +pp_reg(Arg) -> + case hipe_rtl_arch:is_precoloured(Arg) of + true -> + pp_hard_reg(hipe_rtl:reg_index(Arg)); + false -> + io:format("r~w", [hipe_rtl:reg_index(Arg)]) + end. + +pp_var(Arg) -> + case hipe_rtl_arch:is_precoloured(Arg) of + true -> + pp_hard_reg(hipe_rtl:var_index(Arg)); + false -> + io:format("v~w", [hipe_rtl:var_index(Arg)]) + end. + +remove_precoloured(List) -> + List. + %% [X || X <- List, not hipe_rtl_arch:is_precoloured(X)]. + +-ifdef(DEBUG_LIVENESS). +cfg_bb_add(CFG, L, NewBB) -> + hipe_rtl_cfg:bb_add(CFG, L, NewBB). + +mk_comment(Text) -> + hipe_rtl:mk_comment(Text). +-endif. |