OSDN Git Service

* misc.c (gnat_types_compatible_p, LANG_HOOKS_TYPES_COMPATIBLE_P):
[pf3gnuchains/gcc-fork.git] / gcc / cfg.c
index 0669bed..c469661 100644 (file)
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -52,7 +52,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tree.h"
 #include "rtl.h"
 #include "hard-reg-set.h"
-#include "basic-block.h"
 #include "regs.h"
 #include "flags.h"
 #include "output.h"
@@ -60,15 +59,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "except.h"
 #include "toplev.h"
 #include "tm_p.h"
-#include "obstack.h"
 #include "alloc-pool.h"
 #include "timevar.h"
 #include "ggc.h"
 
 /* The obstack on which the flow graph components are allocated.  */
 
-struct obstack flow_obstack;
-static char *flow_firstobj;
+struct bitmap_obstack reg_obstack;
 
 /* Number of basic blocks in the current function.  */
 
@@ -103,22 +100,8 @@ enum profile_status profile_status;
 void
 init_flow (void)
 {
-  static int initialized;
-
   n_edges = 0;
 
-  if (!initialized)
-    {
-      gcc_obstack_init (&flow_obstack);
-      flow_firstobj = obstack_alloc (&flow_obstack, 0);
-      initialized = 1;
-    }
-  else
-    {
-      obstack_free (&flow_obstack, flow_firstobj);
-      flow_firstobj = obstack_alloc (&flow_obstack, 0);
-    }
-
   ENTRY_BLOCK_PTR = ggc_alloc_cleared (sizeof (*ENTRY_BLOCK_PTR));
   ENTRY_BLOCK_PTR->index = ENTRY_BLOCK;
   EXIT_BLOCK_PTR = ggc_alloc_cleared (sizeof (*EXIT_BLOCK_PTR));
@@ -270,12 +253,15 @@ unchecked_make_edge (basic_block src, basic_block dst, int flags)
   e = ggc_alloc_cleared (sizeof (*e));
   n_edges++;
 
-  VEC_safe_insert (edge, src->succs, 0, e);
-  VEC_safe_insert (edge, dst->preds, 0, e);
+  VEC_safe_push (edge, src->succs, e);
+  VEC_safe_push (edge, dst->preds, e);
 
   e->src = src;
   e->dest = dst;
   e->flags = flags;
+  e->dest_idx = EDGE_COUNT (dst->preds) - 1;
+
+  execute_on_growing_pred (e);
 
   return e;
 }
@@ -288,7 +274,6 @@ 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.  */
@@ -309,12 +294,12 @@ cached_make_edge (sbitmap *edge_cache, basic_block src, basic_block dst, int fla
 
       /* Fall through.  */
     case 0:
-      FOR_EACH_EDGE (e, ei, src->succs)
-       if (e->dest == dst)
-         {
-           e->flags |= flags;
-           return NULL;
-         }
+      e = find_edge (src, dst);
+      if (e)
+       {
+         e->flags |= flags;
+         return NULL;
+       }
       break;
     }
 
