OSDN Git Service

2008-03-04 Uros Bizjak <ubizjak@gmail.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-ch.c
index 0184578..ff62c68 100644 (file)
@@ -1,11 +1,11 @@
 /* Loop header copying on trees.
 /* Loop header copying on trees.
-   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 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
    
 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
 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
 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"
 
 #include "config.h"
 #include "system.h"
@@ -87,7 +86,7 @@ should_duplicate_loop_header_p (basic_block header, struct loop *loop,
       if (get_call_expr_in (last))
        return false;
 
       if (get_call_expr_in (last))
        return false;
 
-      *limit -= estimate_num_insns (last);
+      *limit -= estimate_num_insns (last, &eni_size_weights);
       if (*limit < 0)
        return false;
     }
       if (*limit < 0)
        return false;
     }
@@ -120,11 +119,10 @@ do_while_loop_p (struct loop *loop)
    of the loop.  This is beneficial since it increases efficiency of
    code motion optimizations.  It also saves one jump on entry to the loop.  */
 
    of the loop.  This is beneficial since it increases efficiency of
    code motion optimizations.  It also saves one jump on entry to the loop.  */
 
-static void
+static unsigned int
 copy_loop_headers (void)
 {
 copy_loop_headers (void)
 {
-  struct loops *loops;
-  unsigned i;
+  loop_iterator li;
   struct loop *loop;
   basic_block header;
   edge exit, entry;
   struct loop *loop;
   basic_block header;
   edge exit, entry;
@@ -132,30 +130,27 @@ copy_loop_headers (void)
   unsigned n_bbs;
   unsigned bbs_size;
 
   unsigned n_bbs;
   unsigned bbs_size;
 
-  loops = loop_optimizer_init (dump_file);
-  if (!loops)
-    return;
-  
-  /* We do not try to keep the information about irreducible regions
-     up-to-date.  */
-  loops->state &= ~LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS;
+  loop_optimizer_init (LOOPS_HAVE_PREHEADERS
+                      | LOOPS_HAVE_SIMPLE_LATCHES);
+  if (number_of_loops () <= 1)
+    {
+      loop_optimizer_finalize ();
+      return 0;
+    }
 
 #ifdef ENABLE_CHECKING
 
 #ifdef ENABLE_CHECKING
-  verify_loop_structure (loops);
+  verify_loop_structure ();
 #endif
 
 #endif
 
-  bbs = xmalloc (sizeof (basic_block) * n_basic_blocks);
-  copied_bbs = xmalloc (sizeof (basic_block) * n_basic_blocks);
+  bbs = XNEWVEC (basic_block, n_basic_blocks);
+  copied_bbs = XNEWVEC (basic_block, n_basic_blocks);
   bbs_size = n_basic_blocks;
 
   bbs_size = n_basic_blocks;
 
-  for (i = 1; i < loops->num; i++)
+  FOR_EACH_LOOP (li, loop, 0)
     {
       /* Copy at most 20 insns.  */
       int limit = 20;
 
     {
       /* Copy at most 20 insns.  */
       int limit = 20;
 
-      loop = loops->parray[i];
-      if (!loop)
-       continue;
       header = loop->header;
 
       /* If the loop is already a do-while style one (either because it was
       header = loop->header;
 
       /* If the loop is already a do-while style one (either because it was
@@ -197,7 +192,7 @@ copy_loop_headers (void)
       /* Ensure that the header will have just the latch as a predecessor
         inside the loop.  */
       if (!single_pred_p (exit->dest))
       /* Ensure that the header will have just the latch as a predecessor
         inside the loop.  */
       if (!single_pred_p (exit->dest))
-       exit = single_succ_edge (loop_split_edge_with (exit, NULL));
+       exit = single_pred_edge (split_edge (exit));
 
       entry = loop_preheader_edge (loop);
 
 
       entry = loop_preheader_edge (loop);
 
@@ -207,16 +202,49 @@ copy_loop_headers (void)
          continue;
        }
 
          continue;
        }
 
+      /* If the loop has the form "for (i = j; i < j + 10; i++)" then
+        this copying can introduce a case where we rely on undefined
+        signed overflow to eliminate the preheader condition, because
+        we assume that "j < j + 10" is true.  We don't want to warn
+        about that case for -Wstrict-overflow, because in general we
+        don't warn about overflow involving loops.  Prevent the
+        warning by setting TREE_NO_WARNING.  */
+      if (warn_strict_overflow > 0)
+       {
+         unsigned int i;
+
+         for (i = 0; i < n_bbs; ++i)
+           {
+             block_stmt_iterator bsi;
+
+             for (bsi = bsi_start (copied_bbs[i]);
+                  !bsi_end_p (bsi);
+                  bsi_next (&bsi))
+               {
+                 tree stmt = bsi_stmt (bsi);
+                 if (TREE_CODE (stmt) == COND_EXPR)
+                   TREE_NO_WARNING (stmt) = 1;
+                 else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+                   {
+                     tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+                     if (COMPARISON_CLASS_P (rhs))
+                       TREE_NO_WARNING (stmt) = 1;
+                   }
+               }
+           }
+       }
+
       /* Ensure that the latch and the preheader is simple (we know that they
         are not now, since there was the loop exit condition.  */
       /* Ensure that the latch and the preheader is simple (we know that they
         are not now, since there was the loop exit condition.  */
-      loop_split_edge_with (loop_preheader_edge (loop), NULL);
-      loop_split_edge_with (loop_latch_edge (loop), NULL);
+      split_edge (loop_preheader_edge (loop));
+      split_edge (loop_latch_edge (loop));
     }
 
   free (bbs);
   free (copied_bbs);
 
     }
 
   free (bbs);
   free (copied_bbs);
 
-  loop_optimizer_finalize (loops, NULL);
+  loop_optimizer_finalize ();
+  return 0;
 }
 
 static bool
 }
 
 static bool