On Mon, Oct 1, 2012 at 11:37 AM, Jan Hubicka <hubi...@ucw.cz> wrote:
> Hi,
> this patch commonizes the maximal iteration estimate logic in between SCEV and
> loop-iv.  Both are now using loop->nb_iterations_upper_bound.  I decided to
> keep same API for SCEV code as for RTL code, so I made
> estimated_loop_iterations and max_loop_iterations to not try to recompute
> bounds and ICE when invoked without SCEV fired on.
>
> The patch updates RTL optimizers to use the estimated_loop_iterations and
> max_loop_iterations. This has few advantages:
>   1) loop unroller can now take into account estimates stored into
>      loop structure by earlier pass (I think none exist though)
>      It is however better then using expected_loop_iterations since
>      profile might get out of date with expansion.
>
>   2) loop peeling code now use max iterations bounds. This makes it i.e.
>      to peel vectorizer prologues/epilogues/scalar loops so -fpeel-loops
>      now improves my low iteration count testcase by about 10%
>
>   3) Same for loop unswithcing.
>
> I am not really friend with the new double_int API. I copied some existing
> examples but find it ugly.  Why do we miss operators for comparsions and
> division? Why from_*/to_* can't be a cast at least for basic integer types?
>
> Regtested/bootstrapped x86_64-linux, seems sane?

Yes.  Can you add a testcase or two?  I tweaked RTL unroll/peel after preserving
loops to not blindly unroll/peel everything 8 times (not sure if _I_
added testcases ...).

> I also wonder if loop vectorizer should not update the estimates after
> loop iteration count is reduced by vectorizing.

Probably yes.

Thanks,
Richard.

