aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/rtl/hipe_rtl_liveness.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe/rtl/hipe_rtl_liveness.erl')
-rw-r--r--lib/hipe/rtl/hipe_rtl_liveness.erl145
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.