OSDN Git Service

* tree-ssa-dce.c (remove_dead_statement): When removing a dead
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-dce.c
index 8902d2a..c8a30a4 100644 (file)
@@ -64,6 +64,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "tree-pass.h"
 #include "timevar.h"
 #include "flags.h"
+#include "cfgloop.h"
+#include "tree-scalar-evolution.h"
 \f
 static struct stmt_stats
 {
@@ -180,7 +182,7 @@ find_control_dependence (struct edge_list *el, int edge_index)
   gcc_assert (INDEX_EDGE_PRED_BB (el, edge_index) != EXIT_BLOCK_PTR);
 
   if (INDEX_EDGE_PRED_BB (el, edge_index) == ENTRY_BLOCK_PTR)
-    ending_block = ENTRY_BLOCK_PTR->next_bb;
+    ending_block = single_succ (ENTRY_BLOCK_PTR);
   else
     ending_block = find_pdom (INDEX_EDGE_PRED_BB (el, edge_index));
 
@@ -283,8 +285,7 @@ static void
 mark_stmt_if_obviously_necessary (tree stmt, bool aggressive)
 {
   stmt_ann_t ann;
-  tree op, def;
-  ssa_op_iter iter;
+  tree op;
 
   /* With non-call exceptions, we have to assume that all statements could
      throw.  If a statement may throw, it is inherently necessary.  */
@@ -370,14 +371,6 @@ mark_stmt_if_obviously_necessary (tree stmt, bool aggressive)
       return;
     }
 
-  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
-    {
-      if (is_global_var (SSA_NAME_VAR (def)))
-       {
-         mark_stmt_necessary (stmt, true);
-         return;
-        }
-    }
   if (is_hidden_global_store (stmt))
     {
       mark_stmt_necessary (stmt, true);
@@ -741,23 +734,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.  */
@@ -771,13 +768,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))
@@ -797,7 +789,7 @@ remove_dead_stmt (block_stmt_iterator *i, basic_block bb)
       tree def = DEF_FROM_PTR (def_p);
       mark_sym_for_renaming (SSA_NAME_VAR (def));
     }
-  bsi_remove (i);  
+  bsi_remove (i, true);  
   release_defs (t); 
 }
 \f
@@ -835,8 +827,7 @@ tree_dce_init (bool aggressive)
     {
       int i;
 
-      control_dependence_map 
-       = xmalloc (last_basic_block * sizeof (bitmap));
+      control_dependence_map = XNEWVEC (bitmap, last_basic_block);
       for (i = 0; i < last_basic_block; ++i)
        control_dependence_map[i] = BITMAP_ALLOC (NULL);
 
@@ -942,6 +933,14 @@ tree_ssa_dce (void)
 }
 
 static void
+tree_ssa_dce_loop (void)
+{
+  perform_tree_ssa_dce (/*aggressive=*/false);
+  free_numbers_of_iterations_estimates (current_loops);
+  scev_reset ();
+}
+
+static void
 tree_ssa_cd_dce (void)
 {
   perform_tree_ssa_dce (/*aggressive=*/optimize >= 2);
@@ -967,9 +966,30 @@ struct tree_opt_pass pass_dce =
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   TODO_dump_func 
-    | TODO_update_ssa_no_phi 
+    | TODO_update_ssa
     | TODO_cleanup_cfg
     | TODO_ggc_collect
+    | TODO_verify_ssa
+    | TODO_remove_unused_locals,       /* todo_flags_finish */
+  0                                    /* letter */
+};
+
+struct tree_opt_pass pass_dce_loop =
+{
+  "dceloop",                           /* name */
+  gate_dce,                            /* gate */
+  tree_ssa_dce_loop,                   /* execute */
+  NULL,                                        /* sub */
+  NULL,                                        /* next */
+  0,                                   /* static_pass_number */
+  TV_TREE_DCE,                         /* tv_id */
+  PROP_cfg | PROP_ssa | PROP_alias,    /* properties_required */
+  0,                                   /* properties_provided */
+  0,                                   /* properties_destroyed */
+  0,                                   /* todo_flags_start */
+  TODO_dump_func 
+    | TODO_update_ssa
+    | TODO_cleanup_cfg
     | TODO_verify_ssa,                 /* todo_flags_finish */
   0                                    /* letter */
 };
@@ -988,11 +1008,10 @@ struct tree_opt_pass pass_cd_dce =
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
   TODO_dump_func
-    | TODO_update_ssa_no_phi
+    | TODO_update_ssa
     | TODO_cleanup_cfg
     | TODO_ggc_collect
     | TODO_verify_ssa
     | TODO_verify_flow,                        /* todo_flags_finish */
   0                                    /* letter */
 };
-