[clang] [Clang][BPF] Add __bpf_cpu_version__ macro (PR #71856)

via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 9 15:22:22 PST 2023


https://github.com/yonghong-song updated https://github.com/llvm/llvm-project/pull/71856

>From fd2b39e869cf3b8395113bac409486cc052ca749 Mon Sep 17 00:00:00 2001
From: Yonghong Song <yonghong.song at linux.dev>
Date: Thu, 9 Nov 2023 15:16:03 -0800
Subject: [PATCH] [Clang][BPF] Add __bpf_cpu_version__ macro

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/
---
 clang/lib/Basic/Targets/BPF.cpp               | 31 +++++++
 .../test/Preprocessor/bpf-predefined-macros.c | 83 ++++++++++++++++++-
 2 files changed, 112 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Basic/Targets/BPF.cpp b/clang/lib/Basic/Targets/BPF.cpp
index d6288d2e0d0e176..e713e084792233e 100644
--- a/clang/lib/Basic/Targets/BPF.cpp
+++ b/clang/lib/Basic/Targets/BPF.cpp
@@ -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",
diff --git a/clang/test/Preprocessor/bpf-predefined-macros.c b/clang/test/Preprocessor/bpf-predefined-macros.c
index bcb985f95426622..ff4d00ac3bcfcc1 100644
--- a/clang/test/Preprocessor/bpf-predefined-macros.c
+++ b/clang/test/Preprocessor/bpf-predefined-macros.c
@@ -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;



More information about the cfe-commits mailing list