OSDN Git Service

* ifcvt.c (find_if_case_1): Reinstate 2005-01-04 change, now that
[pf3gnuchains/gcc-fork.git] / gcc / dominance.c
index 2782547..7970e24 100644 (file)
@@ -39,6 +39,7 @@
 #include "tm.h"
 #include "rtl.h"
 #include "hard-reg-set.h"
+#include "obstack.h"
 #include "basic-block.h"
 #include "errors.h"
 #include "et-forest.h"
@@ -206,7 +207,8 @@ calc_dfs_tree_nonrec (struct dom_info *di, basic_block bb,
   /* We call this _only_ if bb is not already visited.  */
   edge e;
   TBB child_i, my_i = 0;
-  edge *stack;
+  edge_iterator *stack;
+  edge_iterator ei, einext;
   int sp;
   /* Start block (ENTRY_BLOCK_PTR for forward problem, EXIT_BLOCK for backward
      problem).  */
@@ -214,19 +216,19 @@ calc_dfs_tree_nonrec (struct dom_info *di, basic_block bb,
   /* Ending block.  */
   basic_block ex_block;
 
-  stack = xmalloc ((n_basic_blocks + 3) * sizeof (edge));
+  stack = xmalloc ((n_basic_blocks + 3) * sizeof (edge_iterator));
   sp = 0;
 
   /* Initialize our border blocks, and the first edge.  */
   if (reverse)
     {
-      e = bb->pred;
+      ei = ei_start (bb->preds);
       en_block = EXIT_BLOCK_PTR;
       ex_block = ENTRY_BLOCK_PTR;
     }
   else
     {
-      e = bb->succ;
+      ei = ei_start (bb->succs);
       en_block = ENTRY_BLOCK_PTR;
       ex_block = EXIT_BLOCK_PTR;
     }
@@ -238,9 +240,9 @@ calc_dfs_tree_nonrec (struct dom_info *di, basic_block bb,
 
       /* This loop traverses edges e in depth first manner, and fills the
          stack.  */
-      while (e)
+      while (!ei_end_p (ei))
        {
-         edge e_next;
+         e = ei_edge (ei);
 
          /* Deduce from E the current and the next block (BB and BN), and the
             next edge.  */
@@ -253,22 +255,22 @@ calc_dfs_tree_nonrec (struct dom_info *di, basic_block bb,
                 with the next edge out of the current node.  */
              if (bn == ex_block || di->dfs_order[bn->index])
                {
-                 e = e->pred_next;
+                 ei_next (&ei);
                  continue;
                }
              bb = e->dest;
-             e_next = bn->pred;
+             einext = ei_start (bn->preds);
            }
          else
            {
              bn = e->dest;
              if (bn == ex_block || di->dfs_order[bn->index])
                {
-                 e = e->succ_next;
+                 ei_next (&ei);
                  continue;
                }
              bb = e->src;
-             e_next = bn->succ;
+             einext = ei_start (bn->succs);
            }
 
          gcc_assert (bn != en_block);
@@ -283,13 +285,13 @@ calc_dfs_tree_nonrec (struct dom_info *di, basic_block bb,
          di->dfs_parent[child_i] = my_i;
 
          /* Save the current point in the CFG on the stack, and recurse.  */
-         stack[sp++] = e;
-         e = e_next;
+         stack[sp++] = ei;
+         ei = einext;
        }
 
       if (!sp)
        break;
-      e = stack[--sp];
+      ei = stack[--sp];
 
       /* OK.  The edge-list was exhausted, meaning normally we would
          end the recursion.  After returning from the recursive call,
@@ -300,10 +302,7 @@ calc_dfs_tree_nonrec (struct dom_info *di, basic_block bb,
          the block not yet completed (the parent of the one above)
          in e->src.  This could be used e.g. for computing the number of
          descendants or the tree depth.  */
-      if (reverse)
-       e = e->pred_next;
-      else
-       e = e->succ_next;
+      ei_next (&ei);
     }
   free (stack);
 }
@@ -341,7 +340,7 @@ calc_dfs_tree (struct dom_info *di, enum cdi_direction reverse)
 
       FOR_EACH_BB_REVERSE (b)
        {
-         if (b->succ)
+         if (EDGE_COUNT (b->succs) > 0)
            {
              if (di->dfs_order[b->index] == 0)
                saw_unconnected = true;
@@ -478,6 +477,8 @@ calc_idoms (struct dom_info *di, enum cdi_direction reverse)
 {
   TBB v, w, k, par;
   basic_block en_block;
+  edge_iterator ei, einext;
+
   if (reverse)
     en_block = EXIT_BLOCK_PTR;
   else
@@ -488,43 +489,38 @@ calc_idoms (struct dom_info *di, enum cdi_direction reverse)
   while (v > 1)
     {
       basic_block bb = di->dfs_to_bb[v];
-      edge e, e_next;
+      edge e;
 
       par = di->dfs_parent[v];
       k = v;
+
+      ei = (reverse) ? ei_start (bb->succs) : ei_start (bb->preds);
+
       if (reverse)
        {
-         e = bb->succ;
-
          /* If this block has a fake edge to exit, process that first.  */
          if (bitmap_bit_p (di->fake_exit_edge, bb->index))
            {
-             e_next = e;
+             einext = ei;
+             einext.index = 0;
              goto do_fake_exit_edge;
            }
        }
-      else
-       e = bb->pred;
 
       /* Search all direct predecessors for the smallest node with a path
          to them.  That way we have the smallest node with also a path to
          us only over nodes behind us.  In effect we search for our
          semidominator.  */
-      for (; e ; e = e_next)
+      while (!ei_end_p (ei))
        {
          TBB k1;
          basic_block b;
 
-         if (reverse)
-           {
-             b = e->dest;
-             e_next = e->succ_next;
-           }
-         else
-           {
-             b = e->src;
-             e_next = e->pred_next;
-           }
+         e = ei_edge (ei);
+         b = (reverse) ? e->dest : e->src;
+         einext = ei;
+         ei_next (&einext);
+
          if (b == en_block)
            {
            do_fake_exit_edge:
@@ -539,6 +535,8 @@ calc_idoms (struct dom_info *di, enum cdi_direction reverse)
            k1 = di->key[eval (di, k1)];
          if (k1 < k)
            k = k1;
+
+         ei = einext;
        }
 
       di->key[v] = k;
@@ -595,7 +593,7 @@ compute_dom_fast_query (enum cdi_direction dir)
   int num = 0;
   basic_block bb;
 
-  gcc_assert (dom_computed[dir] >= DOM_NO_FAST_QUERY);
+  gcc_assert (dom_info_available_p (dir));
 
   if (dom_computed[dir] == DOM_OK)
     return;
@@ -621,11 +619,8 @@ calculate_dominance_info (enum cdi_direction dir)
   if (dom_computed[dir] == DOM_OK)
     return;
 
-  if (dom_computed[dir] != DOM_NO_FAST_QUERY)
+  if (!dom_info_available_p (dir))
     {
-      if (dom_computed[dir] != DOM_NONE)
-       free_dominance_info (dir);
-
       gcc_assert (!n_bbs_in_dom_tree[dir]);
 
       FOR_ALL_BB (b)
@@ -659,7 +654,7 @@ free_dominance_info (enum cdi_direction dir)
 {
   basic_block bb;
 
-  if (!dom_computed[dir])
+  if (!dom_info_available_p (dir))
     return;
 
   FOR_ALL_BB (bb)
@@ -824,23 +819,27 @@ verify_dominators (enum cdi_direction dir)
   int err = 0;
   basic_block bb;
 
-  gcc_assert (dom_computed[dir]);
+  gcc_assert (dom_info_available_p (dir));
 
   FOR_EACH_BB (bb)
     {
       basic_block dom_bb;
+      basic_block imm_bb;
 
       dom_bb = recount_dominator (dir, bb);
-      if (dom_bb != get_immediate_dominator (dir, bb))
+      imm_bb = get_immediate_dominator (dir, bb);
+      if (dom_bb != imm_bb)
        {
-         error ("dominator of %d should be %d, not %d",
-          bb->index, dom_bb->index, get_immediate_dominator(dir, bb)->index);
+         if ((dom_bb == NULL) || (imm_bb == NULL))
+           error ("dominator of %d status unknown", bb->index);
+         else
+           error ("dominator of %d should be %d, not %d",
+                  bb->index, dom_bb->index, imm_bb->index);
          err = 1;
        }
     }
 
-  if (dir == CDI_DOMINATORS
-      && dom_computed[dir] >= DOM_NO_FAST_QUERY)
+  if (dir == CDI_DOMINATORS)
     {
       FOR_EACH_BB (bb)
        {
@@ -865,12 +864,13 @@ recount_dominator (enum cdi_direction dir, basic_block bb)
 {
   basic_block dom_bb = NULL;
   edge e;
+  edge_iterator ei;
 
   gcc_assert (dom_computed[dir]);
 
   if (dir == CDI_DOMINATORS)
     {
-      for (e = bb->pred; e; e = e->pred_next)
+      FOR_EACH_EDGE (e, ei, bb->preds)
        {
          /* Ignore the predecessors that either are not reachable from
             the entry block, or whose dominator was not determined yet.  */
@@ -883,7 +883,7 @@ recount_dominator (enum cdi_direction dir, basic_block bb)
     }
   else
     {
-      for (e = bb->succ; e; e = e->succ_next)
+      FOR_EACH_EDGE (e, ei, bb->succs)
        {
          if (!dominated_by_p (dir, e->dest, bb))
            dom_bb = nearest_common_dominator (dir, dom_bb, e->dest);
@@ -974,6 +974,14 @@ next_dom_son (enum cdi_direction dir, basic_block bb)
   return next->father->son == next ? NULL : next->data;
 }
 
+/* Returns true if dominance information for direction DIR is available.  */
+
+bool
+dom_info_available_p (enum cdi_direction dir)
+{
+  return dom_computed[dir] != DOM_NONE;
+}
+
 void
 debug_dominance_info (enum cdi_direction dir)
 {