diff options
| author | Tzu-Ching Yang <shingekinocore@gmail.com> | 2026-10-22 19:59:22 +0800 |
|---|---|---|
| committer | Yury Norov <ynorov@nvidia.com> | 2026-10-28 10:58:11 -0400 |
| commit | 3e02ace831695cd0162e45ae6bfa946927d1075f (patch) | |
| tree | 169a2d7c438aa7430746fe982e6bb0b040a12d58 /scripts/Makefile.thinlto | |
| parent | 65ba8f34ec886ec72b2c07ddc8cf3d815c32869d (diff) | |
| download | linux-next-3e02ace831695cd0162e45ae6bfa946927d1075f.tar.gz linux-next-3e02ace831695cd0162e45ae6bfa946927d1075f.zip | |
csky: bitops: Use the compiler builtin for __fls()
The csky __fls() is a C wrapper, fls(x) - 1, around the ff1 asm
volatile in fls(), so the compiler can neither fold it for a constant
argument nor merge repeated calls. GCC implements __builtin_clzl()
with the same ff1 instruction for CK807, CK810 and CK860; CK610
(abiv1) cannot be built with upstream GCC.
Use the asm-generic builtin __fls() instead. ffs(), __ffs() and fls()
keep their asm: GCC has no ctz pattern for csky, so builtin ffs() and
__ffs() would become calls to __ffssi2() and __ctzsi2(), and a builtin
fls() needs a test for zero that ff1 makes unnecessary by returning 32
for 0.
__fls() now returns unsigned int instead of unsigned long, like the
asm-generic version; both are 32 bits wide on csky. __fls(0) remains
undefined.
With GCC 9 to 16, the text of every defconfig-based vmlinux tested
shrinks by 128 to 320 bytes.
[Yury: below more details from the discussion [1]]
scripts/bloat-o-meter -t on csky defconfig (CK807) vmlinux, GCC 16.2:
add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-196 (-196)
Function old new delta
fib6_add 1634 1630 -4
build_sched_domains 3948 3916 -32
skb_try_coalesce 1766 1606 -160
Total: Before=4621444, After=4621248, chg -0.00%
Run-time code generation: 4 instructions before and after with
GCC 9 to 16; with GCC 11 to 16 both are this sequence:
unsigned long f(unsigned long x) { return __fls(x); }
ff1 r0, r0
movi r3, 31
subu r0, r3, r0
rts
Constant argument. PP_DMA_INDEX_SHIFT in include/linux/mm.h is
1 + __fls(PP_SIGNATURE - POISON_POINTER_DELTA), which is
1 + __fls(0x40):
unsigned int f(void) { return 1 + __fls(0x40); }
before:
movi r3, 64
ff1 r3, r3
movi r0, 32
subu r0, r3
rts
after:
movi r0, 7
rts
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/all/affe7da1-41aa-4710-bee0-5e3c2b8a8dfc@app.fastmail.com/
Link: https://lore.kernel.org/all/20261027062319.1700461-1-shingekinocore@gmail.com/ [1]
Signed-off-by: Tzu-Ching Yang <shingekinocore@gmail.com>
Signed-off-by: Yury Norov <ynorov@nvidia.com>
Diffstat (limited to 'scripts/Makefile.thinlto')
0 files changed, 0 insertions, 0 deletions
