This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Optimize n?rotate(x,n):x


> 
> Thank you for the comments. If I understand correctly:
> 
> - it is always ok to look at edge->probability (no need to check that the
>   probabilities are available as Richard feared)

Actually with -fno-guess-branch-probabilities (default only at -O0) the probability
is not computed.  You can check profile_status >= PROFILE_GUESSED

> - PROB_EVEN is an ok threshold for division (not sure I understood your last
>   sentence)
> - for cheaper operations like addition, I should be less conservative and do
>   the transformation always, or use a threshold of PROB_UNLIKELY.

PROB_EVEN is really coming from the way one value counter is implemented.
If its probability is less than 50%, the value predicted may be wrong and may
not be the most common value.

It does not apply for your case. If you always eliminate branch, I would always
disable the transformation only if the faster path you are going to slow down
is more than PROB_LIKELY.
For probabilities PROB_LIKELY...PROB_EVEN you are going to slow down the common
path, but you will eliminate branch that is most likely data dependent and not
well predictable.

For really expensive operations (division by non-constant) you probably want
to use PROB_EVEN. But perhaps for start you don't need to make a difference and
lets see.
> 
> Are there other operations than division (among those listed in
> neutral_element_p or absorbing_element_p) that fall in the "expensive"
> category? I guess there are some platforms where multiplication is
> expensive, but few, and querying the target for the cost of operations
> seems exagerated. So I would go with:
> 
> [move definition of code_def]
> if ((code_def == TRUNC_DIV_EXPR || code_def == CEIL_DIV_EXPR
>      || code_def == FLOOR_DIV_EXPR || code_def == ROUND_DIV_EXPR
>      || code_def == EXACT_DIV_EXPR)
>     && EDGE_PRED (middle_bb, 0)->probability < PROB_EVEN)
>   return 0;
> 
> (and change the testsuite example with __builtin_expect to use division)
> 
> or (my favorite):
> 
> [move definition of code_def]
> int threshold = PROB_UNLIKELY;
> if (code_def == TRUNC_DIV_EXPR || code_def == CEIL_DIV_EXPR
>     || code_def == FLOOR_DIV_EXPR || code_def == ROUND_DIV_EXPR
>     || code_def == EXACT_DIV_EXPR)
>   threshold = PROB_EVEN;
> if (EDGE_PRED (middle_bb, 0)->probability < threshold)
>   return 0;

You may probably ask time estimate of estimate_num_insns for expensive
operations. It is not terribly smarter than what you propose (modulo
special casing the constant divisor), but this way we will have all
the magic at one place that is good for maintanibility.

With these changes it is OK.
Honza
> 
> 
> Is that ok, after re-testing?
> 
> -- 
> Marc Glisse


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]