mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 09:08:10 +02:00
clover/llvm: Add get_[cl|language]_version, validation and some helpers
Used to calculate the default CLC language version based on the --cl-std in build args
and the device capabilities.
According to section 5.8.4.5 of the 2.0 spec, the CL C version is chosen by:
1) If you have -cl-std=CL1.1+ use the version specified
2) If not, use the highest 1.x version that the device supports
Curiously, there is no valid value for -cl-std=CL1.0
Validates requested cl-std against device_clc_version
Signed-off-by: Aaron Watry <awatry@gmail.com>
Reviewed-by: Pierre Moreau <pierre.morrow@free.fr>
v7: (Pierre) Split cl/clc versions into separate lists and
make more references const.
v6: (Pierre) Add more const and fix some whitespace
v5: (Aaron) Use a collection of cl versions instead of switch cases
Consolidates the string, numeric version, and clc langstandard::kind
v4: (Pierre) Split get_language_version addition and use into separate patches
Squash patches that add the helpers and validate the language standard
v3: Change device_version to device_clc_version
v2: (Pierre) Move create_compiler_instance changes to correct patch
to prevent temporary build breakage.
Convert version_str into unsigned and use it to find language version
Add build_error for unknown language version string
Whitespace fixes
This commit is contained in:
parent
14fffefc60
commit
29b4090d18
1 changed files with 88 additions and 0 deletions
|
|
@ -63,6 +63,34 @@ using ::llvm::Module;
|
|||
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;
|
||||
const cl_version cl_versions[] = {
|
||||
{ "1.0", 100},
|
||||
{ "1.1", 110},
|
||||
{ "1.2", 120},
|
||||
{ "2.0", 200},
|
||||
{ "2.1", 210},
|
||||
{ "2.2", 220},
|
||||
};
|
||||
|
||||
struct clc_version_lang_std {
|
||||
unsigned 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},
|
||||
};
|
||||
|
||||
void
|
||||
init_targets() {
|
||||
static bool targets_initialized = false;
|
||||
|
|
@ -93,6 +121,66 @@ namespace {
|
|||
return ctx;
|
||||
}
|
||||
|
||||
const struct clc_version_lang_std&
|
||||
get_cl_lang_standard(unsigned requested, unsigned max = ANY_VERSION) {
|
||||
for (const struct clc_version_lang_std &version : cl_version_lang_stds) {
|
||||
if (version.version_number == max ||
|
||||
version.version_number == requested) {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
throw build_error("Unknown/Unsupported language version");
|
||||
}
|
||||
|
||||
clang::LangStandard::Kind
|
||||
get_lang_standard_from_version_str(const std::string &version_str,
|
||||
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);
|
||||
|
||||
const struct clc_version_lang_std standard =
|
||||
get_cl_lang_standard(version.version_number);
|
||||
|
||||
return standard.clc_lang_standard;
|
||||
}
|
||||
|
||||
clang::LangStandard::Kind
|
||||
get_language_version(const std::vector<std::string> &opts,
|
||||
const std::string &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) {
|
||||
throw build_error();
|
||||
}
|
||||
return get_lang_standard_from_version_str(ver, true);
|
||||
}
|
||||
}
|
||||
|
||||
return get_lang_standard_from_version_str(device_version);
|
||||
}
|
||||
|
||||
std::unique_ptr<clang::CompilerInstance>
|
||||
create_compiler_instance(const device &dev,
|
||||
const std::vector<std::string> &opts,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue