OSDN Git Service

PR middle-end/27478
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-dce.c
index 1b25f27..684ea78 100644 (file)
@@ -1,5 +1,5 @@
 /* Dead code elimination pass for the GNU compiler.
-   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    Contributed by Ben Elliston <bje@redhat.com>
    and Andrew MacLeod <amacleod@redhat.com>
    Adapted to use control dependence by Steven Bosscher, SUSE Labs.
@@ -105,17 +105,12 @@ static sbitmap visited_control_parents;
    to be recomputed.  */
 static bool cfg_altered;
 
-/* Execute CODE for each edge (given number EDGE_NUMBER within the CODE)
-   for which the block with index N is control dependent.  */
-#define EXECUTE_IF_CONTROL_DEPENDENT(N, EDGE_NUMBER, CODE)                   \
-  {                                                                          \
-    bitmap_iterator bi;                                                              \
-                                                                             \
-    EXECUTE_IF_SET_IN_BITMAP (control_dependence_map[N], 0, EDGE_NUMBER, bi)  \
-      {                                                                              \
-       CODE;                                                                 \
-      }                                                                              \
-  }
+/* Execute code that follows the macro for each edge (given number
+   EDGE_NUMBER within the CODE) for which the block with index N is
+   control dependent.  */
+#define EXECUTE_IF_CONTROL_DEPENDENT(BI, N, EDGE_NUMBER)       \
+  EXECUTE_IF_SET_IN_BITMAP (control_dependence_map[(N)], 0,    \
+                           (EDGE_NUMBER), (BI))
 
 /* Local function prototypes.  */
 static inline void set_control_dependence_map_bit (basic_block, int);
@@ -152,8 +147,8 @@ set_control_dependence_map_bit (basic_block bb, int edge_index)
 }
 
 /* Clear all control dependences for block BB.  */
-static inline
-void clear_control_dependence_bitmap (basic_block bb)
+static inline void
+clear_control_dependence_bitmap (basic_block bb)
 {
   bitmap_clear (control_dependence_map[bb->index]);
 }
@@ -443,6 +438,7 @@ find_obviously_necessary_stmts (struct edge_list *el)
 static void
 mark_control_dependent_edges_necessary (basic_block bb, struct edge_list *el)
 {
+  bitmap_iterator bi;
   unsigned edge_number;
 
   gcc_assert (bb != EXIT_BLOCK_PTR);
@@ -450,7 +446,7 @@ mark_control_dependent_edges_necessary (basic_block bb, struct edge_list *el)
   if (bb == ENTRY_BLOCK_PTR)
     return;
 
-  EXECUTE_IF_CONTROL_DEPENDENT (bb->index, edge_number,
+  EXECUTE_IF_CONTROL_DEPENDENT (bi, bb->index, edge_number)
     {
       tree t;
       basic_block cd_bb = INDEX_EDGE_PRED_BB (el, edge_number);
@@ -462,7 +458,7 @@ mark_control_dependent_edges_necessary (basic_block bb, struct edge_list *el)
       t = last_stmt (cd_bb);
       if (t && is_ctrl_stmt (t))
        mark_stmt_necessary (t, true);
-    });
+    }
 }
 \f
 /* Propagate necessity using the operands of necessary statements.  Process
@@ -724,7 +720,7 @@ remove_dead_stmt (block_stmt_iterator *i, basic_block bb)
      nothing to the program, then we not only remove it, but we also change
      the flow graph so that the current block will simply fall-thru to its
      immediate post-dominator.  The blocks we are circumventing will be
-     removed by cleaup_tree_cfg if this change in the flow graph makes them
+     removed by cleanup_tree_cfg if this change in the flow graph makes them
      unreachable.  */
   if (is_ctrl_stmt (t))
     {
@@ -734,23 +730,27 @@ remove_dead_stmt (block_stmt_iterator *i, basic_block bb)
       gcc_assert (dom_computed[CDI_POST_DOMINATORS] == DOM_OK);
       /* Get the immediate post dominator of bb.  */
       post_dom_bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
-      /* Some blocks don't have an immediate post dominator.  This can happen
-        for example with infinite loops.  Removing an infinite loop is an
-        inappropriate transformation anyway...  */
-      if (! post_dom_bb)
-       {
-         bsi_next (i);
-         return;
-       }
 
-      /* If the post dominator block has PHI nodes, we might be unable
-        to compute the right PHI args for them.  Since the control
-        statement is unnecessary, all edges can be regarded as
-        equivalent, but we have to get rid of the condition, since it
-        might reference a variable that was determined to be
-        unnecessary and thus removed.  */
-      if (phi_nodes (post_dom_bb))
-       post_dom_bb = EDGE_SUCC (bb, 0)->dest;
+      /* There are three particularly problematical cases.
+
+        1. Blocks that do not have an immediate post dominator.  This
+           can happen with infinite loops.
+
+        2. Blocks that are only post dominated by the exit block.  These
+           can also happen for infinite loops as we create fake edges
+           in the dominator tree.
+
+        3. If the post dominator has PHI nodes we may be able to compute
+           the right PHI args for them.
+
+
+        In each of these cases we must remove the control statement
+        as it may reference SSA_NAMEs which are going to be removed and
+        we remove all but one outgoing edge from the block.  */
+      if (! post_dom_bb
+         || post_dom_bb == EXIT_BLOCK_PTR
+         || phi_nodes (post_dom_bb))
+       ;
       else
        {
          /* Redirect the first edge out of BB to reach POST_DOM_BB.  */
@@ -764,13 +764,8 @@ remove_dead_stmt (block_stmt_iterator *i, basic_block bb)
         not have TRUE/FALSE flags.  */
       EDGE_SUCC (bb, 0)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
 
-      /* If the edge reaches any block other than the exit, then it is a
-        fallthru edge; if it reaches the exit, then it is not a fallthru
-        edge.  */
-      if (post_dom_bb != EXIT_BLOCK_PTR)
-       EDGE_SUCC (bb, 0)->flags |= EDGE_FALLTHRU;
-      else
-       EDGE_SUCC (bb, 0)->flags &= ~EDGE_FALLTHRU;
+      /* The lone outgoing edge from BB will be a fallthru edge.  */
+      EDGE_SUCC (bb, 0)->flags |= EDGE_FALLTHRU;
 
       /* Remove the remaining the outgoing edges.  */
       while (!single_succ_p (bb))
@@ -927,24 +922,27 @@ perform_tree_ssa_dce (bool aggressive)
 }
 
 /* Pass entry points.  */
-static void
+static unsigned int
 tree_ssa_dce (void)
 {
   perform_tree_ssa_dce (/*aggressive=*/false);
+  return 0;
 }
 
-static void
+static unsigned int
 tree_ssa_dce_loop (void)
 {
   perform_tree_ssa_dce (/*aggressive=*/false);
   free_numbers_of_iterations_estimates (current_loops);
   scev_reset ();
+  return 0;
 }
 
-static void
+static unsigned int
 tree_ssa_cd_dce (void)
 {
   perform_tree_ssa_dce (/*aggressive=*/optimize >= 2);
+  return 0;
 }
 
 static bool