OSDN Git Service

2008-08-31 Andrey Belevantsev <abel@ispras.ru>
[pf3gnuchains/gcc-fork.git] / gcc / cfgloop.c
index 66461d9..0e95323 100644 (file)
@@ -1,11 +1,12 @@
 /* Natural loop discovery code for GNU compiler.
-   Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -14,9 +15,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -284,9 +284,6 @@ establish_preds (struct loop *loop, struct loop *father)
   unsigned depth = loop_depth (father) + 1;
   unsigned i;
 
-  /* Remember the current loop depth if it is the largest seen so far.  */
-  cfun->max_loop_depth = MAX (cfun->max_loop_depth, (int) depth);
-
   VEC_truncate (loop_p, loop->superloops, 0);
   VEC_reserve (loop_p, gc, loop->superloops, depth);
   for (i = 0; VEC_iterate (loop_p, father->superloops, i, ploop); i++)
@@ -345,6 +342,29 @@ alloc_loop (void)
   return loop;
 }
 
+/* Initializes loops structure LOOPS, reserving place for NUM_LOOPS loops
+   (including the root of the loop tree).  */
+
+static void
+init_loops_structure (struct loops *loops, unsigned num_loops)
+{
+  struct loop *root;
+
+  memset (loops, 0, sizeof *loops);
+  loops->larray = VEC_alloc (loop_p, gc, num_loops);
+
+  /* Dummy loop containing whole function.  */
+  root = alloc_loop ();
+  root->num_nodes = n_basic_blocks;
+  root->latch = EXIT_BLOCK_PTR;
+  root->header = ENTRY_BLOCK_PTR;
+  ENTRY_BLOCK_PTR->loop_father = root;
+  EXIT_BLOCK_PTR->loop_father = root;
+
+  VEC_quick_push (loop_p, loops->larray, root);
+  loops->tree_root = root;
+}
+
 /* Find all the natural loops in the function and save in LOOPS structure and
    recalculate loop_depth information in basic block structures.
    Return the number of natural loops found.  */
@@ -360,25 +380,21 @@ flow_loops_find (struct loops *loops)
   int *rc_order;
   basic_block header;
   basic_block bb;
-  struct loop *root;
-
-  memset (loops, 0, sizeof *loops);
 
-  /* We are going to recount the maximum loop depth,
-     so throw away the last count.  */
-  cfun->max_loop_depth = 0;
+  /* Ensure that the dominators are computed.  */
+  calculate_dominance_info (CDI_DOMINATORS);
 
   /* Taking care of this degenerate case makes the rest of
      this code simpler.  */
   if (n_basic_blocks == NUM_FIXED_BLOCKS)
-    return 0;
+    {
+      init_loops_structure (loops, 1);
+      return 1;
+    }
 
   dfs_order = NULL;
   rc_order = NULL;
 
-  /* Ensure that the dominators are computed.  */
-  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);
@@ -421,18 +437,7 @@ flow_loops_find (struct loops *loops)
     }
 
   /* Allocate loop structures.  */
-  loops->larray = VEC_alloc (loop_p, gc, num_loops + 1);
-
-  /* Dummy loop containing whole function.  */
-  root = alloc_loop ();
-  root->num_nodes = n_basic_blocks;
-  root->latch = EXIT_BLOCK_PTR;
-  root->header = ENTRY_BLOCK_PTR;
-  ENTRY_BLOCK_PTR->loop_father = root;
-  EXIT_BLOCK_PTR->loop_father = root;
-
-  VEC_quick_push (loop_p, loops->larray, root);
-  loops->tree_root = root;
+  init_loops_structure (loops, num_loops + 1);
 
   /* Find and record information about all the natural loops
      in the CFG.  */
@@ -497,7 +502,6 @@ flow_loops_find (struct loops *loops)
   sbitmap_free (headers);
 
   loops->exits = NULL;
-  loops->state = 0;
   return VEC_length (loop_p, loops->larray);
 }
 
@@ -559,11 +563,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.  */
@@ -578,15 +584,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;
 
@@ -761,7 +768,7 @@ disambiguate_loops_with_multiple_latches (void)
 
 /* Return nonzero if basic block BB belongs to LOOP.  */
 bool
-flow_bb_inside_loop_p (const struct loop *loop, const basic_block bb)
+flow_bb_inside_loop_p (const struct loop *loop, const_basic_block bb)
 {
   struct loop *source_loop;
 
@@ -774,9 +781,9 @@ flow_bb_inside_loop_p (const struct loop *loop, const basic_block bb)
 
 /* Enumeration predicate for get_loop_body_with_size.  */
 static bool
-glb_enum_p (basic_block bb, void *glb_loop)
+glb_enum_p (const_basic_block bb, const void *glb_loop)
 {
-  struct loop *loop = glb_loop;
+  const struct loop *const loop = (const struct loop *) glb_loop;
   return (bb != loop->header
          && dominated_by_p (CDI_DOMINATORS, bb, loop->header));
 }
@@ -793,7 +800,7 @@ get_loop_body_with_size (const struct loop *loop, basic_block *body,
                         unsigned max_size)
 {
   return dfs_enumerate_from (loop->header, 1, glb_enum_p,
-                            body, max_size, (void *) loop);
+                            body, max_size, loop);
 }
 
 /* Gets basic blocks of a LOOP.  Header is the 0-th block, rest is in dfs
@@ -880,6 +887,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 *
@@ -936,7 +956,7 @@ get_loop_body_in_bfs_order (const struct loop *loop)
 static hashval_t
 loop_exit_hash (const void *ex)
 {
-  struct loop_exit *exit = (struct loop_exit *) ex;
+  const struct loop_exit *const exit = (const struct loop_exit *) ex;
 
   return htab_hash_pointer (exit->e);
 }
@@ -946,7 +966,7 @@ loop_exit_hash (const void *ex)
 static int
 loop_exit_eq (const void *ex, const void *e)
 {
-  struct loop_exit *exit = (struct loop_exit *) ex;
+  const struct loop_exit *const exit = (const struct loop_exit *) ex;
 
   return exit->e == e;
 }
@@ -974,8 +994,8 @@ loop_exit_free (void *ex)
 static struct loop_exit *
 get_exit_descriptions (edge e)
 {
-  return htab_find_with_hash (current_loops->exits, e,
-                             htab_hash_pointer (e));
+  return (struct loop_exit *) htab_find_with_hash (current_loops->exits, e,
+                                                  htab_hash_pointer (e));
 }
 
 /* Updates the lists of loop exits in that E appears.
@@ -991,7 +1011,7 @@ rescan_loop_exit (edge e, bool new_edge, bool removed)
   struct loop_exit *exits = NULL, *exit;
   struct loop *aloop, *cloop;
 
-  if ((current_loops->state & LOOPS_HAVE_RECORDED_EXITS) == 0)
+  if (!loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
     return;
 
   if (!removed
@@ -1049,9 +1069,9 @@ record_loop_exits (void)
   if (!current_loops)
     return;
 
-  if (current_loops->state & LOOPS_HAVE_RECORDED_EXITS)
+  if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
     return;
-  current_loops->state |= LOOPS_HAVE_RECORDED_EXITS;
+  loops_state_set (LOOPS_HAVE_RECORDED_EXITS);
 
   gcc_assert (current_loops->exits == NULL);
   current_loops->exits = htab_create_alloc (2 * number_of_loops (),
@@ -1075,14 +1095,14 @@ record_loop_exits (void)
 static int
 dump_recorded_exit (void **slot, void *file)
 {
-  struct loop_exit *exit = *slot;
+  struct loop_exit *exit = (struct loop_exit *) *slot;
   unsigned n = 0;
   edge e = exit->e;
 
   for (; exit != NULL; exit = exit->next_e)
     n++;
 
-  fprintf (file, "Edge %d->%d exits %u loops\n",
+  fprintf ((FILE*) file, "Edge %d->%d exits %u loops\n",
           e->src->index, e->dest->index, n);
 
   return 1;
@@ -1104,10 +1124,10 @@ dump_recorded_exits (FILE *file)
 void
 release_recorded_exits (void)
 {
-  gcc_assert (current_loops->state & LOOPS_HAVE_RECORDED_EXITS);
+  gcc_assert (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS));
   htab_delete (current_loops->exits);
   current_loops->exits = NULL;
-  current_loops->state &= ~LOOPS_HAVE_RECORDED_EXITS;
+  loops_state_clear (LOOPS_HAVE_RECORDED_EXITS);
 }
 
 /* Returns the list of the exit edges of a LOOP.  */
