tree-ssa-dce.c File Reference

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "ggc.h"
#include "rtl.h"
#include "tm_p.h"
#include "hard-reg-set.h"
#include "obstack.h"
#include "basic-block.h"
#include "tree.h"
#include "diagnostic.h"
#include "tree-flow.h"
#include "tree-gimple.h"
#include "tree-dump.h"
#include "tree-pass.h"
#include "timevar.h"
#include "flags.h"
#include "cfgloop.h"
#include "tree-scalar-evolution.h"

Include dependency graph for tree-ssa-dce.c:

Go to the source code of this file.

Data Structures

struct  stmt_stats

Defines

#define EXECUTE_IF_CONTROL_DEPENDENT(BI, N, EDGE_NUMBER)
#define NECESSARY(stmt)   stmt->common.asm_written_flag

Functions

static VEC (static inline void mark_stmt_necessary(tree, heap)
static void clear_control_dependence_bitmap ()
static void find_all_control_dependences ()
static void find_control_dependence ()
static basic_block find_pdom ()
static void mark_stmt_necessary ()
static void mark_operand_necessary ()
static void mark_stmt_if_obviously_necessary ()
static void find_obviously_necessary_stmts ()
static void mark_control_dependent_edges_necessary ()
static void propagate_necessity ()
static void mark_really_necessary_kill_operand_phis ()
static void eliminate_unnecessary_stmts ()
static void remove_dead_phis ()
static void remove_dead_stmt ()
static void print_stats ()
static void tree_dce_init ()
static void tree_dce_done ()
static void perform_tree_ssa_dce ()
static unsigned int tree_ssa_dce ()
static unsigned int tree_ssa_dce_loop ()
static unsigned int tree_ssa_cd_dce ()
static bool gate_dce ()

Variables

static struct stmt_stats stats
tree_opt_pass pass_dce
tree_opt_pass pass_dce_loop
tree_opt_pass pass_cd_dce


Define Documentation

#define EXECUTE_IF_CONTROL_DEPENDENT BI,
N,
EDGE_NUMBER   ) 
 

Value:

EXECUTE_IF_SET_IN_BITMAP (control_dependence_map[(N)], 0,       \
                            (EDGE_NUMBER), (BI))

Referenced by mark_control_dependent_edges_necessary().

#define NECESSARY stmt   )     stmt->common.asm_written_flag
 

Definition at line 219 of file tree-ssa-dce.c.

Referenced by eliminate(), eliminate_unnecessary_stmts(), find_obviously_necessary_stmts(), insert_extra_phis(), insert_fake_stores(), mark_operand_necessary(), mark_really_necessary_kill_operand_phis(), mark_stmt_necessary(), realify_fake_stores(), remove_dead_inserted_code(), and remove_dead_phis().


Function Documentation

static void clear_control_dependence_bitmap  )  [inline, static]
 

Clear all control dependences for block BB.   

Definition at line 151 of file tree-ssa-dce.c.

00152 {
00153   bitmap_clear (control_dependence_map[bb->index]);
00154 }

static void eliminate_unnecessary_stmts  )  [static]
 

Eliminate unnecessary statements. Any instruction not marked as necessary
   contributes nothing to the program, and can be deleted.   

Definition at line 625 of file tree-ssa-dce.c.

References bsi_end_p(), bsi_next(), bsi_start, bsi_stmt(), clear_special_calls(), dump_file, dump_flags, get_call_expr_in(), NECESSARY, notice_special_calls(), remove_dead_phis(), remove_dead_stmt(), stats, TDF_DETAILS, and stmt_stats::total.

Referenced by perform_tree_ssa_dce().

00626 {
00627   basic_block bb;
00628   block_stmt_iterator i;
00629 
00630   if (dump_file && (dump_flags & TDF_DETAILS))
00631     fprintf (dump_file, "\nEliminating unnecessary statements:\n");
00632   
00633   clear_special_calls ();
00634   FOR_EACH_BB (bb)
00635     {
00636       /* Remove dead PHI nodes.  */
00637       remove_dead_phis (bb);
00638     }
00639 
00640   FOR_EACH_BB (bb)
00641     {
00642       /* Remove dead statements.  */
00643       for (i = bsi_start (bb); ! bsi_end_p (i) ; )
00644         {
00645          tree t = bsi_stmt (i);
00646 
00647          stats.total++;
00648 
00649          /* If `i' is not necessary then remove it.  */
00650          if (! NECESSARY (t))
00651            remove_dead_stmt (&i, bb);
00652          else
00653            {
00654              tree call = get_call_expr_in (t);
00655              if (call)
00656                notice_special_calls (call);
00657              bsi_next (&i);
00658            }
00659         }
00660     }
00661  }

static void find_all_control_dependences  )  [static]
 

Record all blocks' control dependences on all edges in the edge
   list EL, ala Morgan, Section 3.6.   