> Honza
>         * loop-unswitch.c (unswitch_single_loop): Use
>         estimated_loop_iterations_int to prevent unswitching when loop
>         is known to not roll.
>         * tree-ssa-loop-niter.c (estimated_loop_iterations): Do not segfault
>         when SCEV is not initialized.
>         (max_loop_iterations): Likewise.
>         * tree-ssa-loop-unswitch.c (tree_ssa_unswitch_loops): Use
>         estimated_loop_iterations_int to prevent unswithcing when
>         loop is known to not roll.
>         * tree-scalar-evolution.c (scev_initialized_p): New function.
>         * tree-scalar-evolution.h (scev_initialized_p): Likewise.
>         * loop-unroll.c (decide_peel_once_rolling): Use
>         max_loop_iterations_int.
>         (unroll_loop_constant_iterations): Update
>         nb_iterations_upper_bound and nb_iterations_estimate.
>         (decide_unroll_runtime_iterations): Use
>         estimated_loop_iterations or max_loop_iterations;
>         (unroll_loop_runtime_iterations): fix profile updating.
>         (decide_peel_simple): Use estimated_loop_iterations
>         and max_loop_iterations.
>         (decide_unroll_stupid): Use estimated_loop_iterations
>         ad max_loop_iterations.
>         * loop-doloop.c (doloop_modify): Use max_loop_iterations_int.
>         (doloop_optimize): Likewise.
>         * loop-iv.c (iv_number_of_iterations): Use record_niter_bound.
>         (find_simple_exit): Likewise.
>         * cfgloop.h (struct niter_desc): Remove niter_max.
>
> Index: loop-unswitch.c
> ===================================================================
> *** loop-unswitch.c     (revision 191867)
> --- loop-unswitch.c     (working copy)
> *************** unswitch_single_loop (struct loop *loop,
> *** 257,262 ****
> --- 257,263 ----
>     rtx cond, rcond = NULL_RTX, conds, rconds, acond, cinsn;
>     int repeat;
>     edge e;
> +   HOST_WIDE_INT iterations;
>
>     /* Do not unswitch too much.  */
>     if (num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL))
> *************** unswitch_single_loop (struct loop *loop,
> *** 299,305 ****
>       }
>
>     /* Nor if the loop usually does not roll.  */
> !   if (expected_loop_iterations (loop) < 1)
>       {
>         if (dump_file)
>         fprintf (dump_file, ";; Not unswitching, loop iterations < 1\n");
> --- 300,307 ----
>       }
>
>     /* Nor if the loop usually does not roll.  */
> !   iterations = estimated_loop_iterations_int (loop);
> !   if (iterations >= 0 && iterations <= 1)
>       {
>         if (dump_file)
>         fprintf (dump_file, ";; Not unswitching, loop iterations < 1\n");
> Index: tree-ssa-loop-niter.c
> ===================================================================
> *** tree-ssa-loop-niter.c       (revision 191867)
> --- tree-ssa-loop-niter.c       (working copy)
> *************** estimate_numbers_of_iterations_loop (str
> *** 3012,3020 ****
>   bool
>   estimated_loop_iterations (struct loop *loop, double_int *nit)
>   {
> !   estimate_numbers_of_iterations_loop (loop);
>     if (!loop->any_estimate)
> !     return false;
>
>     *nit = loop->nb_iterations_estimate;
>     return true;
> --- 3012,3034 ----
>   bool
>   estimated_loop_iterations (struct loop *loop, double_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);
> !
> !   /* Even if the bound is not recorded, possibly we can derrive one from
> !      profile.  */
>     if (!loop->any_estimate)
> !     {
> !       if (loop->header->count)
> !       {
> !           *nit = gcov_type_to_double_int
> !                  (expected_loop_iterations_unbounded (loop) + 1);
> !         return true;
> !       }
> !       return false;
> !     }
>
>     *nit = loop->nb_iterations_estimate;
>     return true;
> *************** estimated_loop_iterations (struct loop *
> *** 3027,3033 ****
>   bool
>   max_loop_iterations (struct loop *loop, double_int *nit)
>   {
> !   estimate_numbers_of_iterations_loop (loop);
>     if (!loop->any_upper_bound)
>       return false;
>
> --- 3041,3050 ----
>   bool
>   max_loop_iterations (struct loop *loop, double_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);
>     if (!loop->any_upper_bound)
>       return false;
>
> Index: tree-ssa-loop-unswitch.c
> ===================================================================
> *** tree-ssa-loop-unswitch.c    (revision 191867)
> --- tree-ssa-loop-unswitch.c    (working copy)
> *************** tree_ssa_unswitch_loops (void)
> *** 78,83 ****
> --- 78,84 ----
>     loop_iterator li;
>     struct loop *loop;
>     bool changed = false;
> +   HOST_WIDE_INT iterations;
>
>     /* Go through inner loops (only original ones).  */
>     FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST)
> *************** tree_ssa_unswitch_loops (void)
> *** 102,107 ****
> --- 103,118 ----
>             continue;
>           }
>
> +       /* If the loop is not expected to iterate, there is no need
> +        for unswitching.  */
> +       iterations = estimated_loop_iterations_int (loop);
> +       if (iterations >= 0 && iterations <= 1)
> +       {
> +           if (dump_file && (dump_flags & TDF_DETAILS))
> +             fprintf (dump_file, ";; Not unswitching, loop is not expected 
> to iterate\n");
> +           continue;
> +       }
> +
>         changed |= tree_unswitch_single_loop (loop, 0);
>       }
>
> Index: tree-scalar-evolution.c
> ===================================================================
> *** tree-scalar-evolution.c     (revision 191867)
> --- tree-scalar-evolution.c     (working copy)
> *************** scev_initialize (void)
> *** 3124,3129 ****
> --- 3124,3137 ----
>       }
>   }
>
> + /* Return true if SCEV is initialized.  */
> +
> + bool
> + scev_initialized_p (void)
> + {
> +   return scalar_evolution_info != NULL;
> + }
> +
>   /* Cleans up the information cached by the scalar evolutions analysis
>      in the hash table.  */
>
> Index: tree-scalar-evolution.h
> ===================================================================
> *** tree-scalar-evolution.h     (revision 191867)
> --- tree-scalar-evolution.h     (working copy)
> *************** extern tree number_of_exit_cond_executio
> *** 27,32 ****
> --- 27,33 ----
>   extern gimple get_loop_exit_condition (const struct loop *);
>
>   extern void scev_initialize (void);
> + extern bool scev_initialized_p (void);
>   extern void scev_reset (void);
>   extern void scev_reset_htab (void);
>   extern void scev_finalize (void);
> Index: loop-unroll.c
> ===================================================================
> *** loop-unroll.c       (revision 191867)
> --- loop-unroll.c       (working copy)
> *************** decide_peel_once_rolling (struct loop *l
> *** 341,347 ****
>         || desc->assumptions
>         || desc->infinite
>         || !desc->const_iter
> !       || desc->niter != 0)
>       {
>         if (dump_file)
>         fprintf (dump_file,
> --- 341,348 ----
>         || desc->assumptions
>         || desc->infinite
>         || !desc->const_iter
> !       || (desc->niter != 0
> !         && max_loop_iterations_int (loop) != 0))
>       {
>         if (dump_file)
>         fprintf (dump_file,
> *************** unroll_loop_constant_iterations (struct
> *** 695,701 ****
>
>           desc->noloop_assumptions = NULL_RTX;
>           desc->niter -= exit_mod;
> !         desc->niter_max -= exit_mod;
>         }
>
>         SET_BIT (wont_exit, 1);
> --- 696,708 ----
>
>           desc->noloop_assumptions = NULL_RTX;
>           desc->niter -= exit_mod;
> !         loop->nb_iterations_upper_bound -= double_int::from_uhwi (exit_mod);
> !         if (loop->any_estimate
> !             && double_int::from_uhwi (exit_mod).ule
> !                  (loop->nb_iterations_estimate))
> !           loop->nb_iterations_estimate -= double_int::from_uhwi (exit_mod);
> !         else
> !           loop->any_estimate = false;
>         }
>
>         SET_BIT (wont_exit, 1);
> *************** unroll_loop_constant_iterations (struct
> *** 733,739 ****
>             apply_opt_in_copies (opt_info, exit_mod + 1, false, false);
>
>           desc->niter -= exit_mod + 1;
> !         desc->niter_max -= exit_mod + 1;
>           desc->noloop_assumptions = NULL_RTX;
>
>           SET_BIT (wont_exit, 0);
> --- 740,751 ----
>             apply_opt_in_copies (opt_info, exit_mod + 1, false, false);
>
>           desc->niter -= exit_mod + 1;
> !         if (loop->any_estimate
> !             && double_int::from_uhwi (exit_mod + 1).ule
> !                  (loop->nb_iterations_estimate))
> !           loop->nb_iterations_estimate -= double_int::from_uhwi (exit_mod + 
> 1);
> !         else
> !           loop->any_estimate = false;
>           desc->noloop_assumptions = NULL_RTX;
>
>           SET_BIT (wont_exit, 0);
> *************** unroll_loop_constant_iterations (struct
> *** 782,788 ****
>       }
>
>     desc->niter /= max_unroll + 1;
> !   desc->niter_max /= max_unroll + 1;
>     desc->niter_expr = GEN_INT (desc->niter);
>
>     /* Remove the edges.  */
> --- 794,808 ----
>       }
>
>     desc->niter /= max_unroll + 1;
> !   loop->nb_iterations_upper_bound
> !     = loop->nb_iterations_upper_bound.udiv (double_int::from_uhwi (exit_mod
> !                                                                  + 1),
> !                                           FLOOR_DIV_EXPR);
> !   if (loop->any_estimate)
> !     loop->nb_iterations_estimate
> !       = loop->nb_iterations_estimate.udiv (double_int::from_uhwi (exit_mod
> !                                                                 + 1),
> !                                          FLOOR_DIV_EXPR);
>     desc->niter_expr = GEN_INT (desc->niter);
>
>     /* Remove the edges.  */
> *************** decide_unroll_runtime_iterations (struct
> *** 803,808 ****
> --- 823,829 ----
>   {
>     unsigned nunroll, nunroll_by_av, i;
>     struct niter_desc *desc;
> +   double_int iterations;
>
>     if (!(flags & UAP_UNROLL))
>       {
> *************** decide_unroll_runtime_iterations (struct
> *** 856,864 ****
>       }
>
>     /* If we have profile feedback, check whether the loop rolls.  */
> !   if ((loop->header->count
> !        && expected_loop_iterations (loop) < 2 * nunroll)
> !       || desc->niter_max < 2 * nunroll)
>       {
>         if (dump_file)
>         fprintf (dump_file, ";; Not unrolling loop, doesn't roll\n");
> --- 877,886 ----
>       }
>
>     /* If we have profile feedback, check whether the loop rolls.  */
> !   if ((estimated_loop_iterations (loop, &iterations)
> !        || max_loop_iterations (loop, &iterations))
> !       && iterations.fits_shwi ()
> !       && iterations.to_shwi () <= 2 * nunroll)
>       {
>         if (dump_file)
>         fprintf (dump_file, ";; Not unrolling loop, doesn't roll\n");
> *************** unroll_loop_runtime_iterations (struct l
> *** 1092,1097 ****
> --- 1114,1120 ----
>         single_pred_edge (swtch)->probability = REG_BR_PROB_BASE - p;
>         e = make_edge (swtch, preheader,
>                      single_succ_edge (swtch)->flags & EDGE_IRREDUCIBLE_LOOP);
> +       e->count = RDIV (preheader->count * REG_BR_PROB_BASE, p);
>         e->probability = p;
>       }
>
> *************** unroll_loop_runtime_iterations (struct l
> *** 1111,1116 ****
> --- 1134,1140 ----
>         single_succ_edge (swtch)->probability = REG_BR_PROB_BASE - p;
>         e = make_edge (swtch, preheader,
>                      single_succ_edge (swtch)->flags & EDGE_IRREDUCIBLE_LOOP);
> +       e->count = RDIV (preheader->count * REG_BR_PROB_BASE, p);
>         e->probability = p;
>       }
>
> *************** unroll_loop_runtime_iterations (struct l
> *** 1172,1184 ****
>     desc->niter_expr =
>       simplify_gen_binary (UDIV, desc->mode, old_niter,
>                          GEN_INT (max_unroll + 1));
> !   desc->niter_max /= max_unroll + 1;
>     if (exit_at_end)
>       {
>         desc->niter_expr =
>         simplify_gen_binary (MINUS, desc->mode, desc->niter_expr, const1_rtx);
>         desc->noloop_assumptions = NULL_RTX;
> !       desc->niter_max--;
>       }
>
>     if (dump_file)
> --- 1196,1221 ----
>     desc->niter_expr =
>       simplify_gen_binary (UDIV, desc->mode, old_niter,
>                          GEN_INT (max_unroll + 1));
> !   loop->nb_iterations_upper_bound
> !     = loop->nb_iterations_upper_bound.udiv (double_int::from_uhwi 
> (max_unroll
> !                                                                  + 1),
> !                                           FLOOR_DIV_EXPR);
> !   if (loop->any_estimate)
> !     loop->nb_iterations_estimate
> !       = loop->nb_iterations_estimate.udiv (double_int::from_uhwi (max_unroll
> !                                                                 + 1),
> !                                          FLOOR_DIV_EXPR);
>     if (exit_at_end)
>       {
>         desc->niter_expr =
>         simplify_gen_binary (MINUS, desc->mode, desc->niter_expr, const1_rtx);
>         desc->noloop_assumptions = NULL_RTX;
> !       --loop->nb_iterations_upper_bound;
> !       if (loop->any_estimate
> !         && loop->nb_iterations_estimate != double_int_zero)
> !       --loop->nb_iterations_estimate;
> !       else
> !       loop->any_estimate = false;
>       }
>
>     if (dump_file)
> *************** decide_peel_simple (struct loop *loop, i
> *** 1196,1201 ****
> --- 1233,1239 ----
>   {
>     unsigned npeel;
>     struct niter_desc *desc;
> +   double_int iterations;
>
>     if (!(flags & UAP_PEEL))
>       {
> *************** decide_peel_simple (struct loop *loop, i
> *** 1239,1261 ****
>         return;
>       }
>
> !   if (loop->header->count)
>       {
> !       unsigned niter = expected_loop_iterations (loop);
> !       if (niter + 1 > npeel)
>         {
>           if (dump_file)
>             {
>               fprintf (dump_file, ";; Not peeling loop, rolls too much (");
>               fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
> !                      (HOST_WIDEST_INT) (niter + 1));
>               fprintf (dump_file, " iterations > %d [maximum peelings])\n",
>                        npeel);
>             }
>           return;
>         }
> !       npeel = niter + 1;
>       }
>     else
>       {
>         /* For now we have no good heuristics to decide whether loop peeling
> --- 1277,1306 ----
>         return;
>       }
>
> !   /* If we have realistic estimate on number of iterations, use it.  */
> !   if (estimated_loop_iterations (loop, &iterations))
>       {
> !       if (!iterations.fits_shwi ()
> !         || iterations.to_shwi () + 1 > npeel)
>         {
>           if (dump_file)
>             {
>               fprintf (dump_file, ";; Not peeling loop, rolls too much (");
>               fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC,
> !                      (HOST_WIDEST_INT) (iterations.to_shwi () + 1));
>               fprintf (dump_file, " iterations > %d [maximum peelings])\n",
>                        npeel);
>             }
>           return;
>         }
> !       npeel = iterations.to_shwi () + 1;
>       }
> +   /* If we have small enough bound on iterations, we can still peel 
> (completely
> +      unroll).  */
> +   else if (max_loop_iterations (loop, &iterations)
> +            && iterations.fits_shwi ()
> +            && iterations.to_shwi () + 1 <= npeel)
> +     npeel = iterations.to_shwi () + 1;
>     else
>       {
>         /* For now we have no good heuristics to decide whether loop peeling
> *************** decide_unroll_stupid (struct loop *loop,
> *** 1349,1354 ****
> --- 1394,1400 ----
>   {
>     unsigned nunroll, nunroll_by_av, i;
>     struct niter_desc *desc;
> +   double_int iterations;
>
>     if (!(flags & UAP_UNROLL_ALL))
>       {
> *************** decide_unroll_stupid (struct loop *loop,
> *** 1401,1409 ****
>       }
>
>     /* If we have profile feedback, check whether the loop rolls.  */
> !   if ((loop->header->count
> !        && expected_loop_iterations (loop) < 2 * nunroll)
> !       || desc->niter_max < 2 * nunroll)
>       {
>         if (dump_file)
>         fprintf (dump_file, ";; Not unrolling loop, doesn't roll\n");
> --- 1447,1456 ----
>       }
>
>     /* If we have profile feedback, check whether the loop rolls.  */
> !   if ((estimated_loop_iterations (loop, &iterations)
> !        || max_loop_iterations (loop, &iterations))
> !       && iterations.fits_shwi ()
> !       && iterations.to_shwi () <= 2 * nunroll)
>       {
>         if (dump_file)
>         fprintf (dump_file, ";; Not unrolling loop, doesn't roll\n");
> Index: loop-doloop.c
> ===================================================================
> *** loop-doloop.c       (revision 191867)
> --- loop-doloop.c       (working copy)
> *************** doloop_modify (struct loop *loop, struct
> *** 410,415 ****
> --- 410,416 ----
>     basic_block loop_end = desc->out_edge->src;
>     enum machine_mode mode;
>     rtx true_prob_val;
> +   HOST_WIDE_INT iterations;
>
>     jump_insn = BB_END (loop_end);
>
> *************** doloop_modify (struct loop *loop, struct
> *** 460,468 ****
>
>         /* Determine if the iteration counter will be non-negative.
>          Note that the maximum value loaded is iterations_max - 1.  */
> !       if (desc->niter_max
> !         <= ((unsigned HOST_WIDEST_INT) 1
> !             << (GET_MODE_PRECISION (mode) - 1)))
>         nonneg = 1;
>         break;
>
> --- 461,471 ----
>
>         /* Determine if the iteration counter will be non-negative.
>          Note that the maximum value loaded is iterations_max - 1.  */
> !       iterations = max_loop_iterations_int (loop);
> !       if (iterations >= 0
> !         && (iterations
> !             <= ((unsigned HOST_WIDEST_INT) 1
> !                 << (GET_MODE_PRECISION (mode) - 1))))
>         nonneg = 1;
>         break;
>
> *************** doloop_modify (struct loop *loop, struct
> *** 548,556 ****
>     {
>       rtx init;
>       unsigned level = get_loop_level (loop) + 1;
>       init = gen_doloop_begin (counter_reg,
>                              desc->const_iter ? desc->niter_expr : const0_rtx,
> !                            GEN_INT (desc->niter_max),
>                              GEN_INT (level));
>       if (init)
>         {
> --- 551,567 ----
>     {
>       rtx init;
>       unsigned level = get_loop_level (loop) + 1;
> +     double_int iter;
> +     rtx iter_rtx;
> +
> +     if (!max_loop_iterations (loop, &iter)
> +       || !iter.fits_shwi ())
> +       iter_rtx = const0_rtx;
> +     else
> +       iter_rtx = GEN_INT (iter.to_shwi());
>       init = gen_doloop_begin (counter_reg,
>                              desc->const_iter ? desc->niter_expr : const0_rtx,
> !                            iter_rtx,
>                              GEN_INT (level));
>       if (init)
>         {
> *************** doloop_optimize (struct loop *loop)
> *** 608,613 ****
> --- 619,625 ----
>     struct niter_desc *desc;
>     unsigned word_mode_size;
>     unsigned HOST_WIDE_INT word_mode_max;
> +   double_int iter;
>
>     if (dump_file)
>       fprintf (dump_file, "Doloop: Processing loop %d.\n", loop->num);
> *************** doloop_optimize (struct loop *loop)
> *** 658,664 ****
>
>     count = copy_rtx (desc->niter_expr);
>     iterations = desc->const_iter ? desc->niter_expr : const0_rtx;
> !   iterations_max = GEN_INT (desc->niter_max);
>     level = get_loop_level (loop) + 1;
>
>     /* Generate looping insn.  If the pattern FAILs then give up trying
> --- 670,680 ----
>
>     count = copy_rtx (desc->niter_expr);
>     iterations = desc->const_iter ? desc->niter_expr : const0_rtx;
> !   if (!max_loop_iterations (loop, &iter)
> !       || !iter.fits_shwi ())
> !     iterations_max = const0_rtx;
> !   else
> !     iterations_max = GEN_INT (iter.to_shwi());
>     level = get_loop_level (loop) + 1;
>
>     /* Generate looping insn.  If the pattern FAILs then give up trying
> *************** doloop_optimize (struct loop *loop)
> *** 678,684 ****
>          computed, we must be sure that the number of iterations fits into
>          the new mode.  */
>         && (word_mode_size >= GET_MODE_PRECISION (mode)
> !         || desc->niter_max <= word_mode_max))
>       {
>         if (word_mode_size > GET_MODE_PRECISION (mode))
>         {
> --- 694,700 ----
>          computed, we must be sure that the number of iterations fits into
>          the new mode.  */
>         && (word_mode_size >= GET_MODE_PRECISION (mode)
> !         || iter <= double_int::from_shwi (word_mode_max)))
>       {
>         if (word_mode_size > GET_MODE_PRECISION (mode))
>         {
> Index: loop-iv.c
> ===================================================================
> *** loop-iv.c   (revision 191867)
> --- loop-iv.c   (working copy)
> *************** iv_number_of_iterations (struct loop *lo
> *** 2293,2302 ****
>
>     desc->const_iter = false;
>     desc->niter_expr = NULL_RTX;
> -   desc->niter_max = 0;
> -   if (loop->any_upper_bound
> -       && loop->nb_iterations_upper_bound.fits_uhwi ())
> -     desc->niter_max = loop->nb_iterations_upper_bound.low;
>
>     cond = GET_CODE (condition);
>     gcc_assert (COMPARISON_P (condition));
> --- 2293,2298 ----
> *************** iv_number_of_iterations (struct loop *lo
> *** 2566,2574 ****
>                          ? iv0.base
>                          : mode_mmin);
>           max = (up - down) / inc + 1;
> !         if (!desc->niter_max
> !             || max < desc->niter_max)
> !           desc->niter_max = max;
>
>           if (iv0.step == const0_rtx)
>             {
> --- 2562,2569 ----
>                          ? iv0.base
>                          : mode_mmin);
>           max = (up - down) / inc + 1;
> !         record_niter_bound (loop, double_int::from_shwi (max),
> !                             false, true);
>
>           if (iv0.step == const0_rtx)
>             {
> *************** iv_number_of_iterations (struct loop *lo
> *** 2779,2792 ****
>         unsigned HOST_WIDEST_INT val = INTVAL (desc->niter_expr);
>
>         desc->const_iter = true;
> !       desc->niter_max = desc->niter = val & GET_MODE_MASK (desc->mode);
>       }
>     else
>       {
>         max = determine_max_iter (loop, desc, old_niter);
> !       if (!desc->niter_max
> !         || max < desc->niter_max)
> !       desc->niter_max = max;
>
>         /* simplify_using_initial_values does a copy propagation on the 
> registers
>          in the expression for the number of iterations.  This prolongs life
> --- 2774,2789 ----
>         unsigned HOST_WIDEST_INT val = INTVAL (desc->niter_expr);
>
>         desc->const_iter = true;
> !       desc->niter = val & GET_MODE_MASK (desc->mode);
> !       record_niter_bound (loop, double_int::from_shwi (desc->niter),
> !                         false, true);
>       }
>     else
>       {
>         max = determine_max_iter (loop, desc, old_niter);
> !       gcc_assert (max);
> !       record_niter_bound (loop, double_int::from_shwi (max),
> !                         false, true);
>
>         /* simplify_using_initial_values does a copy propagation on the 
> registers
>          in the expression for the number of iterations.  This prolongs life
> *************** zero_iter_simplify:
> *** 2811,2817 ****
>   zero_iter:
>     desc->const_iter = true;
>     desc->niter = 0;
> !   desc->niter_max = 0;
>     desc->noloop_assumptions = NULL_RTX;
>     desc->niter_expr = const0_rtx;
>     return;
> --- 2808,2815 ----
>   zero_iter:
>     desc->const_iter = true;
>     desc->niter = 0;
> !   record_niter_bound (loop, double_int_zero,
> !                     true, true);
>     desc->noloop_assumptions = NULL_RTX;
>     desc->niter_expr = const0_rtx;
>     return;
> *************** find_simple_exit (struct loop *loop, str
> *** 2945,2953 ****
>           print_rtl (dump_file, desc->niter_expr);
>                   fprintf (dump_file, "\n");
>
> !         fprintf (dump_file, "  upper bound: ");
> !         fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, desc->niter_max);
> !                 fprintf (dump_file, "\n");
>         }
>         else
>         fprintf (dump_file, "Loop %d is not simple.\n", loop->num);
> --- 2943,2952 ----
>           print_rtl (dump_file, desc->niter_expr);
>                   fprintf (dump_file, "\n");
>
> !         fprintf (dump_file, "  upper bound: %li\n",
> !                  (long)max_loop_iterations_int (loop));
> !         fprintf (dump_file, "  realistic bound: %li\n",
> !                  (long)estimated_loop_iterations_int (loop));
>         }
>         else
>         fprintf (dump_file, "Loop %d is not simple.\n", loop->num);
> Index: cfgloop.h
> ===================================================================
> *** cfgloop.h   (revision 191867)
> --- cfgloop.h   (working copy)
> *************** struct niter_desc
> *** 386,394 ****
>     /* Number of iterations if constant.  */
>     unsigned HOST_WIDEST_INT niter;
>
> -   /* Upper bound on the number of iterations.  */
> -   unsigned HOST_WIDEST_INT niter_max;
> -
>     /* Assumptions under that the rest of the information is valid.  */
>     rtx assumptions;
>
> --- 386,391 ----

Reply via email to