OSDN Git Service

[gcc/ChangeLog]
[pf3gnuchains/gcc-fork.git] / gcc / dominance.c
index 1b6c9fd..2b6e806 100644 (file)
@@ -1,5 +1,5 @@
 /* Calculate (post)dominators in slightly super-linear time.
-   Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc.
    Contributed by Michael Matz (matz@ifh.de).
 
    This file is part of GCC.
@@ -537,7 +537,7 @@ assign_dfs_numbers (struct et_node *node, int *num)
   node->dfs_num_out = (*num)++;
 }
 
-/* Compute the data neccesary for fast resolving of dominator queries in a
+/* Compute the data necessary for fast resolving of dominator queries in a
    static dominator tree.  */
 
 static void
@@ -659,7 +659,7 @@ set_immediate_dominator (enum cdi_direction dir, basic_block bb,
     dom_computed[dir] = DOM_NO_FAST_QUERY;
 }
 
-/* Store all basic blocks immediatelly dominated by BB into BBS and return
+/* Store all basic blocks immediately dominated by BB into BBS and return
    their number.  */
 int
 get_dominated_by (enum cdi_direction dir, basic_block bb, basic_block **bbs)
@@ -769,23 +769,38 @@ verify_dominators (enum cdi_direction dir)
     abort ();
 }
 
-/* Recount dominator of BB.  */
+/* Determine immediate dominator (or postdominator, according to DIR) of BB,
+   assuming that dominators of other blocks are correct.  We also use it to
+   recompute the dominators in a restricted area, by iterating it until it
+   reaches a fixpoint.  */
+
 basic_block
 recount_dominator (enum cdi_direction dir, basic_block bb)
 {
-   basic_block dom_bb = NULL;
-   edge e;
+  basic_block dom_bb = NULL;
+  edge e;
 
   if (!dom_computed[dir])
     abort ();
 
-   for (e = bb->pred; e; e = e->pred_next)
-     {
-       if (!dominated_by_p (dir, e->src, bb))
-         dom_bb = nearest_common_dominator (dir, dom_bb, e->src);
-     }
+  if (dir == CDI_DOMINATORS)
+    {
+      for (e = bb->pred; e; e = e->pred_next)
+       {
+         if (!dominated_by_p (dir, e->src, bb))
+           dom_bb = nearest_common_dominator (dir, dom_bb, e->src);
+       }
+    }
+  else
+    {
+      for (e = bb->succ; e; e = e->succ_next)
+       {
+         if (!dominated_by_p (dir, e->dest, bb))
+           dom_bb = nearest_common_dominator (dir, dom_bb, e->dest);
+       }
+    }
 
-   return dom_bb;
+  return dom_bb;
 }
 
 /* Iteratively recount dominators of BBS. The change is supposed to be local