Definition at line 160 of file tree-ssa-dce.c.

References find_control_dependence().

Referenced by perform_tree_ssa_dce().

00161 {
00162   int i;
00163 
00164   for (i = 0; i < NUM_EDGES (el); ++i)
00165     find_control_dependence (el, i);
00166 }

static void find_control_dependence  )  [static]
 

Determine all blocks' control dependences on the given edge with edge_list
   EL index EDGE_INDEX, ala Morgan, Section 3.6.   

Definition at line 172 of file tree-ssa-dce.c.

References find_pdom().

Referenced by find_all_control_dependences().

00173 {
00174   basic_block current_block;
00175   basic_block ending_block;
00176 
00177   gcc_assert (INDEX_EDGE_PRED_BB (el, edge_index) != EXIT_BLOCK_PTR);
00178 
00179   if (INDEX_EDGE_PRED_BB (el, edge_index) == ENTRY_BLOCK_PTR)
00180     ending_block = single_succ (ENTRY_BLOCK_PTR);
00181   else
00182     ending_block = find_pdom (INDEX_EDGE_PRED_BB (el, edge_index));
00183 
00184   for (current_block = INDEX_EDGE_SUCC_BB (el, edge_index);
00185        current_block != ending_block && current_block != EXIT_BLOCK_PTR;
00186        current_block = find_pdom (current_block))
00187     {
00188       edge e = INDEX_EDGE (el, edge_index);
00189 
00190       /* For abnormal edges, we don't make current_block control
00191          dependent because instructions that throw are always necessary
00192          anyway.  */
00193       if (e->flags & EDGE_ABNORMAL)
00194         continue;
00195 
00196       set_control_dependence_map_bit (current_block, edge_index);
00197     }
00198 }

static void find_obviously_necessary_stmts  )  [static]
 

Find obviously necessary statements.  These are things like most function
   calls, and stores to file level variables.

   If EL is NULL, control statements are conservatively marked as
   necessary.  Otherwise it contains the list of edges used by control
   dependence analysis.   

Definition at line 386 of file tree-ssa-dce.c.

References bsi_end_p(), bsi_next(), bsi_start, bsi_stmt(), is_gimple_reg(), is_global_var(), mark_stmt_if_obviously_necessary(), mark_stmt_necessary(), NECESSARY, PHI_CHAIN, phi_nodes(), PHI_RESULT, and SSA_NAME_VAR.

Referenced by perform_tree_ssa_dce().

00387 {
00388   basic_block bb;
00389   block_stmt_iterator i;
00390   edge e;
00391 
00392   FOR_EACH_BB (bb)
00393     {
00394       tree phi;
00395 
00396       /* Check any PHI nodes in the block.  */
00397       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00398         {
00399           NECESSARY (phi) = 0;
00400 
00401           /* PHIs for virtual variables do not directly affect code
00402              generation and need not be considered inherently necessary
00403              regardless of the bits set in their decl.
00404 
00405              Thus, we only need to mark PHIs for real variables which
00406              need their result preserved as being inherently necessary.  */
00407           if (is_gimple_reg (PHI_RESULT (phi))
00408               && is_global_var (SSA_NAME_VAR (PHI_RESULT (phi))))
00409             mark_stmt_necessary (phi, true);
00410         }
00411 
00412       /* Check all statements in the block.  */
00413       for (i = bsi_start (bb); ! bsi_end_p (i); bsi_next (&i))
00414         {
00415           tree stmt = bsi_stmt (i);
00416           NECESSARY (stmt) = 0;
00417           mark_stmt_if_obviously_necessary (stmt, el != NULL);
00418         }
00419     }
00420 
00421   if (el)
00422     {
00423       /* Prevent the loops from being removed.  We must keep the infinite loops,
00424          and we currently do not have a means to recognize the finite ones.  */
00425       FOR_EACH_BB (bb)
00426         {
00427           edge_iterator ei;
00428           FOR_EACH_EDGE (e, ei, bb->succs)
00429             if (e->flags & EDGE_DFS_BACK)
00430               mark_control_dependent_edges_necessary (e->dest, el);
00431         }
00432     }
00433 }

static basic_block find_pdom  )  [inline, static]
 

Find the immediate postdominator PDOM of the specified basic block BLOCK.
   This function is necessary because some blocks have negative numbers.   

Definition at line 204 of file tree-ssa-dce.c.

Referenced by find_control_dependence().

00205 {
00206   gcc_assert (block != ENTRY_BLOCK_PTR);
00207 
00208   if (block == EXIT_BLOCK_PTR)
00209     return EXIT_BLOCK_PTR;
00210   else
00211     {
00212       basic_block bb = get_immediate_dominator (CDI_POST_DOMINATORS, block);
00213       if (! bb)
00214         return EXIT_BLOCK_PTR;
00215       return bb;
00216     }
00217 }

