Re: [Patch][RFC?] Re-guess probability when unswitch hoists a condition before the loop [PR126664]

Richard Biener <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
On Fri, 7 Aug 2026, Tobias Burnus wrote:

> Richard Biener wrote:
> >> Back to the attached patch:
> >>
> >> The patch is based on the assumption that the probability can be
> >> different when moved outside of the loop - and just re-guesses it
> >> makes sense, which yields the expected 41% and 59% edge probabilities.
> >>
> >> Is the patch OK – or at least like the right approach?
> > unconditionally re-guessing seems overly conservative when the
> > unswitched condition is always executed in the loop.
> 
> But the question is what to do otherwise?
> 
> (1) Only do so when any of the probabilities is 'never'? Namely:
> 
>     profile_probability prob_true = edge_true->probability;
>     profile_probability prob_false = prob_true.invert ();
>     if (prob_true.nonzero_p() && prob_false.nonzero_p())
>       prob_true = prob_false = profile_probability::uninitialized ();
> 
>     This will fix the 0% / 100% case and yield here 41% / 59%;
>     it might not fix other cases, but also has not much overhead.
> 
> (2) Use conditionally profile_probability::even () ?
> 
>     This will use 50% / 50% – which is not as good as the 41% / 59%
>     but less expensive - and surely better than 0% / 100%. It might
>     pessimize cases where the probability is finite but highly
>     unbalanced and correctly guessed.
> 
> (3) do something else – but what?

So I think the invariant we know is that the BB counts in
the original

  do { if (outer) if (inner) <true-count>; else <false-count>; } while ();

should be preserved even when the inner if is moved and so we have

  if (inner)
    do { if (outer) <true-count>; } while ();
  else
    do { if (outer) <false-count>; } while ();

the task is to compute a reasonable count setup and from that adjust
probabilities.  I'll note that the probabilities of the if (outer)
is not fixed either.

>     ?
> 
> * * *
> 
> > -  scale_loop_frequencies (loop, then_scale);
> > -  scale_loop_frequencies (nloop, else_scale);
> > +  if (then_scale.initialized_p () && else_scale.initialized_p ())
> > +    {
> > +      scale_loop_frequencies (loop, then_scale);
> > +      scale_loop_frequencies (nloop, else_scale);
> > +    }
> > +  else
> > +    {
> > +      edge te = EDGE_SUCC (cond_bb, 0);
> > +      edge ee = EDGE_SUCC (cond_bb, 1);
> > +      scale_loop_frequencies (loop, te->probability);
> > +      scale_loop_frequencies (nloop, ee->probability);
> > +    }
> >
> > doesn't the 2nd hunk always work? (are you sure of the
> > first/second edge going to the respective loops?)
> 
> Do you mean 'does the 2nd ...'? If so, see below. If you
> really meant 'does not the 2nd ...' than I think I don't
> understand the question.

It depends whether you update then/else scale or the edge
probabilties reliably (IIRC the edges are only created downstream,
so you have to update the scales).

> In any case:
> 
> cond_bb = lv_adjust_loop_entry_edge (...)
> 
> and that function returns 'new_head'. That is created
> (current GCC version for simplicity):
> 
>   new_head = split_edge (e);
>   lv_add_condition_to_bb (first_head, second_head, new_head,
>                           cond_expr);
>   e = single_succ_edge (new_head);
>   e1 = make_edge (new_head, first_head,
>                   current_ir_type () == IR_GIMPLE ? EDGE_TRUE_VALUE : 0);
>   e1->probability = then_prob;
>   e->probability = else_prob;
> 
> where single_succ_edge returns EDGE_SUCC (bb, 0) and checks that
> this is the only edge.
> 
> And as lv_adjust_loop_entry_edge states, it does:
>    --- edge e ---- > [second_head]
>    Split it and insert new conditional expression and adjust edges.
>     --- edge e ---> [cond expr] ---> [first_head]
>                         |
>                         +---------> [second_head]
> 
> Thus, I think that code should be always fine (until the function
> is largely modified).
> 
> Tobias
> 
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Abhinav Puri; (HRB 36809, AG Nuernberg)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.