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

Tobias Burnus <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
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?

     ?

* * *

> -  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.

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
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.