static bool gate_dce  )  [static]
 

Definition at line 949 of file tree-ssa-dce.c.

00950 {
00951   return flag_tree_dce != 0;
00952 }

static void mark_control_dependent_edges_necessary  )  [static]
 

Make corresponding control dependent edges necessary.  We only
   have to do this once for each basic block, so we clear the bitmap
   after we're done.   

Definition at line 439 of file tree-ssa-dce.c.

References EXECUTE_IF_CONTROL_DEPENDENT, is_ctrl_stmt(), last_stmt(), and mark_stmt_necessary().

Referenced by propagate_necessity().

00440 {
00441   bitmap_iterator bi;
00442   unsigned edge_number;
00443 
00444   gcc_assert (bb != EXIT_BLOCK_PTR);
00445 
00446   if (bb == ENTRY_BLOCK_PTR)
00447     return;
00448 
00449   EXECUTE_IF_CONTROL_DEPENDENT (bi, bb->index, edge_number)
00450     {
00451       tree t;
00452       basic_block cd_bb = INDEX_EDGE_PRED_BB (el, edge_number);
00453 
00454       if (TEST_BIT (last_stmt_necessary, cd_bb->index))
00455         continue;
00456       SET_BIT (last_stmt_necessary, cd_bb->index);
00457 
00458       t = last_stmt (cd_bb);
00459       if (t && is_ctrl_stmt (t))
00460         mark_stmt_necessary (t, true);
00461     }
00462 }

static void mark_operand_necessary  )  [inline, static]
 

Mark the statement defining operand OP as necessary.  PHIONLY is true
   if we should only mark it necessary if it is a phi node.   

Definition at line 248 of file tree-ssa-dce.c.

References IS_EMPTY_STMT, NECESSARY, SSA_NAME_DEF_STMT, SSA_NAME_VERSION, and TREE_CODE.

Referenced by mark_really_necessary_kill_operand_phis(), and propagate_necessity().

00249 {
00250   tree stmt;
00251   int ver;
00252 
00253   gcc_assert (op);
00254 
00255   ver = SSA_NAME_VERSION (op);
00256   if (TEST_BIT (processed, ver))
00257     return;
00258   SET_BIT (processed, ver);
00259 
00260   stmt = SSA_NAME_DEF_STMT (op);
00261   gcc_assert (stmt);
00262 
00263   if (NECESSARY (stmt)
00264       || IS_EMPTY_STMT (stmt)
00265       || (phionly && TREE_CODE (stmt) != PHI_NODE))
00266     return;
00267 
00268   NECESSARY (stmt) = 1;
00269   VEC_safe_push (tree, heap, worklist, stmt);
00270 }

static void mark_really_necessary_kill_operand_phis  )  [static]
 

Propagate necessity around virtual phi nodes used in kill operands.
   The reason this isn't done during propagate_necessity is because we don't
   want to keep phis around that are just there for must-defs, unless we
   absolutely have to.  After we've rewritten the reaching definitions to be
   correct in the previous part of the fixup routine, we can simply propagate
   around the information about which of these virtual phi nodes are really
   used, and set the NECESSARY flag accordingly.
   Note that we do the minimum here to ensure that we keep alive the phis that
   are actually used in the corrected SSA form.  In particular, some of these
   phis may now have all of the same operand, and will be deleted by some
   other pass.   

Definition at line 568 of file tree-ssa-dce.c.

References bsi_end_p(), bsi_last, bsi_prev(), bsi_stmt(), FOR_EACH_SSA_USE_OPERAND, is_gimple_reg(), mark_operand_necessary(), NECESSARY, PHI_ARG_DEF, PHI_CHAIN, phi_nodes(), PHI_NUM_ARGS, PHI_RESULT, SSA_OP_VIRTUAL_KILLS, SSA_OP_VIRTUAL_USES, and USE_FROM_PTR.

Referenced by perform_tree_ssa_dce().

00569 {
00570   basic_block bb;
00571   int i;
00572 
00573   /* Seed the worklist with the new virtual phi arguments and virtual
00574      uses */
00575   FOR_EACH_BB (bb)
00576     {
00577       block_stmt_iterator bsi;
00578       tree phi;
00579       
00580       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00581         {
00582           if (!is_gimple_reg (PHI_RESULT (phi)) && NECESSARY (phi))
00583             {
00584               for (i = 0; i < PHI_NUM_ARGS (phi); i++)
00585                 mark_operand_necessary (PHI_ARG_DEF (phi, i), true);
00586             }
00587         }
00588       
00589       for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
00590         {
00591           tree stmt = bsi_stmt (bsi);
00592         
00593           if (NECESSARY (stmt))
00594             {
00595               use_operand_p use_p;
00596               ssa_op_iter iter;
00597               FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
00598                                         SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
00599                 {
00600                   tree use = USE_FROM_PTR (use_p);
00601                   mark_operand_necessary (use, true);
00602                 }
00603             }
00604         }
00605     }
00606   
00607   /* Mark all virtual phis still in use as necessary, and all of their
00608      arguments that are phis as necessary.  */
00609   while (VEC_length (tree, worklist) > 0)
00610     {
00611       tree use = VEC_pop (tree, worklist);
00612       
00613       for (i = 0; i < PHI_NUM_ARGS (use); i++)
00614         mark_operand_necessary (PHI_ARG_DEF (use, i), true);
00615     }
00616 }

