OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / cfgloopmanip.c
index 459a1fd..1824421 100644 (file)
@@ -1,6 +1,6 @@
 /* Loop manipulation code for GNU compiler.
-   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software
-   Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -130,7 +130,7 @@ fix_loop_placement (struct loop *loop)
   struct loop *father = current_loops->tree_root, *act;
   bool ret = false;
 
-  for (i = 0; VEC_iterate (edge, exits, i, e); i++)
+  FOR_EACH_VEC_ELT (edge, exits, i, e)
     {
       act = find_common_loop (loop, e->dest->loop_father);
       if (flow_loop_nested_p (father, act))
@@ -146,7 +146,7 @@ fix_loop_placement (struct loop *loop)
 
       /* The exit edges of LOOP no longer exits its original immediate
         superloops; remove them from the appropriate exit lists.  */
-      for (i = 0; VEC_iterate (edge, exits, i, e); i++)
+      FOR_EACH_VEC_ELT (edge, exits, i, e)
        rescan_loop_exit (e, false, false);
 
       ret = true;
@@ -174,7 +174,7 @@ fix_bb_placements (basic_block from,
 {
   sbitmap in_queue;
   basic_block *queue, *qtop, *qbeg, *qend;
-  struct loop *base_loop;
+  struct loop *base_loop, *target_loop;
   edge e;
 
   /* We pass through blocks back-reachable from FROM, testing whether some
@@ -185,7 +185,11 @@ fix_bb_placements (basic_block from,
      fix_loop_placement.  */
 
   base_loop = from->loop_father;
-  if (base_loop == current_loops->tree_root)
+  /* If we are already in the outermost loop, the basic blocks cannot be moved
+     outside of it.  If FROM is the header of the base loop, it cannot be moved
+     outside of it, either.  In both cases, we can end now.  */
+  if (base_loop == current_loops->tree_root
+      || from == base_loop->header)
     return;
 
   in_queue = sbitmap_alloc (last_basic_block);
@@ -214,12 +218,14 @@ fix_bb_placements (basic_block from,
          /* Subloop header, maybe move the loop upward.  */
          if (!fix_loop_placement (from->loop_father))
            continue;
+         target_loop = loop_outer (from->loop_father);
        }
       else
        {
          /* Ordinary basic block.  */
          if (!fix_bb_placement (from))
            continue;
+         target_loop = from->loop_father;
        }
 
       FOR_EACH_EDGE (e, ei, from->succs)
@@ -248,9 +254,12 @@ fix_bb_placements (basic_block from,
              && (nca == base_loop
                  || nca != pred->loop_father))
            pred = pred->loop_father->header;
-         else if (!flow_loop_nested_p (from->loop_father, pred->loop_father))
+         else if (!flow_loop_nested_p (target_loop, pred->loop_father))
            {
-             /* No point in processing it.  */
+             /* If PRED is already higher in the loop hierarchy than the
+                TARGET_LOOP to that we moved FROM, the change of the position
+                of FROM does not affect the position of PRED, so there is no
+                point in processing it.  */
              continue;
            }
 
@@ -278,10 +287,9 @@ remove_path (edge e)
   edge ae;
   basic_block *rem_bbs, *bord_bbs, from, bb;
   VEC (basic_block, heap) *dom_bbs;
-  int i, nrem, n_bord_bbs, nreml;
+  int i, nrem, n_bord_bbs;
   sbitmap seen;
   bool irred_invalidated = false;
-  struct loop **deleted_loop;
 
   if (!can_remove_branch_p (e))
     return false;
@@ -342,15 +350,9 @@ remove_path (edge e)
   dom_bbs = NULL;
 
   /* Cancel loops contained in the path.  */
-  deleted_loop = XNEWVEC (struct loop *, nrem);
-  nreml = 0;
   for (i = 0; i < nrem; i++)
     if (rem_bbs[i]->loop_father->header == rem_bbs[i])
-      deleted_loop[nreml++] = rem_bbs[i]->loop_father;
-
-  for (i = 0; i < nreml; i++)
-    cancel_loop_tree (deleted_loop[i]);
-  free (deleted_loop);
+      cancel_loop_tree (rem_bbs[i]->loop_father);
 
   remove_bbs (rem_bbs, nrem);
   free (rem_bbs);
@@ -1278,7 +1280,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e,
       bb->aux = 0;
 
       dom_bbs = get_dominated_by (CDI_DOMINATORS, bb);
-      for (j = 0; VEC_iterate (basic_block, dom_bbs, j, dominated); j++)
+      FOR_EACH_VEC_ELT (basic_block, dom_bbs, j, dominated)
        {
          if (flow_bb_inside_loop_p (loop, dominated))
            continue;
@@ -1545,7 +1547,10 @@ loop_version (struct loop *loop,
   /* Duplicate loop.  */
   if (!cfg_hook_duplicate_loop_to_header_edge (loop, entry, 1,
                                               NULL, NULL, NULL, 0))
-    return NULL;
+    {
+      entry->flags |= irred_flag;
+      return NULL;
+    }
 
   /* After duplication entry edge now points to new loop head block.
      Note down new head as second_head.  */