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>
This commit is contained in:
committed by
Dave Airlie
parent
b8a96199cb
commit
330c524762
@@ -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());
|
||||
const auto device_ver = get_cl_version(device_version);
|
||||
const auto requested = get_cl_version(ver);
|
||||
if (requested.version_number > device_ver.version_number) {
|
||||
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();
|
||||
}
|
||||
return get_lang_standard_from_version_str(ver, true);
|
||||
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 > device_ver) {
|
||||
throw build_error();
|
||||
}
|
||||
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");
|
||||
|
||||
Reference in New Issue
Block a user