static void mark_stmt_if_obviously_necessary  )  [static]
 

Mark STMT as necessary if it obviously is.  Add it to the worklist if
   it can make other statements necessary.

   If AGGRESSIVE is false, control statements are conservatively marked as
   necessary.   

Definition at line 280 of file tree-ssa-dce.c.

References bb_for_stmt(), get_call_expr_in(), stmt_ann_d::has_volatile_ops, is_ctrl_altering_stmt(), is_hidden_global_store(), mark_stmt_necessary(), simple_goto_p(), stmt_ann, TREE_CODE, tree_could_throw_p(), TREE_OPERAND, and TREE_SIDE_EFFECTS.

Referenced by find_obviously_necessary_stmts().

00281 {
00282   stmt_ann_t ann;
00283   tree op;
00284 
00285   /* With non-call exceptions, we have to assume that all statements could
00286      throw.  If a statement may throw, it is inherently necessary.  */
00287   if (flag_non_call_exceptions
00288       && tree_could_throw_p (stmt))
00289     {
00290       mark_stmt_necessary (stmt, true);
00291       return;
00292     }
00293 
00294   /* Statements that are implicitly live.  Most function calls, asm and return
00295      statements are required.  Labels and BIND_EXPR nodes are kept because
00296      they are control flow, and we have no way of knowing whether they can be
00297      removed.  DCE can eliminate all the other statements in a block, and CFG
00298      can then remove the block and labels.  */
00299   switch (TREE_CODE (stmt))
00300     {
00301     case BIND_EXPR:
00302     case LABEL_EXPR:
00303     case CASE_LABEL_EXPR:
00304       mark_stmt_necessary (stmt, false);
00305       return;
00306 
00307     case ASM_EXPR:
00308     case RESX_EXPR:
00309     case RETURN_EXPR:
00310       mark_stmt_necessary (stmt, true);
00311       return;
00312 
00313     case CALL_EXPR:
00314       /* Most, but not all function calls are required.  Function calls that
00315          produce no result and have no side effects (i.e. const pure
00316          functions) are unnecessary.  */
00317       if (TREE_SIDE_EFFECTS (stmt))
00318         mark_stmt_necessary (stmt, true);
00319       return;
00320 
00321     case MODIFY_EXPR:
00322       op = get_call_expr_in (stmt);
00323       if (op && TREE_SIDE_EFFECTS (op))
00324         {
00325           mark_stmt_necessary (stmt, true);
00326           return;
00327         }
00328 
00329       /* These values are mildly magic bits of the EH runtime.  We can't
00330          see the entire lifetime of these values until landing pads are
00331          generated.  */
00332       if (TREE_CODE (TREE_OPERAND (stmt, 0)) == EXC_PTR_EXPR
00333           || TREE_CODE (TREE_OPERAND (stmt, 0)) == FILTER_EXPR)
00334         {
00335           mark_stmt_necessary (stmt, true);
00336           return;
00337         }
00338       break;
00339 
00340     case GOTO_EXPR:
00341       gcc_assert (!simple_goto_p (stmt));
00342       mark_stmt_necessary (stmt, true);
00343       return;
00344 
00345     case COND_EXPR:
00346       gcc_assert (EDGE_COUNT (bb_for_stmt (stmt)->succs) == 2);
00347       /* Fall through.  */
00348 
00349     case SWITCH_EXPR:
00350       if (! aggressive)
00351         mark_stmt_necessary (stmt, true);
00352       break;
00353 
00354     default:
00355       break;
00356     }
00357 
00358   ann = stmt_ann (stmt);
00359 
00360   /* If the statement has volatile operands, it needs to be preserved.
00361      Same for statements that can alter control flow in unpredictable
00362      ways.  */
00363   if (ann->has_volatile_ops || is_ctrl_altering_stmt (stmt))
00364     {
00365       mark_stmt_necessary (stmt, true);
00366       return;
00367     }
00368 
00369   if (is_hidden_global_store (stmt))
00370     {
00371       mark_stmt_necessary (stmt, true);
00372       return;
00373     }
00374 
00375   return;
00376 }

static void mark_stmt_necessary  )  [inline, static]
 

