From: Bin Cheng Date: Fri, 22 Jul 2016 13:22:03 +0000 (+0000) Subject: tree-ssa-loop-niter.h (number_of_iterations_exit_assumptions): New Parameter. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=faa1612aa309b073803613c82712bc940393ad74;p=gcc.git tree-ssa-loop-niter.h (number_of_iterations_exit_assumptions): New Parameter. * tree-ssa-loop-niter.h (number_of_iterations_exit_assumptions): New Parameter. * tree-ssa-loop-niter.c (number_of_iterations_exit_assumptions): New Parameter. (number_of_iterations_exit): Warn missed loop optimization for possible infinite loops. gcc/testsuite * gcc.dg/tree-ssa/pr19210-1.c: Refine test strings. * gcc.dg/tree-ssa/pr19210-2.c: Delete. From-SVN: r238641 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b44bae6d32a..e8c40d829e9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2016-07-22 Bin Cheng + + * tree-ssa-loop-niter.h (number_of_iterations_exit_assumptions): New + Parameter. + * tree-ssa-loop-niter.c (number_of_iterations_exit_assumptions): New + Parameter. + (number_of_iterations_exit): Warn missed loop optimization for + possible infinite loops. + 2016-07-22 Segher Boessenkool * config/rs6000/rs6000.c (rs6000_file_start): Fix condition for diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index feb3236fef9..7cef33787ad 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-07-22 Bin Cheng + + * gcc.dg/tree-ssa/pr19210-1.c: Refine test strings. + * gcc.dg/tree-ssa/pr19210-2.c: Delete. + 2016-07-22 Thomas Koenig PR fortran/71795 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr19210-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr19210-1.c index 906132c6916..3c8ee06016f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr19210-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr19210-1.c @@ -6,10 +6,10 @@ void f (unsigned n) { unsigned k; - for(k = 0;k <= n;k++) /* { dg-warning "cannot optimize.*infinite loops" } */ + for(k = 0;k <= n;k++) /* { dg-warning "missed loop optimization.*overflow" } */ g(); - for(k = 0;k <= n;k += 4) /* { dg-warning "cannot optimize.*overflow" } */ + for(k = 0;k <= n;k += 4) /* { dg-warning "missed loop optimization.*overflow" } */ g(); /* We used to get warning for this loop. However, since then # of iterations @@ -21,9 +21,9 @@ f (unsigned n) g(); /* So we need the following loop, instead. */ - for(k = 4;k <= n;k += 5) /* { dg-warning "cannot optimize.*overflow" } */ + for(k = 4;k <= n;k += 5) /* { dg-warning "missed loop optimization.*overflow" } */ g(); - for(k = 15;k >= n;k--) /* { dg-warning "cannot optimize.*infinite" } */ + for(k = 15;k >= n;k--) /* { dg-warning "missed loop optimization.*overflow" } */ g(); } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr19210-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr19210-2.c deleted file mode 100644 index 9116e97ec4f..00000000000 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr19210-2.c +++ /dev/null @@ -1,29 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-O2 -funsafe-loop-optimizations -Wunsafe-loop-optimizations" } */ -extern void g(void); - -void -f (unsigned n) -{ - unsigned k; - for(k = 0;k <= n;k++) /* { dg-warning "assuming.*not infinite" } */ - g(); - - for(k = 5;k <= n;k += 4) /* { dg-warning "assuming.*not overflow" } */ - g(); - - /* We used to get warning for this loop. However, since then # of iterations - analysis improved, and we can now prove that this loop does not verflow. - This is because the only case when it would overflow is if n = ~0 (since - ~0 is divisible by 5), and this cannot be the case, since when we got - here, the previous loop exited, thus there exists k > n. */ - for(k = 5;k <= n;k += 5) - g(); - - for(k = 4;k <= n;k += 5) /* { dg-warning "assuming.*not overflow" } */ - g(); - - for(k = 15;k >= n;k--) /* { dg-warning "assuming.*not infinite" } */ - g(); - -} diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 3b4d4f31502..ee6d5cfe0fd 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -2132,12 +2132,13 @@ loop_only_exit_p (const struct loop *loop, const_edge exit) in comments at struct tree_niter_desc declaration), false otherwise. When EVERY_ITERATION is true, only tests that are known to be executed every iteration are considered (i.e. only test that alone bounds the loop). - */ + If AT_STMT is not NULL, this function stores LOOP's condition statement in + it when returning true. */ bool number_of_iterations_exit_assumptions (struct loop *loop, edge exit, struct tree_niter_desc *niter, - bool every_iteration) + gcond **at_stmt, bool every_iteration) { gimple *last; gcond *stmt; @@ -2254,6 +2255,9 @@ number_of_iterations_exit_assumptions (struct loop *loop, edge exit, if (TREE_CODE (niter->niter) == INTEGER_CST) niter->max = wi::to_widest (niter->niter); + if (at_stmt) + *at_stmt = stmt; + return (!integer_zerop (niter->assumptions)); } @@ -2263,13 +2267,26 @@ number_of_iterations_exit_assumptions (struct loop *loop, edge exit, bool number_of_iterations_exit (struct loop *loop, edge exit, struct tree_niter_desc *niter, - bool, bool every_iteration) + bool warn, bool every_iteration) { + gcond *stmt; if (!number_of_iterations_exit_assumptions (loop, exit, niter, - every_iteration)) + &stmt, every_iteration)) return false; - return (integer_nonzerop (niter->assumptions)); + if (integer_nonzerop (niter->assumptions)) + return true; + + if (warn) + { + const char *wording; + + wording = N_("missed loop optimization, the loop counter may overflow"); + warning_at (gimple_location_safe (stmt), + OPT_Wunsafe_loop_optimizations, "%s", gettext (wording)); + } + + return false; } /* Try to determine the number of iterations of LOOP. If we succeed, diff --git a/gcc/tree-ssa-loop-niter.h b/gcc/tree-ssa-loop-niter.h index 97400cb6884..f5e2259186f 100644 --- a/gcc/tree-ssa-loop-niter.h +++ b/gcc/tree-ssa-loop-niter.h @@ -29,7 +29,7 @@ extern bool number_of_iterations_exit (struct loop *, edge, bool every_iteration = true); extern bool number_of_iterations_exit_assumptions (struct loop *, edge, struct tree_niter_desc *, - bool = true); + gcond **, bool = true); extern tree find_loop_niter (struct loop *, edge *); extern bool finite_loop_p (struct loop *); extern tree loop_niter_by_eval (struct loop *, edge);