Function attribute to indicate a likely (or unlikely) return value

Martin Liška mliska@suse.cz
Thu Aug 5 11:55:13 GMT 2021


On 7/25/21 7:33 PM, Dominique Pellé via Gcc wrote:

> Hi

Hello.



> 

> I read https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html

> but was left wondering: is there a way to annotate a function

> to indicate that a return value is likely (or unlikely)?

Interesting idea :) No, we don't support that right now.



> 

> For example, let's say we have this function:

> 

>    // Return OK (=0) in case of success (frequent case)

>    // or an error code != 0 in case of failure (rare case).

>    int do_something();

> 

> If it's unlikely to fail, I wish I could declare the function like

> this (pseudo-code!):

> 

>    int do_something() __likely_return(OK);

> 

> So wherever it's used, the optimizer can optimize branch

> prediction and the instruction cache.  In other words, lines

> like this:

> 

>    if (do_something() == OK)> 

> ...  would implicitly be similar to:

> 

>    // LIKELY defined as __builtin_expect((x), 1).

>    if (LIKELY(do_something() == OK))

> 

> The advantage of being able to annotate the declaration,

> is that we only need to annotate once in the header, and

> all uses of the function can benefit from the optimization

> without polluting/modifying all code where the function

> is called.

I see your point, seems like a good idea. The question is,

how much would it take to implement and what's benefit

of the suggested hints.



> 

> Another example: a function that would be unlikely to

> return NULL could be declared as:

> 

>    void *foo() __unlikely_returns(NULL);

Note that modern CPUs have branch predictors and a condition

of 'if (ptr == 0)' can be guessed quite easily.



> 

> This last example would be a bit similar to the

> __attribute__((malloc)) since I read about it in the doc:

> 

>> In addition, the GCC predicts that a function with

>> the attribute returns non-null in most cases.

> 

> Of course __attribute__((malloc)) gives other guarantees

> (return value cannot alias any other pointer) so it's not

> equivalent.

Note we have a special branch probability for malloc:

gcc/predict.def:54



> 

> Would attribute __likely_return() and  __unlikely_return()

> make sense?

Similarly, we have now:



/* Branch to basic block containing call marked by noreturn attribute.  */

DEF_PREDICTOR (PRED_NORETURN, "noreturn call", PROB_VERY_LIKELY,

	       PRED_FLAG_FIRST_MATCH)



Thanks for the ideas,

Martin



> 

> Is there already a way to achieve this which I missed in

> the doc?

> 

> Regards

> Dominique

> 



More information about the Gcc mailing list