[Clang][BPF] Add __BPF_CPU_VERSION__ macro (#71856)

Sometimes bpf developer might want to develop different codes
based on particular cpu versioins. For example, cpu v1/v2/v3
branch target is 16bit while cpu v4 branch target is 32bit,
thus cpu v4 allows more aggressive loop unrolling than cpu v1/v2/v3
(see [1] for a kernel selftest failure due to this).
We would like to maintain aggressive loop unrolling for cpu v4
while limit loop unrolling for earlier cpu versions.
Another example, signed divide also only available with cpu v4.

Actually, adding cpu specific macros are fairly common
in llvm. For example, x86 has maco like 'i486', '__pentium_mmx__', etc.
AArch64 has '__ARM_NEON', '__ARM_FEATURE_SVE', etc.

This patch added __BPF_CPU_VERSION__ macro. Current possible values
are 0/1/2/3/4. The following are the -mcpu=... to __BPF_CPU_VERSION__
mapping:
```
       cpu                  __BPF_CPU_VERSION__
       no -mcpu=<...>       1
       -mcpu=v1             1
       -mcpu=v2             2
       -mcpu=v3             3
       -mcpu=v4             4
       -mcpu=generic        1
       -mcpu=probe          0
```
    
This patch also added some macros for developers to identify some cpu
insn features:
```
      feature macro               enabled in which cpu
      __BPF_FEATURE_JMP_EXT       >= v2
      __BPF_FEATURE_JMP32         >= v3
      __BPF_FEATURE_ALU32         >= v3
      __BPF_FEATURE_LDSX          >= v4
      __BPF_FEATURE_MOVSX         >= v4
      __BPF_FEATURE_BSWAP         >= v4
      __BPF_FEATURE_SDIV_SMOD     >= v4
      __BPF_FEATURE_GOTOL         >= v4
      __BPF_FEATURE_ST            >= v4
```    
[1]
https://lore.kernel.org/bpf/3e3a8a30-dde0-43a1-981e-2274962780ef@linux.dev/
This commit is contained in:
yonghong-song 2023-11-10 10:18:54 -08:00 committed by GitHub
parent 8909ff6927
commit 4e67234357
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 112 additions and 2 deletions

View File

@ -29,6 +29,37 @@ void BPFTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("__bpf__");
Builder.defineMacro("__BPF__");
std::string CPU = getTargetOpts().CPU;
if (CPU == "probe") {
Builder.defineMacro("__BPF_CPU_VERSION__", "0");
return;
}
if (CPU.empty() || CPU == "generic" || CPU == "v1") {
Builder.defineMacro("__BPF_CPU_VERSION__", "1");
return;
}
std::string CpuVerNumStr = CPU.substr(1);
Builder.defineMacro("__BPF_CPU_VERSION__", CpuVerNumStr);
int CpuVerNum = std::stoi(CpuVerNumStr);
if (CpuVerNum >= 2)
Builder.defineMacro("__BPF_FEATURE_JMP_EXT");
if (CpuVerNum >= 3) {
Builder.defineMacro("__BPF_FEATURE_JMP32");
Builder.defineMacro("__BPF_FEATURE_ALU32");
}
if (CpuVerNum >= 4) {
Builder.defineMacro("__BPF_FEATURE_LDSX");
Builder.defineMacro("__BPF_FEATURE_MOVSX");
Builder.defineMacro("__BPF_FEATURE_BSWAP");
Builder.defineMacro("__BPF_FEATURE_SDIV_SMOD");
Builder.defineMacro("__BPF_FEATURE_GOTOL");
Builder.defineMacro("__BPF_FEATURE_ST");
}
}
static constexpr llvm::StringLiteral ValidCPUNames[] = {"generic", "v1", "v2",

View File

@ -1,5 +1,11 @@
// RUN: %clang -E -target bpfel -x c -o - %s | FileCheck %s
// RUN: %clang -E -target bpfeb -x c -o - %s | FileCheck %s
// RUN: %clang -E -target bpfel -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_NO %s
// RUN: %clang -E -target bpfeb -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_NO %s
// RUN: %clang -E -target bpfel -mcpu=v1 -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_V1 %s
// RUN: %clang -E -target bpfel -mcpu=v2 -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_V2 %s
// RUN: %clang -E -target bpfel -mcpu=v3 -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_V3 %s
// RUN: %clang -E -target bpfel -mcpu=v4 -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_V4 %s
// RUN: %clang -E -target bpfel -mcpu=generic -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_GENERIC %s
// RUN: %clang -E -target bpfel -mcpu=probe -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_PROBE %s
#ifdef __bpf__
int b;
@ -10,7 +16,80 @@ int c;
#ifdef bpf
int d;
#endif
#ifdef __BPF_CPU_VERSION__
int e;
#endif
#if __BPF_CPU_VERSION__ == 0
int f;
#endif
#if __BPF_CPU_VERSION__ == 1
int g;
#endif
#if __BPF_CPU_VERSION__ == 2
int h;
#endif
#if __BPF_CPU_VERSION__ == 3
int i;
#endif
#if __BPF_CPU_VERSION__ == 4
int j;
#endif
#ifdef __BPF_FEATURE_JMP_EXT
int k;
#endif
#ifdef __BPF_FEATURE_JMP32
int l;
#endif
#ifdef __BPF_FEATURE_ALU32
int m;
#endif
#ifdef __BPF_FEATURE_LDSX
int n;
#endif
#ifdef __BPF_FEATURE_MOVSX
int o;
#endif
#ifdef __BPF_FEATURE_BSWAP
int p;
#endif
#ifdef __BPF_FEATURE_SDIV_SMOD
int q;
#endif
#ifdef __BPF_FEATURE_GOTOL
int r;
#endif
#ifdef __BPF_FEATURE_ST
int s;
#endif
// CHECK: int b;
// CHECK: int c;
// CHECK-NOT: int d;
// CHECK: int e;
// CPU_NO: int g;
// CPU_V1: int g;
// CPU_V2: int h;
// CPU_V2: int k;
// CPU_V3: int i;
// CPU_V3: int k;
// CPU_V3: int l;
// CPU_V3: int m;
// CPU_V4: int j;
// CPU_V4: int k;
// CPU_V4: int l;
// CPU_V4: int m;
// CPU_V4: int n;
// CPU_V4: int o;
// CPU_V4: int p;
// CPU_V4: int q;
// CPU_V4: int r;
// CPU_V4: int s;
// CPU_GENERIC: int g;
// CPU_PROBE: int f;