Intel® Implicit SPMD Program Compiler (Intel® ISPC)  1.13.0
main.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2010-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 main.cpp
35  @brief main() entrypoint implementation for ispc
36 */
37 
38 #include "ispc.h"
39 #include "module.h"
40 #include "target_registry.h"
41 #include "type.h"
42 #include "util.h"
43 #include <cstdarg>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #ifdef ISPC_HOST_IS_WINDOWS
47 #include <time.h>
48 #else
49 #include <unistd.h>
50 #endif // ISPC_HOST_IS_WINDOWS
51 #include <llvm/Support/CommandLine.h>
52 #include <llvm/Support/Debug.h>
53 #include <llvm/Support/Signals.h>
54 #include <llvm/Support/TargetRegistry.h>
55 #include <llvm/Support/TargetSelect.h>
56 
57 #ifdef ISPC_HOST_IS_WINDOWS
58 #define strcasecmp stricmp
59 #ifndef BUILD_DATE
60 #define BUILD_DATE __DATE__
61 #endif
62 #define BUILD_VERSION ""
63 #if _MSC_VER >= 1900
64 #define ISPC_VS_VERSION "Visual Studio 2015 and later"
65 #else
66 #define ISPC_VS_VERSION "Visual Studio 2013 and earlier"
67 #endif
68 #endif // ISPC_HOST_IS_WINDOWS
69 
70 static void lPrintVersion() {
71 #ifdef ISPC_HOST_IS_WINDOWS
72  printf("Intel(r) Implicit SPMD Program Compiler (Intel(r) ISPC), %s (build date %s, LLVM %s)\n"
73  "Supported Visual Studio versions: %s.\n",
74  ISPC_VERSION, BUILD_DATE, ISPC_LLVM_VERSION_STRING, ISPC_VS_VERSION);
75 #else
76  printf("Intel(r) Implicit SPMD Program Compiler (Intel(r) ISPC), %s (build %s @ %s, LLVM %s)\n", ISPC_VERSION,
77  BUILD_VERSION, BUILD_DATE, ISPC_LLVM_VERSION_STRING);
78 #endif
79 
80 // The recommended way to build ISPC assumes custom LLVM build with a set of patches.
81 // If the default LLVM distribution is used, then the resuling ISPC binary may contain
82 // known and already fixed stability and performance problems.
83 #ifdef ISPC_NO_DUMPS
84  printf("This version is likely linked against non-recommended LLVM binaries.\n"
85  "For best stability and performance please use official binary distribution from "
86  "http://ispc.github.io/downloads.html");
87 #endif
88 }
89 
90 [[noreturn]] static void usage(int ret) {
91  lPrintVersion();
92  printf("\nusage: ispc\n");
93  printf(" [--addressing={32,64}]\t\tSelect 32- or 64-bit addressing. (Note that 32-bit\n");
94  printf(" \t\taddressing calculations are done by default, even\n");
95  printf(" \t\ton 64-bit target architectures.)\n");
96  printf(" [--arch={%s}]\t\tSelect target architecture\n", g->target_registry->getSupportedArchs().c_str());
97  printf(" [--c++-include-file=<name>]\t\tSpecify name of file to emit in #include statement in generated C++ "
98  "code.\n");
99 #ifndef ISPC_HOST_IS_WINDOWS
100  printf(" [--colored-output]\t\tAlways use terminal colors in error/warning messages\n");
101 #endif
102  printf(" ");
103  char cpuHelp[2048];
104  snprintf(cpuHelp, sizeof(cpuHelp), "[--cpu=<cpu>]\t\t\tSelect target CPU type\n<cpu>={%s}\n",
105  Target::SupportedCPUs().c_str());
106  PrintWithWordBreaks(cpuHelp, 16, TerminalWidth(), stdout);
107  printf(" [-D<foo>]\t\t\t\t#define given value when running preprocessor\n");
108  printf(" [--dev-stub <filename>]\t\tEmit device-side offload stub functions to file\n");
109  printf(" [--dllexport]\t\t\tMake non-static functions DLL exported. Windows target only\n");
110  printf(" [--dwarf-version={2,3,4}]\t\tGenerate source-level debug information with given DWARF version "
111  "(triggers -g). Ignored for Windows target\n");
112  printf(" [--emit-asm]\t\t\tGenerate assembly language file as output\n");
113  printf(" [--x86-asm-syntax=<option>]\t\tSelect style of code if generating assembly\n");
114  printf(" intel\t\t\t\tEmit Intel-style assembly\n");
115  printf(" att\t\t\t\tEmit AT&T-style assembly\n");
116  printf(" [--emit-c++]\t\t\tEmit a C++ source file as output\n");
117  printf(" [--emit-llvm]\t\t\tEmit LLVM bitcode file as output\n");
118  printf(" [--emit-llvm-text]\t\t\tEmit LLVM bitcode file as output in textual form\n");
119  printf(" [--emit-obj]\t\t\tGenerate object file file as output (default)\n");
120  printf(" [--force-alignment=<value>]\t\tForce alignment in memory allocations routine to be <value>\n");
121  printf(" [--error-limit=<value>]\t\tLimit maximum number of errors emitting by ISPC to <value>\n");
122  printf(" [-g]\t\t\t\tGenerate source-level debug information\n");
123  printf(" [--help]\t\t\t\tPrint help\n");
124  printf(" [--help-dev]\t\t\tPrint help for developer options\n");
125  printf(" [--host-stub <filename>]\t\tEmit host-side offload stub functions to file\n");
126  printf(" [-h <name>/--header-outfile=<name>]\tOutput filename for header\n");
127  printf(" [-I <path>]\t\t\t\tAdd <path> to #include file search path\n");
128  printf(" [--instrument]\t\t\tEmit instrumentation to gather performance data\n");
129  printf(" [--math-lib=<option>]\t\tSelect math library\n");
130  printf(" default\t\t\t\tUse ispc's built-in math functions\n");
131  printf(" fast\t\t\t\tUse high-performance but lower-accuracy math functions\n");
132  printf(" svml\t\t\t\tUse the Intel(r) SVML math libraries\n");
133  printf(" system\t\t\t\tUse the system's math library (*may be quite slow*)\n");
134  printf(" [-MMM <filename>]\t\t\tWrite #include dependencies to given file.\n");
135  printf(" [-M]\t\t\t\tOutput a rule suitable for `make' describing the dependencies of the main source file to "
136  "stdout.\n");
137  printf(" [-MF <filename>]\t\t\tWhen used with `-M', specifies a file to write the dependencies to.\n");
138  printf(" [-MT <filename>]\t\t\tWhen used with `-M', changes the target of the rule emitted by dependency "
139  "generation.\n");
140  printf(" [--no-omit-frame-pointer]\t\tDisable frame pointer omission. It may be useful for profiling\n");
141  printf(" [--nostdlib]\t\t\tDon't make the ispc standard library available\n");
142  printf(" [--no-pragma-once]\t\t\tDon't use #pragma once in created headers\n");
143  printf(" [--nocpp]\t\t\t\tDon't run the C preprocessor\n");
144  printf(" [-o <name>/--outfile=<name>]\tOutput filename (may be \"-\" for standard output)\n");
145  printf(" [-O0/-O(1/2/3)]\t\t\tSet optimization level. Default behavior is to optimize for speed.\n");
146  printf(" -O0\t\t\t\tOptimizations disabled.\n");
147  printf(" -O1\t\t\t\tOptimization for size.\n");
148  printf(" -O2/O3\t\t\t\tOptimization for speed.\n");
149  printf(" [--opt=<option>]\t\t\tSet optimization option\n");
150  printf(" disable-assertions\t\tRemove assertion statements from final code.\n");
151  printf(" disable-fma\t\t\tDisable 'fused multiply-add' instructions (on targets that support them)\n");
152  printf(" disable-loop-unroll\t\tDisable loop unrolling.\n");
153 #if ISPC_LLVM_VERSION >= ISPC_LLVM_8_0
154  printf(" disable-zmm\t\tDisable using zmm registers for avx512 targets in favour of ymm. This also affects "
155  "ABI.\n");
156 #endif
157  printf(" fast-masked-vload\t\tFaster masked vector loads on SSE (may go past end of array)\n");
158  printf(" fast-math\t\t\tPerform non-IEEE-compliant optimizations of numeric expressions\n");
159  printf(" force-aligned-memory\t\tAlways issue \"aligned\" vector load and store instructions\n");
160  printf(" [--pic]\t\t\t\tGenerate position-independent code. Ignored for Windows target\n");
161  printf(" [--quiet]\t\t\t\tSuppress all output\n");
162  printf(" [--support-matrix]\t\t\tPrint full matrix of supported targets, architectures and OSes\n");
163  printf(" ");
164  char targetHelp[2048];
165  snprintf(targetHelp, sizeof(targetHelp),
166  "[--target=<t>]\t\t\tSelect target ISA and width.\n"
167  "<t>={%s}",
169  PrintWithWordBreaks(targetHelp, 24, TerminalWidth(), stdout);
170  printf(" ");
171  snprintf(targetHelp, sizeof(targetHelp), "[--target-os=<os>]\t\t\tSelect target OS. <os>={%s}",
172  g->target_registry->getSupportedOSes().c_str());
173  PrintWithWordBreaks(targetHelp, 24, TerminalWidth(), stdout);
174  printf(" [--version]\t\t\t\tPrint ispc version\n");
175  printf(" [--werror]\t\t\t\tTreat warnings as errors\n");
176  printf(" [--woff]\t\t\t\tDisable warnings\n");
177  printf(" [--wno-perf]\t\t\tDon't issue warnings related to performance-related issues\n");
178  printf(" [@<filename>]\t\t\tRead additional arguments from the given file\n");
179  printf(" <file to compile or \"-\" for stdin>\n");
180  exit(ret);
181 }
182 
183 [[noreturn]] static void devUsage(int ret) {
184  lPrintVersion();
185  printf("\nusage (developer options): ispc\n");
186  printf(" [--debug]\t\t\t\tPrint information useful for debugging ispc\n");
187  printf(" [--debug-llvm]\t\t\tEnable LLVM debugging information (dumps to stderr)\n");
188  printf(" [--print-target]\t\t\tPrint target's information\n");
189  printf(" [--fuzz-test]\t\t\tRandomly perturb program input to test error conditions\n");
190  printf(" [--fuzz-seed=<value>]\t\tSeed value for RNG for fuzz testing\n");
191  printf(" [--opt=<option>]\t\t\tSet optimization option\n");
192  printf(" disable-all-on-optimizations\t\tDisable optimizations that take advantage of \"all on\" mask\n");
193  printf(" disable-blended-masked-stores\t\tScalarize masked stores on SSE (vs. using vblendps)\n");
194  printf(" disable-blending-removal\t\tDisable eliminating blend at same scope\n");
195  printf(" disable-coalescing\t\t\tDisable gather coalescing\n");
196  printf(" disable-coherent-control-flow\t\tDisable coherent control flow optimizations\n");
197  printf(" disable-gather-scatter-flattening\tDisable flattening when all lanes are on\n");
198  printf(" disable-gather-scatter-optimizations\tDisable improvements to gather/scatter\n");
199  printf(" disable-handle-pseudo-memory-ops\tLeave __pseudo_* calls for gather/scatter/etc. in final IR\n");
200  printf(" disable-uniform-control-flow\t\tDisable uniform control flow optimizations\n");
201  printf(" disable-uniform-memory-optimizations\tDisable uniform-based coherent memory access\n");
202  printf(" [--yydebug]\t\t\t\tPrint debugging information during parsing\n");
203 #ifndef ISPC_NO_DUMPS
204  printf(" [--debug-phase=<value>]\t\tSet optimization phases to dump. "
205  "--debug-phase=first,210:220,300,305,310:last\n");
206  printf(" [--dump-file]\t\t\tDump module IR to file(s) in current directory\n");
207 #endif
208  printf(" [--off-phase=<value>]\t\tSwitch off optimization phases. --off-phase=first,210:220,300,305,310:last\n");
209  exit(ret);
210 }
211 
212 /** Define an abstract base-class that implements the parsing of an character source and
213  * the breaking of it into the individual arguments
214  */
215 class ArgFactory {
216  private:
217  char *AllocateString(std::string string) {
218  int len = string.length();
219  char *ptr = new char[len + 1];
220  strncpy(ptr, string.c_str(), len);
221  ptr[len] = '\0';
222  return ptr;
223  }
224 
225  /** Method provided by the derived classes to retrieve the next character from the stream.
226  */
227  virtual char GetNextChar() = 0;
228 
229  public:
231 
232  char *GetNextArg() {
233  bool insideDQ = false;
234  bool insideSQ = false;
235  std::string arg;
236  char c = GetNextChar();
237 
238  // First consume any white-space before the argument
239  while (isspace(c))
240  c = GetNextChar();
241 
242  if (c == '\0')
243  // Reached the end so no more arguments
244  return NULL;
245 
246  // c now has the first character of the next argument, so collect the rest
247  while (c != '\0' && !(isspace(c) && !insideDQ && !insideSQ)) {
248  if (c == '\"' && !insideSQ) {
249  c = GetNextChar();
250  insideDQ = !insideDQ;
251  continue;
252  }
253  if (c == '\'' && !insideDQ) {
254  c = GetNextChar();
255  insideSQ = !insideSQ;
256  continue;
257  }
258  arg += c;
259  c = GetNextChar();
260  }
261 
262  return AllocateString(arg);
263  }
264 };
265 
266 /** Define a class to break the contents of an open file into the individual arguments */
267 class FileArgFactory : public ArgFactory {
268  private:
269  FILE *InputFile;
270 
271  virtual char GetNextChar() {
272  int c = fgetc(InputFile);
273  if (c == EOF) {
274  return '\0';
275  } else {
276  return c;
277  }
278  }
279 
280  public:
281  FileArgFactory(FILE *file) : InputFile(file) {}
282 };
283 
284 /** Define a class to break a NUL-terminated string into the individual arguments */
285 class StringArgFactory : public ArgFactory {
286  private:
287  const char *InputString;
288 
289  virtual char GetNextChar() {
290  char c = *InputString;
291 
292  if (c != '\0')
293  ++InputString;
294 
295  return c;
296  }
297 
298  public:
299  StringArgFactory(const char *string) : InputString(string) {}
300 };
301 
302 // Forward reference
303 static void lAddSingleArg(char *arg, std::vector<char *> &argv);
304 
305 /** Add all args from a given factory to the argv passed as parameters, which could
306  * include recursing into another ArgFactory.
307  */
308 static void lAddArgsFromFactory(ArgFactory &Args, std::vector<char *> &argv) {
309  while (true) {
310  char *NextArg = Args.GetNextArg();
311  if (NextArg == NULL)
312  break;
313  lAddSingleArg(NextArg, argv);
314  }
315 }
316 
317 /** Parse an open file for arguments and add them to the argv passed as parameters */
318 static void lAddArgsFromFile(FILE *file, std::vector<char *> &argv) {
319  FileArgFactory args(file);
320  lAddArgsFromFactory(args, argv);
321 }
322 
323 /** Parse a string for arguments and add them to the argv passed as parameters */
324 static void lAddArgsFromString(const char *string, std::vector<char *> &argv) {
325  StringArgFactory args(string);
326  lAddArgsFromFactory(args, argv);
327 }
328 
329 /** Add a single argument to the argv passed as parameters. If the argument is of the
330  * form @<filename> and <filename> exists and is readable, the arguments in the file will be
331  * inserted into argv in place of the original argument.
332  */
333 static void lAddSingleArg(char *arg, std::vector<char *> &argv) {
334  if (arg[0] == '@') {
335  char *filename = &arg[1];
336  FILE *file = fopen(filename, "r");
337  if (file != NULL) {
338  lAddArgsFromFile(file, argv);
339  fclose(file);
340  arg = NULL;
341  }
342  }
343  if (arg != NULL) {
344  argv.push_back(arg);
345  }
346 }
347 
348 /** We take arguments from both the command line as well as from the
349  * ISPC_ARGS environment variable - and each of these can include a file containing
350  * additional arguments using @<filename>. This function returns a new set of
351  * arguments representing the ones from all these sources merged together.
352  */
353 static void lGetAllArgs(int Argc, char *Argv[], std::vector<char *> &argv) {
354  // Copy over the command line arguments (passed in)
355  for (int i = 0; i < Argc; ++i)
356  lAddSingleArg(Argv[i], argv);
357 
358  // See if we have any set via the environment variable
359  const char *env = getenv("ISPC_ARGS");
360  if (env)
361  lAddArgsFromString(env, argv);
362 }
363 
364 static void lSignal(void *) { FATAL("Unhandled signal sent to process; terminating."); }
365 
366 // ArgErrors accumulates error and warning messages during arguments parsing
367 // prints them after the parsing is done. We need to delay printing to take
368 // into account such options as --quite, --nowrap --werror, which affects how
369 // errors and warnings are treated and printed.
370 class ArgErrors {
371  enum class MsgType { warning, error };
372  std::vector<std::pair<MsgType, std::string>> m_messages;
373  void AddMessage(MsgType msg_type, const char *format, va_list args) {
374  char *messageBuf;
375  if (vasprintf(&messageBuf, format, args) == -1) {
376  fprintf(stderr, "vasprintf() unable to allocate memory!\n");
377  exit(-1);
378  }
379 
380  m_messages.push_back(std::make_pair(msg_type, messageBuf));
381 
382  free(messageBuf);
383  }
384 
385  public:
387  void AddError(const char *format, ...) PRINTF_FUNC {
388  va_list args;
389  va_start(args, format);
390  AddMessage(MsgType::error, format, args);
391  va_end(args);
392  }
393  void AddWarning(const char *format, ...) PRINTF_FUNC {
394  va_list args;
395  va_start(args, format);
396  AddMessage(MsgType::warning, format, args);
397  va_end(args);
398  }
399  void Emit() {
400  bool errors = false;
401  for (auto &message : m_messages) {
402  if (message.first == MsgType::error || g->warningsAsErrors) {
403  errors = true;
404  Error(SourcePos(), "%s", message.second.c_str());
405  } else {
406  Warning(SourcePos(), "%s", message.second.c_str());
407  }
408  }
409  if (errors) {
410  exit(-1);
411  }
412  }
413 };
414 
415 static int ParsingPhaseName(char *stage, ArgErrors &errorHandler) {
416  if (strncmp(stage, "first", 5) == 0) {
417  return 0;
418  } else if (strncmp(stage, "last", 4) == 0) {
419  return LAST_OPT_NUMBER;
420  } else {
421  int t = atoi(stage);
422  if (t < 0 || t > LAST_OPT_NUMBER) {
423  errorHandler.AddError("Phases must be from 0 to %d. %s is incorrect.", LAST_OPT_NUMBER, stage);
424  return 0;
425  } else {
426  return t;
427  }
428  }
429 }
430 
431 static std::set<int> ParsingPhases(char *stages, ArgErrors &errorHandler) {
432  constexpr int parsing_limit = 100;
433  std::set<int> phases;
434  auto len = strnlen(stages, parsing_limit);
435  if (len == 0) {
436  errorHandler.AddError("Empty phase list.");
437  return phases;
438  }
439  if (len == parsing_limit && stages[parsing_limit] != '\0') {
440  errorHandler.AddError("Phase list is too long.");
441  return phases;
442  }
443  int begin = ParsingPhaseName(stages, errorHandler);
444  int end = begin;
445 
446  for (unsigned i = 0; i < strlen(stages); i++) {
447  if ((stages[i] == ',') || (i == strlen(stages) - 1)) {
448  for (int j = begin; j < end + 1; j++) {
449  phases.insert(j);
450  }
451  begin = ParsingPhaseName(stages + i + 1, errorHandler);
452  end = begin;
453  } else if (stages[i] == ':') {
454  end = ParsingPhaseName(stages + i + 1, errorHandler);
455  }
456  }
457  return phases;
458 }
459 
460 static void lParseInclude(const char *path) {
461 #ifdef ISPC_HOST_IS_WINDOWS
462  char delim = ';';
463 #else
464  char delim = ':';
465 #endif
466  size_t pos = 0, pos_end;
467  std::string str_path(path);
468  do {
469  pos_end = str_path.find(delim, pos);
470  size_t len = (pos_end == std::string::npos) ?
471  // Not found, copy till end of the string.
472  std::string::npos
473  :
474  // Copy [pos, pos_end).
475  (pos_end - pos);
476  std::string s = str_path.substr(pos, len);
477  g->includePath.push_back(s);
478  pos = pos_end + 1;
479  } while (pos_end != std::string::npos);
480 }
481 
482 int main(int Argc, char *Argv[]) {
483  std::vector<char *> argv;
484  lGetAllArgs(Argc, Argv, argv);
485  int argc = argv.size();
486 
487  llvm::sys::AddSignalHandler(lSignal, NULL);
488 
489  // initialize available LLVM targets
490  // TO-DO : Revisit after experimenting on arm and aarch64 hardware.
491 #ifndef __arm__
492  // FIXME: LLVM build on ARM doesn't build the x86 targets by default.
493  // It's not clear that anyone's going to want to generate x86 from an
494  // ARM host, though...
495  LLVMInitializeX86TargetInfo();
496  LLVMInitializeX86Target();
497  LLVMInitializeX86AsmPrinter();
498  LLVMInitializeX86AsmParser();
499  LLVMInitializeX86Disassembler();
500  LLVMInitializeX86TargetMC();
501 #endif // !__ARM__
502 
503 #ifdef ISPC_ARM_ENABLED
504  // Generating ARM and AARCH64 from x86 is more likely to be useful, though.
505  LLVMInitializeARMTargetInfo();
506  LLVMInitializeARMTarget();
507  LLVMInitializeARMAsmPrinter();
508  LLVMInitializeARMAsmParser();
509  LLVMInitializeARMDisassembler();
510  LLVMInitializeARMTargetMC();
511 
512  LLVMInitializeAArch64TargetInfo();
513  LLVMInitializeAArch64Target();
514  LLVMInitializeAArch64AsmPrinter();
515  LLVMInitializeAArch64AsmParser();
516  LLVMInitializeAArch64Disassembler();
517  LLVMInitializeAArch64TargetMC();
518 #endif
519 
520 #ifdef ISPC_WASM_ENABLED
521  LLVMInitializeWebAssemblyAsmParser();
522  LLVMInitializeWebAssemblyAsmPrinter();
523  LLVMInitializeWebAssemblyDisassembler();
524  LLVMInitializeWebAssemblyTarget();
525  LLVMInitializeWebAssemblyTargetInfo();
526  LLVMInitializeWebAssemblyTargetMC();
527 #endif
528 
529  char *file = NULL;
530  const char *headerFileName = NULL;
531  const char *outFileName = NULL;
532  const char *includeFileName = NULL;
533  const char *depsFileName = NULL;
534  const char *depsTargetName = NULL;
535  const char *hostStubFileName = NULL;
536  const char *devStubFileName = NULL;
537  // Initiailize globals early so that we can set various option values
538  // as we're parsing below
539  g = new Globals;
540 
543  Arch arch = Arch::none;
544  std::vector<ISPCTarget> targets;
545  const char *cpu = NULL, *intelAsmSyntax = NULL;
546 
547  ArgErrors errorHandler;
548 
549  for (int i = 1; i < argc; ++i) {
550  if (!strcmp(argv[i], "--help")) {
551  usage(0);
552  } else if (!strcmp(argv[i], "--help-dev")) {
553  devUsage(0);
554  } else if (!strcmp(argv[i], "--support-matrix")) {
556  exit(0);
557  } else if (!strncmp(argv[i], "-D", 2)) {
558  g->cppArgs.push_back(argv[i]);
559  } else if (!strncmp(argv[i], "--addressing=", 13)) {
560  if (atoi(argv[i] + 13) == 64)
561  // FIXME: this doesn't make sense on 32 bit platform.
562  g->opt.force32BitAddressing = false;
563  else if (atoi(argv[i] + 13) == 32)
564  g->opt.force32BitAddressing = true;
565  else {
566  errorHandler.AddError("Addressing width \"%s\" invalid -- only 32 and "
567  "64 are allowed.",
568  argv[i] + 13);
569  }
570  } else if (!strncmp(argv[i], "--arch=", 7)) {
571  Arch prev_arch = arch;
572 
573  arch = ParseArch(argv[i] + 7);
574  if (arch == Arch::error) {
575  errorHandler.AddError("Unsupported value for --arch, supported values are: %s",
576  g->target_registry->getSupportedArchs().c_str());
577  }
578 
579  if (prev_arch != Arch::none && prev_arch != arch) {
580  std::string prev_arch_str = ArchToString(prev_arch);
581  std::string arch_str = ArchToString(arch);
582  errorHandler.AddWarning("Overwriting --arch=%s with --arch=%s", prev_arch_str.c_str(),
583  arch_str.c_str());
584  }
585  } else if (!strncmp(argv[i], "--x86-asm-syntax=", 17)) {
586  intelAsmSyntax = argv[i] + 17;
587  if (!((std::string(intelAsmSyntax) == "intel") || (std::string(intelAsmSyntax) == "att"))) {
588  intelAsmSyntax = NULL;
589  errorHandler.AddError("Invalid value for --x86-asm-syntax: \"%s\" -- "
590  "only intel and att are allowed.",
591  argv[i] + 17);
592  }
593  } else if (!strncmp(argv[i], "--cpu=", 6)) {
594  cpu = argv[i] + 6;
595  } else if (!strcmp(argv[i], "--fast-math")) {
596  errorHandler.AddError("--fast-math option has been renamed to --opt=fast-math!");
597  } else if (!strcmp(argv[i], "--fast-masked-vload")) {
598  errorHandler.AddError("--fast-masked-vload option has been renamed to "
599  "--opt=fast-masked-vload!");
600  } else if (!strcmp(argv[i], "--debug"))
601  g->debugPrint = true;
602  else if (!strcmp(argv[i], "--debug-llvm"))
603  llvm::DebugFlag = true;
604  else if (!strcmp(argv[i], "--dllexport"))
605  g->dllExport = true;
606  else if (!strncmp(argv[i], "--dwarf-version=", 16)) {
607  int val = atoi(argv[i] + 16);
608  if (2 <= val && val <= 4) {
609  g->generateDebuggingSymbols = true;
610  g->generateDWARFVersion = val;
611  } else {
612  errorHandler.AddError("Invalid value for DWARF version: \"%s\" -- "
613  "only 2, 3 and 4 are allowed.",
614  argv[i] + 16);
615  }
616  } else if (!strcmp(argv[i], "--print-target"))
617  g->printTarget = true;
618  else if (!strcmp(argv[i], "--no-omit-frame-pointer"))
619  g->NoOmitFramePointer = true;
620  else if (!strcmp(argv[i], "--instrument"))
621  g->emitInstrumentation = true;
622  else if (!strcmp(argv[i], "--no-pragma-once"))
623  g->noPragmaOnce = true;
624  else if (!strcmp(argv[i], "-g")) {
625  g->generateDebuggingSymbols = true;
626  } else if (!strcmp(argv[i], "--emit-asm"))
627  ot = Module::Asm;
628  else if (!strcmp(argv[i], "--emit-c++"))
629  ot = Module::CXX;
630  else if (!strcmp(argv[i], "--emit-llvm"))
631  ot = Module::Bitcode;
632  else if (!strcmp(argv[i], "--emit-llvm-text"))
633  ot = Module::BitcodeText;
634  else if (!strcmp(argv[i], "--emit-obj"))
635  ot = Module::Object;
636  else if (!strcmp(argv[i], "-I")) {
637  if (++i != argc) {
638  lParseInclude(argv[i]);
639  } else {
640  errorHandler.AddError("No path specified after -I option.");
641  }
642  } else if (!strncmp(argv[i], "-I", 2))
643  lParseInclude(argv[i] + 2);
644  else if (!strcmp(argv[i], "--fuzz-test"))
645  g->enableFuzzTest = true;
646  else if (!strncmp(argv[i], "--fuzz-seed=", 12))
647  g->fuzzTestSeed = atoi(argv[i] + 12);
648  else if (!strcmp(argv[i], "--target")) {
649  // FIXME: should remove this way of specifying the target...
650  if (++i != argc) {
651  auto result = ParseISPCTargets(argv[i]);
652  targets = result.first;
653  if (!result.second.empty()) {
654  errorHandler.AddError("Incorrect targets: %s. Choices are: %s.", result.second.c_str(),
656  }
657  } else {
658  errorHandler.AddError("No target specified after --target option.");
659  }
660  } else if (!strncmp(argv[i], "--target=", 9)) {
661  auto result = ParseISPCTargets(argv[i] + 9);
662  targets = result.first;
663  if (!result.second.empty()) {
664  errorHandler.AddError("Incorrect targets: %s. Choices are: %s.", result.second.c_str(),
666  }
667  } else if (!strncmp(argv[i], "--target-os=", 12)) {
668  g->target_os = ParseOS(argv[i] + 12);
669  if (g->target_os == TargetOS::error) {
670  errorHandler.AddError("Unsupported value for --target-os, supported values are: %s",
671  g->target_registry->getSupportedOSes().c_str());
672  }
673  } else if (!strncmp(argv[i], "--math-lib=", 11)) {
674  const char *lib = argv[i] + 11;
675  if (!strcmp(lib, "default"))
677  else if (!strcmp(lib, "fast"))
679  else if (!strcmp(lib, "svml"))
681  else if (!strcmp(lib, "system"))
683  else {
684  errorHandler.AddError("Unknown --math-lib= option \"%s\".", lib);
685  }
686  } else if (!strncmp(argv[i], "--opt=", 6)) {
687  const char *opt = argv[i] + 6;
688  if (!strcmp(opt, "fast-math"))
689  g->opt.fastMath = true;
690  else if (!strcmp(opt, "fast-masked-vload"))
691  g->opt.fastMaskedVload = true;
692  else if (!strcmp(opt, "disable-assertions"))
693  g->opt.disableAsserts = true;
694  else if (!strcmp(opt, "disable-loop-unroll"))
695  g->opt.unrollLoops = false;
696  else if (!strcmp(opt, "disable-fma"))
697  g->opt.disableFMA = true;
698 #if ISPC_LLVM_VERSION >= ISPC_LLVM_8_0
699  else if (!strcmp(opt, "disable-zmm"))
700  g->opt.disableZMM = true;
701 #endif
702  else if (!strcmp(opt, "force-aligned-memory"))
703  g->opt.forceAlignedMemory = true;
704 
705  // These are only used for performance tests of specific
706  // optimizations
707  else if (!strcmp(opt, "disable-all-on-optimizations"))
709  else if (!strcmp(opt, "disable-coalescing"))
710  g->opt.disableCoalescing = true;
711  else if (!strcmp(opt, "disable-handle-pseudo-memory-ops"))
713  else if (!strcmp(opt, "disable-blended-masked-stores"))
715  else if (!strcmp(opt, "disable-coherent-control-flow"))
717  else if (!strcmp(opt, "disable-uniform-control-flow"))
719  else if (!strcmp(opt, "disable-gather-scatter-optimizations"))
721  else if (!strcmp(opt, "disable-blending-removal"))
723  else if (!strcmp(opt, "disable-gather-scatter-flattening"))
725  else if (!strcmp(opt, "disable-uniform-memory-optimizations"))
727  else {
728  errorHandler.AddError("Unknown --opt= option \"%s\".", opt);
729  }
730  } else if (!strncmp(argv[i], "--force-alignment=", 18)) {
731  g->forceAlignment = atoi(argv[i] + 18);
732  } else if (!strcmp(argv[i], "--woff") || !strcmp(argv[i], "-woff")) {
733  g->disableWarnings = true;
734  g->emitPerfWarnings = false;
735  } else if (!strcmp(argv[i], "--werror"))
736  g->warningsAsErrors = true;
737  else if (!strncmp(argv[i], "--error-limit=", 14)) {
738  int errLimit = atoi(argv[i] + 14);
739  if (errLimit >= 0)
740  g->errorLimit = errLimit;
741  else
742  errorHandler.AddError("Invalid value for --error-limit: \"%d\" -- "
743  "value cannot be a negative number.",
744  errLimit);
745  } else if (!strcmp(argv[i], "--nowrap"))
746  g->disableLineWrap = true;
747  else if (!strcmp(argv[i], "--wno-perf") || !strcmp(argv[i], "-wno-perf"))
748  g->emitPerfWarnings = false;
749  else if (!strcmp(argv[i], "-o")) {
750  if (++i != argc) {
751  outFileName = argv[i];
752  } else {
753  errorHandler.AddError("No output file specified after -o option.");
754  }
755  } else if (!strncmp(argv[i], "--outfile=", 10))
756  outFileName = argv[i] + strlen("--outfile=");
757  else if (!strcmp(argv[i], "-h")) {
758  if (++i != argc) {
759  headerFileName = argv[i];
760  } else {
761  errorHandler.AddError("No header file name specified after -h option.");
762  }
763  } else if (!strncmp(argv[i], "--header-outfile=", 17)) {
764  headerFileName = argv[i] + strlen("--header-outfile=");
765  } else if (!strncmp(argv[i], "--c++-include-file=", 19)) {
766  includeFileName = argv[i] + strlen("--c++-include-file=");
767  } else if (!strcmp(argv[i], "-O0")) {
768  g->opt.level = 0;
769  g->codegenOptLevel = Globals::CodegenOptLevel::None;
770  } else if (!strcmp(argv[i], "-O") || !strcmp(argv[i], "-O1") || !strcmp(argv[i], "-O2") ||
771  !strcmp(argv[i], "-O3")) {
772  g->opt.level = 1;
773  g->codegenOptLevel = Globals::CodegenOptLevel::Aggressive;
774  if (!strcmp(argv[i], "-O1"))
776  } else if (!strcmp(argv[i], "-")) {
777  file = argv[i];
778  } else if (!strcmp(argv[i], "--nostdlib"))
779  g->includeStdlib = false;
780  else if (!strcmp(argv[i], "--nocpp"))
781  g->runCPP = false;
782  else if (!strcmp(argv[i], "--pic"))
783  flags |= Module::GeneratePIC;
784 #ifndef ISPC_IS_HOST_WINDOWS
785  else if (!strcmp(argv[i], "--colored-output"))
786  g->forceColoredOutput = true;
787 #endif // !ISPC_IS_HOST_WINDOWS
788  else if (!strcmp(argv[i], "--quiet"))
789  g->quiet = true;
790  else if (!strcmp(argv[i], "--yydebug")) {
791  extern int yydebug;
792  yydebug = 1;
793  } else if (!strcmp(argv[i], "-MMM")) {
794  if (++i != argc) {
795  depsFileName = argv[i];
796  flags |= Module::GenerateFlatDeps;
797  } else {
798  errorHandler.AddError("No output file name specified after -MMM option.");
799  }
800  } else if (!strcmp(argv[i], "-M")) {
802  } else if (!strcmp(argv[i], "-MF")) {
803  depsFileName = nullptr;
804  if (++i != argc) {
805  depsFileName = argv[i];
806  } else {
807  errorHandler.AddError("No output file name specified after -MF option.");
808  }
809  } else if (!strcmp(argv[i], "-MT")) {
810  depsTargetName = nullptr;
811  if (++i != argc) {
812  depsTargetName = argv[i];
813  } else {
814  errorHandler.AddError("No target name specified after -MT option.");
815  }
816  } else if (!strcmp(argv[i], "--dev-stub")) {
817  if (++i != argc) {
818  devStubFileName = argv[i];
819  } else {
820  errorHandler.AddError("No output file name specified after --dev-stub option.");
821  }
822  } else if (!strcmp(argv[i], "--host-stub")) {
823  if (++i != argc) {
824  hostStubFileName = argv[i];
825  } else {
826  errorHandler.AddError("No output file name specified after --host-stub option.");
827  }
828  }
829 #ifndef ISPC_NO_DUMPS
830  else if (strncmp(argv[i], "--debug-phase=", 14) == 0) {
831  errorHandler.AddWarning("Adding debug phases may change the way PassManager"
832  "handles the phases and it may possibly make some bugs go"
833  "away or introduce the new ones.");
834  g->debug_stages = ParsingPhases(argv[i] + strlen("--debug-phase="), errorHandler);
835  } else if (strncmp(argv[i], "--dump-file", 11) == 0)
836  g->dumpFile = true;
837 #endif
838 
839  else if (strncmp(argv[i], "--off-phase=", 12) == 0) {
840  g->off_stages = ParsingPhases(argv[i] + strlen("--off-phase="), errorHandler);
841  } else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
842  lPrintVersion();
843  return 0;
844  } else if (argv[i][0] == '-') {
845  errorHandler.AddError("Unknown option \"%s\".", argv[i]);
846  } else {
847  if (file != NULL) {
848  errorHandler.AddError("Multiple input files specified on command "
849  "line: \"%s\" and \"%s\".",
850  file, argv[i]);
851  } else {
852  file = argv[i];
853  }
854  }
855  }
856 
857  // Emit accumulted errors and warnings, if any.
858  // All the rest of errors and warnigns will be processed in regullar way.
859  errorHandler.Emit();
860 
861  if (file == NULL) {
862  Error(SourcePos(), "No input file were specified. To read text from stdin use \"-\" as file name.");
863  exit(1);
864  }
865 
866  // Default settings for PS4
867  if (g->target_os == TargetOS::ps4) {
868  flags |= Module::GeneratePIC;
869  if (!cpu) {
870  // Default is btver2, but do not enforce it.
871  cpu = "btver2";
872  }
873  /*
874  if (cpu && std::string(cpu) != "btver2" && std::string(cpu) != "ps4") {
875  Warning(SourcePos(), "--cpu switch is ignored for PS4 target OS. btver2 (ps4) cpu is used.");
876  }
877  */
878  if (arch != Arch::x86_64) {
879  Warning(SourcePos(), "--arch switch is ignored for PS4 target OS. x86-64 arch is used.");
880  arch = Arch::x86_64;
881  }
882  }
883 
884  // Default setting for "custom_linux"
886  flags |= Module::GeneratePIC;
887  if (!cpu) {
888  cpu = "cortex-a57";
889  }
890  if (targets.empty()) {
891  targets.push_back(ISPCTarget::neon_i32x4);
892  std::string target_string = ISPCTargetToString(targets[0]);
893  Warning(SourcePos(),
894  "No --target specified on command-line."
895  " Using \"%s\".",
896  target_string.c_str());
897  }
898  }
899 
900  if (g->enableFuzzTest) {
901  if (g->fuzzTestSeed == -1) {
902 #ifdef ISPC_HOST_IS_WINDOWS
903  int seed = (unsigned)time(NULL);
904 #else
905  int seed = getpid();
906 #endif
907  g->fuzzTestSeed = seed;
908  Warning(SourcePos(), "Using seed %d for fuzz testing", g->fuzzTestSeed);
909  }
910 #ifdef ISPC_HOST_IS_WINDOWS
911  srand(g->fuzzTestSeed);
912 #else
913  srand48(g->fuzzTestSeed);
914 #endif
915  }
916 
917  if (depsFileName != NULL)
918  flags &= ~Module::OutputDepsToStdout;
919 
920  if (depsFileName != NULL && 0 == (flags & (Module::GenerateFlatDeps | Module::GenerateMakeRuleForDeps))) {
921  Warning(SourcePos(), "Dependency file name specified with -MF, but no "
922  "mode specified; did you forget to specify -M or -MMM? "
923  "No dependency output will be generated.");
924  depsFileName = NULL;
925  }
926 
929  Warning(SourcePos(), "Both -M and -MMM specified on the command line. "
930  "-MMM takes precedence.");
932  }
933 
934  if (outFileName == NULL && headerFileName == NULL &&
935  (depsFileName == NULL && 0 == (flags & Module::OutputDepsToStdout)) && hostStubFileName == NULL &&
936  devStubFileName == NULL) {
937  Warning(SourcePos(), "No output file or header file name specified. "
938  "Program will be compiled and warnings/errors will "
939  "be issued, but no output will be generated.");
940  }
941 
942  if (g->target_os == TargetOS::windows && (flags & Module::GeneratePIC) != 0) {
943  Warning(SourcePos(), "--pic switch for Windows target will be ignored.");
944  }
945 
946  if (g->target_os != TargetOS::windows && g->dllExport) {
947  Warning(SourcePos(), "--dllexport switch will be ignored, as the target OS is not Windows.");
948  }
949 
950  if (targets.size() > 1)
951  g->isMultiTargetCompilation = true;
952 
953  if ((ot == Module::Asm) && (intelAsmSyntax != NULL)) {
954  std::vector<const char *> Args(3);
955  Args[0] = "ispc (LLVM option parsing)";
956  Args[2] = nullptr;
957  if (std::string(intelAsmSyntax) == "intel")
958  Args[1] = "--x86-asm-syntax=intel";
959  else
960  Args[1] = "--x86-asm-syntax=att";
961  llvm::cl::ParseCommandLineOptions(2, Args.data());
962  }
963 
964  for (auto target : targets) {
965  if (target == ISPCTarget::wasm_i32x4) {
966  Assert(targets.size() == 1 && "wasm32 supports only one target: i32x4");
967  arch = Arch::wasm32;
969  }
970  }
971 
972  return Module::CompileAndOutput(file, arch, cpu, targets, flags, ot, outFileName, headerFileName, includeFileName,
973  depsFileName, depsTargetName, hostStubFileName, devStubFileName);
974 }
bool disableFMA
Definition: ispc.h:420
TargetOS target_os
Definition: ispc.h:515
std::string ArchToString(Arch arch)
bool isMultiTargetCompilation
Definition: ispc.h:636
std::vector< std::pair< MsgType, std::string > > m_messages
Definition: main.cpp:372
Opt opt
Definition: ispc.h:509
bool disableWarnings
Definition: ispc.h:558
void AddMessage(MsgType msg_type, const char *format, va_list args)
Definition: main.cpp:373
TargetLibRegistry * target_registry
Definition: ispc.h:506
This structure collects together a number of global variables.
Definition: ispc.h:502
static int ParsingPhaseName(char *stage, ArgErrors &errorHandler)
Definition: main.cpp:415
bool disableBlendedMaskedStores
Definition: ispc.h:447
int TerminalWidth()
Definition: util.cpp:76
static void lSignal(void *)
Definition: main.cpp:364
bool forceColoredOutput
Definition: ispc.h:576
Registry to handle bitcode libraries.
virtual char GetNextChar()=0
std::vector< std::string > includePath
Definition: ispc.h:623
bool emitPerfWarnings
Definition: ispc.h:569
bool warningsAsErrors
Definition: ispc.h:561
bool NoOmitFramePointer
Definition: ispc.h:542
void AddWarning(const char *format,...) PRINTF_FUNC
Definition: main.cpp:393
std::string getSupportedTargets()
bool forceAlignedMemory
Definition: ispc.h:426
static void lAddSingleArg(char *arg, std::vector< char *> &argv)
Definition: main.cpp:333
char * AllocateString(std::string string)
Definition: main.cpp:217
int fuzzTestSeed
Definition: ispc.h:608
OutputType
Definition: module.h:86
static void devUsage(int ret)
Definition: main.cpp:183
bool disableLineWrap
Definition: ispc.h:565
bool disableCoalescing
Definition: ispc.h:487
virtual char GetNextChar()
Definition: main.cpp:289
ArgFactory()
Definition: main.cpp:230
bool includeStdlib
Definition: ispc.h:528
void Emit()
Definition: main.cpp:399
std::set< int > debug_stages
Definition: ispc.h:545
bool disableMaskAllOnOptimizations
Definition: ispc.h:431
int level
Definition: ispc.h:392
static std::string SupportedCPUs()
Definition: ispc.cpp:1119
bool disableGatherScatterOptimizations
Definition: ispc.h:465
bool debugPrint
Definition: ispc.h:536
bool disableZMM
Definition: ispc.h:491
bool disableCoherentControlFlow
Definition: ispc.h:453
std::string getSupportedOSes()
static void lPrintVersion()
Definition: main.cpp:70
bool enableFuzzTest
Definition: ispc.h:605
static void lAddArgsFromFactory(ArgFactory &Args, std::vector< char *> &argv)
Definition: main.cpp:308
int errorLimit
Definition: ispc.h:639
#define ISPC_LLVM_VERSION_STRING
Definition: ispc_version.h:64
bool printTarget
Definition: ispc.h:539
Definition: module.h:51
FILE * InputFile
Definition: main.cpp:269
const char * InputString
Definition: main.cpp:287
bool runCPP
Definition: ispc.h:532
Arch ParseArch(std::string arch)
CodegenOptLevel codegenOptLevel
Definition: ispc.h:524
bool emitInstrumentation
Definition: ispc.h:582
bool unrollLoops
Definition: ispc.h:406
void printSupportMatrix() const
Representation of a range of positions in a source file.
Definition: ispc.h:123
std::string ISPCTargetToString(ISPCTarget target)
bool disableUniformMemoryOptimizations
Definition: ispc.h:483
bool generateDebuggingSymbols
Definition: ispc.h:588
bool fastMath
Definition: ispc.h:396
static void lAddArgsFromFile(FILE *file, std::vector< char *> &argv)
Definition: main.cpp:318
static void lParseInclude(const char *path)
Definition: main.cpp:460
bool fastMaskedVload
Definition: ispc.h:402
bool disableHandlePseudoMemoryOps
Definition: ispc.h:437
bool force32BitAddressing
Definition: ispc.h:412
bool dllExport
Definition: ispc.h:630
static std::set< int > ParsingPhases(char *stages, ArgErrors &errorHandler)
Definition: main.cpp:431
void Error(SourcePos p, const char *fmt,...)
Definition: util.cpp:351
int main(int Argc, char *Argv[])
Definition: main.cpp:482
#define FATAL(message)
Definition: util.h:116
StringArgFactory(const char *string)
Definition: main.cpp:299
#define PRINTF_FUNC
Definition: util.h:63
TargetOS ParseOS(std::string os)
MathLib mathLib
Definition: ispc.h:520
ArgErrors()
Definition: main.cpp:386
bool disableUniformControlFlow
Definition: ispc.h:459
bool disableMaskedStoreToStore
Definition: ispc.h:471
static void lAddArgsFromString(const char *string, std::vector< char *> &argv)
Definition: main.cpp:324
void AddError(const char *format,...) PRINTF_FUNC
Definition: main.cpp:387
#define Assert(expr)
Definition: util.h:128
OutputFlags
Definition: module.h:100
bool dumpFile
Definition: ispc.h:548
Globals * g
Definition: ispc.cpp:72
int generateDWARFVersion
Definition: ispc.h:596
char * GetNextArg()
Definition: main.cpp:232
int forceAlignment
Definition: ispc.h:627
void PrintWithWordBreaks(const char *buf, int indent, int columnWidth, FILE *out)
Definition: util.cpp:210
bool quiet
Definition: ispc.h:572
std::set< int > off_stages
Definition: ispc.h:555
bool noPragmaOnce
Definition: ispc.h:584
#define ISPC_VERSION
Definition: ispc_version.h:42
static int CompileAndOutput(const char *srcFile, Arch arch, const char *cpu, std::vector< ISPCTarget > targets, OutputFlags outputFlags, OutputType outputType, const char *outFileName, const char *headerFileName, const char *includeFileName, const char *depsFileName, const char *depsTargetName, const char *hostStubFileName, const char *devStubFileName)
Definition: module.cpp:2390
std::vector< std::string > cppArgs
Definition: ispc.h:619
virtual char GetNextChar()
Definition: main.cpp:271
Declaration of the Module class, which is the ispc-side representation of the results of compiling a ...
static void lGetAllArgs(int Argc, char *Argv[], std::vector< char *> &argv)
Definition: main.cpp:353
#define LAST_OPT_NUMBER
Definition: ispc.h:72
Main ispc.header file. Defines Target, Globals and Opt classes.
static void usage(int ret)
Definition: main.cpp:90
void Warning(SourcePos p, const char *fmt,...)
Definition: util.cpp:378
Arch
Definition: target_enums.h:50
std::pair< std::vector< ISPCTarget >, std::string > ParseISPCTargets(const char *target)
bool disableAsserts
Definition: ispc.h:416
File with declarations for classes related to type representation.
bool disableGatherScatterFlattening
Definition: ispc.h:477
FileArgFactory(FILE *file)
Definition: main.cpp:281
std::string getSupportedArchs()