@@ -355,17 +340,21 @@ remove_edge (edge e)
 {
   edge tmp;
   basic_block src, dest;
+  unsigned int dest_idx;
   bool found = false;
   edge_iterator ei;
 
+  execute_on_shrinking_pred (e);
+
   src = e->src;
   dest = e->dest;
+  dest_idx = e->dest_idx;
 
   for (ei = ei_start (src->succs); (tmp = ei_safe_edge (ei)); )
     {
       if (tmp == e)
        {
-         VEC_ordered_remove (edge, src->succs, ei.index);
+         VEC_unordered_remove (edge, src->succs, ei.index);
          found = true;
          break;
        }
@@ -375,20 +364,12 @@ remove_edge (edge e)
 
   gcc_assert (found);
 
-  found = false;
-  for (ei = ei_start (dest->preds); (tmp = ei_safe_edge (ei)); )
-    {
-      if (tmp == e)
-       {
-         VEC_ordered_remove (edge, dest->preds, ei.index);
-         found = true;
-         break;
-       }
-      else
-       ei_next (&ei);
-    }
+  VEC_unordered_remove (edge, dest->preds, dest_idx);
 
-  gcc_assert (found);
+  /* If we removed an edge in the middle of the edge vector, we need
+     to update dest_idx of the edge that moved into the "hole".  */
+  if (dest_idx < EDGE_COUNT (dest->preds))
+    EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx;
 
   free_edge (e);
 }
@@ -398,28 +379,23 @@ remove_edge (edge e)
 void
 redirect_edge_succ (edge e, basic_block new_succ)
 {
-  edge tmp;
-  edge_iterator ei;
-  bool found = false;
+  basic_block dest = e->dest;
+  unsigned int dest_idx = e->dest_idx;
 
-  /* Disconnect the edge from the old successor block.  */
-  for (ei = ei_start (e->dest->preds); (tmp = ei_safe_edge (ei)); )
-    {
-      if (tmp == e)
-       {
-         VEC_ordered_remove (edge, e->dest->preds, ei.index);
-         found = true;
-         break;
-       }
-      else
-       ei_next (&ei);
-    }
+  execute_on_shrinking_pred (e);
 
-  gcc_assert (found);
+  VEC_unordered_remove (edge, dest->preds, dest_idx);
+
+  /* If we removed an edge in the middle of the edge vector, we need
+     to update dest_idx of the edge that moved into the "hole".  */
+  if (dest_idx < EDGE_COUNT (dest->preds))
+    EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx;
 
   /* Reconnect the edge to the new successor block.  */
-  VEC_safe_insert (edge, new_succ->preds, 0, e);
+  VEC_safe_push (edge, new_succ->preds, e);
   e->dest = new_succ;
+  e->dest_idx = EDGE_COUNT (new_succ->preds) - 1;
+  execute_on_growing_pred (e);
 }
 
 /* Like previous but avoid possible duplicate edge.  */
@@ -428,14 +404,9 @@ edge
 redirect_edge_succ_nodup (edge e, basic_block new_succ)
 {
   edge s;
-  edge_iterator ei;
 
-  /* Check whether the edge is already present.  */
-  FOR_EACH_EDGE (s, ei, e->src->succs)
-    if (s->dest == new_succ && s != e)
-      break;
-
-  if (s)
+  s = find_edge (e->src, new_succ);
+  if (s && s != e)
     {
       s->flags |= e->flags;
       s->probability += e->probability;
@@ -465,7 +436,7 @@ redirect_edge_pred (edge e, basic_block new_pred)
     {
       if (tmp == e)
        {
-         VEC_ordered_remove (edge, e->src->succs, ei.index);
+         VEC_unordered_remove (edge, e->src->succs, ei.index);
          found = true;
          break;
        }
@@ -476,7 +447,7 @@ redirect_edge_pred (edge e, basic_block new_pred)
   gcc_assert (found);
 
   /* Reconnect the edge to the new predecessor block.  */
-  VEC_safe_insert (edge, new_pred->succs, 0, e);
+  VEC_safe_push (edge, new_pred->succs, e);
   e->src = new_pred;
 }
 
@@ -620,14 +591,6 @@ dump_flow_info (FILE *file)
       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:");
@@ -967,9 +930,13 @@ update_bb_profile_for_threading (basic_block bb, int edge_frequency,
       for (; (c = ei_safe_edge (ei)); ei_next (&ei))
        c->probability = 0;
     }
-  else
-    FOR_EACH_EDGE (c, ei, bb->succs)
-      c->probability = ((c->probability * REG_BR_PROB_BASE) / (double) prob);
+  else if (prob != REG_BR_PROB_BASE)
+    {
+      int scale = REG_BR_PROB_BASE / prob;
+
+      FOR_EACH_EDGE (c, ei, bb->succs)
+       c->probability *= scale;
+    }
 
   if (bb != taken_edge->src)
     abort ();