Commit cd0f6278 by Jan Hubicka Committed by Jan Hubicka

tree-ssa-loop-niter.c (number_of_iterations_exit): New parameter EVERY_ITERATION…

tree-ssa-loop-niter.c (number_of_iterations_exit): New parameter EVERY_ITERATION with implicit value of true.


	* tree-ssa-loop-niter.c (number_of_iterations_exit): New parameter
	EVERY_ITERATION with implicit value of true.
	(record_estimate): Check dominance relationship of the basic block
	we are estimating on instead of relying on UPPER to be false.
	(struct ilb_data): Drop RELIABLE.
	(idx_infer_loop_bounds): Update.
	(infer_loop_bounds_from_ref): Drop parameter RELIABLE.
	(infer_loop_bounds_from_array): Drop parameter RELIABLE.
	(infer_loop_bounds_from_undefined): Update comments and handling
	of RELIABLE.
	(estimate_numbers_of_iterations_loop): Record all bounds.

From-SVN: r192989
parent baa061be
2012-10-30 Jan Hubicka <jh@suse.cz>
* tree-ssa-loop-niter.c (number_of_iterations_exit): New parameter
EVERY_ITERATION with implicit value of true.
(record_estimate): Check dominance relationship of the basic block
we are estimating on instead of relying on UPPER to be false.
(struct ilb_data): Drop RELIABLE.
(idx_infer_loop_bounds): Update.
(infer_loop_bounds_from_ref): Drop parameter RELIABLE.
(infer_loop_bounds_from_array): Drop parameter RELIABLE.
(infer_loop_bounds_from_undefined): Update comments and handling
of RELIABLE.
(estimate_numbers_of_iterations_loop): Record all bounds.
2012-10-30 Richard Sandiford <r.sandiford@uk.ibm.com> 2012-10-30 Richard Sandiford <r.sandiford@uk.ibm.com>
* lra-eliminations.c (lra_eliminate_regs_1): Use simplify_gen_subreg * lra-eliminations.c (lra_eliminate_regs_1): Use simplify_gen_subreg
...@@ -1793,12 +1793,15 @@ loop_only_exit_p (const struct loop *loop, const_edge exit) ...@@ -1793,12 +1793,15 @@ loop_only_exit_p (const struct loop *loop, const_edge exit)
meaning described in comments at struct tree_niter_desc meaning described in comments at struct tree_niter_desc
declaration), false otherwise. If WARN is true and declaration), false otherwise. If WARN is true and
-Wunsafe-loop-optimizations was given, warn if the optimizer is going to use -Wunsafe-loop-optimizations was given, warn if the optimizer is going to use
potentially unsafe assumptions. */ potentially unsafe assumptions.
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).
*/
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 warn) bool warn, bool every_iteration)
{ {
gimple stmt; gimple stmt;
tree type; tree type;
...@@ -1806,7 +1809,8 @@ number_of_iterations_exit (struct loop *loop, edge exit, ...@@ -1806,7 +1809,8 @@ number_of_iterations_exit (struct loop *loop, edge exit,
enum tree_code code; enum tree_code code;
affine_iv iv0, iv1; affine_iv iv0, iv1;
if (!dominated_by_p (CDI_DOMINATORS, loop->latch, exit->src)) if (every_iteration
&& !dominated_by_p (CDI_DOMINATORS, loop->latch, exit->src))
return false; return false;
niter->assumptions = boolean_false_node; niter->assumptions = boolean_false_node;
...@@ -2568,6 +2572,11 @@ record_estimate (struct loop *loop, tree bound, double_int i_bound, ...@@ -2568,6 +2572,11 @@ record_estimate (struct loop *loop, tree bound, double_int i_bound,
loop->bounds = elt; loop->bounds = elt;
} }
/* If statement is executed on every path to the loop latch, we can directly
infer the upper bound on the # of iterations of the loop. */
if (!dominated_by_p (CDI_DOMINATORS, loop->latch, gimple_bb (at_stmt)))
return;
/* Update the number of iteration estimates according to the bound. /* Update the number of iteration estimates according to the bound.
If at_stmt is an exit then the loop latch is executed at most BOUND times, If at_stmt is an exit then the loop latch is executed at most BOUND times,
otherwise it can be executed BOUND + 1 times. We will lower the estimate otherwise it can be executed BOUND + 1 times. We will lower the estimate
...@@ -2651,7 +2660,6 @@ struct ilb_data ...@@ -2651,7 +2660,6 @@ struct ilb_data
{ {
struct loop *loop; struct loop *loop;
gimple stmt; gimple stmt;
bool reliable;
}; };
static bool static bool
...@@ -2660,7 +2668,7 @@ idx_infer_loop_bounds (tree base, tree *idx, void *dta) ...@@ -2660,7 +2668,7 @@ idx_infer_loop_bounds (tree base, tree *idx, void *dta)
struct ilb_data *data = (struct ilb_data *) dta; struct ilb_data *data = (struct ilb_data *) dta;
tree ev, init, step; tree ev, init, step;
tree low, high, type, next; tree low, high, type, next;
bool sign, upper = data->reliable, at_end = false; bool sign, upper = true, at_end = false;
struct loop *loop = data->loop; struct loop *loop = data->loop;
if (TREE_CODE (base) != ARRAY_REF) if (TREE_CODE (base) != ARRAY_REF)
...@@ -2737,14 +2745,12 @@ idx_infer_loop_bounds (tree base, tree *idx, void *dta) ...@@ -2737,14 +2745,12 @@ idx_infer_loop_bounds (tree base, tree *idx, void *dta)
STMT is guaranteed to be executed in every iteration of LOOP.*/ STMT is guaranteed to be executed in every iteration of LOOP.*/
static void static void
infer_loop_bounds_from_ref (struct loop *loop, gimple stmt, tree ref, infer_loop_bounds_from_ref (struct loop *loop, gimple stmt, tree ref)
bool reliable)
{ {
struct ilb_data data; struct ilb_data data;
data.loop = loop; data.loop = loop;
data.stmt = stmt; data.stmt = stmt;
data.reliable = reliable;
for_each_index (&ref, idx_infer_loop_bounds, &data); for_each_index (&ref, idx_infer_loop_bounds, &data);
} }
...@@ -2753,7 +2759,7 @@ infer_loop_bounds_from_ref (struct loop *loop, gimple stmt, tree ref, ...@@ -2753,7 +2759,7 @@ infer_loop_bounds_from_ref (struct loop *loop, gimple stmt, tree ref,
executed in every iteration of LOOP. */ executed in every iteration of LOOP. */
static void static void
infer_loop_bounds_from_array (struct loop *loop, gimple stmt, bool reliable) infer_loop_bounds_from_array (struct loop *loop, gimple stmt)
{ {
if (is_gimple_assign (stmt)) if (is_gimple_assign (stmt))
{ {
...@@ -2763,10 +2769,10 @@ infer_loop_bounds_from_array (struct loop *loop, gimple stmt, bool reliable) ...@@ -2763,10 +2769,10 @@ infer_loop_bounds_from_array (struct loop *loop, gimple stmt, bool reliable)
/* For each memory access, analyze its access function /* For each memory access, analyze its access function
and record a bound on the loop iteration domain. */ and record a bound on the loop iteration domain. */
if (REFERENCE_CLASS_P (op0)) if (REFERENCE_CLASS_P (op0))
infer_loop_bounds_from_ref (loop, stmt, op0, reliable); infer_loop_bounds_from_ref (loop, stmt, op0);
if (REFERENCE_CLASS_P (op1)) if (REFERENCE_CLASS_P (op1))
infer_loop_bounds_from_ref (loop, stmt, op1, reliable); infer_loop_bounds_from_ref (loop, stmt, op1);
} }
else if (is_gimple_call (stmt)) else if (is_gimple_call (stmt))
{ {
...@@ -2775,13 +2781,13 @@ infer_loop_bounds_from_array (struct loop *loop, gimple stmt, bool reliable) ...@@ -2775,13 +2781,13 @@ infer_loop_bounds_from_array (struct loop *loop, gimple stmt, bool reliable)
lhs = gimple_call_lhs (stmt); lhs = gimple_call_lhs (stmt);
if (lhs && REFERENCE_CLASS_P (lhs)) if (lhs && REFERENCE_CLASS_P (lhs))
infer_loop_bounds_from_ref (loop, stmt, lhs, reliable); infer_loop_bounds_from_ref (loop, stmt, lhs);
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
arg = gimple_call_arg (stmt, i); arg = gimple_call_arg (stmt, i);
if (REFERENCE_CLASS_P (arg)) if (REFERENCE_CLASS_P (arg))
infer_loop_bounds_from_ref (loop, stmt, arg, reliable); infer_loop_bounds_from_ref (loop, stmt, arg);
} }
} }
} }
...@@ -2910,14 +2916,15 @@ infer_loop_bounds_from_undefined (struct loop *loop) ...@@ -2910,14 +2916,15 @@ infer_loop_bounds_from_undefined (struct loop *loop)
/* If BB is not executed in each iteration of the loop, we cannot /* If BB is not executed in each iteration of the loop, we cannot
use the operations in it to infer reliable upper bound on the use the operations in it to infer reliable upper bound on the
# of iterations of the loop. However, we can use it as a guess. */ # of iterations of the loop. However, we can use it as a guess.
Reliable guesses come only from array bounds. */
reliable = dominated_by_p (CDI_DOMINATORS, loop->latch, bb); reliable = dominated_by_p (CDI_DOMINATORS, loop->latch, bb);
for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
{ {
gimple stmt = gsi_stmt (bsi); gimple stmt = gsi_stmt (bsi);
infer_loop_bounds_from_array (loop, stmt, reliable); infer_loop_bounds_from_array (loop, stmt);
if (reliable) if (reliable)
{ {
...@@ -3078,7 +3085,7 @@ estimate_numbers_of_iterations_loop (struct loop *loop) ...@@ -3078,7 +3085,7 @@ estimate_numbers_of_iterations_loop (struct loop *loop)
likely_exit = single_likely_exit (loop); likely_exit = single_likely_exit (loop);
FOR_EACH_VEC_ELT (edge, exits, i, ex) FOR_EACH_VEC_ELT (edge, exits, i, ex)
{ {
if (!number_of_iterations_exit (loop, ex, &niter_desc, false)) if (!number_of_iterations_exit (loop, ex, &niter_desc, false, false))
continue; continue;
niter = niter_desc.niter; niter = niter_desc.niter;
......
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