1 /*
2 * Copyright (C) 2020-2021 Intel Corporation
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 */
7
8 #pragma once
9
10 #include "shared/source/compiler_interface/compiler_options/compiler_options_base.h"
11 #include "shared/source/utilities/const_stringref.h"
12
13 #include <cstdint>
14 #include <cstring>
15 #include <memory>
16 #include <string>
17 #include <type_traits>
18
19 namespace NEO {
20
21 namespace KernelArgMetadata {
22
23 enum AccessQualifier : uint8_t {
24 AccessUnknown,
25 AccessNone,
26 AccessReadOnly,
27 AccessWriteOnly,
28 AccessReadWrite,
29 };
30
31 namespace AccessQualifierStrings {
32 constexpr ConstStringRef none = "NONE";
33 constexpr ConstStringRef readOnly = "read_only";
34 constexpr ConstStringRef writeOnly = "write_only";
35 constexpr ConstStringRef readWrite = "read_write";
36 constexpr ConstStringRef underscoreReadOnly = "__read_only";
37 constexpr ConstStringRef underscoreWriteOnly = "__write_only";
38 constexpr ConstStringRef underscoreReadWrite = "__read_write";
39 } // namespace AccessQualifierStrings
40
41 enum AddressSpaceQualifier : uint8_t {
42 AddrUnknown,
43 AddrGlobal,
44 AddrLocal,
45 AddrPrivate,
46 AddrConstant
47 };
48
49 namespace AddressSpaceQualifierStrings {
50 constexpr ConstStringRef addrGlobal = "__global";
51 constexpr ConstStringRef addrLocal = "__local";
52 constexpr ConstStringRef addrPrivate = "__private";
53 constexpr ConstStringRef addrConstant = "__constant";
54 constexpr ConstStringRef addrNotSpecified = "not_specified";
55 } // namespace AddressSpaceQualifierStrings
56
parseAccessQualifier(ConstStringRef str)57 constexpr AccessQualifier parseAccessQualifier(ConstStringRef str) {
58 using namespace AccessQualifierStrings;
59 if (str.empty() || (none == str)) {
60 return AccessNone;
61 }
62
63 if (str.length() < 3) {
64 return AccessUnknown;
65 }
66
67 ConstStringRef strNoUnderscore = ('_' == str[0]) ? ConstStringRef(str.data() + 2, str.length() - 2) : str;
68 static_assert(writeOnly[0] != readOnly[0], "");
69 static_assert(writeOnly[0] != readWrite[0], "");
70 if (strNoUnderscore[0] == writeOnly[0]) {
71 return (writeOnly == strNoUnderscore) ? AccessWriteOnly : AccessUnknown;
72 }
73
74 if (readOnly == strNoUnderscore) {
75 return AccessReadOnly;
76 }
77
78 return (readWrite == strNoUnderscore) ? AccessReadWrite : AccessUnknown;
79 }
80
parseAddressSpace(ConstStringRef str)81 constexpr AddressSpaceQualifier parseAddressSpace(ConstStringRef str) {
82 using namespace AddressSpaceQualifierStrings;
83 if (str.empty()) {
84 return AddrGlobal;
85 }
86
87 if (str.length() < 3) {
88 return AddrUnknown;
89 }
90
91 switch (str[2]) {
92 default:
93 return AddrUnknown;
94 case addrNotSpecified[2]:
95 return (str == addrNotSpecified) ? AddrPrivate : AddrUnknown;
96 case addrGlobal[2]:
97 return (str == addrGlobal) ? AddrGlobal : AddrUnknown;
98 case addrLocal[2]:
99 return (str == addrLocal) ? AddrLocal : AddrUnknown;
100 case addrPrivate[2]:
101 return (str == addrPrivate) ? AddrPrivate : AddrUnknown;
102 case addrConstant[2]:
103 return (str == addrConstant) ? AddrConstant : AddrUnknown;
104 }
105 }
106
107 union TypeQualifiers {
108 uint8_t packed = 0U;
109 struct {
110 bool constQual : 1;
111 bool volatileQual : 1;
112 bool restrictQual : 1;
113 bool pipeQual : 1;
114 bool unknownQual : 1;
115 };
empty()116 bool empty() const {
117 return 0U == packed;
118 }
119 };
120
121 namespace TypeQualifierStrings {
122 constexpr ConstStringRef qualConst = "const";
123 constexpr ConstStringRef qualVolatile = "volatile";
124 constexpr ConstStringRef qualRestrict = "restrict";
125 constexpr ConstStringRef qualPipe = "pipe";
126 } // namespace TypeQualifierStrings
127
parseTypeQualifiers(ConstStringRef str)128 inline TypeQualifiers parseTypeQualifiers(ConstStringRef str) {
129 using namespace TypeQualifierStrings;
130 TypeQualifiers ret = {};
131 auto tokenized = CompilerOptions::tokenize(str);
132 for (const auto &tok : tokenized) {
133 bool knownQualifier = true;
134 switch (tok[0]) {
135 default:
136 knownQualifier = false;
137 break;
138 case qualConst[0]:
139 knownQualifier = (qualConst == tok);
140 ret.constQual |= knownQualifier;
141 break;
142 case qualVolatile[0]:
143 knownQualifier = (qualVolatile == tok);
144 ret.volatileQual |= knownQualifier;
145 break;
146 case qualRestrict[0]:
147 knownQualifier = (qualRestrict == tok);
148 ret.restrictQual |= knownQualifier;
149 break;
150 case qualPipe[0]:
151 knownQualifier = (qualPipe == tok);
152 ret.pipeQual |= knownQualifier;
153 break;
154 }
155 ret.unknownQual |= !knownQualifier;
156 }
157 return ret;
158 }
159
160 } // namespace KernelArgMetadata
161
parseLimitedString(const char * str,size_t maxSize)162 inline std::string parseLimitedString(const char *str, size_t maxSize) {
163 std::string ret{str, str + maxSize};
164 size_t minSize = strlen(ret.c_str());
165 ret.assign(str, minSize);
166 return ret;
167 }
168
169 struct ArgTypeTraits {
ArgTypeTraitsArgTypeTraits170 ArgTypeTraits() {
171 accessQualifier = KernelArgMetadata::AccessUnknown;
172 addressQualifier = KernelArgMetadata::AddrGlobal;
173 }
174 uint16_t argByValSize = 0U;
175 struct {
176 std::underlying_type_t<KernelArgMetadata::AccessQualifier> accessQualifier : 4;
177 std::underlying_type_t<KernelArgMetadata::AddressSpaceQualifier> addressQualifier : 4;
178 };
179 KernelArgMetadata::TypeQualifiers typeQualifiers;
180
getAccessQualifierArgTypeTraits181 KernelArgMetadata::AccessQualifier getAccessQualifier() const {
182 return static_cast<KernelArgMetadata::AccessQualifier>(accessQualifier);
183 }
184
getAddressQualifierArgTypeTraits185 KernelArgMetadata::AddressSpaceQualifier getAddressQualifier() const {
186 return static_cast<KernelArgMetadata::AddressSpaceQualifier>(addressQualifier);
187 }
188 };
189
190 namespace {
191 static constexpr auto ArgTypeMetadataSize = sizeof(ArgTypeTraits);
192 static_assert(ArgTypeMetadataSize <= 4, "Keep it small");
193 } // namespace
194
195 struct ArgTypeMetadataExtended {
196 std::string argName;
197 std::string type;
198 std::string accessQualifier;
199 std::string addressQualifier;
200 std::string typeQualifiers;
201 };
202
203 } // namespace NEO
204