On Mon, May 30, 2016 at 02:38:40PM +0200, Jan Hubicka wrote:
> Hi,
> this patch fixes profile updates in loop peeling pass.  First it correctly
> set wont_exit which can only be set when we know the number of iterations
> tested by EXIT and this number is higher than maximal number of iterations
> (an unlikely case which is usually removed by VRP pass or earlier cunroll).
> 
> Second problem is that we determine number of peelings as number of estimated
> iterations + 1.  After peeling we currently underflow updating estimates
> which makes them to be re-computed later to bogus values.
> 
> Last change is way we netermine profile for the new loop header.  We used to
> drop the loop frequency 1/1000.  This patch makes use of the info on remaining
> entry edges to the loop.
> 
> While working on this I noticed that try_peel_loop has tendency to iterate
> and peel one loop many times.  I will prepare followup for that.  Also
> testcases will come once I commit the change enabling loop peeling at -O3
> by using likely estimates.
> 
> Bootstrapped/regtested x86_64-linux.
> 
>       * tree-ssa-loop-ivcanon.c (try_peel_loop): Correctly set wont_exit
>       for peeled copies; avoid underflow when updating estimates; correctly
>       scale loop profile.
> 
> Index: tree-ssa-loop-ivcanon.c
> ===================================================================
> --- tree-ssa-loop-ivcanon.c   (revision 236874)
> +++ tree-ssa-loop-ivcanon.c   (working copy)

> @@ -1053,14 +1065,48 @@ try_peel_loop (struct loop *loop,
>        fprintf (dump_file, "Peeled loop %d, %i times.\n",
>              loop->num, (int) npeel);
>      }
> +  if (loop->any_estimate)
> +    {
> +      if (wi::ltu_p (npeel, loop->nb_iterations_estimate))
> +        loop->nb_iterations_estimate -= npeel;
> +      else
> +     loop->nb_iterations_estimate = 0;
> +    }
>    if (loop->any_upper_bound)
> -    loop->nb_iterations_upper_bound -= npeel;
> +    {
> +      if (wi::ltu_p (npeel, loop->nb_iterations_estimate))

shouldn't this compare loop->nb_iterations_upper_bound to npeel instead
of nb_iterations_estimate ?

> +        loop->nb_iterations_upper_bound -= npeel;
> +      else
> +        loop->nb_iterations_upper_bound = 0;
> +    }
>    if (loop->any_likely_upper_bound)
> -    loop->nb_iterations_likely_upper_bound -= npeel;
> -  loop->nb_iterations_estimate = 0;
> -  /* Make sure to mark loop cold so we do not try to peel it more.  */
> -  scale_loop_profile (loop, 1, 0);
> -  loop->header->count = 0;
> +    {
> +      if (wi::ltu_p (npeel, loop->nb_iterations_estimate))

nb_iterations_likely_upper_bound ?
What am i missing?

> +     loop->nb_iterations_likely_upper_bound -= npeel;
> +      else
> +     {
> +       loop->any_estimate = true;
> +       loop->nb_iterations_estimate = 0;
> +       loop->nb_iterations_likely_upper_bound = 0;

I don't immediately understand this else branch but didn't try hard.
Can you please explain or maybe add a comment?

thanks,
> +     }
> +    }
> +  gcov_type entry_count = 0;
> +  int entry_freq = 0;
> +
> +  edge_iterator ei;
> +  FOR_EACH_EDGE (e, ei, loop->header->preds)
> +    if (e->src != loop->latch)
> +      {
> +     entry_count += e->src->count;
> +     entry_freq += e->src->frequency;
> +     gcc_assert (!flow_bb_inside_loop_p (loop, e->src));
> +      }
> +  int scale = 1;
> +  if (loop->header->count)
> +    scale = RDIV (entry_count * REG_BR_PROB_BASE, loop->header->count);
> +  else if (loop->header->frequency)
> +    scale = RDIV (entry_freq * REG_BR_PROB_BASE, loop->header->frequency);
> +  scale_loop_profile (loop, scale, 0);
>    return true;
>  }
>  /* Adds a canonical induction variable to LOOP if suitable.

Reply via email to