Mesa (master): clover/llvm: don't use strings for version handling.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Nov 10 20:56:33 UTC 2020


Module: Mesa
Branch: master
Commit: 330c52476292d2cfba15499f2f74ca224f227260
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=330c52476292d2cfba15499f2f74ca224f227260

Author: Pierre Moreau <dev at pmoreau.org>
Date:   Tue Nov 10 11:39:08 2020 +1000

clover/llvm: don't use strings for version handling.

This is extracted from Pierre's WIP versioning patch.

Reviewed-by: Dave Airlie <airlied at redhat.com>
Reviewed-by: Karol Herbst <kherbst at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7520>

---

 src/gallium/frontends/clover/llvm/invocation.cpp | 87 ++++++++++++++----------
 1 file changed, 51 insertions(+), 36 deletions(-)

diff --git a/src/gallium/frontends/clover/llvm/invocation.cpp b/src/gallium/frontends/clover/llvm/invocation.cpp
index fefb178429a..93e9cbc360b 100644
--- a/src/gallium/frontends/clover/llvm/invocation.cpp
+++ b/src/gallium/frontends/clover/llvm/invocation.cpp
@@ -70,37 +70,41 @@ using ::llvm::raw_string_ostream;
 
 namespace {
 
-    struct cl_version {
-        std::string version_str; // CL Version
-        unsigned version_number; // Numeric CL Version
-    };
-
-   static const unsigned ANY_VERSION = 999;
+   static const cl_version ANY_VERSION = CL_MAKE_VERSION(9, 9, 9);
    const cl_version cl_versions[] = {
-      { "1.0", 100},
-      { "1.1", 110},
-      { "1.2", 120},
-      { "2.0", 200},
-      { "2.1", 210},
-      { "2.2", 220},
-      { "3.0", 300},
+      CL_MAKE_VERSION(1, 1, 0),
+      CL_MAKE_VERSION(1, 2, 0),
+      CL_MAKE_VERSION(2, 0, 0),
+      CL_MAKE_VERSION(2, 1, 0),
+      CL_MAKE_VERSION(2, 2, 0),
+      CL_MAKE_VERSION(3, 0, 0),
    };
 
     struct clc_version_lang_std {
-        unsigned version_number; // CLC Version
+        cl_version version_number; // CLC Version
         clang::LangStandard::Kind clc_lang_standard;
     };
 
     const clc_version_lang_std cl_version_lang_stds[] = {
-       { 100, clang::LangStandard::lang_opencl10},
-       { 110, clang::LangStandard::lang_opencl11},
-       { 120, clang::LangStandard::lang_opencl12},
-       { 200, clang::LangStandard::lang_opencl20},
+       { CL_MAKE_VERSION(1, 0, 0), clang::LangStandard::lang_opencl10},
+       { CL_MAKE_VERSION(1, 1, 0), clang::LangStandard::lang_opencl11},
+       { CL_MAKE_VERSION(1, 2, 0), clang::LangStandard::lang_opencl12},
+       { CL_MAKE_VERSION(2, 0, 0), clang::LangStandard::lang_opencl20},
 #if LLVM_VERSION_MAJOR >= 12
-       { 300, clang::LangStandard::lang_opencl30},
+       { CL_MAKE_VERSION(3, 0, 0), clang::LangStandard::lang_opencl30},
 #endif
     };
 
+   bool
+   are_equal(cl_version_khr version1, cl_version_khr version2,
+             bool ignore_patch_version = false) {
+      if (ignore_patch_version) {
+         version1 &= ~CL_VERSION_PATCH_MASK_KHR;
+         version2 &= ~CL_VERSION_PATCH_MASK_KHR;
+      }
+      return version1 == version2;
+   }
+
    void
    init_targets() {
       static bool targets_initialized = false;
@@ -144,11 +148,12 @@ namespace {
        throw build_error("Unknown/Unsupported language version");
    }
 
-   const struct cl_version&
-   get_cl_version(const std::string &version_str,
-                  unsigned max = ANY_VERSION) {
-      for (const struct cl_version &version : cl_versions) {
-         if (version.version_number == max || version.version_str == version_str) {
+   const cl_version
+   get_cl_version(cl_version requested,
+                  cl_version max = ANY_VERSION) {
+      for (const auto &version : cl_versions) {
+         if (are_equal(version, max, true) ||
+             are_equal(version, requested, true)) {
             return version;
          }
       }
@@ -156,41 +161,50 @@ namespace {
    }
 
    clang::LangStandard::Kind
-   get_lang_standard_from_version_str(const std::string &version_str,
-                                      bool is_build_opt = false) {
+   get_lang_standard_from_version(const cl_version input_version,
+                                  bool is_build_opt = false) {
 
        //Per CL 2.0 spec, section 5.8.4.5:
        //  If it's an option, use the value directly.
        //  If it's a device version, clamp to max 1.x version, a.k.a. 1.2
       const cl_version version =
-         get_cl_version(version_str, is_build_opt ? ANY_VERSION : 120);
+         get_cl_version(input_version, is_build_opt ? ANY_VERSION : 120);
 
       const struct clc_version_lang_std standard =
-         get_cl_lang_standard(version.version_number);
+         get_cl_lang_standard(version);
 
       return standard.clc_lang_standard;
    }
 
    clang::LangStandard::Kind
    get_language_version(const std::vector<std::string> &opts,
-                        const std::string &device_version) {
+                        const cl_version device_version) {
 
       const std::string search = "-cl-std=CL";
 
       for (auto &opt: opts) {
          auto pos = opt.find(search);
          if (pos == 0){
-            const auto ver = opt.substr(pos + search.size());
+            std::stringstream ver_str(opt.substr(pos + search.size()));
+            unsigned int ver_major = 0;
+            char separator = '\0';
+            unsigned int ver_minor = 0;
+            ver_str >> ver_major >> separator >> ver_minor;
+            if (ver_str.fail() || ver_str.bad() || !ver_str.eof() ||
+                 separator != '.') {
+               throw build_error();
+            }
+            const auto ver = CL_MAKE_VERSION_KHR(ver_major, ver_minor, 0);
             const auto device_ver = get_cl_version(device_version);
             const auto requested = get_cl_version(ver);
-            if (requested.version_number > device_ver.version_number) {
+            if (requested > device_ver) {
                throw build_error();
             }
-            return get_lang_standard_from_version_str(ver, true);
+            return get_lang_standard_from_version(ver, true);
          }
       }
 
-      return get_lang_standard_from_version_str(device_version);
+      return get_lang_standard_from_version(device_version);
    }
 
    std::unique_ptr<clang::CompilerInstance>
@@ -209,7 +223,7 @@ namespace {
          map(std::mem_fn(&std::string::c_str), opts);
 
       const target &target = ir_target;
-      const std::string &device_clc_version = dev.device_clc_version_as_string();
+      const cl_version device_clc_version = dev.device_clc_version();
 
       if (!compat::create_compiler_invocation_from_args(
              c->getInvocation(), copts, diag))
@@ -272,9 +286,10 @@ namespace {
       }
 
       // Add definition for the OpenCL version
+      const auto dev_version = dev.device_version();
       c.getPreprocessorOpts().addMacroDef("__OPENCL_VERSION__=" +
-              std::to_string(get_cl_version(
-                                  dev.device_version_as_string()).version_number));
+                                          std::to_string(CL_VERSION_MAJOR_KHR(dev_version)) +
+                                          std::to_string(CL_VERSION_MINOR_KHR(dev_version)) + "0");
 
       // clc.h requires that this macro be defined:
       c.getPreprocessorOpts().addMacroDef("cl_clang_storage_class_specifiers");



More information about the mesa-commit mailing list