1 /*
2  * Copyright (C) 2019-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #pragma once
9 
10 #include "shared/source/utilities/const_stringref.h"
11 #include "shared/source/utilities/stackvec.h"
12 
13 #include <algorithm>
14 #include <functional>
15 
16 namespace NEO {
17 namespace CompilerOptions {
18 static constexpr ConstStringRef greaterThan4gbBuffersRequired = "-cl-intel-greater-than-4GB-buffer-required";
19 static constexpr ConstStringRef hasBufferOffsetArg = "-cl-intel-has-buffer-offset-arg";
20 static constexpr ConstStringRef kernelDebugEnable = "-cl-kernel-debug-enable";
21 static constexpr ConstStringRef arch32bit = "-m32";
22 static constexpr ConstStringRef arch64bit = "-m64";
23 static constexpr ConstStringRef debugKernelEnable = "-cl-kernel-debug-enable";
24 static constexpr ConstStringRef optDisable = "-cl-opt-disable";
25 static constexpr ConstStringRef argInfo = "-cl-kernel-arg-info";
26 static constexpr ConstStringRef gtpinRera = "-cl-intel-gtpin-rera";
27 static constexpr ConstStringRef finiteMathOnly = "-cl-finite-math-only";
28 static constexpr ConstStringRef fastRelaxedMath = "-cl-fast-relaxed-math";
29 static constexpr ConstStringRef preserveVec3Type = "-fpreserve-vec3-type";
30 static constexpr ConstStringRef createLibrary = "-create-library";
31 static constexpr ConstStringRef generateDebugInfo = "-g";
32 static constexpr ConstStringRef bindlessMode = "-cl-intel-use-bindless-mode -cl-intel-use-bindless-advanced-mode";
33 static constexpr ConstStringRef uniformWorkgroupSize = "-cl-uniform-work-group-size";
34 static constexpr ConstStringRef forceEmuInt32DivRem = "-cl-intel-force-emu-int32divrem";
35 static constexpr ConstStringRef forceEmuInt32DivRemSP = "-cl-intel-force-emu-sp-int32divrem";
36 static constexpr ConstStringRef allowZebin = "-allow-zebin";
37 static constexpr ConstStringRef enableImageSupport = "-D__IMAGE_SUPPORT__=1";
38 static constexpr ConstStringRef optLevel = "-ze-opt-level=O";
39 static constexpr ConstStringRef excludeIrFromZebin = "-exclude-ir-from-zebin";
40 static constexpr ConstStringRef noRecompiledFromIr = "-Wno-recompiled-from-ir";
41 
42 constexpr size_t nullterminateSize = 1U;
43 constexpr size_t spaceSeparatorSize = 1U;
44 
45 template <size_t Length>
length(const char (& array)[Length])46 constexpr size_t length(const char (&array)[Length]) {
47     return Length;
48 }
49 
length(ConstStringRef string)50 constexpr size_t length(ConstStringRef string) {
51     return string.length();
52 }
53 
length(const std::string & string)54 inline size_t length(const std::string &string) {
55     return string.length();
56 }
57 
length(const char * string)58 constexpr size_t length(const char *string) {
59     return constLength(string);
60 }
61 
data(ConstStringRef string)62 constexpr const char *data(ConstStringRef string) {
63     return string.data();
64 }
65 
data(const std::string & string)66 inline const char *data(const std::string &string) {
67     return string.data();
68 }
69 
data(const char * string)70 constexpr const char *data(const char *string) {
71     return string;
72 }
73 
74 template <typename T>
concatenationLength(const T & t)75 constexpr size_t concatenationLength(const T &t) {
76     return length(t);
77 }
78 
79 template <typename T, typename... RestT>
concatenationLength(const T & arg,const RestT &...rest)80 constexpr size_t concatenationLength(const T &arg, const RestT &...rest) {
81     return length(arg) + spaceSeparatorSize + concatenationLength(rest...);
82 }
83 
84 template <typename ContainerT, typename T>
concatenateAppend(ContainerT & out,T && arg)85 inline void concatenateAppend(ContainerT &out, T &&arg) {
86     if ((false == out.empty()) && (*out.rbegin() != ' ')) {
87         out.push_back(' ');
88     }
89     out.insert(out.end(), data(arg), data(arg) + length(arg));
90 }
91 
92 template <typename ContainerT, typename T, typename... RestT>
concatenateAppend(ContainerT & out,T && arg,RestT &&...rest)93 inline void concatenateAppend(ContainerT &out, T &&arg, RestT &&...rest) {
94     concatenateAppend(out, std::forward<T>(arg));
95     concatenateAppend(out, std::forward<RestT>(rest)...);
96 }
97 
98 template <typename T, typename... RestT>
concatenate(T && arg,RestT &&...rest)99 inline std::string concatenate(T &&arg, RestT &&...rest) {
100     std::string ret;
101     ret.reserve(nullterminateSize + concatenationLength(arg, rest...));
102     concatenateAppend(ret, std::forward<T>(arg), std::forward<RestT>(rest)...);
103     return ret;
104 }
105 
106 template <size_t NumOptions>
concatenationLength(const ConstStringRef (& options)[NumOptions])107 constexpr size_t concatenationLength(const ConstStringRef (&options)[NumOptions]) {
108     size_t ret = 0U;
109     for (auto opt : options) {
110         ret += spaceSeparatorSize + opt.length();
111     }
112     return (ret != 0U) ? ret - nullterminateSize : 0U;
113 }
114 
115 template <typename ContainerT>
extract(const ConstStringRef & toBeExtracted,ContainerT & options)116 inline bool extract(const ConstStringRef &toBeExtracted, ContainerT &options) {
117     const auto first{std::search(options.begin(), options.end(),
118                                  std::default_searcher{toBeExtracted.begin(), toBeExtracted.end()})};
119 
120     if (first == options.end()) {
121         return false;
122     }
123 
124     const auto last{std::next(first, toBeExtracted.length())};
125     options.erase(first, last);
126 
127     return true;
128 }
129 
130 template <size_t MaxLength = 256>
131 class ConstConcatenation {
132   public:
133     template <size_t NumOptions>
ConstConcatenation(const ConstStringRef (& options)[NumOptions])134     constexpr ConstConcatenation(const ConstStringRef (&options)[NumOptions]) {
135         size_t i = 0U;
136         for (auto opt : options) {
137             for (size_t j = 0U, e = opt.length(); j < e; ++j, ++i) {
138                 storage[i] = opt[j];
139             }
140             storage[i] = ' ';
141             ++i;
142         }
143         length = i;
144         if (i > 0U) {
145             storage[i - 1] = '\0';
146         }
147     }
148 
ConstStringRef()149     constexpr operator ConstStringRef() const {
150         return ConstStringRef(storage, (length > 0U) ? (length - 1) : 0U);
151     }
152 
153     constexpr operator const char *() const {
154         return storage;
155     }
156 
157   protected:
158     char storage[MaxLength + nullterminateSize] = {};
159     size_t length = 0U;
160 };
161 
162 template <size_t MaxLength>
163 bool operator==(const ConstStringRef &lhs, const ConstConcatenation<MaxLength> &rhs) {
164     return lhs == rhs.operator ConstStringRef();
165 }
166 
167 template <size_t MaxLength>
168 bool operator==(const ConstConcatenation<MaxLength> &lhs, const ConstStringRef &rhs) {
169     return rhs == lhs;
170 }
171 
172 bool contains(const char *options, ConstStringRef optionToFind);
173 
174 bool contains(const std::string &options, ConstStringRef optionToFind);
175 
176 using TokenizedString = StackVec<ConstStringRef, 32>;
177 TokenizedString tokenize(ConstStringRef src, char sperator = ' ');
178 } // namespace CompilerOptions
179 } // namespace NEO
180