/* * Copyright (C) 2020-2022 Intel Corporation * * SPDX-License-Identifier: MIT * */ #pragma once #include "shared/source/compiler_interface/compiler_options.h" #include "shared/source/utilities/const_stringref.h" #include #include #include #include #include namespace NEO { namespace KernelArgMetadata { enum AccessQualifier : uint8_t { AccessUnknown, AccessNone, AccessReadOnly, AccessWriteOnly, AccessReadWrite, }; namespace AccessQualifierStrings { inline constexpr ConstStringRef none = "NONE"; inline constexpr ConstStringRef readOnly = "read_only"; inline constexpr ConstStringRef writeOnly = "write_only"; inline constexpr ConstStringRef readWrite = "read_write"; inline constexpr ConstStringRef underscoreReadOnly = "__read_only"; inline constexpr ConstStringRef underscoreWriteOnly = "__write_only"; inline constexpr ConstStringRef underscoreReadWrite = "__read_write"; } // namespace AccessQualifierStrings enum AddressSpaceQualifier : uint8_t { AddrUnknown, AddrGlobal, AddrLocal, AddrPrivate, AddrConstant }; namespace AddressSpaceQualifierStrings { inline constexpr ConstStringRef addrGlobal = "__global"; inline constexpr ConstStringRef addrLocal = "__local"; inline constexpr ConstStringRef addrPrivate = "__private"; inline constexpr ConstStringRef addrConstant = "__constant"; inline 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 { inline constexpr ConstStringRef qualConst = "const"; inline constexpr ConstStringRef qualVolatile = "volatile"; inline constexpr ConstStringRef qualRestrict = "restrict"; inline 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 accessQualifier : 4; std::underlying_type_t addressQualifier : 4; }; KernelArgMetadata::TypeQualifiers typeQualifiers; KernelArgMetadata::AccessQualifier getAccessQualifier() const { return static_cast(accessQualifier); } KernelArgMetadata::AddressSpaceQualifier getAddressQualifier() const { return static_cast(addressQualifier); } }; namespace { inline 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