cfgloop.c (record_niter_bound): Record likely upper bounds.
authorJan Hubicka <hubicka@ucw.cz>
Fri, 27 May 2016 12:10:34 +0000 (14:10 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 27 May 2016 12:10:34 +0000 (12:10 +0000)
* cfgloop.c (record_niter_bound): Record likely upper bounds.
(likely_max_stmt_executions_int, get_likely_max_loop_iterations,
get_likely_max_loop_iterations_int): New.
* cfgloop.h (struct loop): Add nb_iterations_likely_upper_bound,
any_likely_upper_bound.
(get_likely_max_loop_iterations_int, get_likely_max_loop_iterations):
Declare.
* cfgloopmanip.c (copy_loop_info): Copy likely upper bounds.
* loop-unroll.c (unroll_loop_constant_iterations): Update likely
upper bound.
(unroll_loop_constant_iterations): Likewise.
(unroll_loop_runtime_iterations): Likewise.
* lto-streamer-in.c (input_cfg): Stream likely upper bounds.
* lto-streamer-out.c (output_cfg): Likewise.
* tree-ssa-loop-ivcanon.c (try_peel_loop): Update likely upper
bounds.
(canonicalize_loop_induction_variables): Dump likely upper bounds.
* tree-ssa-loop-niter.c (record_estimate): Record likely upper bounds.
(likely_max_loop_iterations): New.
(likely_max_loop_iterations_int): New.
(likely_max_stmt_executions): New.
* tree-ssa-loop-niter.h (likely_max_loop_iterations,
likely_max_loop_iterations_int, likely_max_stmt_executions_int,
likely_max_stmt_executions): Declare.

From-SVN: r236816

gcc/ChangeLog
gcc/cfgloop.c
gcc/cfgloop.h
gcc/cfgloopmanip.c
gcc/loop-unroll.c
gcc/lto-streamer-in.c
gcc/lto-streamer-out.c
gcc/tree-ssa-loop-ivcanon.c
gcc/tree-ssa-loop-niter.c
gcc/tree-ssa-loop-niter.h

index 14ba165d82c034923121f783b1750ce40084fa61..eb34a284658ac1b1a1583b870f16f8e5f209cf96 100644 (file)
@@ -1,3 +1,30 @@
+2016-05-27  Jan Hubicka  <hubicka@ucw.cz>
+
+       * cfgloop.c (record_niter_bound): Record likely upper bounds.
+       (likely_max_stmt_executions_int, get_likely_max_loop_iterations,
+       get_likely_max_loop_iterations_int): New.
+       * cfgloop.h (struct loop): Add nb_iterations_likely_upper_bound,
+       any_likely_upper_bound.
+       (get_likely_max_loop_iterations_int, get_likely_max_loop_iterations):
+       Declare.
+       * cfgloopmanip.c (copy_loop_info): Copy likely upper bounds.
+       * loop-unroll.c (unroll_loop_constant_iterations): Update likely
+       upper bound.
+       (unroll_loop_constant_iterations): Likewise.
+       (unroll_loop_runtime_iterations): Likewise.
+       * lto-streamer-in.c (input_cfg): Stream likely upper bounds.
+       * lto-streamer-out.c (output_cfg): Likewise.
+       * tree-ssa-loop-ivcanon.c (try_peel_loop): Update likely upper
+       bounds.
+       (canonicalize_loop_induction_variables): Dump likely upper bounds.
+       * tree-ssa-loop-niter.c (record_estimate): Record likely upper bounds.
+       (likely_max_loop_iterations): New.
+       (likely_max_loop_iterations_int): New.
+       (likely_max_stmt_executions): New.
+       * tree-ssa-loop-niter.h (likely_max_loop_iterations,
+       likely_max_loop_iterations_int, likely_max_stmt_executions_int,
+       likely_max_stmt_executions): Declare.
+
 2016-05-27  Marek Polacek  <polacek@redhat.com>
 
        PR middle-end/71308
index 02234173b08ff8280e1499223ed5dfabed9aebc6..27ccfb226c9778119046c3c95fff978533291451 100644 (file)
@@ -1790,6 +1790,11 @@ record_niter_bound (struct loop *loop, const widest_int &i_bound,
     {
       loop->any_upper_bound = true;
       loop->nb_iterations_upper_bound = i_bound;
+      if (!loop->any_likely_upper_bound)
+       {
+         loop->any_likely_upper_bound = true;
+         loop->nb_iterations_likely_upper_bound = i_bound;
+       }
     }
   if (realistic
       && (!loop->any_estimate
@@ -1798,6 +1803,13 @@ record_niter_bound (struct loop *loop, const widest_int &i_bound,
       loop->any_estimate = true;
       loop->nb_iterations_estimate = i_bound;
     }
+  if (!realistic
+      && (!loop->any_likely_upper_bound
+          || wi::ltu_p (i_bound, loop->nb_iterations_likely_upper_bound)))
+    {
+      loop->any_likely_upper_bound = true;
+      loop->nb_iterations_likely_upper_bound = i_bound;
+    }
 
   /* If an upper bound is smaller than the realistic estimate of the
      number of iterations, use the upper bound instead.  */
@@ -1806,6 +1818,11 @@ record_niter_bound (struct loop *loop, const widest_int &i_bound,
       && wi::ltu_p (loop->nb_iterations_upper_bound,
                    loop->nb_iterations_estimate))
     loop->nb_iterations_estimate = loop->nb_iterations_upper_bound;
+  if (loop->any_upper_bound
+      && loop->any_likely_upper_bound
+      && wi::ltu_p (loop->nb_iterations_upper_bound,
+                   loop->nb_iterations_likely_upper_bound))
+    loop->nb_iterations_likely_upper_bound = loop->nb_iterations_upper_bound;
 }
 
 /* Similar to get_estimated_loop_iterations, but returns the estimate only
@@ -1847,6 +1864,25 @@ max_stmt_executions_int (struct loop *loop)
   return snit < 0 ? -1 : snit;
 }
 
+/* Returns an likely upper bound on the number of executions of statements
+   in the LOOP.  For statements before the loop exit, this exceeds
+   the number of execution of the latch by one.  */
+
+HOST_WIDE_INT
+likely_max_stmt_executions_int (struct loop *loop)
+{
+  HOST_WIDE_INT nit = get_likely_max_loop_iterations_int (loop);
+  HOST_WIDE_INT snit;
+
+  if (nit == -1)
+    return -1;
+
+  snit = (HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) nit + 1);
+
+  /* If the computation overflows, return -1.  */
+  return snit < 0 ? -1 : snit;
+}
+
 /* Sets NIT to the estimated number of executions of the latch of the
    LOOP.  If we have no reliable estimate, the function returns false, otherwise
    returns true.  */
@@ -1905,6 +1941,40 @@ get_max_loop_iterations_int (struct loop *loop)
   return hwi_nit < 0 ? -1 : hwi_nit;
 }
 
+/* Sets NIT to an upper bound for the maximum number of executions of the
+   latch of the LOOP.  If we have no reliable estimate, the function returns
+   false, otherwise returns true.  */
+
+bool
+get_likely_max_loop_iterations (struct loop *loop, widest_int *nit)
+{
+  if (!loop->any_likely_upper_bound)
+    return false;
+
+  *nit = loop->nb_iterations_likely_upper_bound;
+  return true;
+}
+
+/* Similar to get_max_loop_iterations, but returns the estimate only
+   if it fits to HOST_WIDE_INT.  If this is not the case, or the estimate
+   on the number of iterations of LOOP could not be derived, returns -1.  */
+
+HOST_WIDE_INT
+get_likely_max_loop_iterations_int (struct loop *loop)
+{
+  widest_int nit;
+  HOST_WIDE_INT hwi_nit;
+
+  if (!get_likely_max_loop_iterations (loop, &nit))
+    return -1;
+
+  if (!wi::fits_shwi_p (nit))
+    return -1;
+  hwi_nit = nit.to_shwi ();
+
+  return hwi_nit < 0 ? -1 : hwi_nit;
+}
+
 /* Returns the loop depth of the loop BB belongs to.  */
 
 int
index 173fda84ba4d752c46667075fcd4a8d2502bc410..aba2988c99e3d83d282f6583ce6ae2de6a4ca5c5 100644 (file)
@@ -160,6 +160,8 @@ struct GTY ((chain_next ("%h.next"))) loop {
      valid if any_upper_bound is true.  */
   widest_int nb_iterations_upper_bound;
 
+  widest_int nb_iterations_likely_upper_bound;
+
   /* An integer giving an estimate on nb_iterations.  Unlike
      nb_iterations_upper_bound, there is no guarantee that it is at least
      nb_iterations.  */
@@ -167,6 +169,7 @@ struct GTY ((chain_next ("%h.next"))) loop {
 
   bool any_upper_bound;
   bool any_estimate;
+  bool any_likely_upper_bound;
 
   /* True if the loop can be parallel.  */
   bool can_be_parallel;
@@ -776,8 +779,10 @@ loop_outermost (struct loop *loop)
 extern void record_niter_bound (struct loop *, const widest_int &, bool, bool);
 extern HOST_WIDE_INT get_estimated_loop_iterations_int (struct loop *);
 extern HOST_WIDE_INT get_max_loop_iterations_int (struct loop *);
+extern HOST_WIDE_INT get_likely_max_loop_iterations_int (struct loop *);
 extern bool get_estimated_loop_iterations (struct loop *loop, widest_int *nit);
 extern bool get_max_loop_iterations (struct loop *loop, widest_int *nit);
+extern bool get_likely_max_loop_iterations (struct loop *loop, widest_int *nit);
 extern int bb_loop_depth (const_basic_block);
 
 /* Converts VAL to widest_int.  */
index 2bffb80e284028a832e2d40189040969441c3905..707a130d26a8b1452a16199fa9a5ce3dac8f21c5 100644 (file)
@@ -1016,6 +1016,9 @@ copy_loop_info (struct loop *loop, struct loop *target)
   gcc_checking_assert (!target->any_upper_bound && !target->any_estimate);
   target->any_upper_bound = loop->any_upper_bound;
   target->nb_iterations_upper_bound = loop->nb_iterations_upper_bound;
+  target->any_likely_upper_bound = loop->any_likely_upper_bound;
+  target->nb_iterations_likely_upper_bound
+    = loop->nb_iterations_likely_upper_bound;
   target->any_estimate = loop->any_estimate;
   target->nb_iterations_estimate = loop->nb_iterations_estimate;
   target->estimate_state = loop->estimate_state;
index 4d26e2f7cd1a19131b2443c30a37c1f8ec68509b..97735a89e5876188ce697554ae9bd5164bef0eeb 100644 (file)
@@ -523,6 +523,11 @@ unroll_loop_constant_iterations (struct loop *loop)
            loop->nb_iterations_estimate -= exit_mod;
          else
            loop->any_estimate = false;
+         if (loop->any_likely_upper_bound
+             && wi::leu_p (exit_mod, loop->nb_iterations_likely_upper_bound))
+           loop->nb_iterations_likely_upper_bound -= exit_mod;
+         else
+           loop->any_likely_upper_bound = false;
        }
 
       bitmap_set_bit (wont_exit, 1);
@@ -566,6 +571,11 @@ unroll_loop_constant_iterations (struct loop *loop)
            loop->nb_iterations_estimate -= exit_mod + 1;
          else
            loop->any_estimate = false;
+         if (loop->any_likely_upper_bound
+             && wi::leu_p (exit_mod + 1, loop->nb_iterations_likely_upper_bound))
+           loop->nb_iterations_likely_upper_bound -= exit_mod + 1;
+         else
+           loop->any_likely_upper_bound = false;
          desc->noloop_assumptions = NULL_RTX;
 
          bitmap_set_bit (wont_exit, 0);
@@ -619,6 +629,9 @@ unroll_loop_constant_iterations (struct loop *loop)
   if (loop->any_estimate)
     loop->nb_iterations_estimate
       = wi::udiv_trunc (loop->nb_iterations_estimate, max_unroll + 1);
+  if (loop->any_likely_upper_bound)
+    loop->nb_iterations_likely_upper_bound
+      = wi::udiv_trunc (loop->nb_iterations_likely_upper_bound, max_unroll + 1);
   desc->niter_expr = GEN_INT (desc->niter);
 
   /* Remove the edges.  */
@@ -1059,6 +1072,9 @@ unroll_loop_runtime_iterations (struct loop *loop)
   if (loop->any_estimate)
     loop->nb_iterations_estimate
       = wi::udiv_trunc (loop->nb_iterations_estimate, max_unroll + 1);
+  if (loop->any_likely_upper_bound)
+    loop->nb_iterations_likely_upper_bound
+      = wi::udiv_trunc (loop->nb_iterations_likely_upper_bound, max_unroll + 1);
   if (exit_at_end)
     {
       desc->niter_expr =
@@ -1070,6 +1086,11 @@ unroll_loop_runtime_iterations (struct loop *loop)
        --loop->nb_iterations_estimate;
       else
        loop->any_estimate = false;
+      if (loop->any_likely_upper_bound
+         && loop->nb_iterations_likely_upper_bound != 0)
+       --loop->nb_iterations_likely_upper_bound;
+      else
+       loop->any_likely_upper_bound = false;
     }
 
   if (dump_file)
index 3a353cd04370e03336ed0451171fc4b85d427963..00db94eac6bead812e4b2c81fecec278ccdcf873 100644 (file)
@@ -835,6 +835,9 @@ input_cfg (struct lto_input_block *ib, struct data_in *data_in,
       loop->any_upper_bound = streamer_read_hwi (ib);
       if (loop->any_upper_bound)
        loop->nb_iterations_upper_bound = streamer_read_wi (ib);
+      loop->any_likely_upper_bound = streamer_read_hwi (ib);
+      if (loop->any_likely_upper_bound)
+       loop->nb_iterations_likely_upper_bound = streamer_read_wi (ib);
       loop->any_estimate = streamer_read_hwi (ib);
       if (loop->any_estimate)
        loop->nb_iterations_estimate = streamer_read_wi (ib);
index 35e58fd24cc911da91f5c79ea9df0d8815548283..ed6f7482dbdc5f13ad71b8e09f16932320a9a091 100644 (file)
@@ -1925,6 +1925,9 @@ output_cfg (struct output_block *ob, struct function *fn)
       streamer_write_hwi (ob, loop->any_upper_bound);
       if (loop->any_upper_bound)
        streamer_write_wi (ob, loop->nb_iterations_upper_bound);
+      streamer_write_hwi (ob, loop->any_likely_upper_bound);
+      if (loop->any_likely_upper_bound)
+       streamer_write_wi (ob, loop->nb_iterations_likely_upper_bound);
       streamer_write_hwi (ob, loop->any_estimate);
       if (loop->any_estimate)
        streamer_write_wi (ob, loop->nb_iterations_estimate);
index e8f67953231f54ce2517a55e1587ccf646b8f74c..de447f40e78576bf07894727b03db2b11332445b 100644 (file)
@@ -1036,6 +1036,8 @@ try_peel_loop (struct loop *loop,
     }
   if (loop->any_upper_bound)
     loop->nb_iterations_upper_bound -= npeel;
+  if (loop->any_likely_upper_bound)
+    loop->nb_iterations_likely_upper_bound -= npeel;
   loop->nb_iterations_estimate = 0;
   /* Make sure to mark loop cold so we do not try to peel it more.  */
   scale_loop_profile (loop, 1, 0);
@@ -1107,6 +1109,12 @@ canonicalize_loop_induction_variables (struct loop *loop,
       fprintf (dump_file, "Loop %d iterates at most %i times.\n", loop->num,
               (int)maxiter);
     }
+  if (dump_file && (dump_flags & TDF_DETAILS)
+      && likely_max_loop_iterations_int (loop) >= 0)
+    {
+      fprintf (dump_file, "Loop likely %d iterates at most %i times.\n", loop->num,
+              (int)likely_max_loop_iterations_int (loop));
+    }
 
   /* Remove exits that are known to be never taken based on loop bound.
      Needs to be called after compilation of max_loop_iterations_int that
index 5afc9b3fdf0284fe9bdae3631e05730d51bff201..e38d2466bb470263fd9d9022f521973fe60f8eef 100644 (file)
@@ -2289,7 +2289,11 @@ number_of_iterations_exit (struct loop *loop, edge exit,
 
   /* If NITER has simplified into a constant, update MAX.  */
   if (TREE_CODE (niter->niter) == INTEGER_CST)
-    niter->max = wi::to_widest (niter->niter);
+    {
+      niter->max = wi::to_widest (niter->niter);
+      record_niter_bound (loop, niter->max, loop_only_exit_p (loop, exit),
+                         true);
+    }
 
   if (integer_onep (niter->assumptions))
     return true;
@@ -2954,8 +2958,6 @@ record_estimate (struct loop *loop, tree bound, const widest_int &i_bound,
     realistic = false;
   else
     gcc_checking_assert (i_bound == wi::to_widest (bound));
-  if (!upper && !realistic)
-    return;
 
   /* If we have a guaranteed upper bound, record it in the appropriate
      list, unless this is an !is_exit bound (i.e. undefined behavior in
@@ -2977,7 +2979,7 @@ record_estimate (struct loop *loop, tree bound, const widest_int &i_bound,
   /* 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;
+    upper = false;
 
   /* 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,
@@ -3850,6 +3852,41 @@ max_loop_iterations_int (struct loop *loop)
   return hwi_nit < 0 ? -1 : hwi_nit;
 }
 
+/* Sets NIT to an likely upper bound for the maximum number of executions of the
+   latch of the LOOP.  If we have no reliable estimate, the function returns
+   false, otherwise returns true.  */
+
+bool
+likely_max_loop_iterations (struct loop *loop, widest_int *nit)
+{
+  /* When SCEV information is available, try to update loop iterations
+     estimate.  Otherwise just return whatever we recorded earlier.  */
+  if (scev_initialized_p ())
+    estimate_numbers_of_iterations_loop (loop);
+
+  return get_likely_max_loop_iterations (loop, nit);
+}
+
+/* Similar to max_loop_iterations, but returns the estimate only
+   if it fits to HOST_WIDE_INT.  If this is not the case, or the estimate
+   on the number of iterations of LOOP could not be derived, returns -1.  */
+
+HOST_WIDE_INT
+likely_max_loop_iterations_int (struct loop *loop)
+{
+  widest_int nit;
+  HOST_WIDE_INT hwi_nit;
+
+  if (!likely_max_loop_iterations (loop, &nit))
+    return -1;
+
+  if (!wi::fits_shwi_p (nit))
+    return -1;
+  hwi_nit = nit.to_shwi ();
+
+  return hwi_nit < 0 ? -1 : hwi_nit;
+}
+
 /* Returns an estimate for the number of executions of statements
    in the LOOP.  For statements before the loop exit, this exceeds
    the number of execution of the latch by one.  */
@@ -3869,7 +3906,7 @@ estimated_stmt_executions_int (struct loop *loop)
   return snit < 0 ? -1 : snit;
 }
 
-/* Sets NIT to the estimated maximum number of executions of the latch of the
+/* Sets NIT to the maximum number of executions of the latch of the
    LOOP, plus one.  If we have no reliable estimate, the function returns
    false, otherwise returns true.  */
 
@@ -3888,6 +3925,25 @@ max_stmt_executions (struct loop *loop, widest_int *nit)
   return wi::gtu_p (*nit, nit_minus_one);
 }
 
+/* Sets NIT to the estimated maximum number of executions of the latch of the
+   LOOP, plus one.  If we have no likely estimate, the function returns
+   false, otherwise returns true.  */
+
+bool
+likely_max_stmt_executions (struct loop *loop, widest_int *nit)
+{
+  widest_int nit_minus_one;
+
+  if (!likely_max_loop_iterations (loop, nit))
+    return false;
+
+  nit_minus_one = *nit;
+
+  *nit += 1;
+
+  return wi::gtu_p (*nit, nit_minus_one);
+}
+
 /* Sets NIT to the estimated number of executions of the latch of the
    LOOP, plus one.  If we have no reliable estimate, the function returns
    false, otherwise returns true.  */
index 84ff0aea11cb18ec040f8386d3dc59bb5492cd04..1b5d111bc3e665fe96f801035cff4c835455163d 100644 (file)
@@ -35,9 +35,13 @@ extern bool estimated_loop_iterations (struct loop *, widest_int *);
 extern HOST_WIDE_INT estimated_loop_iterations_int (struct loop *);
 extern bool max_loop_iterations (struct loop *, widest_int *);
 extern HOST_WIDE_INT max_loop_iterations_int (struct loop *);
+extern bool likely_max_loop_iterations (struct loop *, widest_int *);
+extern HOST_WIDE_INT likely_max_loop_iterations_int (struct loop *);
 extern HOST_WIDE_INT max_stmt_executions_int (struct loop *);
+extern HOST_WIDE_INT likely_max_stmt_executions_int (struct loop *);
 extern HOST_WIDE_INT estimated_stmt_executions_int (struct loop *);
 extern bool max_stmt_executions (struct loop *, widest_int *);
+extern bool likely_max_stmt_executions (struct loop *, widest_int *);
 extern bool estimated_stmt_executions (struct loop *, widest_int *);
 extern void estimate_numbers_of_iterations (void);
 extern bool stmt_dominates_stmt_p (gimple *, gimple *);