This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][2/2] Fix PR44688, use the recorded maximum iterations in the unroller
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 18 Apr 2012 16:23:53 +0200 (CEST)
- Subject: [PATCH][2/2] Fix PR44688, use the recorded maximum iterations in the unroller
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.
Richard.
2012-04-18 Richard Guenther <rguenther@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");