OSDN Git Service

2004-10-23 Daniel Berlin <dberlin@dberlin.org>
[pf3gnuchains/gcc-fork.git] / gcc / cfg.c
index b5d28c3..eae092d 100644 (file)
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -144,34 +144,20 @@ clear_edges (void)
 {
   basic_block bb;
   edge e;
+  edge_iterator ei;
 
   FOR_EACH_BB (bb)
     {
-      edge e = bb->succ;
-
-      while (e)
-       {
-         edge next = e->succ_next;
-
-         free_edge (e);
-         e = next;
-       }
-
-      bb->succ = NULL;
-      bb->pred = NULL;
+      FOR_EACH_EDGE (e, ei, bb->succs)
+       free_edge (e);
+      VEC_truncate (edge, bb->succs, 0);
+      VEC_truncate (edge, bb->preds, 0);
     }
 
-  e = ENTRY_BLOCK_PTR->succ;
-  while (e)
-    {
-      edge next = e->succ_next;
-
-      free_edge (e);
-      e = next;
-    }
-
-  EXIT_BLOCK_PTR->pred = NULL;
-  ENTRY_BLOCK_PTR->succ = NULL;
+  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
+    free_edge (e);
+  VEC_truncate (edge, EXIT_BLOCK_PTR->preds, 0);
+  VEC_truncate (edge, ENTRY_BLOCK_PTR->succs, 0);
 
   gcc_assert (!n_edges);
 }
@@ -284,15 +270,13 @@ unchecked_make_edge (basic_block src, basic_block dst, int flags)
   e = ggc_alloc_cleared (sizeof (*e));
   n_edges++;
 
-  e->succ_next = src->succ;
-  e->pred_next = dst->pred;
+  VEC_safe_insert (edge, src->succs, 0, e);
+  VEC_safe_insert (edge, dst->preds, 0, e);
+
   e->src = src;
   e->dest = dst;
   e->flags = flags;
 
-  src->succ = e;
-  dst->pred = e;
-
   return e;
 }
 
