[clang] [llvm] [BPF] introduce `__attribute__((bpf_fastcall))` (PR #101228)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 7 10:49:54 PDT 2024
eddyz87 wrote:
@AaronBallman,
> But a mismatch can still potentially result in a miscompilation, right? e.g., you have a function in a header file with the `bfp_fastcall` attribute on it. The definition of the function is compiled into a library with Clang 16 and ignores the unknown attribute, so the callee will clobber registers. But the declaration is used by an application compiled with Clang 20 and assumes the attribute means the callee won't clobber registers, so doesn't generate the save/restore code. When the call resolves, the registers are clobbered unexpectedly, right? But if the attribute was part of the function type, this program presumably would not link due to type mismatch.
Not quite, the feature is a bit unusual and pursues several goals:
- allow bpf programs run on new kernels (those that support `bpf_fastcall`) to gain some performance by clobbering less registers;
- allow same code to run unmodified on old kernels (those that do not support `bpf_fastcall`);
- allow `bpf_fastcall` only for "builtin" functions, implemented by kernel, not written in BPF;
- allow new kernels to provide different sets of `bpf_fastcall` builtin functions depending on configuration and architecture;
- do not complicate kernel side implementation much (read as: do not do register allocation in kernel jit).
Suppose there is a function `void foo(void)` marked with `bpf_fastcall` and the following IR:
%v = ... define %v somehow ...
call void @foo
... use %v somehow ...
In such a case:
- only `@foo` prototype is visible to BPF program, not it's body;
- for the BPF backend the attribute serves as a hint for register allocation, the BPF code like below might be generated:
```
r1 = ... definition of %v ...
fp[-32] = r1
call foo
r1 = fp[-32]
... use r1 as %v ...
```
Kernels supporting `bpf_fastcall` for function `foo` would remove `r1` spill and fill, kernels not supporting `bpf_fastcall` would just work as before.
https://github.com/llvm/llvm-project/pull/101228
More information about the cfe-commits
mailing list