OSDN Git Service

2004-02-17 Andrew Pinski <pinskia@physics.uc.edu>
[pf3gnuchains/gcc-fork.git] / gcc / cfgcleanup.c
index 3365a78..38a2915 100644 (file)
@@ -48,6 +48,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "params.h"
 #include "tm_p.h"
 #include "target.h"
+#include "regs.h"
 
 /* cleanup_cfg maintains following flags for each basic block.  */
 
@@ -67,6 +68,8 @@ enum bb_flags
 
 #define FORWARDER_BLOCK_P(BB) (BB_FLAGS (BB) & BB_FORWARDER_BLOCK)
 
+/* Set to true when we are running first pass of try_optimize_cfg loop.  */
+static bool first_pass;
 static bool try_crossjump_to_edge (int, edge, edge);
 static bool try_crossjump_bb (int, basic_block);
 static bool outgoing_edges_match (int, basic_block, basic_block);
@@ -192,8 +195,8 @@ try_simplify_condjump (basic_block cbranch_block)
        }
     }
   /* Delete the block with the unconditional jump, and clean up the mess.  */
-  delete_block (jump_block);
-  tidy_fallthru_edge (cbranch_jump_edge, cbranch_block, cbranch_dest_block);
+  delete_basic_block (jump_block);
+  tidy_fallthru_edge (cbranch_jump_edge);
 
   return true;
 }
@@ -218,7 +221,7 @@ mark_effect (rtx exp, regset nonequal)
          CLEAR_REGNO_REG_SET (nonequal, regno);
          if (regno < FIRST_PSEUDO_REGISTER)
            {
-             int n = HARD_REGNO_NREGS (regno, GET_MODE (dest));
+             int n = hard_regno_nregs[regno][GET_MODE (dest)];
              while (--n > 0)
                CLEAR_REGNO_REG_SET (nonequal, regno + n);
            }
@@ -237,7 +240,7 @@ mark_effect (rtx exp, regset nonequal)
       SET_REGNO_REG_SET (nonequal, regno);
       if (regno < FIRST_PSEUDO_REGISTER)
        {
-         int n = HARD_REGNO_NREGS (regno, GET_MODE (dest));
+         int n = hard_regno_nregs[regno][GET_MODE (dest)];
          while (--n > 0)
            SET_REGNO_REG_SET (nonequal, regno + n);
        }
