1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3
%% DEAD CODE ELIMINATION
5
%% Runs one pass of dead code elimination. Note that we should iterate
6
%% this to eliminate all dead code.
8
%% Another approach is to employ use-def chains + marking, which is
9
%% probably a lot faster. Still, this is simple enough and might come
10
%% in useful. If we can save a lot of time, rewrite it to the use-def
13
-module(hipe_dead_code).
14
-export([eliminate/1]).
16
-define(cfg,hipe_icode_cfg).
17
-define(liveness,hipe_icode_liveness).
18
-define(code,hipe_icode).
21
dce_blocks(?cfg:labels(CFG),?liveness:analyze(CFG),CFG).
23
dce_blocks([],_Live,CFG) -> CFG;
24
dce_blocks([L|Ls],Live,CFG) ->
26
dce_block(L,?cfg:bb(CFG,L),?liveness:liveout(Live,L),CFG)).
28
dce_block(L,BB,LiveOut,CFG) ->
29
{NewXs,_} = dce_instrs(hipe_bb:code(BB),LiveOut),
30
?cfg:bb_update(CFG,L,hipe_bb:mk_bb(NewXs)).
32
dce_instrs([],LiveOut) -> {[],LiveOut};
33
dce_instrs([X|Xs],LiveOut) ->
34
{NewXs,Live} = dce_instrs(Xs,LiveOut),
35
case {eliminable(X), dead(X,Live)} of
39
{[X|NewXs],live_vars(X,Live)}
44
union(U,diff(Live,D)).
48
case intersect(D,Live) of
55
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57
%% Here, we would like to use real sets.
58
%% - convert liveness to use set-module
59
%% - convert def_use to return sets
79
intersect([],_) -> [];
80
intersect([X|Xs],Ys) ->
88
member(_,[]) -> false;
89
member(X,[X|_]) -> true;
90
member(X,[_|Xs]) -> member(X,Xs).
92
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
97
{ ?code:defines(X), ?code:uses(X) }.
100
case hipe_icode:type(X) of