[PATCH] Fix branch probability computation in do_compare_rtx_and_jump (PR tree-optimization/83081)

Jan Hubicka jh@suse.de
Mon Jan 22 13:46:00 GMT 2018


Dne 2018-01-22 14:29, Jakub Jelinek napsal:
> On Mon, Jan 22, 2018 at 01:52:11PM +0100, Jan Hubicka wrote:
>> In new code bb4 is reached by first_prob + (1-first_prob)*second_prob
>> which should be equal to prob.
>> 
>> Say your choosen constant is to obtain first_prob=c*prob is c=0.99 and 
>> you
>> want to know c2 to obtain second_prob=c2*prob
>> 
>> You want the combined probability of branch 
>> (c*prob)+(1-c*prob)*(prob*c2) to
>> be the same prob
>> 
>> This should give c2=(1-c)/(1-c*prob) so
>> (c*prob)+(1-c*prob)*prob*(1-c)/(1-c*prob) cancels out to 
>> c*prob+(1-c)*prob
>> 
>> that is
>>                   profile_probability cprob =
>> profile_probability::guessed_always ().apply_scale (1, 100);
>> 		  first_prob = prob * cprob;
> 
> Yes, if we want it to be done with arbitrary cprob, we can do it the 
> above
> way and move the latter into the helper.
> 
>> 		  prob = cprob.inverse () / (first_prob).inverse ();
> 
> But this looks incorrect, because that computes only the above c2 in 
> prob, not
> second_prob.  It needs to be
>   prob = cprob.invert () * prob / first_prob.invert ();
> or
>   prob *= cprob.invert () / first_prob.invert ();
> or that
>   prob = (prob - first_prob) / first_prob.invert ();
> I had in the patch.  The last one looked to me like cheapest to 
> compute.

Aha, I see.  Ok that makes sense to me now :)
> 
>> void profile_probability::split (profile_probability cprob,
>> profile_probability *first_prob, profile_probability *second_prob)
> 
> This doesn't take prob as an argument, or should it be a method and 
> take
> prob as *this?  Couldn't it simply return first_prob and adjust itself, 
> so
> profile_probability split (profile_probability cprob)
> {
>   profile_probability ret = *this * cprob;
>   *this = (*this - prob) / ret.invert ();
> // or *this = *this * cprob.invert () / ret.invert ();
>   return ret;
> }
> ?

Yep, that is fine.
>> 
>> I would bet we already have something like that but don't see it.
>> 
>> Other cases seems to choose c as 1/2 that  simplifies the formulate 
>> bit it
>> is also easy to get misunderstand such as in:
>>             profile_probability false_prob = prob.invert ();
>>             profile_probability op0_false_prob = 
>> false_prob.apply_scale (1,
>> 2);
>>             profile_probability op1_false_prob = 
>> false_prob.apply_scale (1,
>> 2)
>>                                 / op0_false_prob.invert ();
> 
> Or profile_probability op1_false_prob = op0_false_prob /
> op0_false_prob.invert ();

I would use the splitting function here so once someone decides to 
change the weights the
code will not produce corrupt profile.

Thanks,
Honza
> 
> 	Jakub



More information about the Gcc-patches mailing list