@@ -263,7 +266,7 @@ mentions_nonequal_regs (rtx *x, void *data)
        return 1;
       if (regno < FIRST_PSEUDO_REGISTER)
        {
-         int n = HARD_REGNO_NREGS (regno, GET_MODE (*x));
+         int n = hard_regno_nregs[regno][GET_MODE (*x)];
          while (--n > 0)
            if (REGNO_REG_SET_P (nonequal, regno + n))
              return 1;
@@ -429,6 +432,7 @@ try_forward_edges (int mode, basic_block b)
       int counter;
       bool threaded = false;
       int nthreaded_edges = 0;
+      bool may_thread = first_pass | (b->flags & BB_DIRTY);
 
       next = e->succ_next;
 
@@ -447,6 +451,7 @@ try_forward_edges (int mode, basic_block b)
        {
          basic_block new_target = NULL;
          bool new_target_threaded = false;
+         may_thread |= target->flags & BB_DIRTY;
 
          if (FORWARDER_BLOCK_P (target)
              && target->succ->dest != EXIT_BLOCK_PTR)
@@ -459,7 +464,7 @@ try_forward_edges (int mode, basic_block b)
 
          /* Allow to thread only over one edge at time to simplify updating
             of probabilities.  */
-         else if (mode & CLEANUP_THREADING)
+         else if ((mode & CLEANUP_THREADING) && may_thread)
            {
              edge t = thread_jump (mode, e, target);
              if (t)
@@ -1526,7 +1531,7 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
   to_remove = redirect_from->succ->dest;
 
   redirect_edge_and_branch_force (redirect_from->succ, redirect_to);
-  delete_block (to_remove);
+  delete_basic_block (to_remove);
 
   update_forwarder_flag (redirect_from);
 
@@ -1573,6 +1578,12 @@ try_crossjump_bb (int mode, basic_block bb)
             If there is a match, we'll do it the other way around.  */
          if (e == fallthru)
            continue;
+         /* If nothing changed since the last attempt, there is nothing
+            we can do.  */
+         if (!first_pass
+             && (!(e->src->flags & BB_DIRTY)
+                 && !(fallthru->src->flags & BB_DIRTY)))
+           continue;
 
          if (try_crossjump_to_edge (mode, e, fallthru))
            {
@@ -1615,6 +1626,13 @@ try_crossjump_bb (int mode, basic_block bb)
          if (e->src->index > e2->src->index)
            continue;
 
+         /* If nothing changed since the last attempt, there is nothing
+            we can do.  */
+         if (!first_pass
+             && (!(e->src->flags & BB_DIRTY)
+                 && !(e2->src->flags & BB_DIRTY)))
+           continue;
+
          if (try_crossjump_to_edge (mode, e, e2))
            {
              changed = true;
@@ -1644,11 +1662,12 @@ try_optimize_cfg (int mode)
   FOR_EACH_BB (bb)
     update_forwarder_flag (bb);
 
-  if (mode & CLEANUP_UPDATE_LIFE)
+  if (mode & (CLEANUP_UPDATE_LIFE | CLEANUP_CROSSJUMP | CLEANUP_THREADING))
     clear_bb_flags ();
 
   if (! (* targetm.cannot_modify_jumps_p) ())
     {
+      first_pass = true;
       /* Attempt to merge blocks as made possible by edge removal.  If
         a block has only one successor, and the successor has only
         one predecessor, they may be combined.  */
@@ -1676,7 +1695,7 @@ try_optimize_cfg (int mode)
                    fprintf (rtl_dump_file, "Deleting block %i.\n",
                             b->index);
 
-                 delete_block (b);
+                 delete_basic_block (b);
                  if (!(mode & CLEANUP_CFGLAYOUT))
                    changed = true;
                  b = c;
@@ -1737,7 +1756,7 @@ try_optimize_cfg (int mode)
 
                  c = b->prev_bb == ENTRY_BLOCK_PTR ? b->next_bb : b->prev_bb;
                  redirect_edge_succ_nodup (b->pred, b->succ->dest);
-                 delete_block (b);
+                 delete_basic_block (b);
                  changed = true;
                  b = c;
                }
@@ -1791,7 +1810,7 @@ try_optimize_cfg (int mode)
                  && b->succ->dest != EXIT_BLOCK_PTR
                  && onlyjump_p (BB_END (b))
                  && try_redirect_by_replacing_jump (b->succ, b->succ->dest,
-                                                    (mode & CLEANUP_CFGLAYOUT)))
+                                                    (mode & CLEANUP_CFGLAYOUT) != 0))
                {
                  update_forwarder_flag (b);
                  changed_here = true;
@@ -1824,6 +1843,7 @@ try_optimize_cfg (int mode)
 #endif
 
          changed_overall |= changed;
+         first_pass = false;
        }
       while (changed);
     }
@@ -1854,7 +1874,7 @@ delete_unreachable_blocks (void)
 
       if (!(b->flags & BB_REACHABLE))
        {
-         delete_block (b);
+         delete_basic_block (b);
          changed = true;
        }
     }
@@ -1897,7 +1917,8 @@ cleanup_cfg (int mode)
                                                 PROP_DEATH_NOTES
                                                 | PROP_SCAN_DEAD_CODE
                                                 | PROP_KILL_DEAD_CODE
-                                                | PROP_LOG_LINKS))
+                                                | ((mode & CLEANUP_LOG_LINKS)
+                                                   ? PROP_LOG_LINKS : 0)))
            break;
        }
       else if (!(mode & (CLEANUP_NO_INSN_DEL | CLEANUP_PRE_SIBCALL))