OSDN Git Service

cp/
[pf3gnuchains/gcc-fork.git] / gcc / cfgloop.c
index f565708..0365f56 100644 (file)
@@ -1,5 +1,5 @@
 /* Natural loop discovery code for GNU compiler.
-   Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007
+   Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -338,6 +338,8 @@ alloc_loop (void)
 
   loop->exits = GGC_CNEW (struct loop_exit);
   loop->exits->next = loop->exits->prev = loop->exits;
+  loop->can_be_parallel = false;
+  loop->single_iv = NULL_TREE;
 
   return loop;
 }
@@ -521,7 +523,7 @@ flow_loops_find (struct loops *loops)
    profile is usually too flat and unreliable for this (and it is mostly based
    on the loop structure of the program, so it does not make much sense to
    derive the loop structure from it).  */
-   
+
 static edge
 find_subloop_latch_edge_by_profile (VEC (edge, heap) *latches)
 {
@@ -563,11 +565,13 @@ find_subloop_latch_edge_by_profile (VEC (edge, heap) *latches)
    another edge.  */
 
 static edge
-find_subloop_latch_edge_by_ivs (struct loop *loop, VEC (edge, heap) *latches)
+find_subloop_latch_edge_by_ivs (struct loop *loop ATTRIBUTE_UNUSED, VEC (edge, heap) *latches)
 {
   edge e, latch = VEC_index (edge, latches, 0);
   unsigned i;
-  tree phi, lop;
+  gimple phi;
+  gimple_stmt_iterator psi;
+  tree lop;
   basic_block bb;
 
   /* Find the candidate for the latch edge.  */
@@ -582,15 +586,16 @@ find_subloop_latch_edge_by_ivs (struct loop *loop, VEC (edge, heap) *latches)
 
   /* Check for a phi node that would deny that this is a latch edge of
      a subloop.  */
-  for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
+  for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
     {
+      phi = gsi_stmt (psi);
       lop = PHI_ARG_DEF_FROM_EDGE (phi, latch);
 
       /* Ignore the values that are not changed inside the subloop.  */
       if (TREE_CODE (lop) != SSA_NAME
          || SSA_NAME_DEF_STMT (lop) == phi)
        continue;
-      bb = bb_for_stmt (SSA_NAME_DEF_STMT (lop));
+      bb = gimple_bb (SSA_NAME_DEF_STMT (lop));
       if (!bb || !flow_bb_inside_loop_p (loop, bb))
        continue;
 
@@ -651,7 +656,7 @@ form_subloop (struct loop *loop, edge latch)
   edge_iterator ei;
   edge e, new_entry;
   struct loop *new_loop;
-      
+
   mfb_reis_set = pointer_set_create ();
   FOR_EACH_EDGE (e, ei, loop->header->preds)
     {
@@ -884,6 +889,19 @@ get_loop_body_in_dom_order (const struct loop *loop)
   return tovisit;
 }
 
+/* Gets body of a LOOP sorted via provided BB_COMPARATOR.  */
+
+basic_block *
+get_loop_body_in_custom_order (const struct loop *loop,
+                              int (*bb_comparator) (const void *, const void *))
+{
+  basic_block *bbs = get_loop_body (loop);
+
+  qsort (bbs, loop->num_nodes, sizeof (basic_block), bb_comparator);
+
+  return bbs;
+}
+
 /* Get body of a LOOP in breadth first sort order.  */
 
 basic_block *
@@ -965,7 +983,7 @@ loop_exit_free (void *ex)
   for (; exit; exit = next)
     {
       next = exit->next_e;
-         
+
       exit->next->prev = exit->prev;
       exit->prev->next = exit->next;
 
@@ -1019,7 +1037,7 @@ rescan_loop_exit (edge e, bool new_edge, bool removed)
          exit->next_e = exits;
          exits = exit;
        }
-    } 
+    }
 
   if (!exits && new_edge)
     return;
@@ -1505,7 +1523,7 @@ verify_loop_structure (void)
              exit = get_exit_descriptions (e);
              if (!exit)
                {
-                 error ("Exit %d->%d not recorded", 
+                 error ("Exit %d->%d not recorded",
                         e->src->index, e->dest->index);
                  err = 1;
                }
@@ -1523,7 +1541,7 @@ verify_loop_structure (void)
 
              if (eloops != 0)
                {
-                 error ("Wrong list of exited loops for edge  %d->%d", 
+                 error ("Wrong list of exited loops for edge  %d->%d",
                         e->src->index, e->dest->index);
                  err = 1;
                }
@@ -1604,3 +1622,18 @@ single_exit (const struct loop *loop)
   else
     return NULL;
 }
+
+/* Returns true when BB has an edge exiting LOOP.  */
+
+bool
+is_loop_exit (struct loop *loop, basic_block bb)
+{
+  edge e;
+  edge_iterator ei;
+
+  FOR_EACH_EDGE (e, ei, bb->preds)
+    if (loop_exit_edge_p (loop, e))
+      return true;
+
+  return false;
+}