New test cases.
[gcc.git] / gcc / cfgcleanup.c
index 0e13f7a07cf83430b08b0cf2160efef9820d2fef..c2595ea9dc7f88ca3ec8d6d765c8bd25e1ac1242 100644 (file)
@@ -1,6 +1,7 @@
 /* Control flow optimization code for GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -763,8 +764,6 @@ merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
   if (BB_PARTITION (b) != BB_PARTITION (c))
     return NULL;
 
-
-
   /* If B has a fallthru edge to C, no need to move anything.  */
   if (e->flags & EDGE_FALLTHRU)
     {
@@ -1993,7 +1992,7 @@ try_optimize_cfg (int mode)
              bool changed_here = false;
 
              /* Delete trivially dead basic blocks.  */
-             while (EDGE_COUNT (b->preds) == 0)
+             if (EDGE_COUNT (b->preds) == 0)
                {
                  c = b->prev_bb;
                  if (dump_file)
@@ -2003,7 +2002,9 @@ try_optimize_cfg (int mode)
                  delete_basic_block (b);
                  if (!(mode & CLEANUP_CFGLAYOUT))
                    changed = true;
-                 b = c;
+                 /* Avoid trying to remove ENTRY_BLOCK_PTR.  */
+                 b = (c == ENTRY_BLOCK_PTR ? c->next_bb : c);
+                 continue;
                }
 
              /* Remove code labels no longer used.  */
@@ -2033,6 +2034,8 @@ try_optimize_cfg (int mode)
 
                      reorder_insns_nobb (label, label, bb_note);
                      BB_HEAD (b) = bb_note;
+                     if (BB_END (b) == bb_note)
+                       BB_END (b) = label;
                    }
                  if (dump_file)
                    fprintf (dump_file, "Deleted label in block %i.\n",
@@ -2222,6 +2225,12 @@ cleanup_cfg (int mode)
 {
   bool changed = false;
 
+  /* Set the cfglayout mode flag here.  We could update all the callers
+     but that is just inconvenient, especially given that we eventually
+     want to have cfglayout mode as the default.  */
+  if (current_ir_type () == IR_RTL_CFGLAYOUT)
+    mode |= CLEANUP_CFGLAYOUT;
+
   timevar_push (TV_CLEANUP_CFG);
   if (delete_unreachable_blocks ())
     {
@@ -2230,7 +2239,7 @@ cleanup_cfg (int mode)
         now to introduce more opportunities for try_optimize_cfg.  */
       if (!(mode & (CLEANUP_NO_INSN_DEL | CLEANUP_UPDATE_LIFE))
          && !reload_completed)
-       delete_trivially_dead_insns (get_insns(), max_reg_num ());
+       delete_trivially_dead_insns (get_insns (), max_reg_num ());
     }
 
   compact_blocks ();
@@ -2255,12 +2264,20 @@ cleanup_cfg (int mode)
               && (mode & CLEANUP_EXPENSIVE)
               && !reload_completed)
        {
-         if (!delete_trivially_dead_insns (get_insns(), max_reg_num ()))
+         if (!delete_trivially_dead_insns (get_insns (), max_reg_num ()))
            break;
        }
       else
        break;
-      delete_dead_jumptables ();
+
+      /* Don't call delete_dead_jumptables in cfglayout mode, because
+        that function assumes that jump tables are in the insns stream.
+        But we also don't _have_ to delete dead jumptables in cfglayout
+        mode because we shouldn't even be looking at things that are
+        not in a basic block.  Dead jumptables are cleaned up when
+        going out of cfglayout mode.  */
+      if (!(mode & CLEANUP_CFGLAYOUT))
+       delete_dead_jumptables ();
     }
 
   timevar_pop (TV_CLEANUP_CFG);
@@ -2300,29 +2317,12 @@ struct tree_opt_pass pass_jump =
 static unsigned int
 rest_of_handle_jump2 (void)
 {
-  /* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB.  Do this
-     before jump optimization switches branch directions.  */
-  if (flag_guess_branch_prob)
-    expected_value_to_br_prob ();
-
   delete_trivially_dead_insns (get_insns (), max_reg_num ());
   reg_scan (get_insns (), max_reg_num ());
   if (dump_file)
     dump_flow_info (dump_file, dump_flags);
   cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0)
               | (flag_thread_jumps ? CLEANUP_THREADING : 0));
-
-  purge_line_number_notes ();
-
-  if (optimize)
-    cleanup_cfg (CLEANUP_EXPENSIVE);
-
-  /* Jump optimization, and the removal of NULL pointer checks, may
-     have reduced the number of instructions substantially.  CSE, and
-     future passes, allocate arrays whose dimensions involve the
-     maximum instruction UID, so if we can reduce the maximum UID
-     we'll save big on memory.  */
-  renumber_insns ();
   return 0;
 }