Commit 0e629da
committed
indexcodec: Refine the cmov codegen workaround for gcc
gcc has the same problem as clang, but it can't be solved using an
attribute: gcc doesn't support __builtin_unpredictable and
__builtin_expect_with_probability does not affect the codegen here.
Additionally, some versions of gcc (gcc-16+, possibly earlier versions)
can fuse two reads from edgefifo[] for a/b into a single 64-bit load,
but keep separate stores into edgefifo[]. This breaks store to load
forwarding, as it usually requires that a load is covered by a single
store, which results in further significant performance loss.
Both of these can be fixed with an asm barrier: cf is forced to be
materialized in a register which prevents folding it into the ternary,
at which point the select is simple and emits cmov; the +r restriction
on a also blocks fusing the loads into a single load.
While clang could technically keep using the attribute workaround, the
same workaround appears to work fine for it, so for simplicity we use
the same asm barrier for both compilers for now.
This makes index decoding ~10-12% faster for gcc14/15 and ~19% faster
for gcc16.1 parent a550854 commit 0e629da
1 file changed
Lines changed: 7 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
11 | | - | |
12 | | - | |
13 | | - | |
14 | | - | |
15 | 10 | | |
16 | 11 | | |
17 | 12 | | |
| |||
450 | 445 | | |
451 | 446 | | |
452 | 447 | | |
453 | | - | |
454 | | - | |
455 | | - | |
456 | | - | |
457 | | - | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
458 | 453 | | |
459 | 454 | | |
| 455 | + | |
| 456 | + | |
460 | 457 | | |
461 | 458 | | |
462 | 459 | | |
| |||
0 commit comments