OSDN Git Service

Removed as part of irix config changes.
[pf3gnuchains/gcc-fork.git] / gcc / cfgloop.c
index 6fa8b17..58d9dd0 100644 (file)
@@ -28,6 +28,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "toplev.h"
 #include "cfgloop.h"
 #include "flags.h"
+#include "tree.h"
+#include "tree-flow.h"
 
 /* Ratio of frequencies of edges so that one of more latch edges is
    considered to belong to inner loop with same header.  */
@@ -95,8 +97,23 @@ flow_loops_cfg_dump (const struct loops *loops, FILE *file)
 bool
 flow_loop_nested_p (const struct loop *outer, const struct loop *loop)
 {
-  return loop->depth > outer->depth
-        && loop->pred[outer->depth] == outer;
+  return (loop->depth > outer->depth
+        && loop->pred[outer->depth] == outer);
+}
+
+/* Returns the loop such that LOOP is nested DEPTH (indexed from zero)
+   loops within LOOP.  */
+
+struct loop *
+superloop_at_depth (struct loop *loop, unsigned depth)
+{
+  if (depth > (unsigned) loop->depth)
+    abort ();
+
+  if (depth == (unsigned) loop->depth)
+    return loop;
+
+  return loop->pred[depth];
 }
 
 /* Dump the loop information specified by LOOP to the stream FILE
@@ -558,6 +575,7 @@ update_latch_info (basic_block jump)
   HEADER_BLOCK (jump) = 0;
   alloc_aux_for_edge (jump->pred, sizeof (int));
   LATCH_EDGE (jump->pred) = 0;
+  set_immediate_dominator (CDI_DOMINATORS, jump, jump->pred->src);
 }
 
 /* A callback for make_forwarder block, to redirect all edges except for
@@ -589,9 +607,6 @@ canonicalize_loop_headers (void)
   basic_block header;
   edge e;
 
-  /* Compute the dominators.  */
-  calculate_dominance_info (CDI_DOMINATORS);
-
   alloc_aux_for_blocks (sizeof (int));
   alloc_aux_for_edges (sizeof (int));
 
@@ -621,8 +636,6 @@ canonicalize_loop_headers (void)
        HEADER_BLOCK (header) = num_latches;
     }
 
-  free_dominance_info (CDI_DOMINATORS);
-
   if (HEADER_BLOCK (ENTRY_BLOCK_PTR->succ->dest))
     {
       basic_block bb;
@@ -694,6 +707,10 @@ canonicalize_loop_headers (void)
 
   free_aux_for_blocks ();
   free_aux_for_edges ();
+
+#ifdef ENABLE_CHECKING
+  verify_dominators (CDI_DOMINATORS);
+#endif
 }
 
 /* Find all the natural loops in the function and save in LOOPS structure and
@@ -730,12 +747,12 @@ flow_loops_find (struct loops *loops, int flags)
   dfs_order = NULL;
   rc_order = NULL;
 
+  /* Ensure that the dominators are computed.  */
+  calculate_dominance_info (CDI_DOMINATORS);
+
   /* Join loops with shared headers.  */
   canonicalize_loop_headers ();
 
-  /* Compute the dominators.  */
-  calculate_dominance_info (CDI_DOMINATORS);
-
   /* Count the number of loop headers.  This should be the
      same as the number of natural loops.  */
   headers = sbitmap_alloc (last_basic_block);
@@ -863,10 +880,6 @@ flow_loops_find (struct loops *loops, int flags)
 
       loops->num = num_loops;
     }
-  else
-    {
-      free_dominance_info (CDI_DOMINATORS);
-    }
 
   sbitmap_free (headers);
 
@@ -959,6 +972,62 @@ get_loop_body (const struct loop *loop)
   return tovisit;
 }
 
+/* Fills dominance descendants inside LOOP of the basic block BB into
+   array TOVISIT from index *TV.  */
+
+static void
+fill_sons_in_loop (const struct loop *loop, basic_block bb,
+                  basic_block *tovisit, int *tv)
+{
+  basic_block son, postpone = NULL;
+
+  tovisit[(*tv)++] = bb;
+  for (son = first_dom_son (CDI_DOMINATORS, bb);
+       son;
+       son = next_dom_son (CDI_DOMINATORS, son))
+    {
+      if (!flow_bb_inside_loop_p (loop, son))
+       continue;
+
+      if (dominated_by_p (CDI_DOMINATORS, loop->latch, son))
+       {
+         postpone = son;
+         continue;
+       }
+      fill_sons_in_loop (loop, son, tovisit, tv);
+    }
+
+  if (postpone)
+    fill_sons_in_loop (loop, postpone, tovisit, tv);
+}
+
+/* Gets body of a LOOP (that must be different from the outermost loop)
+   sorted by dominance relation.  Additionally, if a basic block s dominates
+   the latch, then only blocks dominated by s are be after it.  */
+
+basic_block *
+get_loop_body_in_dom_order (const struct loop *loop)
+{
+  basic_block *tovisit;
+  int tv;
+
+  if (!loop->num_nodes)
+    abort ();
+
+  tovisit = xcalloc (loop->num_nodes, sizeof (basic_block));
+
+  if (loop->latch == EXIT_BLOCK_PTR)
+    abort ();
+
+  tv = 0;
+  fill_sons_in_loop (loop, loop->header, tovisit, &tv);
+
+  if (tv != (int) loop->num_nodes)
+    abort ();
+
+  return tovisit;
+}
+
 /* Gets exit edges of a LOOP, returning their number in N_EDGES.  */
 edge *
 get_loop_exit_edges (const struct loop *loop, unsigned int *n_edges)
@@ -988,6 +1057,27 @@ get_loop_exit_edges (const struct loop *loop, unsigned int *n_edges)
   return edges;
 }
 
+/* Counts the number of conditional branches inside LOOP.  */
+
+unsigned
+num_loop_branches (const struct loop *loop)
+{
+  unsigned i, n;
+  basic_block * body;
+
+  if (loop->latch == EXIT_BLOCK_PTR)
+    abort ();
+
+  body = get_loop_body (loop);
+  n = 0;
+  for (i = 0; i < loop->num_nodes; i++)
+    if (body[i]->succ && body[i]->succ->succ_next)
+      n++;
+  free (body);
+
+  return n;
+}
+
 /* Adds basic block BB to LOOP.  */
 void
 add_bb_to_loop (basic_block bb, struct loop *loop)