aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-ivopts.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.c')
-rw-r--r--gcc/tree-ssa-loop-ivopts.c41
1 files changed, 27 insertions, 14 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 41c3794..ce5c05c 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -3745,13 +3745,12 @@ may_eliminate_iv (struct ivopts_data *data,
tree nit, period;
struct loop *loop = data->current_loop;
aff_tree bnd;
- double_int period_value, max_niter;
if (TREE_CODE (cand->iv->step) != INTEGER_CST)
return false;
- /* For now works only for exits that dominate the loop latch. TODO -- extend
- for other conditions inside loop body. */
+ /* For now works only for exits that dominate the loop latch.
+ TODO: extend to other conditions inside loop body. */
ex_bb = bb_for_stmt (use->stmt);
if (use->stmt != last_stmt (ex_bb)
|| TREE_CODE (use->stmt) != COND_EXPR)
@@ -3769,19 +3768,33 @@ may_eliminate_iv (struct ivopts_data *data,
if (!nit)
return false;
- /* Determine whether we may use the variable to test whether niter iterations
- elapsed. This is the case iff the period of the induction variable is
- greater than the number of iterations. */
+ /* Determine whether we can use the variable to test the exit condition.
+ This is the case iff the period of the induction variable is greater
+ than the number of iterations for which the exit condition is true. */
period = iv_period (cand->iv);
- if (!period)
- return false;
- /* Compare the period with the estimate on the number of iterations of the
- loop. */
- if (!estimated_loop_iterations (loop, true, &max_niter))
- return false;
- period_value = tree_to_double_int (period);
- if (double_int_ucmp (period_value, max_niter) <= 0)
+ /* If the number of iterations is constant, compare against it directly. */
+ if (TREE_CODE (nit) == INTEGER_CST)
+ {
+ if (!tree_int_cst_lt (nit, period))
+ return false;
+ }
+
+ /* If not, and if this is the only possible exit of the loop, see whether
+ we can get a conservative estimate on the number of iterations of the
+ entire loop and compare against that instead. */
+ else if (loop_only_exit_p (loop, exit))
+ {
+ double_int period_value, max_niter;
+ if (!estimated_loop_iterations (loop, true, &max_niter))
+ return false;
+ period_value = tree_to_double_int (period);
+ if (double_int_ucmp (max_niter, period_value) >= 0)
+ return false;
+ }
+
+ /* Otherwise, punt. */
+ else
return false;
cand_value_at (loop, cand, use->stmt, nit, &bnd);