If STMT is not already marked necessary, mark it, and add it to the
   worklist if ADD_TO_WORKLIST is true.   

Definition at line 224 of file tree-ssa-dce.c.

References DECL_P, dump_file, dump_flags, NECESSARY, print_generic_stmt(), TDF_DETAILS, and TDF_SLIM.

Referenced by find_obviously_necessary_stmts(), mark_control_dependent_edges_necessary(), and mark_stmt_if_obviously_necessary().

00225 {
00226   gcc_assert (stmt);
00227   gcc_assert (!DECL_P (stmt));
00228 
00229   if (NECESSARY (stmt))
00230     return;
00231 
00232   if (dump_file && (dump_flags & TDF_DETAILS))
00233     {
00234       fprintf (dump_file, "Marking useful stmt: ");
00235       print_generic_stmt (dump_file, stmt, TDF_SLIM);
00236       fprintf (dump_file, "\n");
00237     }
00238 
00239   NECESSARY (stmt) = 1;
00240   if (add_to_worklist)
00241     VEC_safe_push (tree, heap, worklist, stmt);
00242 }

static void perform_tree_ssa_dce  )  [static]
 

Main routine to eliminate dead code.

   AGGRESSIVE controls the aggressiveness of the algorithm.
   In conservative mode, we ignore control dependence and simply declare
   all but the most trivially dead branches necessary.  This mode is fast.
   In aggressive mode, control dependences are taken into account, which
   results in more dead code elimination, but at the cost of some time.

   FIXME: Aggressive mode before PRE doesn't work currently because
	  the dominance info is not invalidated after DCE1.  This is
	  not an issue right now because we only run aggressive DCE
	  as the last tree SSA pass, but keep this in mind when you
	  start experimenting with pass ordering.   

Definition at line 878 of file tree-ssa-dce.c.

References dump_file, eliminate_unnecessary_stmts(), find_all_control_dependences(), find_obviously_necessary_stmts(), mark_really_necessary_kill_operand_phis(), print_stats(), propagate_necessity(), tree_dce_done(), and tree_dce_init().

Referenced by tree_ssa_cd_dce(), tree_ssa_dce(), and tree_ssa_dce_loop().

00879 {
00880   struct edge_list *el = NULL;
00881 
00882   tree_dce_init (aggressive);
00883 
00884   if (aggressive)
00885     {
00886       /* Compute control dependence.  */
00887       timevar_push (TV_CONTROL_DEPENDENCES);
00888       calculate_dominance_info (CDI_POST_DOMINATORS);
00889       el = create_edge_list ();
00890       find_all_control_dependences (el);
00891       timevar_pop (TV_CONTROL_DEPENDENCES);
00892 
00893       visited_control_parents = sbitmap_alloc (last_basic_block);
00894       sbitmap_zero (visited_control_parents);
00895 
00896       mark_dfs_back_edges ();
00897     }
00898 
00899   find_obviously_necessary_stmts (el);
00900 
00901   propagate_necessity (el);
00902 
00903   mark_really_necessary_kill_operand_phis ();
00904   eliminate_unnecessary_stmts ();
00905 
00906   if (aggressive)
00907     free_dominance_info (CDI_POST_DOMINATORS);
00908 
00909   /* If we removed paths in the CFG, then we need to update
00910      dominators as well.  I haven't investigated the possibility
00911      of incrementally updating dominators.  */
00912   if (cfg_altered)
00913     free_dominance_info (CDI_DOMINATORS);
00914 
00915   /* Debugging dumps.  */
00916   if (dump_file)
00917     print_stats ();
00918 
00919   tree_dce_done (aggressive);
00920 
00921   free_edge_list (el);
00922 }

static void print_stats  )  [static]
 

Print out removed statement statistics.   

Definition at line 795 of file tree-ssa-dce.c.

References dump_file, dump_flags, stmt_stats::removed, stmt_stats::removed_phis, stats, TDF_DETAILS, TDF_STATS, stmt_stats::total, and stmt_stats::total_phis.

Referenced by perform_tree_ssa_dce().

00796 {
00797   if (dump_file && (dump_flags & (TDF_STATS|TDF_DETAILS)))
00798     {
00799       float percg;
00800 
00801       percg = ((float) stats.removed / (float) stats.total) * 100;
00802       fprintf (dump_file, "Removed %d of %d statements (%d%%)\n",
00803                stats.removed, stats.total, (int) percg);
00804 
00805       if (stats.total_phis == 0)
00806         percg = 0;
00807       else
00808         percg = ((float) stats.removed_phis / (float) stats.total_phis) * 100;
00809 
00810       fprintf (dump_file, "Removed %d of %d PHI nodes (%d%%)\n",
00811                stats.removed_phis, stats.total_phis, (int) percg);
00812     }
00813 }

static void propagate_necessity  )  [static]
 

