[PATCH 36/42] use a more generic solution for pocl_get_distro_kernellib_name()
authorAndreas Beckmann <anbe@debian.org>
Wed, 23 Mar 2022 13:24:18 +0000 (14:24 +0100)
committerAndreas Beckmann <anbe@debian.org>
Tue, 12 Dec 2023 15:33:19 +0000 (16:33 +0100)
Gbp-Pq: Name 0036-use-a-more-generic-solution-for-pocl_get_distro_kern.patch

lib/CL/pocl_llvm_build.cc
lib/CL/pocl_llvm_utils.cc

index 1ae2c785a064a138828b6e804c2207188a7aaa2f..257d80e8200262dfa316241cf57431f25a4a0b50 100644 (file)
@@ -942,48 +942,6 @@ int pocl_llvm_link_program(cl_program program, unsigned device_i,
   return CL_SUCCESS;
 }
 
-/* for "distro" style kernel libs, return which kernellib to use, at runtime */
-#ifdef KERNELLIB_HOST_DISTRO_VARIANTS
-const char *pocl_get_distro_kernellib_name() {
-  StringMap<bool> Features;
-  const char *res = NULL;
-
-  if (!llvm::sys::getHostCPUFeatures(Features)) {
-    POCL_MSG_WARN("LLVM can't get host CPU flags!\n");
-    return NULL;
-  }
-
-#if defined(__x86_64__)
-  if (Features["sse2"])
-    res = "sse2";
-  if (Features["ssse3"] && Features["cx16"])
-    res = "ssse3";
-  if (Features["sse4.1"] && Features["cx16"])
-    res = "sse41";
-  if (Features["avx"] && Features["cx16"] && Features["popcnt"])
-    res = "avx";
-  if (Features["avx"] && Features["cx16"] && Features["popcnt"] && Features["f16c"])
-    res = "avx_f16c";
-  if (Features["avx"] && Features["cx16"] && Features["popcnt"]
-      && Features["xop"] && Features["fma4"])
-    res = "avx_fma4";
-  if (Features["avx"] && Features["avx2"] && Features["cx16"]
-      && Features["popcnt"] && Features["lzcnt"] && Features["f16c"]
-      && Features["fma"] && Features["bmi"] && Features["bmi2"])
-    res = "avx2";
-  if (Features["avx512f"] )
-    res = "avx512";
-#endif
-
-  if (!res)
-    POCL_MSG_WARN("Can't find a kernellib supported by the host CPU (%s)\n",
-                  llvm::sys::getHostCPUName());
-
-  return res;
-}
-#endif
-
-
 /**
  * Return the OpenCL C built-in function library bitcode
  * for the given device.
index dba89cc2c45e5b6259d4cf5feec11118ba5058d0..c55ee075d0d8fd1052e3fb3b164660aa4b2aa706 100644 (file)
@@ -157,6 +157,65 @@ char *pocl_get_llvm_cpu_name() {
   return cpu_name;
 }
 
+#ifdef KERNELLIB_HOST_DISTRO_VARIANTS
+const struct kernellib_features {
+  const char *kernellib_name;
+  const char *features[12];
+} kernellib_feature_map[] = {
+// order the entries s.t. if a cpu matches multiple entries, the "best" match
+// comes last
+#if defined(__x86_64__)
+    "sse2",
+    {"sse2", NULL},
+    "ssse3",
+    {"sse2", "ssse3", "cx16", NULL},
+    "sse41",
+    {"sse2", "sse4.1", "cx16", NULL},
+    "avx",
+    {"sse2", "avx", "cx16", "popcnt", NULL},
+    "avx_f16c",
+    {"sse2", "avx", "cx16", "popcnt", "f16c", NULL},
+    "avx_fma4",
+    {"sse2", "avx", "cx16", "popcnt", "xop", "fma4", NULL},
+    "avx2",
+    {"sse2", "avx", "avx2", "cx16", "popcnt", "lzcnt", "f16c", "fma", "bmi",
+     "bmi2", NULL},
+    "avx512",
+    {"sse2", "avx512f", NULL},
+#endif
+    NULL,
+    {NULL}};
+
+/* for "distro" style kernel libs, return which kernellib to use, at runtime */
+const char *pocl_get_distro_kernellib_name() {
+  StringMap<bool> Features;
+
+  if (!llvm::sys::getHostCPUFeatures(Features)) {
+    POCL_MSG_WARN("LLVM can't get host CPU flags!\n");
+    return "";
+  }
+
+  const kernellib_features *best_match = NULL;
+  for (const kernellib_features *kf = kernellib_feature_map; kf->kernellib_name;
+       ++kf) {
+    bool matches = true;
+    for (const char *const *f = kf->features; *f; ++f)
+      matches &= Features[*f];
+    if (matches) {
+      best_match = kf;
+    }
+  }
+
+  if (!best_match) {
+    POCL_MSG_WARN("Can't find a kernellib supported by the host CPU (%s)\n",
+                  llvm::sys::getHostCPUName());
+    return "";
+  }
+
+  return best_match->kernellib_name;
+}
+#endif
+
 int pocl_bitcode_is_triple(const char *bitcode, size_t size, const char *triple) {
   std::string Triple;
   if (getModuleTriple(bitcode, size, Triple) == 0)