Patchwork Make loop optimizers more profile aware

login
register
mail settings
Submitter Jan Hubicka
Date July 5, 2010, 3:47 p.m.
Message ID <20100705154757.GF29130@kam.mff.cuni.cz>
Download mbox | patch
Permalink /patch/57919/
State New
Headers show

Comments

Jan Hubicka - July 5, 2010, 3:47 p.m.
Hi,
estimated_loop_iterations is used by loop optimizers (such as prefetching) to decide
whether to apply the transfromation.  This function ignore profile that is returned
by expected_loop_iterations_unbounded.

Making it to do so has one unwanted effect making predict_loops to use it too.
This is wrong, since we want predict_loops to be purely based on static information
(so predictor statistics works).

Bootstrapped/regtested x86_64-linux, OK?

	* double-int.h (uhwti_to_double_int): New function.
	* predict.c (predict_loops): Avoid estimated_loop_iterations_int to
	return estimates based on profile; be ready for 0 estimated iterations.
	* tree-data-ref.c (estimated_loop_iterations): Use profile if
	available.
Richard Guenther - July 5, 2010, 4:02 p.m.
On Mon, 5 Jul 2010, Jan Hubicka wrote:

> Hi,
> estimated_loop_iterations is used by loop optimizers (such as prefetching) to decide
> whether to apply the transfromation.  This function ignore profile that is returned
> by expected_loop_iterations_unbounded.
> 
> Making it to do so has one unwanted effect making predict_loops to use it too.
> This is wrong, since we want predict_loops to be purely based on static information
> (so predictor statistics works).
> 
> Bootstrapped/regtested x86_64-linux, OK?

Ok.

Thanks,
Richard.

> 	* double-int.h (uhwti_to_double_int): New function.
> 	* predict.c (predict_loops): Avoid estimated_loop_iterations_int to
> 	return estimates based on profile; be ready for 0 estimated iterations.
> 	* tree-data-ref.c (estimated_loop_iterations): Use profile if
> 	available.
> Index: double-int.h
> ===================================================================
> --- double-int.h	(revision 161810)
> +++ double-int.h	(working copy)
> @@ -97,6 +97,24 @@ uhwi_to_double_int (unsigned HOST_WIDE_I
>    return r;
>  }
>  
> +/* Constructs double_int from unsigned integer CST.  The bits over the
> +   precision of HOST_WIDEST_INT are filled with zeros.  */
> +
> +static inline double_int
> +uhwti_to_double_int (unsigned HOST_WIDEST_INT cst)
> +{
> +  double_int r;
> +
> +  r.low = cst;
> +#if HOST_BITS_PER_WIDEST_INT != HOST_BITS_PER_WIDE_INT
> +  r.high = cst >> HOST_BITS_PER_WIDEST_INT;
> +#else
> +  r.high = 0;
> +#endif
> +
> +  return r;
> +}
> +
>  /* Returns value of CST as a signed number.  CST must satisfy
>     double_int_fits_in_shwi_p.  */
>  
> Index: predict.c
> ===================================================================
> --- predict.c	(revision 161810)
> +++ predict.c	(working copy)
> @@ -968,7 +968,13 @@ predict_loops (void)
>  	     the loop, use it to predict this exit.  */
>  	  else if (n_exits == 1)
>  	    {
> +	      enum profile_status_d old_profile_status = profile_status;
> +
> +	      /* We do not want estimated_loop_iterations_int to use profile info
> +		 when available or dumping of statistics would be biassed.  */
> +	      profile_status = PROFILE_ABSENT;
>  	      nitercst = estimated_loop_iterations_int (loop, false);
> +	      profile_status = old_profile_status;
>  	      if (nitercst < 0)
>  		continue;
>  	      if (nitercst > max)
> @@ -979,7 +985,10 @@ predict_loops (void)
>  	  else
>  	    continue;
>  
> -	  probability = ((REG_BR_PROB_BASE + nitercst / 2) / nitercst);
> +	  if (!nitercst)
> +	    probability = REG_BR_PROB_BASE;
> +	  else
> +	    probability = ((REG_BR_PROB_BASE + nitercst / 2) / nitercst);
>  	  predict_edge (ex, predictor, probability);
>  	}
>        VEC_free (edge, heap, exits);
> Index: tree-data-ref.c
> ===================================================================
> --- tree-data-ref.c	(revision 161810)
> +++ tree-data-ref.c	(working copy)
> @@ -1724,6 +1724,10 @@ estimated_loop_iterations (struct loop *
>  
>        *nit = loop->nb_iterations_upper_bound;
>      }
> +  /* When we do have profile, see what real number of iterations is.  */
> +  else if (profile_status == PROFILE_READ
> +	   && (loop->latch->count || loop->header->count))
> +    *nit = uhwti_to_double_int (expected_loop_iterations_unbounded (loop));
>    else
>      {
>        if (!loop->any_estimate)
> 
>

Patch

Index: double-int.h
===================================================================
--- double-int.h	(revision 161810)
+++ double-int.h	(working copy)
@@ -97,6 +97,24 @@  uhwi_to_double_int (unsigned HOST_WIDE_I
   return r;
 }
 
+/* Constructs double_int from unsigned integer CST.  The bits over the
+   precision of HOST_WIDEST_INT are filled with zeros.  */
+
+static inline double_int
+uhwti_to_double_int (unsigned HOST_WIDEST_INT cst)
+{
+  double_int r;
+
+  r.low = cst;
+#if HOST_BITS_PER_WIDEST_INT != HOST_BITS_PER_WIDE_INT
+  r.high = cst >> HOST_BITS_PER_WIDEST_INT;
+#else
+  r.high = 0;
+#endif
+
+  return r;
+}
+
 /* Returns value of CST as a signed number.  CST must satisfy
    double_int_fits_in_shwi_p.  */
 
Index: predict.c
===================================================================
--- predict.c	(revision 161810)
+++ predict.c	(working copy)
@@ -968,7 +968,13 @@  predict_loops (void)
 	     the loop, use it to predict this exit.  */
 	  else if (n_exits == 1)
 	    {
+	      enum profile_status_d old_profile_status = profile_status;
+
+	      /* We do not want estimated_loop_iterations_int to use profile info
+		 when available or dumping of statistics would be biassed.  */
+	      profile_status = PROFILE_ABSENT;
 	      nitercst = estimated_loop_iterations_int (loop, false);
+	      profile_status = old_profile_status;
 	      if (nitercst < 0)
 		continue;
 	      if (nitercst > max)
@@ -979,7 +985,10 @@  predict_loops (void)
 	  else
 	    continue;
 
-	  probability = ((REG_BR_PROB_BASE + nitercst / 2) / nitercst);
+	  if (!nitercst)
+	    probability = REG_BR_PROB_BASE;
+	  else
+	    probability = ((REG_BR_PROB_BASE + nitercst / 2) / nitercst);
 	  predict_edge (ex, predictor, probability);
 	}
       VEC_free (edge, heap, exits);
Index: tree-data-ref.c
===================================================================
--- tree-data-ref.c	(revision 161810)
+++ tree-data-ref.c	(working copy)
@@ -1724,6 +1724,10 @@  estimated_loop_iterations (struct loop *
 
       *nit = loop->nb_iterations_upper_bound;
     }
+  /* When we do have profile, see what real number of iterations is.  */
+  else if (profile_status == PROFILE_READ
+	   && (loop->latch->count || loop->header->count))
+    *nit = uhwti_to_double_int (expected_loop_iterations_unbounded (loop));
   else
     {
       if (!loop->any_estimate)