Propagate necessity using the operands of necessary statements.  Process
   the uses on each statement in the worklist, and add all feeding statements
   which contribute to the calculation of this value to the worklist.

   In conservative mode, EL is NULL.   

Definition at line 471 of file tree-ssa-dce.c.

References bb_for_stmt(), dump_file, dump_flags, mark_control_dependent_edges_necessary(), mark_operand_necessary(), PHI_ARG_DEF, PHI_ARG_EDGE, PHI_NUM_ARGS, print_generic_stmt(), TDF_DETAILS, TDF_SLIM, and TREE_CODE.

Referenced by perform_tree_ssa_dce().

00472 {
00473   tree i;
00474   bool aggressive = (el ? true : false); 
00475 
00476   if (dump_file && (dump_flags & TDF_DETAILS))
00477     fprintf (dump_file, "\nProcessing worklist:\n");
00478 
00479   while (VEC_length (tree, worklist) > 0)
00480     {
00481       /* Take `i' from worklist.  */
00482       i = VEC_pop (tree, worklist);
00483 
00484       if (dump_file && (dump_flags & TDF_DETAILS))
00485         {
00486           fprintf (dump_file, "processing: ");
00487           print_generic_stmt (dump_file, i, TDF_SLIM);
00488           fprintf (dump_file, "\n");
00489         }
00490 
00491       if (aggressive)
00492         {
00493           /* Mark the last statements of the basic blocks that the block
00494              containing `i' is control dependent on, but only if we haven't
00495              already done so.  */
00496           basic_block bb = bb_for_stmt (i);
00497           if (bb != ENTRY_BLOCK_PTR
00498               && ! TEST_BIT (visited_control_parents, bb->index))
00499             {
00500               SET_BIT (visited_control_parents, bb->index);
00501               mark_control_dependent_edges_necessary (bb, el);
00502             }
00503         }
00504 
00505       if (TREE_CODE (i) == PHI_NODE)
00506         {
00507           /* PHI nodes are somewhat special in that each PHI alternative has
00508              data and control dependencies.  All the statements feeding the
00509              PHI node's arguments are always necessary.  In aggressive mode,
00510              we also consider the control dependent edges leading to the
00511              predecessor block associated with each PHI alternative as
00512              necessary.  */
00513           int k;
00514           for (k = 0; k < PHI_NUM_ARGS (i); k++)
00515             {
00516               tree arg = PHI_ARG_DEF (i, k);
00517               if (TREE_CODE (arg) == SSA_NAME)
00518                 mark_operand_necessary (arg, false);
00519             }
00520 
00521           if (aggressive)
00522             {
00523               for (k = 0; k < PHI_NUM_ARGS (i); k++)
00524                 {
00525                   basic_block arg_bb = PHI_ARG_EDGE (i, k)->src;
00526                   if (arg_bb != ENTRY_BLOCK_PTR
00527                       && ! TEST_BIT (visited_control_parents, arg_bb->index))
00528                     {
00529                       SET_BIT (visited_control_parents, arg_bb->index);
00530                       mark_control_dependent_edges_necessary (arg_bb, el);
00531                     }
00532                 }
00533             }
00534         }
00535       else
00536         {
00537           /* Propagate through the operands.  Examine all the USE, VUSE and
00538              V_MAY_DEF operands in this statement.  Mark all the statements 
00539              which feed this statement's uses as necessary.  */
00540           ssa_op_iter iter;
00541           tree use;
00542 
00543           /* The operands of V_MAY_DEF expressions are also needed as they
00544              represent potential definitions that may reach this
00545              statement (V_MAY_DEF operands allow us to follow def-def 
00546              links).  */
00547 
00548           FOR_EACH_SSA_TREE_OPERAND (use, i, iter, SSA_OP_ALL_USES)
00549             mark_operand_necessary (use, false);
00550         }
00551     }
00552 }

static void remove_dead_phis  )  [static]
 

Remove dead PHI nodes from block BB.   

Definition at line 666 of file tree-ssa-dce.c.

References dump_file, dump_flags, NECESSARY, NULL_TREE, PHI_CHAIN, phi_nodes(), print_generic_stmt(), remove_phi_node(), stmt_stats::removed_phis, stats, TDF_DETAILS, TDF_SLIM, and stmt_stats::total_phis.

Referenced by eliminate_unnecessary_stmts().

00667 {
00668   tree prev, phi;
00669 
00670   prev = NULL_TREE;
00671   phi = phi_nodes (bb);
00672   while (phi)
00673     {
00674       stats.total_phis++;
00675 
00676       if (! NECESSARY (phi))
00677         {
00678           tree next = PHI_CHAIN (phi);
00679 
00680           if (dump_file && (dump_flags & TDF_DETAILS))
00681             {
00682               fprintf (dump_file, "Deleting : ");
00683               print_generic_stmt (dump_file, phi, TDF_SLIM);
00684               fprintf (dump_file, "\n");
00685             }
00686 
00687           remove_phi_node (phi, prev);
00688           stats.removed_phis++;
00689           phi = next;
00690         }
00691       else
00692         {
00693           prev = phi;
00694           phi = PHI_CHAIN (phi);
00695         }
00696     }
00697 }

