X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Ftree-ssa-loop-ch.c;h=ff62c686c2851d84189347cc11fe695690df05af;hp=2b3094622d71c8ffdb1a02aad9de300f35ff5a91;hb=f2852046a2c3bac1d4455e33876fc9991e9fc713;hpb=00bd8b4402db49aeb3edfbfd278b1566b02a9563 diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c index 2b3094622d7..ff62c686c28 100644 --- a/gcc/tree-ssa-loop-ch.c +++ b/gcc/tree-ssa-loop-ch.c @@ -1,11 +1,11 @@ /* 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 -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 +. */ #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; - *limit -= estimate_num_insns (last); + *limit -= estimate_num_insns (last, &eni_size_weights); 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. */ -static void +static unsigned int copy_loop_headers (void) { - struct loops *loops; - unsigned i; + loop_iterator li; struct loop *loop; basic_block header; edge exit, entry; @@ -132,30 +130,27 @@ copy_loop_headers (void) 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 - verify_loop_structure (loops); + verify_loop_structure (); #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; - for (i = 1; i < loops->num; i++) + FOR_EACH_LOOP (li, loop, 0) { /* 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 @@ -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)) - exit = single_pred_edge (loop_split_edge_with (exit, NULL)); + exit = single_pred_edge (split_edge (exit)); entry = loop_preheader_edge (loop); @@ -207,16 +202,49 @@ copy_loop_headers (void) 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. */ - 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); - loop_optimizer_finalize (loops, NULL); + loop_optimizer_finalize (); + return 0; } static bool