On Wed, 18 Apr 2012, Richard Guenther wrote: > > This teaches loop-iv (RTL IV analysis) about loop->nb_iterations_upper_bound. > It avoids poinless unrolling of vectorizer prologue loops for now. > > Bootstrap and regtest pending on x86_64-unknown-linux-gnu.
Finished. Needs the following testsuite adjustment * gcc.dg/var-expand1.c: Increase array size to make unrolling possibly profitable. Index: gcc/testsuite/gcc.dg/var-expand1.c =================================================================== --- gcc/testsuite/gcc.dg/var-expand1.c.orig 2012-04-19 10:45:32.000000000 +0200 +++ gcc/testsuite/gcc.dg/var-expand1.c 2012-04-19 10:45:43.475201279 +0200 @@ -6,7 +6,7 @@ extern void abort (void); -float array[10] = { 1,2,3,4,5,6,7,8,9,10 }; +float array[30] = { 1,2,3,4,5,6,7,8,9,10 }; int foo (int n) { because otherwise we see that the loop rolls at most 10 times and thus unrolling by a factor of 8 is pointless (well, yes, we are somewhat inflexible with the amount of unrolling here). Committed. Richard. > Richard. > > 2012-04-18 Richard Guenther <rguent...@suse.de> > > PR rtl-optimization/44688 > * loop-iv.c (determine_max_iter): Only return max_iter. > (iv_number_of_iterations): Also use the recorded loop bound > on the maximum number of iterations. > * loop-unroll.c (decide_unroll_runtime_iterations): Use > max_iter to avoid unrolling loops that do not roll. > (decide_unroll_stupid): Likewise. > > Index: gcc/loop-iv.c > =================================================================== > *** gcc/loop-iv.c.orig 2012-04-18 15:29:39.000000000 +0200 > --- gcc/loop-iv.c 2012-04-18 16:03:21.911222247 +0200 > *************** canonicalize_iv_subregs (struct rtx_iv * > *** 2190,2197 **** > return true; > } > > ! /* Tries to estimate the maximum number of iterations in LOOP, and store the > ! result in DESC. This function is called from iv_number_of_iterations > with > a number of fields in DESC already filled in. OLD_NITER is the original > expression for the number of iterations, before we tried to simplify it. > */ > > --- 2190,2197 ---- > return true; > } > > ! /* Tries to estimate the maximum number of iterations in LOOP, and return > the > ! result. This function is called from iv_number_of_iterations with > a number of fields in DESC already filled in. OLD_NITER is the original > expression for the number of iterations, before we tried to simplify it. > */ > > *************** determine_max_iter (struct loop *loop, s > *** 2207,2216 **** > { > nmax = INTVAL (XEXP (niter, 0)); > if (!(nmax & (nmax + 1))) > ! { > ! desc->niter_max = nmax; > ! return nmax; > ! } > } > > get_mode_bounds (desc->mode, desc->signed_p, desc->mode, &mmin, &mmax); > --- 2207,2213 ---- > { > nmax = INTVAL (XEXP (niter, 0)); > if (!(nmax & (nmax + 1))) > ! return nmax; > } > > get_mode_bounds (desc->mode, desc->signed_p, desc->mode, &mmin, &mmax); > *************** determine_max_iter (struct loop *loop, s > *** 2219,2228 **** > if (GET_CODE (niter) == UDIV) > { > if (!CONST_INT_P (XEXP (niter, 1))) > ! { > ! desc->niter_max = nmax; > ! return nmax; > ! } > inc = INTVAL (XEXP (niter, 1)); > niter = XEXP (niter, 0); > } > --- 2216,2222 ---- > if (GET_CODE (niter) == UDIV) > { > if (!CONST_INT_P (XEXP (niter, 1))) > ! return nmax; > inc = INTVAL (XEXP (niter, 1)); > niter = XEXP (niter, 0); > } > *************** determine_max_iter (struct loop *loop, s > *** 2241,2247 **** > if (dump_file) > fprintf (dump_file, ";; improved upper bound by one.\n"); > } > - desc->niter_max = nmax / inc; > return nmax / inc; > } > > --- 2235,2240 ---- > *************** iv_number_of_iterations (struct loop *lo > *** 2259,2265 **** > enum rtx_code cond; > enum machine_mode mode, comp_mode; > rtx mmin, mmax, mode_mmin, mode_mmax; > ! unsigned HOST_WIDEST_INT s, size, d, inv; > HOST_WIDEST_INT up, down, inc, step_val; > int was_sharp = false; > rtx old_niter; > --- 2252,2258 ---- > enum rtx_code cond; > enum machine_mode mode, comp_mode; > rtx mmin, mmax, mode_mmin, mode_mmax; > ! unsigned HOST_WIDEST_INT s, size, d, inv, max; > HOST_WIDEST_INT up, down, inc, step_val; > int was_sharp = false; > rtx old_niter; > *************** iv_number_of_iterations (struct loop *lo > *** 2279,2284 **** > --- 2272,2280 ---- > desc->const_iter = false; > desc->niter_expr = NULL_RTX; > desc->niter_max = 0; > + if (loop->any_upper_bound > + && double_int_fits_in_uhwi_p (loop->nb_iterations_upper_bound)) > + desc->niter_max = loop->nb_iterations_upper_bound.low; > > cond = GET_CODE (condition); > gcc_assert (COMPARISON_P (condition)); > *************** iv_number_of_iterations (struct loop *lo > *** 2547,2553 **** > down = INTVAL (CONST_INT_P (iv0.base) > ? iv0.base > : mode_mmin); > ! desc->niter_max = (up - down) / inc + 1; > > if (iv0.step == const0_rtx) > { > --- 2543,2552 ---- > down = INTVAL (CONST_INT_P (iv0.base) > ? 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) > { > *************** iv_number_of_iterations (struct loop *lo > *** 2762,2769 **** > } > else > { > ! if (!desc->niter_max) > ! desc->niter_max = determine_max_iter (loop, desc, old_niter); > > /* simplify_using_initial_values does a copy propagation on the > registers > in the expression for the number of iterations. This prolongs life > --- 2761,2770 ---- > } > 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 > Index: gcc/loop-unroll.c > =================================================================== > *** gcc/loop-unroll.c.orig 2012-04-18 15:29:39.000000000 +0200 > --- gcc/loop-unroll.c 2012-04-18 16:10:24.444196989 +0200 > *************** decide_unroll_runtime_iterations (struct > *** 857,863 **** > } > > /* If we have profile feedback, check whether the loop rolls. */ > ! if (loop->header->count && expected_loop_iterations (loop) < 2 * nunroll) > { > if (dump_file) > fprintf (dump_file, ";; Not unrolling loop, doesn't roll\n"); > --- 857,865 ---- > } > > /* 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"); > *************** decide_unroll_stupid (struct loop *loop, > *** 1400,1407 **** > } > > /* If we have profile feedback, check whether the loop rolls. */ > ! if (loop->header->count > ! && expected_loop_iterations (loop) < 2 * nunroll) > { > if (dump_file) > fprintf (dump_file, ";; Not unrolling loop, doesn't roll\n"); > --- 1402,1410 ---- > } > > /* 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"); > -- Richard Guenther <rguent...@suse.de> SUSE / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer