aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-niter.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2019-11-25 07:51:38 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2019-11-25 07:51:38 +0000
commitf10d2d85c90c9c649675c248cd5a99f66288f81f (patch)
tree284bcf852c57a2fa1c05c83c5138e1553cc14a03 /gcc/tree-ssa-loop-niter.c
parent5a34952edb758109a3b919bc149136ee9277ee3a (diff)
downloadgcc-f10d2d85c90c9c649675c248cd5a99f66288f81f.zip
gcc-f10d2d85c90c9c649675c248cd5a99f66288f81f.tar.gz
gcc-f10d2d85c90c9c649675c248cd5a99f66288f81f.tar.bz2
cfgloop.h (get_loop_exit_edges): Add extra parameter denoting loop body, defaulted to NULL.
2019-11-25 Richard Biener <rguenther@suse.de> * cfgloop.h (get_loop_exit_edges): Add extra parameter denoting loop body, defaulted to NULL. (single_likely_exit): Add exit vector argument * tree-ssa-loop-niter.h (loop_only_exit_p): Add loop body argument. (number_of_iterations_exit): Likewise. (number_of_iterations_exit_assumptions): Likewise. * cfgloop.c (get_loop_exit_edges): Use passed in loop body if not NULL. * cfgloopanal.c (single_likely_exit): Use passed in exit vector. * tree-ssa-loop-ivcanon.c (canonicalize_loop_induction_variables): Compute exit vector around call to single_likely_exit. * tree-ssa-loop-ivopts.c (tree_ssa_iv_optimize_loop): Pass down loop body to loop_only_exit_p. * tree-ssa-loop-niter.c (loop_only_exit_p): Get loop body from caller. (number_of_iterations_exit_assumptions): Get loop body from caller if not NULL. (number_of_iterations_exit): Pass through new loop body arg. (infer_loop_bounds_from_undefined): Get loop body from caller. (estimate_numbers_of_iterations): Compute loop body once. From-SVN: r278667
Diffstat (limited to 'gcc/tree-ssa-loop-niter.c')
-rw-r--r--gcc/tree-ssa-loop-niter.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index d5c1b5b..f0dd9a0 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -2367,27 +2367,23 @@ simplify_using_outer_evolutions (class loop *loop, tree expr)
/* Returns true if EXIT is the only possible exit from LOOP. */
bool
-loop_only_exit_p (const class loop *loop, const_edge exit)
+loop_only_exit_p (const class loop *loop, basic_block *body, const_edge exit)
{
- basic_block *body;
gimple_stmt_iterator bsi;
unsigned i;
if (exit != single_exit (loop))
return false;
- body = get_loop_body (loop);
for (i = 0; i < loop->num_nodes; i++)
{
for (bsi = gsi_start_bb (body[i]); !gsi_end_p (bsi); gsi_next (&bsi))
if (stmt_can_terminate_bb_p (gsi_stmt (bsi)))
{
- free (body);
return true;
}
}
- free (body);
return true;
}
@@ -2403,7 +2399,8 @@ loop_only_exit_p (const class loop *loop, const_edge exit)
bool
number_of_iterations_exit_assumptions (class loop *loop, edge exit,
class tree_niter_desc *niter,
- gcond **at_stmt, bool every_iteration)
+ gcond **at_stmt, bool every_iteration,
+ basic_block *body)
{
gimple *last;
gcond *stmt;
@@ -2477,8 +2474,17 @@ number_of_iterations_exit_assumptions (class loop *loop, edge exit,
iv0.base = expand_simple_operations (iv0.base);
iv1.base = expand_simple_operations (iv1.base);
+ bool body_from_caller = true;
+ if (!body)
+ {
+ body = get_loop_body (loop);
+ body_from_caller = false;
+ }
+ bool only_exit_p = loop_only_exit_p (loop, body, exit);
+ if (!body_from_caller)
+ free (body);
if (!number_of_iterations_cond (loop, type, &iv0, code, &iv1, niter,
- loop_only_exit_p (loop, exit), safe))
+ only_exit_p, safe))
{
fold_undefer_and_ignore_overflow_warnings ();
return false;
@@ -2721,11 +2727,12 @@ number_of_iterations_popcount (loop_p loop, edge exit,
bool
number_of_iterations_exit (class loop *loop, edge exit,
class tree_niter_desc *niter,
- bool warn, bool every_iteration)
+ bool warn, bool every_iteration,
+ basic_block *body)
{
gcond *stmt;
if (!number_of_iterations_exit_assumptions (loop, exit, niter,
- &stmt, every_iteration))
+ &stmt, every_iteration, body))
return false;
if (integer_nonzerop (niter->assumptions))
@@ -3837,16 +3844,13 @@ infer_loop_bounds_from_signedness (class loop *loop, gimple *stmt)
*/
static void
-infer_loop_bounds_from_undefined (class loop *loop)
+infer_loop_bounds_from_undefined (class loop *loop, basic_block *bbs)
{
unsigned i;
- basic_block *bbs;
gimple_stmt_iterator bsi;
basic_block bb;
bool reliable;
- bbs = get_loop_body (loop);
-
for (i = 0; i < loop->num_nodes; i++)
{
bb = bbs[i];
@@ -3871,8 +3875,6 @@ infer_loop_bounds_from_undefined (class loop *loop)
}
}
-
- free (bbs);
}
/* Compare wide ints, callback for qsort. */
@@ -4275,8 +4277,9 @@ estimate_numbers_of_iterations (class loop *loop)
diagnose those loops with -Waggressive-loop-optimizations. */
number_of_latch_executions (loop);
- exits = get_loop_exit_edges (loop);
- likely_exit = single_likely_exit (loop);
+ basic_block *body = get_loop_body (loop);
+ exits = get_loop_exit_edges (loop, body);
+ likely_exit = single_likely_exit (loop, exits);
FOR_EACH_VEC_ELT (exits, i, ex)
{
if (ex == likely_exit)
@@ -4296,7 +4299,8 @@ estimate_numbers_of_iterations (class loop *loop)
}
}
- if (!number_of_iterations_exit (loop, ex, &niter_desc, false, false))
+ if (!number_of_iterations_exit (loop, ex, &niter_desc,
+ false, false, body))
continue;
niter = niter_desc.niter;
@@ -4313,7 +4317,7 @@ estimate_numbers_of_iterations (class loop *loop)
exits.release ();
if (flag_aggressive_loop_optimizations)
- infer_loop_bounds_from_undefined (loop);
+ infer_loop_bounds_from_undefined (loop, body);
discover_iteration_bound_by_body_walk (loop);