Page MenuHomeFreeBSD

libkern: Add libcalls for ffs and __ffsdi2
ClosedPublic

Authored by jhb on Fri, Jan 30, 3:06 PM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Feb 10, 9:25 PM
Unknown Object (File)
Mon, Feb 9, 11:15 PM
Unknown Object (File)
Sun, Feb 1, 11:41 AM
Unknown Object (File)
Sun, Feb 1, 4:39 AM
Unknown Object (File)
Sun, Feb 1, 12:53 AM
Unknown Object (File)
Sun, Feb 1, 12:16 AM
Unknown Object (File)
Sat, Jan 31, 11:48 PM
Unknown Object (File)
Sat, Jan 31, 11:48 AM
Subscribers

Details

Summary

These are needed when compiling a RISC-V kernel with GCC which does
not inline __builtin_ffs*.

The __ffsdi2 is adapated from the previous ffsl.c.

This partially reverts commit f4db342d44198973c1c7b9005d0c5683a582707e.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

I don't know why __builtin_ffs for RISC-V on GCC calls ffs rather than __ffssi2 for its libcall. The latter would seem cleaner to me.

mhorne added a subscriber: dougm.

Fine by me.

A little more context: there were previously a handful of places in the kernel which implemented binary search instead of using the slow ffs/fls variants from our libkern. In 2023, @dougm and I cleaned these up, under the assumption that the compiler builtins would always provide an equally optimal implementation, if not better. See also: D40698, D40703, D40704, D40705, ffaea08319.

So this assumption is violated by this particular combination of riscv built by GCC, and the hidden consequence is that it will have a performance penalty in a couple areas, as compared to clang which picks up the compiler-rt versions of these functions. I do not think this is anything to fret over, but I want to note this as being quite obscure, and likely to be forgotten in the future.

This revision is now accepted and ready to land.Fri, Jan 30, 5:58 PM

Fine by me.

A little more context: there were previously a handful of places in the kernel which implemented binary search instead of using the slow ffs/fls variants from our libkern. In 2023, @dougm and I cleaned these up, under the assumption that the compiler builtins would always provide an equally optimal implementation, if not better. See also: D40698, D40703, D40704, D40705, ffaea08319.

So this assumption is violated by this particular combination of riscv built by GCC, and the hidden consequence is that it will have a performance penalty in a couple areas, as compared to clang which picks up the compiler-rt versions of these functions. I do not think this is anything to fret over, but I want to note this as being quite obscure, and likely to be forgotten in the future.

Clang doesn't pick up the compiler-rt versions, it just inlines these things instead of emitting libcalls. GCC tends to fall back to libcalls more often than clang. When I previously tried to build the riscv64 world with GCC it emitted a bunch of libcalls for atomics that are provided by libatomic.a in GCC (and which don't have an equivalent in compiler_rt), but GCC seems to have fixed that and now does direct code-generation instead. My primary goal with building the base system with GCC is getting the extra warning coverage as GCC finds things clang doesn't (and vice versa). I haven't tried to actually boot a kernel/world built with GCC in quite a long time (though I do kind of wish someone was testing that as well).

If we cared about the performance of these, we could certainly make them less dumb following something similar to the ctz* implementations in compiler_rt.

This revision was automatically updated to reflect the committed changes.