OSDN Git Service

* doc/loop.texi: Document number_of_latch_executions and
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 10 Dec 2006 23:34:20 +0000 (23:34 +0000)
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 10 Dec 2006 23:34:20 +0000 (23:34 +0000)
number_of_cond_exit_executions.
* tree-scalar-evolution.c (compute_overall_effect_of_inner_loop,
chrec_is_positive, number_of_iterations_for_all_loops,
scev_const_prop): Use number_of_latch_executions.
(set_nb_iterations_in_loop): Do not increase the value of the
number of iterations.
(number_of_iterations_in_loop): Renamed to ...
(number_of_latch_executions): ... this.
(number_of_exit_cond_executions): New function.
* tree-scalar-evolution.h (number_of_iterations_in_loop): Declaration
removed.
(number_of_latch_executions, number_of_exit_cond_executions): Declare.
* tree-ssa-loop-ivcanon.c (canonicalize_loop_induction_variables): Use
number_of_latch_executions.
* tree-data-ref.c (get_number_of_iters_for_loop): Use
number_of_exit_cond_executions.
* tree-vect-analyze.c (vect_get_loop_niters): Ditto.
* cfgloop.h (struct loop): Improve description of the nb_iterations
field.

* gcc.dg/tree-ssa/loop-17.c: Update outcome.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119718 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cfgloop.h
gcc/doc/loop.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/loop-17.c
gcc/tree-data-ref.c
gcc/tree-scalar-evolution.c
gcc/tree-scalar-evolution.h
gcc/tree-ssa-loop-ivcanon.c
gcc/tree-vect-analyze.c

index cef245c..b069e0f 100644 (file)
@@ -1,3 +1,26 @@
+2006-12-10  Zdenek Dvorak <dvorakz@suse.cz>
+
+       * doc/loop.texi: Document number_of_latch_executions and
+       number_of_cond_exit_executions.
+       * tree-scalar-evolution.c (compute_overall_effect_of_inner_loop,
+       chrec_is_positive, number_of_iterations_for_all_loops,
+       scev_const_prop): Use number_of_latch_executions.
+       (set_nb_iterations_in_loop): Do not increase the value of the
+       number of iterations.
+       (number_of_iterations_in_loop): Renamed to ...
+       (number_of_latch_executions): ... this.
+       (number_of_exit_cond_executions): New function.
+       * tree-scalar-evolution.h (number_of_iterations_in_loop): Declaration
+       removed.
+       (number_of_latch_executions, number_of_exit_cond_executions): Declare.
+       * tree-ssa-loop-ivcanon.c (canonicalize_loop_induction_variables): Use
+       number_of_latch_executions.
+       * tree-data-ref.c (get_number_of_iters_for_loop): Use
+       number_of_exit_cond_executions.
+       * tree-vect-analyze.c (vect_get_loop_niters): Ditto.
+       * cfgloop.h (struct loop): Improve description of the nb_iterations
+       field.
+
 2006-12-10  Daniel Berlin  <dberlin@dberlin.org>
 
        * tree-ssa-alias.c (compact_name_tags): Use sort_tags_by_id.
index d523acf..4a13a6a 100644 (file)
@@ -119,10 +119,10 @@ struct loop
   /* Auxiliary info specific to a pass.  */
   void *aux;
 
-  /* The probable number of times the loop is executed at runtime.
+  /* The number of times the latch of the loop is executed.
      This is an INTEGER_CST or an expression containing symbolic
      names.  Don't access this field directly:
-     number_of_iterations_in_loop computes and caches the computed
+     number_of_latch_executions computes and caches the computed
      information in this field.  */
   tree nb_iterations;
 
index 354241f..1b189c7 100644 (file)
@@ -397,13 +397,15 @@ calculations.
 @cindex Number of iterations analysis
 
 Both on GIMPLE and on RTL, there are functions available to determine
-the number of iterations of a loop, with a similar interface.  In many
-cases, it is not possible to determine number of iterations
-unconditionally -- the determined number is correct only if some
-assumptions are satisfied.  The analysis tries to verify these
-conditions using the information contained in the program; if it fails,
-the conditions are returned together with the result.  The following
-information and conditions are provided by the analysis:
+the number of iterations of a loop, with a similar interface.  The
+number of iterations of a loop in GCC is defined as the number of
+executions of the loop latch.  In many cases, it is not possible to
+determine the number of iterations unconditionally -- the determined
+number is correct only if some assumptions are satisfied.  The analysis
+tries to verify these conditions using the information contained in the
+program; if it fails, the conditions are returned together with the
+result.  The following information and conditions are provided by the
+analysis:
 
 @itemize
 @item @code{assumptions}: If this condition is false, the rest of
