mirror of git://gcc.gnu.org/git/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
This commit is contained in:
parent
01a0d7f57b
commit
faa1612aa3
|
|
@ -1,3 +1,12 @@
|
||||||
|
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
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
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
|
||||||
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)
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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,
|
||||||
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,
|
||||||
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,
|
||||||
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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue