aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-niter.c
diff options
context:
space:
mode:
authorBin Cheng <bin.cheng@arm.com>2016-07-15 09:04:57 +0000
committerBin Cheng <amker@gcc.gnu.org>2016-07-15 09:04:57 +0000
commit43aabfcfd4139e4c9e7b868199e09b97e66010bc (patch)
treebf2cd011c65849144b67a4d65d74e9dc61f556d8 /gcc/tree-ssa-loop-niter.c
parentafc89e58498ef6a275d4e018d26b6fca3940ef1e (diff)
downloadgcc-43aabfcfd4139e4c9e7b868199e09b97e66010bc.zip
gcc-43aabfcfd4139e4c9e7b868199e09b97e66010bc.tar.gz
gcc-43aabfcfd4139e4c9e7b868199e09b97e66010bc.tar.bz2
tree-scalar-evolution.c (simple_iv_with_niters): New funcion.
* tree-scalar-evolution.c (simple_iv_with_niters): New funcion. (derive_simple_iv_with_niters): New function. (simple_iv): Rewrite using simple_iv_with_niters. * tree-scalar-evolution.h (simple_iv_with_niters): New decl. * tree-ssa-loop-niter.c (number_of_iterations_exit_assumptions): New function. (number_of_iterations_exit): Rewrite using above function. * tree-ssa-loop-niter.h (number_of_iterations_exit_assumptions): New Decl. gcc/testsuite * gcc.dg/tree-ssa/loop-41.c: New test. From-SVN: r238367
Diffstat (limited to 'gcc/tree-ssa-loop-niter.c')
-rw-r--r--gcc/tree-ssa-loop-niter.c94
1 files changed, 47 insertions, 47 deletions
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 182753c..d96c03b 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -2176,20 +2176,17 @@ loop_only_exit_p (const struct loop *loop, const_edge exit)
}
/* Stores description of number of iterations of LOOP derived from
- EXIT (an exit edge of the LOOP) in NITER. Returns true if some
- useful information could be derived (and fields of NITER has
- meaning described in comments at struct tree_niter_desc
- declaration), false otherwise. If WARN is true and
- -Wunsafe-loop-optimizations was given, warn if the optimizer is going to use
- potentially unsafe assumptions.
+ EXIT (an exit edge of the LOOP) in NITER. Returns true if some useful
+ information could be derived (and fields of NITER have meaning described
+ in comments at struct tree_niter_desc declaration), false otherwise.
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).
*/
bool
-number_of_iterations_exit (struct loop *loop, edge exit,
- struct tree_niter_desc *niter,
- bool warn, bool every_iteration)
+number_of_iterations_exit_assumptions (struct loop *loop, edge exit,
+ struct tree_niter_desc *niter,
+ bool every_iteration)
{
gimple *last;
gcond *stmt;
@@ -2241,9 +2238,16 @@ number_of_iterations_exit (struct loop *loop, edge exit,
&& !POINTER_TYPE_P (type))
return false;
- if (!simple_iv (loop, loop_containing_stmt (stmt), op0, &iv0, false))
+ tree iv0_niters = NULL_TREE;
+ if (!simple_iv_with_niters (loop, loop_containing_stmt (stmt),
+ op0, &iv0, &iv0_niters, false))
return false;
- if (!simple_iv (loop, loop_containing_stmt (stmt), op1, &iv1, false))
+ tree iv1_niters = NULL_TREE;
+ if (!simple_iv_with_niters (loop, loop_containing_stmt (stmt),
+ op1, &iv1, &iv1_niters, false))
+ return false;
+ /* Give up on complicated case. */
+ if (iv0_niters && iv1_niters)
return false;
/* We don't want to see undefined signed overflow warnings while
@@ -2259,6 +2263,24 @@ number_of_iterations_exit (struct loop *loop, edge exit,
return false;
}
+ /* Incorporate additional assumption implied by control iv. */
+ tree iv_niters = iv0_niters ? iv0_niters : iv1_niters;
+ if (iv_niters)
+ {
+ tree assumption = fold_build2 (LE_EXPR, boolean_type_node, niter->niter,
+ fold_convert (TREE_TYPE (niter->niter),
+ iv_niters));
+
+ if (!integer_nonzerop (assumption))
+ niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
+ niter->assumptions, assumption);
+
+ /* Refine upper bound if possible. */
+ if (TREE_CODE (iv_niters) == INTEGER_CST
+ && niter->max > wi::to_widest (iv_niters))
+ niter->max = wi::to_widest (iv_niters);
+ }
+
if (optimize >= 3)
{
niter->assumptions = simplify_using_outer_evolutions (loop,
@@ -2281,44 +2303,22 @@ number_of_iterations_exit (struct loop *loop, edge exit,
if (TREE_CODE (niter->niter) == INTEGER_CST)
niter->max = wi::to_widest (niter->niter);
- if (integer_onep (niter->assumptions))
- return true;
-
- /* With -funsafe-loop-optimizations we assume that nothing bad can happen.
- But if we can prove that there is overflow or some other source of weird
- behavior, ignore the loop even with -funsafe-loop-optimizations. */
- if (integer_zerop (niter->assumptions) || !single_exit (loop))
- return false;
-
- if (flag_unsafe_loop_optimizations)
- niter->assumptions = boolean_true_node;
+ return (!integer_zerop (niter->assumptions));
+}
- if (warn)
- {
- const char *wording;
- location_t loc = gimple_location (stmt);
-
- /* We can provide a more specific warning if one of the operator is
- constant and the other advances by +1 or -1. */
- if (!integer_zerop (iv1.step)
- ? (integer_zerop (iv0.step)
- && (integer_onep (iv1.step) || integer_all_onesp (iv1.step)))
- : (integer_onep (iv0.step) || integer_all_onesp (iv0.step)))
- wording =
- flag_unsafe_loop_optimizations
- ? N_("assuming that the loop is not infinite")
- : N_("cannot optimize possibly infinite loops");
- else
- wording =
- flag_unsafe_loop_optimizations
- ? N_("assuming that the loop counter does not overflow")
- : N_("cannot optimize loop, the loop counter may overflow");
+/* Like number_of_iterations_exit, but return TRUE only if the niter
+ information holds unconditionally. */
- warning_at ((LOCATION_LINE (loc) > 0) ? loc : input_location,
- OPT_Wunsafe_loop_optimizations, "%s", gettext (wording));
- }
+bool
+number_of_iterations_exit (struct loop *loop, edge exit,
+ struct tree_niter_desc *niter,
+ bool, bool every_iteration)
+{
+ if (!number_of_iterations_exit_assumptions (loop, exit, niter,
+ every_iteration))
+ return false;
- return flag_unsafe_loop_optimizations;
+ return (integer_nonzerop (niter->assumptions));
}
/* Try to determine the number of iterations of LOOP. If we succeed,