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]

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


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