Intel® Implicit SPMD Program Compiler (Intel® ISPC)  1.13.0
target_enums.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2019-2020, Intel Corporation
3  All rights reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are
7  met:
8 
9  * Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11 
12  * Redistributions in binary form must reproduce the above copyright
13  notice, this list of conditions and the following disclaimer in the
14  documentation and/or other materials provided with the distribution.
15 
16  * Neither the name of Intel Corporation nor the names of its
17  contributors may be used to endorse or promote products derived from
18  this software without specific prior written permission.
19 
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
25  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 
34 /** @file target_enums.cpp
35  @brief Define enums describing target platform.
36 */
37 
38 #include "target_enums.h"
39 
40 #include "ispc.h"
41 #include "util.h"
42 
43 #include <cstring>
44 
45 Arch ParseArch(std::string arch) {
46  if (arch == "x86") {
47  return Arch::x86;
48  } else if (arch == "x86_64" || arch == "x86-64") {
49  return Arch::x86_64;
50  } else if (arch == "arm") {
51  return Arch::arm;
52  } else if (arch == "aarch64") {
53  return Arch::aarch64;
54  } else if (arch == "wasm32") {
55  return Arch::wasm32;
56  }
57  return Arch::error;
58 }
59 
60 std::string ArchToString(Arch arch) {
61  switch (arch) {
62  case Arch::none:
63  return "none";
64  case Arch::x86:
65  return "x86";
66  case Arch::x86_64:
67  return "x86-64";
68  case Arch::arm:
69  return "arm";
70  case Arch::aarch64:
71  return "aarch64";
72  case Arch::wasm32:
73  return "wasm32";
74  case Arch::error:
75  return "error";
76  default:
77  // none and error are not supposed to be printed.
78  Error(SourcePos(), "Invalid arch is processed");
79  exit(1);
80  }
81  return "error";
82 }
83 
84 ISPCTarget ParseISPCTarget(std::string target) {
85  // TODO: ensure skx-i32x8 is not enabled and linked for earli LLVM version.
86 
87  // The first matching string for each target is the canonical way to name the target,
88  // all other strings are aliases.
89  if (target == "host") {
90  return ISPCTarget::host;
91  } else if (target == "sse2-i32x4" || target == "sse2") {
93  } else if (target == "sse2-i32x8" || target == "sse2-x2") {
95  } else if (target == "sse4-i8x16") {
97  } else if (target == "sse4-i16x8") {
99  } else if (target == "sse4-i32x4" || target == "sse4") {
100  return ISPCTarget::sse4_i32x4;
101  } else if (target == "sse4-i32x8" || target == "sse4-x2" || target == "sse4x2") {
102  return ISPCTarget::sse4_i32x8;
103  } else if (target == "avx1-i32x4") {
104  return ISPCTarget::avx1_i32x4;
105  } else if (target == "avx1-i32x8" || target == "avx" || target == "avx1") {
106  return ISPCTarget::avx1_i32x8;
107  } else if (target == "avx1-i64x4" || target == "avx-i64x4") {
108  return ISPCTarget::avx1_i64x4;
109  } else if (target == "avx1-i32x16" || target == "avx-x2" || target == "avx1-x2") {
111  } else if (target == "avx2-i32x4") {
112  return ISPCTarget::avx2_i32x4;
113  } else if (target == "avx2-i32x8" || target == "avx2") {
114  return ISPCTarget::avx2_i32x8;
115  } else if (target == "avx2-i64x4") {
116  return ISPCTarget::avx2_i64x4;
117  } else if (target == "avx2-i32x16" || target == "avx2-x2") {
119  } else if (target == "avx512knl-i32x16") {
121  } else if (target == "avx512skx-i32x16") {
123  } else if (target == "avx512skx-i32x8") {
125  } else if (target == "generic-1" || target == "generic-x1") {
126  return ISPCTarget::generic_1;
127  } else if (target == "generic-4" || target == "generic-x4") {
128  return ISPCTarget::generic_4;
129  } else if (target == "generic-8" || target == "generic-x8") {
130  return ISPCTarget::generic_8;
131  } else if (target == "generic-16" || target == "generic-x16") {
132  return ISPCTarget::generic_16;
133  } else if (target == "generic-32" || target == "generic-x32") {
134  return ISPCTarget::generic_32;
135  } else if (target == "generic-64" || target == "generic-x64") {
136  return ISPCTarget::generic_64;
137  } else if (target == "neon-i8x16") {
138  return ISPCTarget::neon_i8x16;
139  } else if (target == "neon-i16x8") {
140  return ISPCTarget::neon_i8x16;
141  } else if (target == "neon-i32x4" || target == "neon") {
142  return ISPCTarget::neon_i32x4;
143  } else if (target == "neon-i32x8") {
144  return ISPCTarget::neon_i32x8;
145  } else if (target == "wasm-i32x4") {
146  return ISPCTarget::wasm_i32x4;
147  }
148 
149  return ISPCTarget::error;
150 }
151 
152 // Given a comma-delimited string with one or more compilation targets of
153 // the form "sse4-i32x4,avx2-i32x8", return a pair. First element of the pair is a vector
154 // of correctly parsed targets, second element of the pair is a strings with targets, which
155 // were not recognized.
156 std::pair<std::vector<ISPCTarget>, std::string> ParseISPCTargets(const char *target) {
157  std::vector<ISPCTarget> targets;
158  std::string error_target;
159  const char *tstart = target;
160  bool done = false;
161  while (!done) {
162  const char *tend = strchr(tstart, ',');
163  if (tend == NULL) {
164  done = true;
165  tend = strchr(tstart, '\0');
166  }
167  std::string target_string = std::string(tstart, tend);
168  ISPCTarget target_parsed = ParseISPCTarget(target_string);
169  if (target_parsed == ISPCTarget::error) {
170  if (!error_target.empty()) {
171  error_target += ",";
172  }
173  error_target += target_string;
174  } else {
175  targets.push_back(target_parsed);
176  }
177  tstart = tend + 1;
178  }
179  return std::make_pair(targets, error_target);
180 }
181 
182 std::string ISPCTargetToString(ISPCTarget target) {
183  switch (target) {
184  case ISPCTarget::host:
185  return "host";
187  return "sse2-i32x4";
189  return "sse2-i32x8";
191  return "sse4-i8x16";
193  return "sse4-i16x8";
195  return "sse4-i32x4";
197  return "sse4-i32x8";
199  return "avx1-i32x4";
201  return "avx1-i32x8";
203  return "avx1-i32x16";
205  return "avx1-i64x4";
207  return "avx2-i32x4";
209  return "avx2-i32x8";
211  return "avx2-i32x16";
213  return "avx2-i64x4";
215  return "avx512knl-i32x16";
217  return "avx512skx-i32x8";
219  return "avx512skx-i32x16";
221  return "generic-1";
223  return "generic-4";
225  return "generic-8";
227  return "generic-16";
229  return "generic-32";
231  return "generic-64";
233  return "neon-i8x16";
235  return "neon-i16x8";
237  return "neon-i32x4";
239  return "neon-i32x8";
241  return "wasm-i32x4";
242  case ISPCTarget::none:
243  case ISPCTarget::error:
244  // Fall through
245  ;
246  }
247  Error(SourcePos(), "Invalid ISPCTarget is processed");
248  exit(1);
249 }
250 
252  switch (target) {
270  return true;
271  default:
272  return false;
273  }
274 }
275 
277  switch (target) {
284  return true;
285  default:
286  return false;
287  }
288 }
289 
291  switch (target) {
296  return true;
297  default:
298  return false;
299  }
300 }
301 
303  switch (target) {
305  return true;
306  default:
307  return false;
308  }
309 }
310 
311 TargetOS ParseOS(std::string os) {
312  std::string supportedOses = g->target_registry->getSupportedOSes().c_str();
313  if (supportedOses.find(os) == std::string::npos) {
314  return TargetOS::error;
315  }
316  if (os == "windows") {
317  return TargetOS::windows;
318  } else if (os == "linux") {
319  return TargetOS::linux;
320  } else if (os == "custom_linux") {
321  return TargetOS::custom_linux;
322  } else if (os == "freebsd") {
323  return TargetOS::freebsd;
324  } else if (os == "macos") {
325  return TargetOS::macos;
326  } else if (os == "android") {
327  return TargetOS::android;
328  } else if (os == "ios") {
329  return TargetOS::ios;
330  } else if (os == "ps4") {
331  return TargetOS::ps4;
332  } else if (os == "web") {
333  return TargetOS::web;
334  }
335  return TargetOS::error;
336 }
337 
338 std::string OSToString(TargetOS os) {
339  switch (os) {
340  case TargetOS::windows:
341  return "Windows";
342  case TargetOS::linux:
343  return "Linux";
345  return "Linux (custom)";
346  case TargetOS::freebsd:
347  return "FreeBSD";
348  case TargetOS::macos:
349  return "macOS";
350  case TargetOS::android:
351  return "Android";
352  case TargetOS::ios:
353  return "iOS";
354  case TargetOS::ps4:
355  return "PS4";
356  case TargetOS::web:
357  return "web";
358  case TargetOS::error:
359  return "error";
360  }
361  UNREACHABLE();
362 }
363 
364 std::string OSToLowerString(TargetOS os) {
365  switch (os) {
366  case TargetOS::windows:
367  return "windows";
368  case TargetOS::linux:
369  return "linux";
371  return "custom_linux";
372  case TargetOS::freebsd:
373  return "freebsd";
374  case TargetOS::macos:
375  return "macos";
376  case TargetOS::android:
377  return "android";
378  case TargetOS::ios:
379  return "ios";
380  case TargetOS::ps4:
381  return "ps4";
382  case TargetOS::web:
383  return "web";
384  case TargetOS::error:
385  return "error";
386  }
387  UNREACHABLE();
388 }
389 
391 #if defined(ISPC_HOST_IS_WINDOWS) && !defined(ISPC_WINDOWS_TARGET_OFF)
392  return TargetOS::windows;
393 #elif defined(ISPC_HOST_IS_LINUX) && !defined(ISPC_LINUX_TARGET_OFF)
394  return TargetOS::linux;
395 #elif defined(ISPC_HOST_IS_FREEBSD) && !defined(ISPC_FREEBSD_TARGET_OFF)
396  return TargetOS::freebsd;
397 #elif defined(ISPC_HOST_IS_APPLE) && !defined(ISPC_MACOS_TARGET_OFF)
398  return TargetOS::macos;
399 #else
400  return TargetOS::error;
401 #endif
402 }
std::string ArchToString(Arch arch)
ISPCTarget
Definition: target_enums.h:55
Define enums describing target platform.
TargetOS
Definition: target_enums.h:43
TargetLibRegistry * target_registry
Definition: ispc.h:506
#define UNREACHABLE()
Definition: util.h:110
std::string getSupportedOSes()
std::string OSToString(TargetOS os)
bool ISPCTargetIsX86(ISPCTarget target)
Arch ParseArch(std::string arch)
ISPCTarget ParseISPCTarget(std::string target)
Representation of a range of positions in a source file.
Definition: ispc.h:123
std::string ISPCTargetToString(ISPCTarget target)
void Error(SourcePos p, const char *fmt,...)
Definition: util.cpp:351
TargetOS GetHostOS()
TargetOS ParseOS(std::string os)
std::string OSToLowerString(TargetOS os)
Globals * g
Definition: ispc.cpp:72
bool ISPCTargetIsNeon(ISPCTarget target)
Main ispc.header file. Defines Target, Globals and Opt classes.
bool ISPCTargetIsWasm(ISPCTarget target)
Arch
Definition: target_enums.h:50
std::pair< std::vector< ISPCTarget >, std::string > ParseISPCTargets(const char *target)
bool ISPCTargetIsGeneric(ISPCTarget target)