[[(un)likely]] attributes and do-while loops

611 views Asked by At

IN SHORT: Is there a place to put the [[(un)likely]] attribute so that the control flow at cond2 is considered likely to take the false branch, without affecting the possibility of branches at cond1?

if (cond1) {
  do {
    foo();
  } while (cond2);
}

If I put [[unlikely]] in do [[unlikely]] { or do { [[unlikely]],does it affect cond1? Since the true-branch of cond1 is the ONLY path that goes into the loop and is the path that ALWAYS goes into the loop, according to cppreference.com:

Applies to a statement to allow the compiler to optimize for the case where paths of execution including that statement are less likely than any alternative path of execution that does not include such a statement.

it seems that cond1 is affected.

If I put [[likely]] after the loop, e.g. do { foo(); } while(cond2); [[likely]];, the attribute is applied to the empty statement. This code is unintuitive and become unclearer whether cond2 and/or cond1 are affected.

Btw, the question is infact asking about the semantics of [[(un)likely]] attribute, not about implementations neither alternatives such as __builtin_expect or breaking the do-while loop to foo(); while(cond2) [[unlikely]] foo();.

2

There are 2 answers

2
Goswin von Brederlow On

I believe this is the correct placement of the attributes:

if (cond1) [[likely]] {
    do [[unlikely]] {
        foo();
    } while (cond2);
}

The attributes are just examples to show where to place each. The likely affects the if while the unlikely affects the do/while. Confusing that the attribute is so far from the condition but that seems to be the place where it compiles.

0
Azmisov On

Not a solution, but as an alternative one could try this:

while (1){
    foo();
    if (cond2) [[unlikely]]
        break;
}