summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Moreau <dev@pmoreau.org>2020-11-10 11:39:08 +1000
committerDave Airlie <airlied@redhat.com>2020-11-11 06:08:59 +1000
commit330c52476292d2cfba15499f2f74ca224f227260 (patch)
treec978ad189725f0b13bffee1fb3f093202b156319
parentb8a96199cbf0a81011c35c594becae083626206c (diff)
clover/llvm: don't use strings for version handling.
This is extracted from Pierre's WIP versioning patch. Reviewed-by: Dave Airlie <airlied@redhat.com> Reviewed-by: Karol Herbst <kherbst@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7520>
-rw-r--r--src/gallium/frontends/clover/llvm/invocation.cpp87
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");