@@ -304,6 +288,7 @@ cached_make_edge (sbitmap *edge_cache, basic_block src, basic_block dst, int fla
 {
   int use_edge_cache;
   edge e;
+  edge_iterator ei;
 
   /* Don't bother with edge cache for ENTRY or EXIT, if there aren't that
      many edges to them, or we didn't allocate memory for it.  */
@@ -324,7 +309,7 @@ cached_make_edge (sbitmap *edge_cache, basic_block src, basic_block dst, int fla
 
       /* Fall through.  */
     case 0:
-      for (e = src->succ; e; e = e->succ_next)
+      FOR_EACH_EDGE (e, ei, src->succs)
        if (e->dest == dst)
          {
            e->flags |= flags;
@@ -368,30 +353,42 @@ make_single_succ_edge (basic_block src, basic_block dest, int flags)
 void
 remove_edge (edge e)
 {
-  edge last_pred = NULL;
-  edge last_succ = NULL;
   edge tmp;
   basic_block src, dest;
+  bool found = false;
+  edge_iterator ei;
 
   src = e->src;
   dest = e->dest;
-  for (tmp = src->succ; tmp && tmp != e; tmp = tmp->succ_next)
-    last_succ = tmp;
 
-  gcc_assert (tmp);
-  if (last_succ)
-    last_succ->succ_next = e->succ_next;
-  else
-    src->succ = e->succ_next;
+  for (ei = ei_start (src->succs); (tmp = ei_safe_edge (ei)); )
+    {
+      if (tmp == e)
+       {
+         VEC_unordered_remove (edge, src->succs, ei.index);
+         found = true;
+         break;
+       }
+      else
+       ei_next (&ei);
+    }
 
-  for (tmp = dest->pred; tmp && tmp != e; tmp = tmp->pred_next)
-    last_pred = tmp;
+  gcc_assert (found);
 
-  gcc_assert (tmp);
-  if (last_pred)
-    last_pred->pred_next = e->pred_next;
-  else
-    dest->pred = e->pred_next;
+  found = false;
+  for (ei = ei_start (dest->preds); (tmp = ei_safe_edge (ei)); )
+    {
+      if (tmp == e)
+       {
+         VEC_unordered_remove (edge, dest->preds, ei.index);
+         found = true;
+         break;
+       }
+      else
+       ei_next (&ei);
+    }
+
+  gcc_assert (found);
 
   free_edge (e);
 }
@@ -401,16 +398,27 @@ remove_edge (edge e)
 void
 redirect_edge_succ (edge e, basic_block new_succ)
 {
-  edge *pe;
+  edge tmp;
+  edge_iterator ei;
+  bool found = false;
 
   /* Disconnect the edge from the old successor block.  */
-  for (pe = &e->dest->pred; *pe != e; pe = &(*pe)->pred_next)
-    continue;
-  *pe = (*pe)->pred_next;
+  for (ei = ei_start (e->dest->preds); (tmp = ei_safe_edge (ei)); )
+    {
+      if (tmp == e)
+       {
+         VEC_unordered_remove (edge, e->dest->preds, ei.index);
+         found = true;
+         break;
+       }
+      else
+       ei_next (&ei);
+    }
+
+  gcc_assert (found);
 
   /* Reconnect the edge to the new successor block.  */
-  e->pred_next = new_succ->pred;
-  new_succ->pred = e;
+  VEC_safe_insert (edge, new_succ->preds, 0, e);
   e->dest = new_succ;
 }
 
@@ -420,9 +428,10 @@ edge
 redirect_edge_succ_nodup (edge e, basic_block new_succ)
 {
   edge s;
+  edge_iterator ei;
 
   /* Check whether the edge is already present.  */
-  for (s = e->src->succ; s; s = s->succ_next)
+  FOR_EACH_EDGE (s, ei, e->src->succs)
     if (s->dest == new_succ && s != e)
       break;
 
@@ -447,17 +456,27 @@ redirect_edge_succ_nodup (edge e, basic_block new_succ)
 void
 redirect_edge_pred (edge e, basic_block new_pred)
 {
-  edge *pe;
+  edge tmp;
+  edge_iterator ei;
+  bool found = false;
 
   /* Disconnect the edge from the old predecessor block.  */
-  for (pe = &e->src->succ; *pe != e; pe = &(*pe)->succ_next)
-    continue;
+  for (ei = ei_start (e->src->succs); (tmp = ei_safe_edge (ei)); )
+    {
+      if (tmp == e)
+       {
+         VEC_unordered_remove (edge, e->src->succs, ei.index);
+         found = true;
+         break;
+       }
+      else
+       ei_next (&ei);
+    }
 
-  *pe = (*pe)->succ_next;
+  gcc_assert (found);
 
   /* Reconnect the edge to the new predecessor block.  */
-  e->succ_next = new_pred->succ;
-  new_pred->succ = e;
+  VEC_safe_insert (edge, new_pred->succs, 0, e);
   e->src = new_pred;
 }
 
@@ -482,35 +501,37 @@ check_bb_profile (basic_block bb, FILE * file)
   edge e;
   int sum = 0;
   gcov_type lsum;
+  edge_iterator ei;
 
   if (profile_status == PROFILE_ABSENT)
     return;
 
   if (bb != EXIT_BLOCK_PTR)
     {
-      for (e = bb->succ; e; e = e->succ_next)
+      FOR_EACH_EDGE (e, ei, bb->succs)
        sum += e->probability;
-      if (bb->succ && abs (sum - REG_BR_PROB_BASE) > 100)
+      if (EDGE_COUNT (bb->succs) && abs (sum - REG_BR_PROB_BASE) > 100)
        fprintf (file, "Invalid sum of outgoing probabilities %.1f%%\n",
                 sum * 100.0 / REG_BR_PROB_BASE);
       lsum = 0;
-      for (e = bb->succ; e; e = e->succ_next)
+      FOR_EACH_EDGE (e, ei, bb->succs)
        lsum += e->count;
-      if (bb->succ && (lsum - bb->count > 100 || lsum - bb->count < -100))
+      if (EDGE_COUNT (bb->succs)
+         && (lsum - bb->count > 100 || lsum - bb->count < -100))
        fprintf (file, "Invalid sum of outgoing counts %i, should be %i\n",
                 (int) lsum, (int) bb->count);
     }
   if (bb != ENTRY_BLOCK_PTR)
     {
       sum = 0;
-      for (e = bb->pred; e; e = e->pred_next)
+      FOR_EACH_EDGE (e, ei, bb->preds)
        sum += EDGE_FREQUENCY (e);
       if (abs (sum - bb->frequency) > 100)
        fprintf (file,
                 "Invalid sum of incoming frequencies %i, should be %i\n",
                 sum, bb->frequency);
       lsum = 0;
-      for (e = bb->pred; e; e = e->pred_next)
+      FOR_EACH_EDGE (e, ei, bb->preds)
        lsum += e->count;
       if (lsum - bb->count > 100 || lsum - bb->count < -100)
        fprintf (file, "Invalid sum of incoming counts %i, should be %i\n",
@@ -577,6 +598,7 @@ dump_flow_info (FILE *file)
   FOR_EACH_BB (bb)
     {
       edge e;
+      edge_iterator ei;
 
       fprintf (file, "\nBasic block %d ", bb->index);
       fprintf (file, "prev %d, next %d, ",
@@ -591,21 +613,13 @@ dump_flow_info (FILE *file)
       fprintf (file, ".\n");
 
       fprintf (file, "Predecessors: ");
-      for (e = bb->pred; e; e = e->pred_next)
+      FOR_EACH_EDGE (e, ei, bb->preds)
        dump_edge_info (file, e, 0);
 
       fprintf (file, "\nSuccessors: ");
-      for (e = bb->succ; e; e = e->succ_next)
+      FOR_EACH_EDGE (e, ei, bb->succs)
        dump_edge_info (file, e, 1);
 
-      fprintf (file, "\nRegisters live at start:");
-      dump_regset (bb->global_live_at_start, file);
-
-      fprintf (file, "\nRegisters live at end:");
-      dump_regset (bb->global_live_at_end, file);
-  
-      putc ('\n', file);
-
       if (bb->global_live_at_start)
        {
          fprintf (file, "\nRegisters live at start:");
@@ -788,8 +802,9 @@ alloc_aux_for_edges (int size)
       FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
        {
          edge e;
+         edge_iterator ei;
 
-         for (e = bb->succ; e; e = e->succ_next)
+         FOR_EACH_EDGE (e, ei, bb->succs)
            alloc_aux_for_edge (e, size);
        }
     }
@@ -805,7 +820,8 @@ clear_aux_for_edges (void)
 
   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
     {
-      for (e = bb->succ; e; e = e->succ_next)
+      edge_iterator ei;
+      FOR_EACH_EDGE (e, ei, bb->succs)
        e->aux = NULL;
     }
 }
@@ -843,6 +859,7 @@ static void
 dump_cfg_bb_info (FILE *file, basic_block bb)
 {
   unsigned i;
+  edge_iterator ei;
   bool first = true;
   static const char * const bb_bitnames[] =
     {
@@ -867,11 +884,11 @@ dump_cfg_bb_info (FILE *file, basic_block bb)
   fprintf (file, "\n");
 
   fprintf (file, "Predecessors: ");
-  for (e = bb->pred; e; e = e->pred_next)
+  FOR_EACH_EDGE (e, ei, bb->preds)
     dump_edge_info (file, e, 0);
 
   fprintf (file, "\nSuccessors: ");
-  for (e = bb->succ; e; e = e->succ_next)
+  FOR_EACH_EDGE (e, ei, bb->succs)
     dump_edge_info (file, e, 1);
   fprintf (file, "\n\n");
 }
@@ -891,17 +908,18 @@ brief_dump_cfg (FILE *file)
 
 /* An edge originally destinating BB of FREQUENCY and COUNT has been proved to
    leave the block by TAKEN_EDGE.  Update profile of BB such that edge E can be
-   redirected to destiantion of TAKEN_EDGE. 
+   redirected to destination of TAKEN_EDGE. 
 
    This function may leave the profile inconsistent in the case TAKEN_EDGE
    frequency or count is believed to be lower than FREQUENCY or COUNT
-   respectivly.  */
+   respectively.  */
 void
 update_bb_profile_for_threading (basic_block bb, int edge_frequency,
                                 gcov_type count, edge taken_edge)
 {
   edge c;
   int prob;
+  edge_iterator ei;
 
   bb->count -= count;
   if (bb->count < 0)
@@ -935,12 +953,14 @@ update_bb_profile_for_threading (basic_block bb, int edge_frequency,
        fprintf (dump_file, "Edge frequencies of bb %i has been reset, "
                 "frequency of block should end up being 0, it is %i\n",
                 bb->index, bb->frequency);
-      bb->succ->probability = REG_BR_PROB_BASE;
-      for (c = bb->succ->succ_next; c; c = c->succ_next)
+      EDGE_SUCC (bb, 0)->probability = REG_BR_PROB_BASE;
+      ei = ei_start (bb->succs);
+      ei_next (&ei);
+      for (; (c = ei_safe_edge (ei)); ei_next (&ei))
        c->probability = 0;
     }
   else
-    for (c = bb->succ; c; c = c->succ_next)
+    FOR_EACH_EDGE (c, ei, bb->succs)
       c->probability = ((c->probability * REG_BR_PROB_BASE) / (double) prob);
 
   if (bb != taken_edge->src)