Commit faa1612a by Bin Cheng Committed by Bin Cheng

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
parent 01a0d7f5
2016-07-22 Bin Cheng <bin.cheng@arm.com>
* 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 <segher@kernel.crashing.org> 2016-07-22 Segher Boessenkool <segher@kernel.crashing.org>
* config/rs6000/rs6000.c (rs6000_file_start): Fix condition for * config/rs6000/rs6000.c (rs6000_file_start): Fix condition for
......
2016-07-22 Bin Cheng <bin.cheng@arm.com>
* gcc.dg/tree-ssa/pr19210-1.c: Refine test strings.
* gcc.dg/tree-ssa/pr19210-2.c: Delete.
2016-07-22 Thomas Koenig <tkoenig@gcc.gnu.org> 2016-07-22 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/71795 PR fortran/71795
......
...@@ -6,10 +6,10 @@ void ...@@ -6,10 +6,10 @@ void
f (unsigned n) f (unsigned n)
{ {
unsigned k; 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(); 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(); g();
/* We used to get warning for this loop. However, since then # of iterations /* We used to get warning for this loop. However, since then # of iterations
...@@ -21,9 +21,9 @@ f (unsigned n) ...@@ -21,9 +21,9 @@ f (unsigned n)
g(); g();
/* So we need the following loop, instead. */ /* 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(); 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(); g();
} }
/* { 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();
}
...@@ -2132,12 +2132,13 @@ loop_only_exit_p (const struct loop *loop, const_edge exit) ...@@ -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. in comments at struct tree_niter_desc declaration), false otherwise.
When EVERY_ITERATION is true, only tests that are known to be executed 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). 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 bool
number_of_iterations_exit_assumptions (struct loop *loop, edge exit, number_of_iterations_exit_assumptions (struct loop *loop, edge exit,
struct tree_niter_desc *niter, struct tree_niter_desc *niter,
bool every_iteration) gcond **at_stmt, bool every_iteration)
{ {
gimple *last; gimple *last;
gcond *stmt; gcond *stmt;
...@@ -2254,6 +2255,9 @@ number_of_iterations_exit_assumptions (struct loop *loop, edge exit, ...@@ -2254,6 +2255,9 @@ number_of_iterations_exit_assumptions (struct loop *loop, edge exit,
if (TREE_CODE (niter->niter) == INTEGER_CST) if (TREE_CODE (niter->niter) == INTEGER_CST)
niter->max = wi::to_widest (niter->niter); niter->max = wi::to_widest (niter->niter);
if (at_stmt)
*at_stmt = stmt;
return (!integer_zerop (niter->assumptions)); return (!integer_zerop (niter->assumptions));
} }
...@@ -2263,13 +2267,26 @@ number_of_iterations_exit_assumptions (struct loop *loop, edge exit, ...@@ -2263,13 +2267,26 @@ number_of_iterations_exit_assumptions (struct loop *loop, edge exit,
bool bool
number_of_iterations_exit (struct loop *loop, edge exit, number_of_iterations_exit (struct loop *loop, edge exit,
struct tree_niter_desc *niter, 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, if (!number_of_iterations_exit_assumptions (loop, exit, niter,
every_iteration)) &stmt, every_iteration))
return false; 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, /* Try to determine the number of iterations of LOOP. If we succeed,
......
...@@ -29,7 +29,7 @@ extern bool number_of_iterations_exit (struct loop *, edge, ...@@ -29,7 +29,7 @@ extern bool number_of_iterations_exit (struct loop *, edge,
bool every_iteration = true); bool every_iteration = true);
extern bool number_of_iterations_exit_assumptions (struct loop *, edge, extern bool number_of_iterations_exit_assumptions (struct loop *, edge,
struct tree_niter_desc *, struct tree_niter_desc *,
bool = true); gcond **, bool = true);
extern tree find_loop_niter (struct loop *, edge *); extern tree find_loop_niter (struct loop *, edge *);
extern bool finite_loop_p (struct loop *); extern bool finite_loop_p (struct loop *);
extern tree loop_niter_by_eval (struct loop *, edge); extern tree loop_niter_by_eval (struct loop *, edge);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment