OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-unswitch.c
index 1736269..b63c209 100644 (file)
@@ -1,11 +1,11 @@
 /* Loop unswitching.
-   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 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
+Free 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
@@ -14,9 +14,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"
@@ -36,6 +35,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "domwalk.h"
 #include "params.h"
 #include "tree-pass.h"
+#include "tree-inline.h"
 
 /* This file implements the loop unswitching, i.e. transformation of loops like
 
@@ -73,38 +73,28 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
    tree-ssa-loop-im.c ensures that all the suitable conditions are in this
    shape.  */
 
-static struct loop *tree_unswitch_loop (struct loops *, struct loop *, basic_block,
-                                  tree);
-static bool tree_unswitch_single_loop (struct loops *, struct loop *, int);
+static struct loop *tree_unswitch_loop (struct loop *, basic_block, tree);
+static bool tree_unswitch_single_loop (struct loop *, int);
 static tree tree_may_unswitch_on (basic_block, struct loop *);
 
-/* Main entry point.  Perform loop unswitching on all suitable LOOPS.  */
+/* Main entry point.  Perform loop unswitching on all suitable loops.  */
 
-void
-tree_ssa_unswitch_loops (struct loops *loops)
+unsigned int
+tree_ssa_unswitch_loops (void)
 {
-  int i, num;
+  loop_iterator li;
   struct loop *loop;
   bool changed = false;
 
   /* Go through inner loops (only original ones).  */
-  num = loops->num;
-
-  for (i = 1; i < num; i++)
+  FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST)
     {
-      /* Removed loop?  */
-      loop = loops->parray[i];
-      if (!loop)
-       continue;
-
-      if (loop->inner)
-       continue;
-
-      changed |= tree_unswitch_single_loop (loops, loop, 0);
+      changed |= tree_unswitch_single_loop (loop, 0);
     }
 
   if (changed)
-    cleanup_tree_cfg_loop ();
+    return TODO_cleanup_cfg;
+  return 0;
 }
 
 /* Checks whether we can unswitch LOOP on condition at end of BB -- one of its
@@ -176,7 +166,7 @@ simplify_using_entry_checks (struct loop *loop, tree cond)
    grow exponentially.  */
 
 static bool
-tree_unswitch_single_loop (struct loops *loops, struct loop *loop, int num)
+tree_unswitch_single_loop (struct loop *loop, int num)
 {
   basic_block *bbs;
   struct loop *nloop;
@@ -201,7 +191,7 @@ tree_unswitch_single_loop (struct loops *loops, struct loop *loop, int num)
     }
 
   /* The loop should not be too large, to limit code growth.  */
-  if (tree_num_loop_insns (loop)
+  if (tree_num_loop_insns (loop, &eni_size_weights)
       > (unsigned) PARAM_VALUE (PARAM_MAX_UNSWITCH_INSNS))
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
@@ -251,17 +241,22 @@ tree_unswitch_single_loop (struct loops *loops, struct loop *loop, int num)
 
   initialize_original_copy_tables ();
   /* Unswitch the loop on this condition.  */
-  nloop = tree_unswitch_loop (loops, loop, bbs[i], cond);
+  nloop = tree_unswitch_loop (loop, bbs[i], cond);
   if (!nloop)
-    return changed;
+    {
+      free_original_copy_tables ();
+      free (bbs);
+      return changed;
+    }
 
   /* Update the SSA form after unswitching.  */
   update_ssa (TODO_update_ssa);
   free_original_copy_tables ();
 
   /* Invoke itself on modified loops.  */
-  tree_unswitch_single_loop (loops, nloop, num + 1);
-  tree_unswitch_single_loop (loops, loop, num + 1);
+  tree_unswitch_single_loop (nloop, num + 1);
+  tree_unswitch_single_loop (loop, num + 1);
+  free (bbs);
   return true;
 }
 
@@ -271,16 +266,20 @@ tree_unswitch_single_loop (struct loops *loops, struct loop *loop, int num)
    if impossible, new loop otherwise.  */
 
 static struct loop *
-tree_unswitch_loop (struct loops *loops, struct loop *loop,
+tree_unswitch_loop (struct loop *loop,
                    basic_block unswitch_on, tree cond)
 {
-  basic_block condition_bb;
+  unsigned prob_true;
+  edge edge_true, edge_false;
 
   /* Some sanity checking.  */
   gcc_assert (flow_bb_inside_loop_p (loop, unswitch_on));
   gcc_assert (EDGE_COUNT (unswitch_on->succs) == 2);
   gcc_assert (loop->inner == NULL);
 
-  return loop_version (loops, loop, unshare_expr (cond), 
-                      &condition_bb);
+  extract_true_false_edges_from_block (unswitch_on, &edge_true, &edge_false);
+  prob_true = edge_true->probability;
+  return loop_version (loop, unshare_expr (cond), 
+                      NULL, prob_true, prob_true,
+                      REG_BR_PROB_BASE - prob_true, false);
 }