diff options
-rw-r--r-- | src/gallium/frontends/clover/llvm/invocation.cpp | 87 |
1 files 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"); |