@@ -431,16 +433,16 @@ number of iterations -- @code{find_loop_niter} on GIMPLE and
 @code{find_simple_exit} on RTL.  Finally, there are functions that
 provide the same information, but additionally cache it, so that
 repeated calls to number of iterations are not so costly --
-@code{number_of_iterations_in_loop} on GIMPLE and
-@code{get_simple_loop_desc} on RTL.
+@code{number_of_latch_executions} on GIMPLE and @code{get_simple_loop_desc}
+on RTL.
 
 Note that some of these functions may behave slightly differently than
 others -- some of them return only the expression for the number of
 iterations, and fail if there are some assumptions.  The function
-@code{number_of_iterations_in_loop} works only for single-exit loops,
-and it returns the value for number of iterations higher by one with
-respect to all other functions (i.e., it returns number of executions of
-the exit statement, not of the loop latch).
+@code{number_of_latch_executions} works only for single-exit loops.
+The function @code{number_of_cond_exit_executions} can be used to
+determine number of executions of the exit condition of a single-exit
+loop (i.e., the @code{number_of_latch_executions} increased by one).
 
 @node Dependency analysis
 @section Data Dependency Analysis
index cfdc64b..0b9b664 100644 (file)
@@ -1,3 +1,7 @@
+2006-12-10  Zdenek Dvorak <dvorakz@suse.cz>
+
+       * gcc.dg/tree-ssa/loop-17.c: Update outcome.
+
 2006-12-10  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/23994
index 26e4986..d2903ce 100644 (file)
@@ -15,5 +15,5 @@ int foo (int *p)
   return i;
 }
 
-/* { dg-final { scan-tree-dump "set_nb_iterations_in_loop = 2" "sccp" } } */
+/* { dg-final { scan-tree-dump "set_nb_iterations_in_loop = 1" "sccp" } } */
 /* { dg-final { cleanup-tree-dump "sccp" } } */
