This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH][2/2] Fix PR44688, use the recorded maximum iterations in the unroller


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  <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");
> 

-- 
Richard Guenther <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]