static void remove_dead_stmt  )  [static]
 

Remove dead statement pointed to by iterator I.  Receives the basic block BB
   containing I so that we don't have to look it up.   

Definition at line 703 of file tree-ssa-dce.c.

References bsi_remove(), bsi_stmt(), DEF_FROM_PTR, dump_file, dump_flags, FOR_EACH_SSA_DEF_OPERAND, is_ctrl_stmt(), mark_sym_for_renaming(), PENDING_STMT, phi_nodes(), print_generic_stmt(), release_defs(), stmt_stats::removed, SSA_NAME_VAR, SSA_OP_VIRTUAL_DEFS, stats, TDF_DETAILS, and TDF_SLIM.

Referenced by eliminate_unnecessary_stmts().

00704 {
00705   tree t = bsi_stmt (*i);
00706   def_operand_p def_p;
00707 
00708   ssa_op_iter iter;
00709 
00710   if (dump_file && (dump_flags & TDF_DETAILS))
00711     {
00712       fprintf (dump_file, "Deleting : ");
00713       print_generic_stmt (dump_file, t, TDF_SLIM);
00714       fprintf (dump_file, "\n");
00715     }
00716 
00717   stats.removed++;
00718 
00719   /* If we have determined that a conditional branch statement contributes
00720      nothing to the program, then we not only remove it, but we also change
00721      the flow graph so that the current block will simply fall-thru to its
00722      immediate post-dominator.  The blocks we are circumventing will be
00723      removed by cleanup_tree_cfg if this change in the flow graph makes them
00724      unreachable.  */
00725   if (is_ctrl_stmt (t))
00726     {
00727       basic_block post_dom_bb;
00728 
00729       /* The post dominance info has to be up-to-date.  */
00730       gcc_assert (dom_computed[CDI_POST_DOMINATORS] == DOM_OK);
00731       /* Get the immediate post dominator of bb.  */
00732       post_dom_bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
00733 
00734       /* There are three particularly problematical cases.
00735 
00736          1. Blocks that do not have an immediate post dominator.  This
00737             can happen with infinite loops.
00738 
00739          2. Blocks that are only post dominated by the exit block.  These
00740             can also happen for infinite loops as we create fake edges
00741             in the dominator tree.
00742 
00743          3. If the post dominator has PHI nodes we may be able to compute
00744             the right PHI args for them.
00745 
00746 
00747          In each of these cases we must remove the control statement
00748          as it may reference SSA_NAMEs which are going to be removed and
00749          we remove all but one outgoing edge from the block.  */
00750       if (! post_dom_bb
00751           || post_dom_bb == EXIT_BLOCK_PTR
00752           || phi_nodes (post_dom_bb))
00753         ;
00754       else
00755         {
00756           /* Redirect the first edge out of BB to reach POST_DOM_BB.  */
00757           redirect_edge_and_branch (EDGE_SUCC (bb, 0), post_dom_bb);
00758           PENDING_STMT (EDGE_SUCC (bb, 0)) = NULL;
00759         }
00760       EDGE_SUCC (bb, 0)->probability = REG_BR_PROB_BASE;
00761       EDGE_SUCC (bb, 0)->count = bb->count;
00762 
00763       /* The edge is no longer associated with a conditional, so it does
00764          not have TRUE/FALSE flags.  */
00765       EDGE_SUCC (bb, 0)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
00766 
00767       /* The lone outgoing edge from BB will be a fallthru edge.  */
00768       EDGE_SUCC (bb, 0)->flags |= EDGE_FALLTHRU;
00769 
00770       /* Remove the remaining the outgoing edges.  */
00771       while (!single_succ_p (bb))
00772         {
00773           /* FIXME.  When we remove the edge, we modify the CFG, which
00774              in turn modifies the dominator and post-dominator tree.
00775              Is it safe to postpone recomputing the dominator and
00776              post-dominator tree until the end of this pass given that
00777              the post-dominators are used above?  */
00778           cfg_altered = true;
00779           remove_edge (EDGE_SUCC (bb, 1));
00780         }
00781     }
00782   
00783   FOR_EACH_SSA_DEF_OPERAND (def_p, t, iter, SSA_OP_VIRTUAL_DEFS)
00784     {
00785       tree def = DEF_FROM_PTR (def_p);
00786       mark_sym_for_renaming (SSA_NAME_VAR (def));
00787     }
00788   bsi_remove (i, true);  
00789   release_defs (t); 
00790 }

