[BPF] Support Stack Arguments (#189060)

Currently, bpf program and kfunc only support 5 register parameters. As
bpf community and use cases keep expanding, there are some need to
extend 5 register parameters by allocating additional parameters on
stack. There are two main use cases here:
1. Currently kfunc is limited to 5 register parameters. In some special
situation, people may want to have more than 5 parameters. One of
example is for sched_ext.
2. Allowing more stack parameters can make bpf prog writer easier since
they do not need to carefully limit the number of parameters for their
programs.

The following is the high-level design:
- Use bpf register R11 as the frame pointer to stack parameters. This is
to avoid mixing stacks due to R10.
  - Stack parameters must be after 5 register parameters.
- All parameters should be at most 16 bytes as ByVal parameters are not
supported.
- Support for cpu v1 to v4 so all cpu versions can use this. A feature
macro __BPF_FEATURE_STACK_ARGUMENT is defined and users can check
whether stack argument is supported or not.

The below is a simple asm code example about stack parameters:
```
  bar:
    /* Retrieve two parameters from the caller of bar(). */
    rX = *(u64 *)(r11 + 8)  // 1st arg
    rY = *(u64 *)(r11 + 16) // 2nd arg
    ...
    /* Prepare the single stack parameters for foo1 */
    *(u64 *)(r11 - 8) = rZ  // 1st arg
    call foo1
    ...
    /* Prepare the single stack parameters for foo2 */
    *(u64 *)(r11 - 8) = rX  // 1st arg
    *(u64 *)(r11 - 16) = rY // 2nd arg
    call foo2
    ...
  foo1:
    /* Retrieve parameter '*(u64 *)(r11 - 8) = rZ' from bar(),
     * and assign the value rZ to rX.
     */
    rX = *(u64 *)(r11 + 8)  // 1st arg
    ...
  foo2:
    /* Retrieve parameters '*(u64 *)(r11 - 8/16) = rZ' from bar(),
     * and assign values rX/rY to rU/rV.
     */
    rU = *(u64 *)(r11 + 8)  // 1st arg
    rV = *(u64 *)(r11 + 16) // 2nd arg
    ...
```

The code patterns in the above try to follow x86_64/arm64 calling
conventions. That is, the first argument is in lower location than
the second argument, etc. The r11 based load should retrieve the value
directly from the caller stack. The r11 based store should push
the value directly on the specificed stack location.

Internally in bpf backend, pseudo insns are generated for
load_stack_arg and store_stack_arg. The BPFMIPeephole pass
changes pseudo insns into proper real bpf insns like the above.
16 files changed
tree: abd035a9dcd11ff00e8c9a170c99af541b9dc77c
  1. .ci/
  2. .github/
  3. bolt/
  4. clang/
  5. clang-tools-extra/
  6. cmake/
  7. compiler-rt/
  8. cross-project-tests/
  9. flang/
  10. flang-rt/
  11. libc/
  12. libclc/
  13. libcxx/
  14. libcxxabi/
  15. libsycl/
  16. libunwind/
  17. lld/
  18. lldb/
  19. llvm/
  20. llvm-libgcc/
  21. mlir/
  22. offload/
  23. openmp/
  24. orc-rt/
  25. polly/
  26. runtimes/
  27. third-party/
  28. utils/
  29. .clang-format
  30. .clang-format-ignore
  31. .clang-tidy
  32. .git-blame-ignore-revs
  33. .gitattributes
  34. .gitignore
  35. .mailmap
  36. CODE_OF_CONDUCT.md
  37. CONTRIBUTING.md
  38. LICENSE.TXT
  39. pyproject.toml
  40. README.md
  41. SECURITY.md
README.md

The LLVM Compiler Infrastructure

OpenSSF Scorecard OpenSSF Best Practices libc++

Welcome to the LLVM project!

This repository contains the source code for LLVM, a toolkit for the construction of highly optimized compilers, optimizers, and run-time environments.

The LLVM project has multiple components. The core of the project is itself called “LLVM”. This contains all of the tools, libraries, and header files needed to process intermediate representations and convert them into object files. Tools include an assembler, disassembler, bitcode analyzer, and bitcode optimizer.

C-like languages use the Clang frontend. This component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode -- and from there into object files, using LLVM.

Other components include: the libc++ C++ standard library, the LLD linker, and more.

Getting the Source Code and Building LLVM

Consult the Getting Started with LLVM page for information on building and running LLVM.

For information on how to contribute to the LLVM project, please take a look at the Contributing to LLVM guide.

Getting in touch

Join the LLVM Discourse forums, Discord chat, LLVM Office Hours or Regular sync-ups.

The LLVM project has adopted a code of conduct for participants to all modes of communication within the project.