OSDN Git Service

* gcc.dg/asm-b.c: Fix comment typos.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-dce.c
index 2c68861..16b9d48 100644 (file)
@@ -1,5 +1,5 @@
 /* Dead code elimination pass for the GNU compiler.
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 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.
@@ -54,6 +54,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "rtl.h"
 #include "tm_p.h"
 #include "hard-reg-set.h"
+#include "obstack.h"
 #include "basic-block.h"
 
 #include "tree.h"
@@ -92,6 +93,10 @@ static sbitmap last_stmt_necessary;
    on the Ith edge.  */
 bitmap *control_dependence_map;
 
+/* Vector indicating that a basic block has already had all the edges
+   processed that it is control dependent on.  */
+sbitmap visited_control_parents;
+
 /* 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)                   \
@@ -263,7 +268,7 @@ mark_operand_necessary (tree op, bool phionly)
 }
 \f
 
-/* Mark STMT as necessary if it is obviously is.  Add it to the worklist if
+/* 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
@@ -325,22 +330,12 @@ mark_stmt_if_obviously_necessary (tree stmt, bool aggressive)
       break;
 
     case GOTO_EXPR:
-      if (! simple_goto_p (stmt))
-       mark_stmt_necessary (stmt, true);
+      gcc_assert (!simple_goto_p (stmt));
+      mark_stmt_necessary (stmt, true);
       return;
 
     case COND_EXPR:
-      if (GOTO_DESTINATION (COND_EXPR_THEN (stmt))
-         == GOTO_DESTINATION (COND_EXPR_ELSE (stmt)))
-       {
-         /* A COND_EXPR is obviously dead if the target labels are the same.
-            We cannot kill the statement at this point, so to prevent the
-            statement from being marked necessary, we replace the condition
-            with a constant.  The stmt is killed later on in cfg_cleanup.  */
-         COND_EXPR_COND (stmt) = integer_zero_node;
-         modify_stmt (stmt);
-         return;
-       }
+      gcc_assert (EDGE_COUNT (bb_for_stmt (stmt)->succs) == 2);
       /* Fall through.  */
 
     case SWITCH_EXPR:
@@ -491,11 +486,6 @@ find_obviously_necessary_stmts (struct edge_list *el)
          NECESSARY (stmt) = 0;
          mark_stmt_if_obviously_necessary (stmt, el != NULL);
        }
-
-      /* Mark this basic block as `not visited'.  A block will be marked
-        visited when the edges that it is control dependent on have been
-        marked.  */
-      bb->flags &= ~BB_VISITED;
     }
 
   if (el)
@@ -518,7 +508,7 @@ find_obviously_necessary_stmts (struct edge_list *el)
 static void
 mark_control_dependent_edges_necessary (basic_block bb, struct edge_list *el)
 {
-  int edge_number;
+  unsigned edge_number;
 
   gcc_assert (bb != EXIT_BLOCK_PTR);
 
@@ -574,9 +564,10 @@ propagate_necessity (struct edge_list *el)
             containing `i' is control dependent on, but only if we haven't
             already done so.  */
          basic_block bb = bb_for_stmt (i);
-         if (! (bb->flags & BB_VISITED))
+         if (bb != ENTRY_BLOCK_PTR
+             && ! TEST_BIT (visited_control_parents, bb->index))
            {
-             bb->flags |= BB_VISITED;
+             SET_BIT (visited_control_parents, bb->index);
              mark_control_dependent_edges_necessary (bb, el);
            }
        }
@@ -602,9 +593,10 @@ propagate_necessity (struct edge_list *el)
              for (k = 0; k < PHI_NUM_ARGS (i); k++)
                {
                  basic_block arg_bb = PHI_ARG_EDGE (i, k)->src;
-                 if (! (arg_bb->flags & BB_VISITED))
+                 if (arg_bb != ENTRY_BLOCK_PTR
+                     && ! TEST_BIT (visited_control_parents, arg_bb->index))
                    {
-                     arg_bb->flags |= BB_VISITED;
+                     SET_BIT (visited_control_parents, arg_bb->index);
                      mark_control_dependent_edges_necessary (arg_bb, el);
                    }
                }
@@ -887,7 +879,7 @@ tree_dce_init (bool aggressive)
       control_dependence_map 
        = xmalloc (last_basic_block * sizeof (bitmap));
       for (i = 0; i < last_basic_block; ++i)
-       control_dependence_map[i] = BITMAP_XMALLOC ();
+       control_dependence_map[i] = BITMAP_ALLOC (NULL);
 
       last_stmt_necessary = sbitmap_alloc (last_basic_block);
       sbitmap_zero (last_stmt_necessary);
@@ -909,9 +901,10 @@ tree_dce_done (bool aggressive)
       int i;
 
       for (i = 0; i < last_basic_block; ++i)
-       BITMAP_XFREE (control_dependence_map[i]);
+       BITMAP_FREE (control_dependence_map[i]);
       free (control_dependence_map);
 
+      sbitmap_free (visited_control_parents);
       sbitmap_free (last_stmt_necessary);
     }
 
@@ -948,6 +941,9 @@ perform_tree_ssa_dce (bool aggressive)
       find_all_control_dependences (el);
       timevar_pop (TV_CONTROL_DEPENDENCES);
 
+      visited_control_parents = sbitmap_alloc (last_basic_block);
+      sbitmap_zero (visited_control_parents);
+
       mark_dfs_back_edges ();
     }
 
@@ -961,14 +957,9 @@ perform_tree_ssa_dce (bool aggressive)
   if (aggressive)
     free_dominance_info (CDI_POST_DOMINATORS);
 
-  cleanup_tree_cfg ();
-
   /* Debugging dumps.  */
   if (dump_file)
-    {
-      dump_function_to_file (current_function_decl, dump_file, dump_flags);
-      print_stats ();
-    }
+    print_stats ();
 
   tree_dce_done (aggressive);
 
@@ -1007,7 +998,7 @@ struct tree_opt_pass pass_dce =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_fix_def_def_chains |TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */
+  TODO_dump_func | TODO_fix_def_def_chains | TODO_cleanup_cfg | TODO_ggc_collect | TODO_verify_ssa,    /* todo_flags_finish */
   0                                    /* letter */
 };
 
@@ -1024,7 +1015,7 @@ struct tree_opt_pass pass_cd_dce =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_fix_def_def_chains | TODO_ggc_collect | TODO_verify_ssa | TODO_verify_flow,
+  TODO_dump_func | TODO_fix_def_def_chains | TODO_cleanup_cfg | TODO_ggc_collect | TODO_verify_ssa | TODO_verify_flow,
                                        /* todo_flags_finish */
   0                                    /* letter */
 };