https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112844

--- Comment #4 from Petr Skocik <pskocik at gmail dot com> ---
(In reply to Jakub Jelinek from comment #1)
> With -Os you ask the code to be small.  So, while internally the hint is
> still present in edge probabilities, -Os is considered more important and
> certain code changes based on the probabilities aren't done if they are
> known or expected to result in larger code.

I think this approach is abit problematic because
(a) it fails to deliver the promised smaller code
e.g., the following

void fn(void);
void maybefn(int X){ if(__builtin_expect(X,0)) fn(); }

under gcc -Os codegens

maybefn:
        testl   %edi, %edi
        je      .L1
        jmp     fn
.L1:
        ret

which is 1-jmp-larger than what you'd get if the compiler followed the hint
(clang's codegen):

maybefn:
        test    edi, edi
        jne     fn@PLT
        ret

(b) when following the branch hints does lead to codesize increases, it's
usually stuff like


before:;
if (unlikely(cnd)){ branch; }
after:;

codegenning:

before: ...; if(cnd) goto branch_begin; after: ...
branch: ... goto after;

rather than the 1-goto-shorter:
before: ...; if(!cnd) goto after; branch: ...; after: ...

IOW, it just tends to be 1 extra jump (which often is near enough to be
2-byte-encoded), which IMO, is not worth worrying about. I would personally
prefer that the compiler always follow the hint when the hint is expressed
since the hint can make (a small but definite) performance difference and the
size cost is negligible (or even negative as shown above).

Reply via email to