Skip to content

Commit 4e67234

Browse files
[Clang][BPF] Add __BPF_CPU_VERSION__ macro (llvm#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/[email protected]/
1 parent 8909ff6 commit 4e67234

File tree

2 files changed

+112
-2
lines changed

2 files changed

+112
-2
lines changed

clang/lib/Basic/Targets/BPF.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,37 @@ void BPFTargetInfo::getTargetDefines(const LangOptions &Opts,
2929
MacroBuilder &Builder) const {
3030
Builder.defineMacro("__bpf__");
3131
Builder.defineMacro("__BPF__");
32+
33+
std::string CPU = getTargetOpts().CPU;
34+
if (CPU == "probe") {
35+
Builder.defineMacro("__BPF_CPU_VERSION__", "0");
36+
return;
37+
}
38+
if (CPU.empty() || CPU == "generic" || CPU == "v1") {
39+
Builder.defineMacro("__BPF_CPU_VERSION__", "1");
40+
return;
41+
}
42+
43+
std::string CpuVerNumStr = CPU.substr(1);
44+
Builder.defineMacro("__BPF_CPU_VERSION__", CpuVerNumStr);
45+
46+
int CpuVerNum = std::stoi(CpuVerNumStr);
47+
if (CpuVerNum >= 2)
48+
Builder.defineMacro("__BPF_FEATURE_JMP_EXT");
49+
50+
if (CpuVerNum >= 3) {
51+
Builder.defineMacro("__BPF_FEATURE_JMP32");
52+
Builder.defineMacro("__BPF_FEATURE_ALU32");
53+
}
54+
55+
if (CpuVerNum >= 4) {
56+
Builder.defineMacro("__BPF_FEATURE_LDSX");
57+
Builder.defineMacro("__BPF_FEATURE_MOVSX");
58+
Builder.defineMacro("__BPF_FEATURE_BSWAP");
59+
Builder.defineMacro("__BPF_FEATURE_SDIV_SMOD");
60+
Builder.defineMacro("__BPF_FEATURE_GOTOL");
61+
Builder.defineMacro("__BPF_FEATURE_ST");
62+
}
3263
}
3364

3465
static constexpr llvm::StringLiteral ValidCPUNames[] = {"generic", "v1", "v2",

clang/test/Preprocessor/bpf-predefined-macros.c

+81-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1-
// RUN: %clang -E -target bpfel -x c -o - %s | FileCheck %s
2-
// RUN: %clang -E -target bpfeb -x c -o - %s | FileCheck %s
1+
// RUN: %clang -E -target bpfel -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_NO %s
2+
// RUN: %clang -E -target bpfeb -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_NO %s
3+
// RUN: %clang -E -target bpfel -mcpu=v1 -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_V1 %s
4+
// RUN: %clang -E -target bpfel -mcpu=v2 -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_V2 %s
5+
// RUN: %clang -E -target bpfel -mcpu=v3 -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_V3 %s
6+
// RUN: %clang -E -target bpfel -mcpu=v4 -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_V4 %s
7+
// RUN: %clang -E -target bpfel -mcpu=generic -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_GENERIC %s
8+
// RUN: %clang -E -target bpfel -mcpu=probe -x c -o - %s | FileCheck -check-prefix=CHECK -check-prefix=CPU_PROBE %s
39

410
#ifdef __bpf__
511
int b;
@@ -10,7 +16,80 @@ int c;
1016
#ifdef bpf
1117
int d;
1218
#endif
19+
#ifdef __BPF_CPU_VERSION__
20+
int e;
21+
#endif
22+
#if __BPF_CPU_VERSION__ == 0
23+
int f;
24+
#endif
25+
#if __BPF_CPU_VERSION__ == 1
26+
int g;
27+
#endif
28+
#if __BPF_CPU_VERSION__ == 2
29+
int h;
30+
#endif
31+
#if __BPF_CPU_VERSION__ == 3
32+
int i;
33+
#endif
34+
#if __BPF_CPU_VERSION__ == 4
35+
int j;
36+
#endif
37+
#ifdef __BPF_FEATURE_JMP_EXT
38+
int k;
39+
#endif
40+
#ifdef __BPF_FEATURE_JMP32
41+
int l;
42+
#endif
43+
#ifdef __BPF_FEATURE_ALU32
44+
int m;
45+
#endif
46+
#ifdef __BPF_FEATURE_LDSX
47+
int n;
48+
#endif
49+
#ifdef __BPF_FEATURE_MOVSX
50+
int o;
51+
#endif
52+
#ifdef __BPF_FEATURE_BSWAP
53+
int p;
54+
#endif
55+
#ifdef __BPF_FEATURE_SDIV_SMOD
56+
int q;
57+
#endif
58+
#ifdef __BPF_FEATURE_GOTOL
59+
int r;
60+
#endif
61+
#ifdef __BPF_FEATURE_ST
62+
int s;
63+
#endif
1364

1465
// CHECK: int b;
1566
// CHECK: int c;
1667
// CHECK-NOT: int d;
68+
// CHECK: int e;
69+
70+
// CPU_NO: int g;
71+
72+
// CPU_V1: int g;
73+
74+
// CPU_V2: int h;
75+
// CPU_V2: int k;
76+
77+
// CPU_V3: int i;
78+
// CPU_V3: int k;
79+
// CPU_V3: int l;
80+
// CPU_V3: int m;
81+
82+
// CPU_V4: int j;
83+
// CPU_V4: int k;
84+
// CPU_V4: int l;
85+
// CPU_V4: int m;
86+
// CPU_V4: int n;
87+
// CPU_V4: int o;
88+
// CPU_V4: int p;
89+
// CPU_V4: int q;
90+
// CPU_V4: int r;
91+
// CPU_V4: int s;
92+
93+
// CPU_GENERIC: int g;
94+
95+
// CPU_PROBE: int f;

0 commit comments

Comments
 (0)