compute-runtime/shared/source/kernel/kernel_arg_metadata.h

204 lines
5.8 KiB
C++

/*
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/compiler_interface/compiler_options/compiler_options_base.h"
#include "shared/source/utilities/const_stringref.h"
#include <cstdint>
#include <cstring>
#include <memory>
#include <string>
#include <type_traits>
namespace NEO {
namespace KernelArgMetadata {
enum AccessQualifier : uint8_t {
AccessUnknown,
AccessNone,
AccessReadOnly,
AccessWriteOnly,
AccessReadWrite,
};
namespace AccessQualifierStrings {
constexpr ConstStringRef none = "NONE";
constexpr ConstStringRef readOnly = "read_only";
constexpr ConstStringRef writeOnly = "write_only";
constexpr ConstStringRef readWrite = "read_write";
constexpr ConstStringRef underscoreReadOnly = "__read_only";
constexpr ConstStringRef underscoreWriteOnly = "__write_only";
constexpr ConstStringRef underscoreReadWrite = "__read_write";
} // namespace AccessQualifierStrings
enum AddressSpaceQualifier : uint8_t {
AddrUnknown,
AddrGlobal,
AddrLocal,
AddrPrivate,
AddrConstant
};
namespace AddressSpaceQualifierStrings {
constexpr ConstStringRef addrGlobal = "__global";
constexpr ConstStringRef addrLocal = "__local";
constexpr ConstStringRef addrPrivate = "__private";
constexpr ConstStringRef addrConstant = "__constant";
constexpr ConstStringRef addrNotSpecified = "not_specified";
} // namespace AddressSpaceQualifierStrings
constexpr AccessQualifier parseAccessQualifier(ConstStringRef str) {
using namespace AccessQualifierStrings;
if (str.empty() || (none == str)) {
return AccessNone;
}
if (str.length() < 3) {
return AccessUnknown;
}
ConstStringRef strNoUnderscore = ('_' == str[0]) ? ConstStringRef(str.data() + 2, str.length() - 2) : str;
static_assert(writeOnly[0] != readOnly[0], "");
static_assert(writeOnly[0] != readWrite[0], "");
if (strNoUnderscore[0] == writeOnly[0]) {
return (writeOnly == strNoUnderscore) ? AccessWriteOnly : AccessUnknown;
}
if (readOnly == strNoUnderscore) {
return AccessReadOnly;
}
return (readWrite == strNoUnderscore) ? AccessReadWrite : AccessUnknown;
}
constexpr AddressSpaceQualifier parseAddressSpace(ConstStringRef str) {
using namespace AddressSpaceQualifierStrings;
if (str.empty()) {
return AddrGlobal;
}
if (str.length() < 3) {
return AddrUnknown;
}
switch (str[2]) {
default:
return AddrUnknown;
case addrNotSpecified[2]:
return (str == addrNotSpecified) ? AddrPrivate : AddrUnknown;
case addrGlobal[2]:
return (str == addrGlobal) ? AddrGlobal : AddrUnknown;
case addrLocal[2]:
return (str == addrLocal) ? AddrLocal : AddrUnknown;
case addrPrivate[2]:
return (str == addrPrivate) ? AddrPrivate : AddrUnknown;
case addrConstant[2]:
return (str == addrConstant) ? AddrConstant : AddrUnknown;
}
}
union TypeQualifiers {
uint8_t packed = 0U;
struct {
bool constQual : 1;
bool volatileQual : 1;
bool restrictQual : 1;
bool pipeQual : 1;
bool unknownQual : 1;
};
bool empty() const {
return 0U == packed;
}
};
namespace TypeQualifierStrings {
constexpr ConstStringRef qualConst = "const";
constexpr ConstStringRef qualVolatile = "volatile";
constexpr ConstStringRef qualRestrict = "restrict";
constexpr ConstStringRef qualPipe = "pipe";
} // namespace TypeQualifierStrings
inline TypeQualifiers parseTypeQualifiers(ConstStringRef str) {
using namespace TypeQualifierStrings;
TypeQualifiers ret = {};
auto tokenized = CompilerOptions::tokenize(str);
for (const auto &tok : tokenized) {
bool knownQualifier = true;
switch (tok[0]) {
default:
knownQualifier = false;
break;
case qualConst[0]:
knownQualifier = (qualConst == tok);
ret.constQual |= knownQualifier;
break;
case qualVolatile[0]:
knownQualifier = (qualVolatile == tok);
ret.volatileQual |= knownQualifier;
break;
case qualRestrict[0]:
knownQualifier = (qualRestrict == tok);
ret.restrictQual |= knownQualifier;
break;
case qualPipe[0]:
knownQualifier = (qualPipe == tok);
ret.pipeQual |= knownQualifier;
break;
}
ret.unknownQual |= !knownQualifier;
}
return ret;
}
} // namespace KernelArgMetadata
inline std::string parseLimitedString(const char *str, size_t maxSize) {
std::string ret{str, str + maxSize};
size_t minSize = strlen(ret.c_str());
ret.assign(str, minSize);
return ret;
}
struct ArgTypeTraits {
ArgTypeTraits() {
accessQualifier = KernelArgMetadata::AccessUnknown;
addressQualifier = KernelArgMetadata::AddrGlobal;
}
uint16_t argByValSize = 0U;
struct {
std::underlying_type_t<KernelArgMetadata::AccessQualifier> accessQualifier : 4;
std::underlying_type_t<KernelArgMetadata::AddressSpaceQualifier> addressQualifier : 4;
};
KernelArgMetadata::TypeQualifiers typeQualifiers;
KernelArgMetadata::AccessQualifier getAccessQualifier() const {
return static_cast<KernelArgMetadata::AccessQualifier>(accessQualifier);
}
KernelArgMetadata::AddressSpaceQualifier getAddressQualifier() const {
return static_cast<KernelArgMetadata::AddressSpaceQualifier>(addressQualifier);
}
};
namespace {
static constexpr auto ArgTypeMetadataSize = sizeof(ArgTypeTraits);
static_assert(ArgTypeMetadataSize <= 4, "Keep it small");
} // namespace
struct ArgTypeMetadataExtended {
std::string argName;
std::string type;
std::string accessQualifier;
std::string addressQualifier;
std::string typeQualifiers;
};
} // namespace NEO