Messages in this thread | | | From | Vincent MAILHOL <> | Date | Wed, 7 Sep 2022 16:49:55 +0900 | Subject | Re: [PATCH v7 0/2] x86/asm/bitops: optimize ff{s,z} functions for constant expressions |
| |
On Wed. 7 Sep. 2022 at 16:04, Nick Desaulniers <ndesaulniers@google.com> wrote: > On Tue, Sep 6, 2022 at 11:26 AM Nick Desaulniers > <ndesaulniers@google.com> wrote: > > > > On Sun, Sep 4, 2022 at 5:38 PM Vincent Mailhol > > <mailhol.vincent@wanadoo.fr> wrote: > > > > > > The compilers provide some builtin expression equivalent to the ffs(), > > > __ffs() and ffz() functions of the kernel. The kernel uses optimized > > > assembly which produces better code than the builtin > > > functions. However, such assembly code can not be folded when used > > > with constant expressions. > > > > Another tact which may help additional sources other than just the > > Linux kernel; it seems that compilers should be able to fold this.
Initially, I thought that you were suggesting folding the asm code (which doesn’t seem trivial at all).
> > Vincent, if you're interested in making such an optimization in LLVM, > > we'd welcome the contribution, and I'd be happy to show you where to > > make such changes within LLVM; please let me know off thread. > > Oh right, it already does. > https://github.com/llvm/llvm-project/blob/ea953b9d9a65c202985a79f1f95da115829baef6/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp#L2635 > I see what's happening. Constant propagation sinks constants into a > specialized version of ffs when there's only 1 callsite in a given > translation unit (or multiple call sites with the same constant). > Then dead argument elimination removes the argument, so libcall > optimization thinks this isn't the ffs(int) you're looking for, and > skips it.
Isn’t it a wise decision to skip it? How should the optimization be able to decide that the redefined ffs() is equivalent to __builtin_ffs()?
More generally, if I write my own foo() which shadows a __builtin_foo() function, the two functions might do something totally different and I would be pissed off if the compiler decided to constant-fold my foo().
Dummy example:
=================== char *s;
/* ffs: fast forward string * @i: how many bytes to move forward * * Move forward the global s pointer by @i or strlen(s) (whoever is smaller). * * Return: how many bytes we move forward. */ int ffs(int i) { int len = strlen(s); int forward = i < len ? i : len;
s += forward; return forward; } ===================
How would you instruct the compiler to constant-fold the kernel’s ffs() but not fold above dummy ffs()?
> Nice. > https://github.com/llvm/llvm-project/issues/57599 > I guess ffs() is usually forward declared in strings.h, so we don't > have such a static inline definition available to constant > prop/specialize in normal C code.
| |