@@ -1126,7 +1146,7 @@ get_loop_exit_edges (const struct loop *loop)
 
   /* If we maintain the lists of exits, use them.  Otherwise we must
      scan the body of the loop.  */
-  if (current_loops->state & LOOPS_HAVE_RECORDED_EXITS)
+  if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
     {
       for (exit = loop->exits->next; exit->e; exit = exit->next)
        VEC_safe_push (edge, heap, edges, exit->e);
@@ -1347,13 +1367,13 @@ verify_loop_structure (void)
     {
       i = loop->num;
 
-      if ((current_loops->state & LOOPS_HAVE_PREHEADERS)
+      if (loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS)
          && EDGE_COUNT (loop->header->preds) != 2)
        {
          error ("loop %d's header does not have exactly 2 entries", i);
          err = 1;
        }
-      if (current_loops->state & LOOPS_HAVE_SIMPLE_LATCHES)
+      if (loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES))
        {
          if (!single_succ_p (loop->latch))
            {
@@ -1376,7 +1396,7 @@ verify_loop_structure (void)
          error ("loop %d's header does not belong directly to it", i);
          err = 1;
        }
-      if ((current_loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
+      if (loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
          && (loop_latch_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP))
        {
          error ("loop %d's latch is marked as part of irreducible region", i);
@@ -1385,7 +1405,7 @@ verify_loop_structure (void)
     }
 
   /* Check irreducible loops.  */
-  if (current_loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
+  if (loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
     {
       /* Record old info.  */
       irreds = sbitmap_alloc (last_basic_block);
@@ -1471,7 +1491,7 @@ verify_loop_structure (void)
            }
        }
 
-      if ((current_loops->state & LOOPS_HAVE_RECORDED_EXITS) == 0)
+      if (!loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
        {
          if (loop->exits->next != loop->exits)
            {
@@ -1482,7 +1502,7 @@ verify_loop_structure (void)
        }
     }
 
-  if (current_loops->state & LOOPS_HAVE_RECORDED_EXITS)
+  if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
     {
       unsigned n_exits = 0, eloops;
 
@@ -1565,7 +1585,7 @@ loop_preheader_edge (const struct loop *loop)
   edge e;
   edge_iterator ei;
 
-  gcc_assert ((current_loops->state & LOOPS_HAVE_PREHEADERS) != 0);
+  gcc_assert (loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS));
 
   FOR_EACH_EDGE (e, ei, loop->header->preds)
     if (e->src != loop->latch)
@@ -1577,7 +1597,7 @@ loop_preheader_edge (const struct loop *loop)
 /* Returns true if E is an exit of LOOP.  */
 
 bool
-loop_exit_edge_p (const struct loop *loop, edge e)
+loop_exit_edge_p (const struct loop *loop, const_edge e)
 {
   return (flow_bb_inside_loop_p (loop, e->src)
          && !flow_bb_inside_loop_p (loop, e->dest));
@@ -1592,7 +1612,7 @@ single_exit (const struct loop *loop)
 {
   struct loop_exit *exit = loop->exits->next;
 
-  if ((current_loops->state & LOOPS_HAVE_RECORDED_EXITS) == 0)
+  if (!loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
     return NULL;
 
   if (exit->e && exit->next == loop->exits)