index 96d57a0..fdaaaaf 100644 (file)
@@ -2305,7 +2305,7 @@ static tree
 get_number_of_iters_for_loop (int loopnum)
 {
   struct loop *loop = get_loop (loopnum);
-  tree numiter = number_of_iterations_in_loop (loop);
+  tree numiter = number_of_exit_cond_executions (loop);
 
   if (TREE_CODE (numiter) == INTEGER_CST)
     return numiter;
index c668bf2..10d5da5 100644 (file)
@@ -468,20 +468,14 @@ compute_overall_effect_of_inner_loop (struct loop *loop, tree evolution_fn)
       if (CHREC_VARIABLE (evolution_fn) >= (unsigned) loop->num)
        {
          struct loop *inner_loop = get_chrec_loop (evolution_fn);
-         tree nb_iter = number_of_iterations_in_loop (inner_loop);
+         tree nb_iter = number_of_latch_executions (inner_loop);
 
          if (nb_iter == chrec_dont_know)
            return chrec_dont_know;
          else
            {
              tree res;
-             tree type = chrec_type (nb_iter);
 
-             /* Number of iterations is off by one (the ssa name we
-                analyze must be defined before the exit).  */
-             nb_iter = chrec_fold_minus (type, nb_iter,
-                                         build_int_cst (type, 1));
-             
              /* evolution_fn is the evolution function in LOOP.  Get
                 its value in the nb_iter-th iteration.  */
              res = chrec_apply (inner_loop->num, evolution_fn, nb_iter);
@@ -510,7 +504,7 @@ bool
 chrec_is_positive (tree chrec, bool *value)
 {
   bool value0, value1, value2;
-  tree type, end_value, nb_iter;
+  tree end_value, nb_iter;
   
   switch (TREE_CODE (chrec))
     {
@@ -533,13 +527,10 @@ chrec_is_positive (tree chrec, bool *value)
       if (!evolution_function_is_affine_p (chrec))
        return false;
 
-      nb_iter = number_of_iterations_in_loop (get_chrec_loop (chrec));
+      nb_iter = number_of_latch_executions (get_chrec_loop (chrec));
       if (chrec_contains_undetermined (nb_iter))
        return false;
 
-      type = chrec_type (nb_iter);
-      nb_iter = chrec_fold_minus (type, nb_iter, build_int_cst (type, 1));
-
 #if 0
       /* TODO -- If the test is after the exit, we may decrease the number of
         iterations by one.  */
@@ -892,19 +883,6 @@ static inline tree
 set_nb_iterations_in_loop (struct loop *loop, 
                           tree res)
 {
-  tree type = chrec_type (res);
-
-  res = chrec_fold_plus (type, res, build_int_cst (type, 1));
-
-  /* FIXME HWI: However we want to store one iteration less than the
-     count of the loop in order to be compatible with the other
-     nb_iter computations in loop-iv.  This also allows the
-     representation of nb_iters that are equal to MAX_INT.  */
-  if (TREE_CODE (res) == INTEGER_CST
-      && (TREE_INT_CST_LOW (res) == 0
-         || TREE_OVERFLOW (res)))
-    res = chrec_dont_know;
-  
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
       fprintf (dump_file, "  (set_nb_iterations_in_loop = ");
@@ -2465,7 +2443,7 @@ resolve_mixers (struct loop *loop, tree chrec)
    the loop body has been executed 6 times.  */
 
 tree 
-number_of_iterations_in_loop (struct loop *loop)
+number_of_latch_executions (struct loop *loop)
 {
   tree res, type;
   edge exit;
@@ -2500,6 +2478,33 @@ end:
   return set_nb_iterations_in_loop (loop, res);
 }
 
+/* Returns the number of executions of the exit condition of LOOP,
+   i.e., the number by one higher than number_of_latch_executions.
+   Note that unline number_of_latch_executions, this number does
+   not necessarily fit in the unsigned variant of the type of
+   the control variable -- if the number of iterations is a constant,
+   we return chrec_dont_know if adding one to number_of_latch_executions
+   overflows; however, in case the number of iterations is symbolic
+   expression, the caller is responsible for dealing with this
+   the possible overflow.  */
+
+tree 
+number_of_exit_cond_executions (struct loop *loop)
+{
+  tree ret = number_of_latch_executions (loop);
+  tree type = chrec_type (ret);
+
+  if (chrec_contains_undetermined (ret))
+    return ret;
+
+  ret = chrec_fold_plus (type, ret, build_int_cst (type, 1));
+  if (TREE_CODE (ret) == INTEGER_CST
+      && TREE_OVERFLOW (ret))
+    return chrec_dont_know;
+
+  return ret;
+}
+
 /* One of the drivers for testing the scalar evolutions analysis.
    This function computes the number of iterations for all the loops
    from the EXIT_CONDITIONS array.  */
@@ -2514,7 +2519,7 @@ number_of_iterations_for_all_loops (VEC(tree,heap) **exit_conditions)
   
   for (i = 0; VEC_iterate (tree, *exit_conditions, i, cond); i++)
     {
-      tree res = number_of_iterations_in_loop (loop_containing_stmt (cond));
+      tree res = number_of_latch_executions (loop_containing_stmt (cond));
       if (chrec_contains_undetermined (res))
        nb_chrec_dont_know_loops++;
       else
@@ -2956,7 +2961,7 @@ scev_const_prop (void)
       if (!exit)
        continue;
 
-      niter = number_of_iterations_in_loop (loop);
+      niter = number_of_latch_executions (loop);
       if (niter == chrec_dont_know
          /* If computing the number of iterations is expensive, it may be
             better not to introduce computations involving it.  */
index 98855b9..464fe8f 100644 (file)
@@ -22,7 +22,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #ifndef GCC_TREE_SCALAR_EVOLUTION_H
 #define GCC_TREE_SCALAR_EVOLUTION_H
 
-extern tree number_of_iterations_in_loop (struct loop *);
+extern tree number_of_latch_executions (struct loop *);
+extern tree number_of_exit_cond_executions (struct loop *);
 extern tree get_loop_exit_condition (struct loop *);
 
 extern void scev_initialize (void);
index 6326801..c26727a 100644 (file)
@@ -279,18 +279,12 @@ canonicalize_loop_induction_variables (struct loop *loop,
   edge exit = NULL;
   tree niter;
 
-  niter = number_of_iterations_in_loop (loop);
+  niter = number_of_latch_executions (loop);
   if (TREE_CODE (niter) == INTEGER_CST)
     {
       exit = single_exit (loop);
       if (!just_once_each_iteration_p (loop, exit->src))
        return false;
-
-      /* The result of number_of_iterations_in_loop is by one higher than
-        we expect (i.e. it returns number of executions of the exit
-        condition, not of the loop latch edge).  */
-      niter = fold_build2 (MINUS_EXPR, TREE_TYPE (niter), niter,
-                          build_int_cst (TREE_TYPE (niter), 1));
     }
   else
     {
index 3189573..7506150 100644 (file)
@@ -2393,7 +2393,7 @@ vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
   if (vect_print_dump_info (REPORT_DETAILS))
     fprintf (vect_dump, "=== get_loop_niters ===");
 
-  niters = number_of_iterations_in_loop (loop);
+  niters = number_of_exit_cond_executions (loop);
 
   if (niters != NULL_TREE
       && niters != chrec_dont_know)