%% $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.