static void tree_dce_done  )  [static]
 

Cleanup after this pass.   

Definition at line 844 of file tree-ssa-dce.c.

Referenced by perform_tree_ssa_dce().

00845 {
00846   if (aggressive)
00847     {
00848       int i;
00849 
00850       for (i = 0; i < last_basic_block; ++i)
00851         BITMAP_FREE (control_dependence_map[i]);
00852       free (control_dependence_map);
00853 
00854       sbitmap_free (visited_control_parents);
00855       sbitmap_free (last_stmt_necessary);
00856     }
00857 
00858   sbitmap_free (processed);
00859 
00860   VEC_free (tree, heap, worklist);
00861 }

static void tree_dce_init  )  [static]
 

Initialization for this pass.  Set up the used data structures.   

Definition at line 818 of file tree-ssa-dce.c.

References num_ssa_names, and stats.

Referenced by perform_tree_ssa_dce().

00819 {
00820   memset ((void *) &stats, 0, sizeof (stats));
00821 
00822   if (aggressive)
00823     {
00824       int i;
00825 
00826       control_dependence_map = XNEWVEC (bitmap, last_basic_block);
00827       for (i = 0; i < last_basic_block; ++i)
00828         control_dependence_map[i] = BITMAP_ALLOC (NULL);
00829 
00830       last_stmt_necessary = sbitmap_alloc (last_basic_block);
00831       sbitmap_zero (last_stmt_necessary);
00832     }
00833 
00834   processed = sbitmap_alloc (num_ssa_names + 1);
00835   sbitmap_zero (processed);
00836 
00837   worklist = VEC_alloc (tree, heap, 64);
00838   cfg_altered = false;
00839 }

static unsigned int tree_ssa_cd_dce  )  [static]
 

Definition at line 942 of file tree-ssa-dce.c.

References perform_tree_ssa_dce().

00943 {
00944   perform_tree_ssa_dce (/*aggressive=*/optimize >= 2);
00945   return 0;
00946 }

static unsigned int tree_ssa_dce  )  [static]
 

Pass entry points.   

Definition at line 926 of file tree-ssa-dce.c.

References perform_tree_ssa_dce().

00927 {
00928   perform_tree_ssa_dce (/*aggressive=*/false);
00929   return 0;
00930 }

static unsigned int tree_ssa_dce_loop  )  [static]
 

Definition at line 933 of file tree-ssa-dce.c.

References current_loops, free_numbers_of_iterations_estimates(), perform_tree_ssa_dce(), and scev_reset().

00934 {
00935   perform_tree_ssa_dce (/*aggressive=*/false);
00936   free_numbers_of_iterations_estimates (current_loops);
00937   scev_reset ();
00938   return 0;
00939 }

static VEC static inline void mark_stmt_necessary (  tree,
heap 
[static]
 

Indicate block BB is control dependent on an edge with index EDGE_INDEX.   

Definition at line 78 of file tree-ssa-dce.c.

00142 {
00143   if (bb == ENTRY_BLOCK_PTR)
00144     return;
00145   gcc_assert (bb != EXIT_BLOCK_PTR);
00146   bitmap_set_bit (control_dependence_map[bb->index], edge_index);
00147 }


Variable Documentation

struct tree_opt_pass pass_cd_dce
 

Initial value:

Definition at line 996 of file tree-ssa-dce.c.

struct tree_opt_pass pass_dce
 

Initial value:

Definition at line 954 of file tree-ssa-dce.c.

struct tree_opt_pass pass_dce_loop
 

Initial value:

{
  "dceloop",                            
  gate_dce,                             
  tree_ssa_dce_loop,                    
  NULL,                                 
  NULL,                                 
  0,                                    
  TV_TREE_DCE,                          
  PROP_cfg | PROP_ssa | PROP_alias,     
  0,                                    
  0,                                    
  0,                                    
  TODO_dump_func 
    | TODO_update_ssa
    | TODO_cleanup_cfg
    | TODO_verify_ssa,                  
  0                                     
}

Definition at line 976 of file tree-ssa-dce.c.

struct stmt_stats stats [static]
 

These RTL headers are needed for basic-block.h.   

Referenced by add_graph_edge(), analyze_scalar_evolution_for_all_loop_phi_nodes(), create_function_info_for(), create_variable_info_for(), dump_chrecs_stats(), dump_sa_points_to_info(), eliminate_unnecessary_stmts(), gather_chrec_stats(), gather_stats_on_scev_database(), init_alias_vars(), int_add_graph_edge(), perform_var_substitution(), print_stats(), process_unification_queue(), remove_dead_phis(), remove_dead_stmt(), reset_chrecs_counters(), solve_graph(), and tree_dce_init().


Generated on Sun Sep 17 18:03:55 2006 for Tree SSA by  doxygen 1.4.6