Intel SPMD Program Compiler  1.11.0
builtins.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2010-2019, 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 builtins.cpp
35  @brief Definitions of functions related to setting up the standard library
36  and other builtins.
37 */
38 
39 #include "builtins.h"
40 #include "ctx.h"
41 #include "expr.h"
42 #include "llvmutil.h"
43 #include "module.h"
44 #include "sym.h"
45 #include "type.h"
46 #include "util.h"
47 
48 #include <math.h>
49 #include <stdlib.h>
50 #if ISPC_LLVM_VERSION == ISPC_LLVM_3_2
51 #include <llvm/Attributes.h>
52 #include <llvm/DerivedTypes.h>
53 #include <llvm/Instructions.h>
54 #include <llvm/Intrinsics.h>
55 #include <llvm/LLVMContext.h>
56 #include <llvm/Module.h>
57 #include <llvm/Type.h>
58 #else
59 #include <llvm/IR/Attributes.h>
60 #include <llvm/IR/DerivedTypes.h>
61 #include <llvm/IR/Instructions.h>
62 #include <llvm/IR/Intrinsics.h>
63 #include <llvm/IR/LLVMContext.h>
64 #include <llvm/IR/Module.h>
65 #include <llvm/IR/Type.h>
66 #endif
67 #if ISPC_LLVM_VERSION >= ISPC_LLVM_3_5
68 #include <llvm/Linker/Linker.h>
69 #else
70 #include <llvm/Linker.h>
71 #endif
72 #include <llvm/ADT/Triple.h>
73 #include <llvm/Support/MemoryBuffer.h>
74 #include <llvm/Target/TargetMachine.h>
75 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_9
76 #include <llvm/Bitcode/ReaderWriter.h>
77 #else
78 #include <llvm/Bitcode/BitcodeReader.h>
79 #endif
80 
81 extern int yyparse();
82 struct yy_buffer_state;
83 extern yy_buffer_state *yy_scan_string(const char *);
84 
85 /** Given an LLVM type, try to find the equivalent ispc type. Note that
86  this is an under-constrained problem due to LLVM's type representations
87  carrying less information than ispc's. (For example, LLVM doesn't
88  distinguish between signed and unsigned integers in its types.)
89 
90  Because this function is only used for generating ispc declarations of
91  functions defined in LLVM bitcode in the builtins-*.ll files, in practice
92  we can get enough of what we need for the relevant cases to make things
93  work, partially with the help of the intAsUnsigned parameter, which
94  indicates whether LLVM integer types should be treated as being signed
95  or unsigned.
96 
97  */
98 static const Type *lLLVMTypeToISPCType(const llvm::Type *t, bool intAsUnsigned) {
99  if (t == LLVMTypes::VoidType)
100  return AtomicType::Void;
101 
102  // uniform
103  else if (t == LLVMTypes::BoolType)
105  else if (t == LLVMTypes::Int8Type)
106  return intAsUnsigned ? AtomicType::UniformUInt8 : AtomicType::UniformInt8;
107  else if (t == LLVMTypes::Int16Type)
108  return intAsUnsigned ? AtomicType::UniformUInt16 : AtomicType::UniformInt16;
109  else if (t == LLVMTypes::Int32Type)
110  return intAsUnsigned ? AtomicType::UniformUInt32 : AtomicType::UniformInt32;
111  else if (t == LLVMTypes::FloatType)
113  else if (t == LLVMTypes::DoubleType)
115  else if (t == LLVMTypes::Int64Type)
116  return intAsUnsigned ? AtomicType::UniformUInt64 : AtomicType::UniformInt64;
117 
118  // varying
119  if (t == LLVMTypes::Int8VectorType)
120  return intAsUnsigned ? AtomicType::VaryingUInt8 : AtomicType::VaryingInt8;
121  else if (t == LLVMTypes::Int16VectorType)
122  return intAsUnsigned ? AtomicType::VaryingUInt16 : AtomicType::VaryingInt16;
123  else if (t == LLVMTypes::Int32VectorType)
124  return intAsUnsigned ? AtomicType::VaryingUInt32 : AtomicType::VaryingInt32;
125  else if (t == LLVMTypes::FloatVectorType)
127  else if (t == LLVMTypes::DoubleVectorType)
129  else if (t == LLVMTypes::Int64VectorType)
130  return intAsUnsigned ? AtomicType::VaryingUInt64 : AtomicType::VaryingInt64;
131  else if (t == LLVMTypes::MaskType)
133 
134  // pointers to uniform
135  else if (t == LLVMTypes::Int8PointerType)
137  else if (t == LLVMTypes::Int16PointerType)
139  else if (t == LLVMTypes::Int32PointerType)
141  else if (t == LLVMTypes::Int64PointerType)
143  else if (t == LLVMTypes::FloatPointerType)
145  else if (t == LLVMTypes::DoublePointerType)
147 
148  // pointers to varying
149  else if (t == LLVMTypes::Int8VectorPointerType)
151  else if (t == LLVMTypes::Int16VectorPointerType)
153  else if (t == LLVMTypes::Int32VectorPointerType)
155  else if (t == LLVMTypes::Int64VectorPointerType)
157  else if (t == LLVMTypes::FloatVectorPointerType)
161 
162  return NULL;
163 }
164 
165 static void lCreateSymbol(const std::string &name, const Type *returnType, llvm::SmallVector<const Type *, 8> &argTypes,
166  const llvm::FunctionType *ftype, llvm::Function *func, SymbolTable *symbolTable) {
167  SourcePos noPos;
168  noPos.name = "__stdlib";
169 
170  FunctionType *funcType = new FunctionType(returnType, argTypes, noPos);
171 
172  Debug(noPos, "Created builtin symbol \"%s\" [%s]\n", name.c_str(), funcType->GetString().c_str());
173 
174  Symbol *sym = new Symbol(name, noPos, funcType);
175  sym->function = func;
176  symbolTable->AddFunction(sym);
177 }
178 
179 /** Given an LLVM function declaration, synthesize the equivalent ispc
180  symbol for the function (if possible). Returns true on success, false
181  on failure.
182  */
183 static bool lCreateISPCSymbol(llvm::Function *func, SymbolTable *symbolTable) {
184  SourcePos noPos;
185  noPos.name = "__stdlib";
186 
187  const llvm::FunctionType *ftype = func->getFunctionType();
188  std::string name = func->getName();
189 
190  if (name.size() < 3 || name[0] != '_' || name[1] != '_')
191  return false;
192 
193  Debug(SourcePos(), "Attempting to create ispc symbol for function \"%s\".", name.c_str());
194 
195  // An unfortunate hack: we want this builtin function to have the
196  // signature "int __sext_varying_bool(bool)", but the ispc function
197  // symbol creation code below assumes that any LLVM vector of i32s is a
198  // varying int32. Here, we need that to be interpreted as a varying
199  // bool, so just have a one-off override for that one...
200  if (g->target->getMaskBitCount() != 1 && name == "__sext_varying_bool") {
201  const Type *returnType = AtomicType::VaryingInt32;
202  llvm::SmallVector<const Type *, 8> argTypes;
203  argTypes.push_back(AtomicType::VaryingBool);
204 
205  FunctionType *funcType = new FunctionType(returnType, argTypes, noPos);
206 
207  Symbol *sym = new Symbol(name, noPos, funcType);
208  sym->function = func;
209  symbolTable->AddFunction(sym);
210  return true;
211  }
212 
213  // If the function has any parameters with integer types, we'll make
214  // two Symbols for two overloaded versions of the function, one with
215  // all of the integer types treated as signed integers and one with all
216  // of them treated as unsigned.
217  for (int i = 0; i < 2; ++i) {
218  bool intAsUnsigned = (i == 1);
219 
220  const Type *returnType = lLLVMTypeToISPCType(ftype->getReturnType(), intAsUnsigned);
221  if (returnType == NULL) {
222  Debug(SourcePos(),
223  "Failed: return type not representable for "
224  "builtin %s.",
225  name.c_str());
226  // return type not representable in ispc -> not callable from ispc
227  return false;
228  }
229 
230  // Iterate over the arguments and try to find their equivalent ispc
231  // types. Track if any of the arguments has an integer type.
232  bool anyIntArgs = false;
233  llvm::SmallVector<const Type *, 8> argTypes;
234  for (unsigned int j = 0; j < ftype->getNumParams(); ++j) {
235  const llvm::Type *llvmArgType = ftype->getParamType(j);
236  const Type *type = lLLVMTypeToISPCType(llvmArgType, intAsUnsigned);
237  if (type == NULL) {
238  Debug(SourcePos(),
239  "Failed: type of parameter %d not "
240  "representable for builtin %s",
241  j, name.c_str());
242  return false;
243  }
244  anyIntArgs |= (Type::Equal(type, lLLVMTypeToISPCType(llvmArgType, !intAsUnsigned)) == false);
245  argTypes.push_back(type);
246  }
247 
248  // Always create the symbol the first time through, in particular
249  // so that we get symbols for things with no integer types!
250  if (i == 0 || anyIntArgs == true)
251  lCreateSymbol(name, returnType, argTypes, ftype, func, symbolTable);
252  }
253 
254  return true;
255 }
256 
257 /** Given an LLVM module, create ispc symbols for the functions in the
258  module.
259  */
260 static void lAddModuleSymbols(llvm::Module *module, SymbolTable *symbolTable) {
261 #if 0
262  // FIXME: handle globals?
263  Assert(module->global_empty());
264 #endif
265 
266  llvm::Module::iterator iter;
267  for (iter = module->begin(); iter != module->end(); ++iter) {
268 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_7 /* 3.2, 3.3, 3.4, 3.5, 3.6, 3.7 */
269  llvm::Function *func = iter;
270 #else /* LLVM 3.8+ */
271  llvm::Function *func = &*iter;
272 #endif
273  lCreateISPCSymbol(func, symbolTable);
274  }
275 }
276 
277 /** In many of the builtins-*.ll files, we have declarations of various LLVM
278  intrinsics that are then used in the implementation of various target-
279  specific functions. This function loops over all of the intrinsic
280  declarations and makes sure that the signature we have in our .ll file
281  matches the signature of the actual intrinsic.
282 */
283 static void lCheckModuleIntrinsics(llvm::Module *module) {
284  llvm::Module::iterator iter;
285  for (iter = module->begin(); iter != module->end(); ++iter) {
286 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_7 /* 3.2, 3.3, 3.4, 3.5, 3.6, 3.7 */
287  llvm::Function *func = iter;
288 #else /* LLVM 3.8+ */
289  llvm::Function *func = &*iter;
290 #endif
291  if (!func->isIntrinsic())
292  continue;
293 
294  const std::string funcName = func->getName().str();
295  // Work around http://llvm.org/bugs/show_bug.cgi?id=10438; only
296  // check the llvm.x86.* intrinsics for now...
297  if (!strncmp(funcName.c_str(), "llvm.x86.", 9)) {
298  llvm::Intrinsic::ID id = (llvm::Intrinsic::ID)func->getIntrinsicID();
299  if (id == 0)
300  fprintf(stderr, "FATAL: intrinsic is not found: %s \n", funcName.c_str());
301  Assert(id != 0);
302  llvm::Type *intrinsicType = llvm::Intrinsic::getType(*g->ctx, id);
303  intrinsicType = llvm::PointerType::get(intrinsicType, 0);
304  Assert(func->getType() == intrinsicType);
305  }
306  }
307 }
308 
309 /** We'd like to have all of these functions declared as 'internal' in
310  their respective bitcode files so that if they aren't needed by the
311  user's program they are elimiated from the final output. However, if
312  we do so, then they aren't brought in by the LinkModules() call below
313  since they aren't yet used by anything in the module they're being
314  linked with (in LLVM 3.1, at least).
315 
316  Therefore, we don't declare them as internal when we first define them,
317  but instead mark them as internal after they've been linked in. This
318  is admittedly a kludge.
319  */
320 static void lSetInternalFunctions(llvm::Module *module) {
321  // clang-format off
322  const char *names[] = {
323  "__add_float",
324  "__add_int32",
325  "__add_uniform_double",
326  "__add_uniform_int32",
327  "__add_uniform_int64",
328  "__add_varying_double",
329  "__add_varying_int32",
330  "__add_varying_int64",
331  "__all",
332  "__any",
333  "__aos_to_soa3_double",
334  "__aos_to_soa3_double1",
335  "__aos_to_soa3_double16",
336  "__aos_to_soa3_double4",
337  "__aos_to_soa3_double8",
338  "__aos_to_soa3_int64",
339  "__aos_to_soa3_float",
340 //#ifdef ISPC_NVPTX_ENABLED
341  "__aos_to_soa3_float1",
342 //#endif /* ISPC_NVPTX_ENABLED */
343  "__aos_to_soa3_float16",
344  "__aos_to_soa3_float4",
345  "__aos_to_soa3_float8",
346  "__aos_to_soa3_int32",
347  "__aos_to_soa4_double",
348  "__aos_to_soa4_double1",
349  "__aos_to_soa4_double16",
350  "__aos_to_soa4_double4",
351  "__aos_to_soa4_double8",
352  "__aos_to_soa4_int64",
353  "__aos_to_soa4_float",
354 //#ifdef ISPC_NVPTX_ENABLED
355  "__aos_to_soa4_float1",
356 //#endif /* ISPC_NVPTX_ENABLED */
357  "__aos_to_soa4_float16",
358  "__aos_to_soa4_float4",
359  "__aos_to_soa4_float8",
360  "__aos_to_soa4_int32",
361  "__atomic_add_int32_global",
362  "__atomic_add_int64_global",
363  "__atomic_add_uniform_int32_global",
364  "__atomic_add_uniform_int64_global",
365  "__atomic_and_int32_global",
366  "__atomic_and_int64_global",
367  "__atomic_and_uniform_int32_global",
368  "__atomic_and_uniform_int64_global",
369  "__atomic_compare_exchange_double_global",
370  "__atomic_compare_exchange_float_global",
371  "__atomic_compare_exchange_int32_global",
372  "__atomic_compare_exchange_int64_global",
373  "__atomic_compare_exchange_uniform_double_global",
374  "__atomic_compare_exchange_uniform_float_global",
375  "__atomic_compare_exchange_uniform_int32_global",
376  "__atomic_compare_exchange_uniform_int64_global",
377  "__atomic_max_uniform_int32_global",
378  "__atomic_max_uniform_int64_global",
379  "__atomic_min_uniform_int32_global",
380  "__atomic_min_uniform_int64_global",
381  "__atomic_or_int32_global",
382  "__atomic_or_int64_global",
383  "__atomic_or_uniform_int32_global",
384  "__atomic_or_uniform_int64_global",
385  "__atomic_sub_int32_global",
386  "__atomic_sub_int64_global",
387  "__atomic_sub_uniform_int32_global",
388  "__atomic_sub_uniform_int64_global",
389  "__atomic_swap_double_global",
390  "__atomic_swap_float_global",
391  "__atomic_swap_int32_global",
392  "__atomic_swap_int64_global",
393  "__atomic_swap_uniform_double_global",
394  "__atomic_swap_uniform_float_global",
395  "__atomic_swap_uniform_int32_global",
396  "__atomic_swap_uniform_int64_global",
397  "__atomic_umax_uniform_uint32_global",
398  "__atomic_umax_uniform_uint64_global",
399  "__atomic_umin_uniform_uint32_global",
400  "__atomic_umin_uniform_uint64_global",
401  "__atomic_xor_int32_global",
402  "__atomic_xor_int64_global",
403  "__atomic_xor_uniform_int32_global",
404  "__atomic_xor_uniform_int64_global",
405 //#ifdef ISPC_NVPTX_ENABLED
406  "__atomic_add_varying_int32_global",
407  "__atomic_add_varying_int64_global",
408  "__atomic_and_varying_int32_global",
409  "__atomic_and_varying_int64_global",
410  "__atomic_compare_exchange_varying_double_global",
411  "__atomic_compare_exchange_varying_float_global",
412  "__atomic_compare_exchange_varying_int32_global",
413  "__atomic_compare_exchange_varying_int64_global",
414  "__atomic_max_varying_int32_global",
415  "__atomic_max_varying_int64_global",
416  "__atomic_min_varying_int32_global",
417  "__atomic_min_varying_int64_global",
418  "__atomic_or_varying_int32_global",
419  "__atomic_or_varying_int64_global",
420  "__atomic_sub_varying_int32_global",
421  "__atomic_sub_varying_int64_global",
422  "__atomic_swap_varying_double_global",
423  "__atomic_swap_varying_float_global",
424  "__atomic_swap_varying_int32_global",
425  "__atomic_swap_varying_int64_global",
426  "__atomic_umax_varying_uint32_global",
427  "__atomic_umax_varying_uint64_global",
428  "__atomic_umin_varying_uint32_global",
429  "__atomic_umin_varying_uint64_global",
430  "__atomic_xor_uniform_int32_global",
431  "__atomic_xor_uniform_int64_global",
432  "__atomic_xor_varying_int32_global",
433  "__atomic_xor_varying_int64_global",
434  "__atomic_xor_varying_int32_global",
435  "__atomic_xor_varying_int64_global",
436 //#endif /* ISPC_NVPTX_ENABLED */
437  "__broadcast_double",
438  "__broadcast_float",
439  "__broadcast_i16",
440  "__broadcast_i32",
441  "__broadcast_i64",
442  "__broadcast_i8",
443  "__cast_mask_to_i1",
444  "__cast_mask_to_i8",
445  "__cast_mask_to_i16",
446  "__ceil_uniform_double",
447  "__ceil_uniform_float",
448  "__ceil_varying_double",
449  "__ceil_varying_float",
450  "__clock",
451  "__count_trailing_zeros_i32",
452  "__count_trailing_zeros_i64",
453  "__count_leading_zeros_i32",
454  "__count_leading_zeros_i64",
455  "__delete_uniform_32rt",
456  "__delete_uniform_64rt",
457  "__delete_varying_32rt",
458  "__delete_varying_64rt",
459  "__do_assert_uniform",
460  "__do_assert_varying",
461  "__do_print",
462 //#ifdef ISPC_NVPTX_ENABLED
463  "__do_print_nvptx",
464 //#endif /* ISPC_NVPTX_ENABLED */
465  "__doublebits_uniform_int64",
466  "__doublebits_varying_int64",
467  "__exclusive_scan_add_double",
468  "__exclusive_scan_add_float",
469  "__exclusive_scan_add_i32",
470  "__exclusive_scan_add_i64",
471  "__exclusive_scan_and_i32",
472  "__exclusive_scan_and_i64",
473  "__exclusive_scan_or_i32",
474  "__exclusive_scan_or_i64",
475  "__extract_int16",
476  "__extract_int32",
477  "__extract_int64",
478  "__extract_int8",
479 //#ifdef ISPC_NVPTX_ENABLED
480  "__extract_float",
481  "__extract_double",
482 //#endif /* ISPC_NVPTX_ENABLED */
483  "__extract_mask_low",
484  "__extract_mask_hi",
485  "__fastmath",
486  "__float_to_half_uniform",
487  "__float_to_half_varying",
488  "__floatbits_uniform_int32",
489  "__floatbits_varying_int32",
490  "__floor_uniform_double",
491  "__floor_uniform_float",
492  "__floor_varying_double",
493  "__floor_varying_float",
494  "__get_system_isa",
495  "__half_to_float_uniform",
496  "__half_to_float_varying",
497  "__insert_int16",
498  "__insert_int32",
499  "__insert_int64",
500  "__insert_int8",
501 //#ifdef ISPC_NVPTX_ENABLED
502  "__insert_float",
503  "__insert_double",
504 //#endif /* ISPC_NVPTX_ENABLED */
505  "__intbits_uniform_double",
506  "__intbits_uniform_float",
507  "__intbits_varying_double",
508  "__intbits_varying_float",
509  "__max_uniform_double",
510  "__max_uniform_float",
511  "__max_uniform_int32",
512  "__max_uniform_int64",
513  "__max_uniform_uint32",
514  "__max_uniform_uint64",
515  "__max_varying_double",
516  "__max_varying_float",
517  "__max_varying_int32",
518  "__max_varying_int64",
519  "__max_varying_uint32",
520  "__max_varying_uint64",
521  "__memory_barrier",
522  "__memcpy32",
523  "__memcpy64",
524  "__memmove32",
525  "__memmove64",
526  "__memset32",
527  "__memset64",
528  "__min_uniform_double",
529  "__min_uniform_float",
530  "__min_uniform_int32",
531  "__min_uniform_int64",
532  "__min_uniform_uint32",
533  "__min_uniform_uint64",
534  "__min_varying_double",
535  "__min_varying_float",
536  "__min_varying_int32",
537  "__min_varying_int64",
538  "__min_varying_uint32",
539  "__min_varying_uint64",
540  "__movmsk",
541 //#ifdef ISPC_NVPTX_ENABLED
542  "__movmsk_ptx",
543 //#endif /* ISPC_NVPTX_ENABLED */
544  "__new_uniform_32rt",
545  "__new_uniform_64rt",
546  "__new_varying32_32rt",
547  "__new_varying32_64rt",
548  "__new_varying64_64rt",
549  "__none",
550  "__num_cores",
551  "__packed_load_active",
552  "__packed_store_active",
553  "__packed_store_active2",
554  "__padds_vi8",
555  "__padds_vi16",
556  "__paddus_vi8",
557  "__paddus_vi16",
558  "__popcnt_int32",
559  "__popcnt_int64",
560  "__prefetch_read_uniform_1",
561  "__prefetch_read_uniform_2",
562  "__prefetch_read_uniform_3",
563  "__prefetch_read_uniform_nt",
564  "__pseudo_prefetch_read_varying_1",
565  "__pseudo_prefetch_read_varying_2",
566  "__pseudo_prefetch_read_varying_3",
567  "__pseudo_prefetch_read_varying_nt",
568  "__psubs_vi8",
569  "__psubs_vi16",
570  "__psubus_vi8",
571  "__psubus_vi16",
572  "__rcp_uniform_float",
573  "__rcp_varying_float",
574  "__rcp_uniform_double",
575  "__rcp_varying_double",
576  "__rdrand_i16",
577  "__rdrand_i32",
578  "__rdrand_i64",
579  "__reduce_add_double",
580  "__reduce_add_float",
581  "__reduce_add_int8",
582  "__reduce_add_int16",
583  "__reduce_add_int32",
584  "__reduce_add_int64",
585  "__reduce_equal_double",
586  "__reduce_equal_float",
587  "__reduce_equal_int32",
588  "__reduce_equal_int64",
589  "__reduce_max_double",
590  "__reduce_max_float",
591  "__reduce_max_int32",
592  "__reduce_max_int64",
593  "__reduce_max_uint32",
594  "__reduce_max_uint64",
595  "__reduce_min_double",
596  "__reduce_min_float",
597  "__reduce_min_int32",
598  "__reduce_min_int64",
599  "__reduce_min_uint32",
600  "__reduce_min_uint64",
601  "__rotate_double",
602  "__rotate_float",
603  "__rotate_i16",
604  "__rotate_i32",
605  "__rotate_i64",
606  "__rotate_i8",
607  "__round_uniform_double",
608  "__round_uniform_float",
609  "__round_varying_double",
610  "__round_varying_float",
611  "__rsqrt_uniform_float",
612  "__rsqrt_varying_float",
613  "__rsqrt_uniform_double",
614  "__rsqrt_varying_double",
615  "__set_system_isa",
616  "__sext_uniform_bool",
617  "__sext_varying_bool",
618  "__shift_double",
619  "__shift_float",
620  "__shift_i16",
621  "__shift_i32",
622  "__shift_i64",
623  "__shift_i8",
624  "__shuffle2_double",
625  "__shuffle2_float",
626  "__shuffle2_i16",
627  "__shuffle2_i32",
628  "__shuffle2_i64",
629  "__shuffle2_i8",
630  "__shuffle_double",
631  "__shuffle_float",
632  "__shuffle_i16",
633  "__shuffle_i32",
634  "__shuffle_i64",
635  "__shuffle_i8",
636  "__soa_to_aos3_double",
637  "__soa_to_aos3_double16",
638  "__soa_to_aos3_double4",
639  "__soa_to_aos3_double8",
640  "__soa_to_aos3_int64",
641  "__soa_to_aos3_float",
642  "__soa_to_aos3_float16",
643  "__soa_to_aos3_float4",
644  "__soa_to_aos3_float8",
645  "__soa_to_aos3_int32",
646  "__soa_to_aos4_float",
647 //#ifdef ISPC_NVPTX_ENABLED
648  "__soa_to_aos3_double1",
649  "__soa_to_aos3_float1",
650  "__soa_to_aos4_float1",
651  "__soa_to_aos4_double1",
652 //#endif /* ISPC_NVPTX_ENABLED */
653  "__soa_to_aos4_double16",
654  "__soa_to_aos4_double4",
655  "__soa_to_aos4_double8",
656  "__soa_to_aos4_double",
657  "__soa_to_aos4_int64",
658  "__soa_to_aos4_float16",
659  "__soa_to_aos4_float4",
660  "__soa_to_aos4_float8",
661  "__soa_to_aos4_int32",
662  "__sqrt_uniform_double",
663  "__sqrt_uniform_float",
664  "__sqrt_varying_double",
665  "__sqrt_varying_float",
666  "__stdlib_acosf",
667  "__stdlib_asinf",
668  "__stdlib_atan",
669  "__stdlib_atan2",
670  "__stdlib_atan2f",
671  "__stdlib_atanf",
672  "__stdlib_cos",
673  "__stdlib_cosf",
674  "__stdlib_exp",
675  "__stdlib_expf",
676  "__stdlib_log",
677  "__stdlib_logf",
678  "__stdlib_pow",
679  "__stdlib_powf",
680  "__stdlib_sin",
681  "__stdlib_asin",
682  "__stdlib_sincos",
683  "__stdlib_sincosf",
684  "__stdlib_sinf",
685  "__stdlib_tan",
686  "__stdlib_tanf",
687  "__streaming_load_uniform_double",
688  "__streaming_load_uniform_float",
689  "__streaming_load_uniform_i8",
690  "__streaming_load_uniform_i16",
691  "__streaming_load_uniform_i32",
692  "__streaming_load_uniform_i64",
693  "__streaming_load_varying_double",
694  "__streaming_load_varying_float",
695  "__streaming_load_varying_i8",
696  "__streaming_load_varying_i16",
697  "__streaming_load_varying_i32",
698  "__streaming_load_varying_i64",
699  "__streaming_store_uniform_double",
700  "__streaming_store_uniform_float",
701  "__streaming_store_uniform_i8",
702  "__streaming_store_uniform_i16",
703  "__streaming_store_uniform_i32",
704  "__streaming_store_uniform_i64",
705  "__streaming_store_varying_double",
706  "__streaming_store_varying_float",
707  "__streaming_store_varying_i8",
708  "__streaming_store_varying_i16",
709  "__streaming_store_varying_i32",
710  "__streaming_store_varying_i64",
711  "__svml_sind",
712  "__svml_asind",
713  "__svml_cosd",
714  "__svml_acosd",
715  "__svml_sincosd",
716  "__svml_tand",
717  "__svml_atand",
718  "__svml_atan2d",
719  "__svml_expd",
720  "__svml_logd",
721  "__svml_powd",
722  "__svml_sinf",
723  "__svml_asinf",
724  "__svml_cosf",
725  "__svml_acosf",
726  "__svml_sincosf",
727  "__svml_tanf",
728  "__svml_atanf",
729  "__svml_atan2f",
730  "__svml_expf",
731  "__svml_logf",
732  "__svml_powf",
733  "__log_uniform_float",
734  "__log_varying_float",
735  "__exp_uniform_float",
736  "__exp_varying_float",
737  "__pow_uniform_float",
738  "__pow_varying_float",
739  "__log_uniform_double",
740  "__log_varying_double",
741  "__exp_uniform_double",
742  "__exp_varying_double",
743  "__pow_uniform_double",
744  "__pow_varying_double",
745  "__sin_varying_float",
746  "__asin_varying_float",
747  "__cos_varying_float",
748  "__acos_varying_float",
749  "__sincos_varying_float",
750  "__tan_varying_float",
751  "__atan_varying_float",
752  "__atan2_varying_float",
753  "__sin_uniform_float",
754  "__asin_uniform_float",
755  "__cos_uniform_float",
756  "__acos_uniform_float",
757  "__sincos_uniform_float",
758  "__tan_uniform_float",
759  "__atan_uniform_float",
760  "__atan2_uniform_float",
761  "__sin_varying_double",
762  "__asin_varying_double",
763  "__cos_varying_double",
764  "__acos_varying_double",
765  "__sincos_varying_double",
766  "__tan_varying_double",
767  "__atan_varying_double",
768  "__atan2_varying_double",
769  "__sin_uniform_double",
770  "__asin_uniform_double",
771  "__cos_uniform_double",
772  "__acos_uniform_double",
773  "__sincos_uniform_double",
774  "__tan_uniform_double",
775  "__atan_uniform_double",
776  "__atan2_uniform_double",
777  "__undef_uniform",
778  "__undef_varying",
779  "__vec4_add_float",
780  "__vec4_add_int32",
781  "__vselect_float",
782 //#ifdef ISPC_NVPTX_ENABLED
783  "__program_index",
784  "__program_count",
785  "__warp_index",
786  "__task_index0",
787  "__task_index1",
788  "__task_index2",
789  "__task_index",
790  "__task_count0",
791  "__task_count1",
792  "__task_count2",
793  "__task_count",
794  "__cvt_loc2gen",
795  "__cvt_loc2gen_var",
796  "__cvt_const2gen",
797  "__puts_nvptx",
798  "ISPCAlloc",
799  "ISPCLaunch",
800  "ISPCSync",
801 //#endif /* ISPC_NVPTX_ENABLED */
802  "__vselect_i32"
803  };
804  // clang-format on
805  int count = sizeof(names) / sizeof(names[0]);
806  for (int i = 0; i < count; ++i) {
807  llvm::Function *f = module->getFunction(names[i]);
808  if (f != NULL && f->empty() == false) {
809  f->setLinkage(llvm::GlobalValue::InternalLinkage);
810  // TO-DO : Revisit adding this back for ARM support.
811  // g->target->markFuncWithTargetAttr(f);
812  }
813  }
814 }
815 
816 /** This utility function takes serialized binary LLVM bitcode and adds its
817  definitions to the given module. Functions in the bitcode that can be
818  mapped to ispc functions are also added to the symbol table.
819 
820  @param bitcode Binary LLVM bitcode (e.g. the contents of a *.bc file)
821  @param length Length of the bitcode buffer
822  @param module Module to link the bitcode into
823  @param symbolTable Symbol table to add definitions to
824  */
825 void AddBitcodeToModule(const unsigned char *bitcode, int length, llvm::Module *module, SymbolTable *symbolTable,
826  bool warn) {
827  llvm::StringRef sb = llvm::StringRef((char *)bitcode, length);
828 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_5
829  llvm::MemoryBuffer *bcBuf = llvm::MemoryBuffer::getMemBuffer(sb);
830 #else // LLVM 3.6+
831  llvm::MemoryBufferRef bcBuf = llvm::MemoryBuffer::getMemBuffer(sb)->getMemBufferRef();
832 #endif
833 
834 #if ISPC_LLVM_VERSION >= ISPC_LLVM_4_0 // LLVM 4.0+
835  llvm::Expected<std::unique_ptr<llvm::Module>> ModuleOrErr = llvm::parseBitcodeFile(bcBuf, *g->ctx);
836  if (!ModuleOrErr) {
837  Error(SourcePos(), "Error parsing stdlib bitcode: %s", toString(ModuleOrErr.takeError()).c_str());
838  } else {
839  llvm::Module *bcModule = ModuleOrErr.get().release();
840 #elif ISPC_LLVM_VERSION >= ISPC_LLVM_3_7 // LLVM 3.7+
841  llvm::ErrorOr<std::unique_ptr<llvm::Module>> ModuleOrErr = llvm::parseBitcodeFile(bcBuf, *g->ctx);
842  if (std::error_code EC = ModuleOrErr.getError())
843  Error(SourcePos(), "Error parsing stdlib bitcode: %s", EC.message().c_str());
844  else {
845  llvm::Module *bcModule = ModuleOrErr.get().release();
846 #elif ISPC_LLVM_VERSION == ISPC_LLVM_3_5 || ISPC_LLVM_VERSION == ISPC_LLVM_3_6
847  llvm::ErrorOr<llvm::Module *> ModuleOrErr = llvm::parseBitcodeFile(bcBuf, *g->ctx);
848  if (std::error_code EC = ModuleOrErr.getError())
849  Error(SourcePos(), "Error parsing stdlib bitcode: %s", EC.message().c_str());
850  else {
851  llvm::Module *bcModule = ModuleOrErr.get();
852 #else // LLVM 3.2 - 3.4
853  std::string bcErr;
854  llvm::Module *bcModule = llvm::ParseBitcodeFile(bcBuf, *g->ctx, &bcErr);
855  if (!bcModule)
856  Error(SourcePos(), "Error parsing stdlib bitcode: %s", bcErr.c_str());
857  else {
858 #endif
859  // FIXME: this feels like a bad idea, but the issue is that when we
860  // set the llvm::Module's target triple in the ispc Module::Module
861  // constructor, we start by calling llvm::sys::getHostTriple() (and
862  // then change the arch if needed). Somehow that ends up giving us
863  // strings like 'x86_64-apple-darwin11.0.0', while the stuff we
864  // compile to bitcode with clang has module triples like
865  // 'i386-apple-macosx10.7.0'. And then LLVM issues a warning about
866  // linking together modules with incompatible target triples..
867  llvm::Triple mTriple(m->module->getTargetTriple());
868  llvm::Triple bcTriple(bcModule->getTargetTriple());
869  Debug(SourcePos(), "module triple: %s\nbitcode triple: %s\n", mTriple.str().c_str(), bcTriple.str().c_str());
870 #if defined(ISPC_ARM_ENABLED) && !defined(__arm__)
871  // FIXME: More ugly and dangerous stuff. We really haven't set up
872  // proper build and runtime infrastructure for ispc to do
873  // cross-compilation, yet it's at minimum useful to be able to emit
874  // ARM code from x86 for ispc development. One side-effect is that
875  // when the build process turns builtins/builtins.c to LLVM bitcode
876  // for us to link in at runtime, that bitcode has been compiled for
877  // an IA target, which in turn causes the checks in the following
878  // code to (appropraitely) fail.
879  //
880  // In order to be able to have some ability to generate ARM code on
881  // IA, we'll just skip those tests in that case and allow the
882  // setTargetTriple() and setDataLayout() calls below to shove in
883  // the values for an ARM target. This maybe won't cause problems
884  // in the generated code, since bulitins.c doesn't do anything too
885  // complex w.r.t. struct layouts, etc.
886  if (g->target->getISA() != Target::NEON32 && g->target->getISA() != Target::NEON16 &&
887  g->target->getISA() != Target::NEON8)
888 #endif // !__arm__
889 #ifdef ISPC_NVPTX_ENABLED
890  if (g->target->getISA() != Target::NVPTX)
891 #endif /* ISPC_NVPTX_ENABLED */
892  {
893  Assert(bcTriple.getArch() == llvm::Triple::UnknownArch || mTriple.getArch() == bcTriple.getArch());
894  Assert(bcTriple.getVendor() == llvm::Triple::UnknownVendor ||
895  mTriple.getVendor() == bcTriple.getVendor());
896 
897  // We unconditionally set module DataLayout to library, but we must
898  // ensure that library and module DataLayouts are compatible.
899  // If they are not, we should recompile the library for problematic
900  // architecture and investigate what happened.
901  // Generally we allow library DataLayout to be subset of module
902  // DataLayout or library DataLayout to be empty.
903 #if ISPC_LLVM_VERSION >= ISPC_LLVM_3_5
904  if (!VerifyDataLayoutCompatibility(module->getDataLayoutStr(), bcModule->getDataLayoutStr()) && warn) {
905  Warning(SourcePos(),
906  "Module DataLayout is incompatible with "
907  "library DataLayout:\n"
908  "Module DL: %s\n"
909  "Library DL: %s\n",
910  module->getDataLayoutStr().c_str(), bcModule->getDataLayoutStr().c_str());
911  }
912 #else
913  if (!VerifyDataLayoutCompatibility(module->getDataLayout(), bcModule->getDataLayout()) && warn) {
914  Warning(SourcePos(),
915  "Module DataLayout is incompatible with "
916  "library DataLayout:\n"
917  "Module DL: %s\n"
918  "Library DL: %s\n",
919  module->getDataLayout().c_str(), bcModule->getDataLayout().c_str());
920  }
921 #endif
922  }
923 
924  bcModule->setTargetTriple(mTriple.str());
925  bcModule->setDataLayout(module->getDataLayout());
926 
927 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_5 // 3.2-3.5
928  std::string(linkError);
929 
930  if (llvm::Linker::LinkModules(module, bcModule, llvm::Linker::DestroySource, &linkError))
931  Error(SourcePos(), "Error linking stdlib bitcode: %s", linkError.c_str());
932 #elif ISPC_LLVM_VERSION <= ISPC_LLVM_3_7 // 3.6-3.7
933  llvm::Linker::LinkModules(module, bcModule);
934 #else // LLVM 3.8+
935  // A hack to move over declaration, which have no definition.
936  // New linker is kind of smart and think it knows better what to do, so
937  // it removes unused declarations without definitions.
938  // This trick should be legal, as both modules use the same LLVMContext.
939  for (llvm::Function &f : *bcModule) {
940  if (f.isDeclaration()) {
941  // Declarations with uses will be moved by Linker.
942  if (f.getNumUses() > 0)
943  continue;
944  module->getOrInsertFunction(f.getName(), f.getFunctionType(), f.getAttributes());
945  }
946  }
947 
948  std::unique_ptr<llvm::Module> M(bcModule);
949  if (llvm::Linker::linkModules(*module, std::move(M))) {
950  Error(SourcePos(), "Error linking stdlib bitcode.");
951  }
952 #endif
953 
954  lSetInternalFunctions(module);
955  if (symbolTable != NULL)
956  lAddModuleSymbols(module, symbolTable);
957  lCheckModuleIntrinsics(module);
958  }
959 }
960 
961 /** Utility routine that defines a constant int32 with given value, adding
962  the symbol to both the ispc symbol table and the given LLVM module.
963  */
964 static void lDefineConstantInt(const char *name, int val, llvm::Module *module, SymbolTable *symbolTable,
965  std::vector<llvm::Constant *> &dbg_sym) {
966  Symbol *sym = new Symbol(name, SourcePos(), AtomicType::UniformInt32->GetAsConstType(), SC_STATIC);
967  sym->constValue = new ConstExpr(sym->type, val, SourcePos());
968  llvm::Type *ltype = LLVMTypes::Int32Type;
969  llvm::Constant *linit = LLVMInt32(val);
970 #if ISPC_LLVM_VERSION < ISPC_LLVM_3_6
971  // Use WeakODRLinkage rather than InternalLinkage so that a definition
972  // survives even if it's not used in the module, so that the symbol is
973  // there in the debugger.
974  llvm::GlobalValue::LinkageTypes linkage =
975  g->generateDebuggingSymbols ? llvm::GlobalValue::WeakODRLinkage : llvm::GlobalValue::InternalLinkage;
976  sym->storagePtr = new llvm::GlobalVariable(*module, ltype, true, linkage, linit, name);
977 #else // LLVM 3.6+
978  auto GV = new llvm::GlobalVariable(*module, ltype, true, llvm::GlobalValue::InternalLinkage, linit, name);
979  dbg_sym.push_back(GV);
980  sym->storagePtr = GV;
981 #endif
982  symbolTable->AddVariable(sym);
983 
984  if (m->diBuilder != NULL) {
985 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
986  llvm::DIFile file;
987  llvm::DIType diType = sym->type->GetDIType(file);
988  Assert(diType.Verify());
989 #else // LLVM 3.7+
990  llvm::DIFile *file = m->diCompileUnit->getFile();
991  llvm::DICompileUnit *cu = m->diCompileUnit;
992  llvm::DIType *diType = sym->type->GetDIType(file);
993 #endif
994  // FIXME? DWARF says that this (and programIndex below) should
995  // have the DW_AT_artifical attribute. It's not clear if this
996  // matters for anything though.
997 
998 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_5
999  llvm::DIGlobalVariable var =
1000  m->diBuilder->createGlobalVariable(name, file, 0 /* line */, diType, true /* static */, sym->storagePtr);
1001 #elif ISPC_LLVM_VERSION == ISPC_LLVM_3_6 // LLVM 3.6
1002  llvm::Constant *sym_const_storagePtr = llvm::dyn_cast<llvm::Constant>(sym->storagePtr);
1003  Assert(sym_const_storagePtr);
1004  llvm::DIGlobalVariable var = m->diBuilder->createGlobalVariable(file, name, name, file, 0 /* line */, diType,
1005  true /* static */, sym_const_storagePtr);
1006 #elif ISPC_LLVM_VERSION >= ISPC_LLVM_3_7 && ISPC_LLVM_VERSION <= ISPC_LLVM_3_9 // LLVM 3.7 - 3.9
1007  llvm::Constant *sym_const_storagePtr = llvm::dyn_cast<llvm::Constant>(sym->storagePtr);
1008  Assert(sym_const_storagePtr);
1009  m->diBuilder->createGlobalVariable(cu, name, name, file, 0 /* line */, diType, true /* static */,
1010  sym_const_storagePtr);
1011 #else // LLVM 4.0+
1012  llvm::GlobalVariable *sym_GV_storagePtr = llvm::dyn_cast<llvm::GlobalVariable>(sym->storagePtr);
1013  llvm::DIGlobalVariableExpression *var =
1014  m->diBuilder->createGlobalVariableExpression(cu, name, name, file, 0 /* line */, diType, true /* static */);
1015  sym_GV_storagePtr->addDebugInfo(var);
1016 #endif
1017 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
1018  Assert(var.Verify());
1019 #else // LLVM 3.7+
1020  // coming soon
1021 #endif
1022  }
1023 }
1024 
1025 static void lDefineConstantIntFunc(const char *name, int val, llvm::Module *module, SymbolTable *symbolTable,
1026  std::vector<llvm::Constant *> &dbg_sym) {
1027  llvm::SmallVector<const Type *, 8> args;
1029  Symbol *sym = new Symbol(name, SourcePos(), ft, SC_STATIC);
1030 
1031  llvm::Function *func = module->getFunction(name);
1032  dbg_sym.push_back(func);
1033  Assert(func != NULL); // it should be declared already...
1034 #if ISPC_LLVM_VERSION == ISPC_LLVM_3_2
1035  func->addFnAttr(llvm::Attributes::AlwaysInline);
1036 #else // LLVM 3.3+
1037  func->addFnAttr(llvm::Attribute::AlwaysInline);
1038 #endif
1039  llvm::BasicBlock *bblock = llvm::BasicBlock::Create(*g->ctx, "entry", func, 0);
1040  llvm::ReturnInst::Create(*g->ctx, LLVMInt32(val), bblock);
1041 
1042  sym->function = func;
1043  symbolTable->AddVariable(sym);
1044 }
1045 
1046 static void lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable,
1047  std::vector<llvm::Constant *> &dbg_sym) {
1048  Symbol *sym = new Symbol("programIndex", SourcePos(), AtomicType::VaryingInt32->GetAsConstType(), SC_STATIC);
1049 
1050  int pi[ISPC_MAX_NVEC];
1051  for (int i = 0; i < g->target->getVectorWidth(); ++i)
1052  pi[i] = i;
1053  sym->constValue = new ConstExpr(sym->type, pi, SourcePos());
1054 
1055  llvm::Type *ltype = LLVMTypes::Int32VectorType;
1056  llvm::Constant *linit = LLVMInt32Vector(pi);
1057 #if ISPC_LLVM_VERSION < ISPC_LLVM_3_6
1058  // See comment in lDefineConstantInt() for why WeakODRLinkage is used here
1059  llvm::GlobalValue::LinkageTypes linkage =
1060  g->generateDebuggingSymbols ? llvm::GlobalValue::WeakODRLinkage : llvm::GlobalValue::InternalLinkage;
1061  sym->storagePtr = new llvm::GlobalVariable(*module, ltype, true, linkage, linit, sym->name.c_str());
1062 #else // LLVM 3.6+
1063  auto GV =
1064  new llvm::GlobalVariable(*module, ltype, true, llvm::GlobalValue::InternalLinkage, linit, sym->name.c_str());
1065  dbg_sym.push_back(GV);
1066  sym->storagePtr = GV;
1067 #endif
1068  symbolTable->AddVariable(sym);
1069 
1070  if (m->diBuilder != NULL) {
1071 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
1072  llvm::DIFile file;
1073  llvm::DIType diType = sym->type->GetDIType(file);
1074  Assert(diType.Verify());
1075 #else // LLVM 3.7+
1076  llvm::DIFile *file = m->diCompileUnit->getFile();
1077  llvm::DICompileUnit *cu = m->diCompileUnit;
1078  llvm::DIType *diType = sym->type->GetDIType(file);
1079 #endif
1080 #if ISPC_LLVM_VERSION == ISPC_LLVM_3_6 // LLVM 3.6
1081  llvm::Constant *sym_const_storagePtr = llvm::dyn_cast<llvm::Constant>(sym->storagePtr);
1082  Assert(sym_const_storagePtr);
1083  llvm::DIGlobalVariable var =
1084  m->diBuilder->createGlobalVariable(file, sym->name.c_str(), sym->name.c_str(), file, 0 /* line */, diType,
1085  false /* static */, sym_const_storagePtr);
1086 #elif ISPC_LLVM_VERSION <= ISPC_LLVM_3_5
1087  llvm::DIGlobalVariable var = m->diBuilder->createGlobalVariable(sym->name.c_str(), file, 0 /* line */, diType,
1088  false /* static */, sym->storagePtr);
1089 #elif ISPC_LLVM_VERSION >= ISPC_LLVM_3_7 && ISPC_LLVM_VERSION <= ISPC_LLVM_3_9 // LLVM 3.7 - 3.9
1090  llvm::Constant *sym_const_storagePtr = llvm::dyn_cast<llvm::Constant>(sym->storagePtr);
1091  Assert(sym_const_storagePtr);
1092  m->diBuilder->createGlobalVariable(cu, sym->name.c_str(), sym->name.c_str(), file, 0 /* line */, diType,
1093  false /* static */, sym_const_storagePtr);
1094 #else // LLVM 4.0+
1095  llvm::GlobalVariable *sym_GV_storagePtr = llvm::dyn_cast<llvm::GlobalVariable>(sym->storagePtr);
1096  llvm::DIGlobalVariableExpression *var = m->diBuilder->createGlobalVariableExpression(
1097  cu, sym->name.c_str(), sym->name.c_str(), file, 0 /* line */, diType, false /* static */);
1098  sym_GV_storagePtr->addDebugInfo(var);
1099 #endif
1100 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
1101  Assert(var.Verify());
1102 #else // LLVM 3.7+
1103  // coming soon
1104 #endif
1105  }
1106 }
1107 
1108 #if ISPC_LLVM_VERSION >= ISPC_LLVM_3_6 // LLVM 3.6+
1109 static void emitLLVMUsed(llvm::Module &module, std::vector<llvm::Constant *> &list) {
1110  // Convert list to what ConstantArray needs.
1111  llvm::SmallVector<llvm::Constant *, 8> UsedArray;
1112  UsedArray.reserve(list.size());
1113  for (auto c : list) {
1114  UsedArray.push_back(llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(llvm::cast<llvm::Constant>(c),
1116  }
1117 
1118  llvm::ArrayType *ATy = llvm::ArrayType::get(LLVMTypes::Int8PointerType, UsedArray.size());
1119 
1120  auto *GV = new llvm::GlobalVariable(module, ATy, false, llvm::GlobalValue::AppendingLinkage,
1121  llvm::ConstantArray::get(ATy, UsedArray), "llvm.used");
1122 
1123  GV->setSection("llvm.metadata");
1124 }
1125 #endif
1126 
1127 void DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *module, bool includeStdlibISPC) {
1128  // debug_symbols are symbols that supposed to be preserved in debug information.
1129  // They will be referenced in llvm.used intrinsic to prevent they removal from
1130  // the object file.
1131  std::vector<llvm::Constant *> debug_symbols;
1132  bool runtime32 = g->target->is32Bit();
1133  bool warn = g->target->getISA() != Target::GENERIC;
1134 
1135 #define EXPORT_MODULE_COND_WARN(export_module, warnings) \
1136  extern unsigned char export_module[]; \
1137  extern int export_module##_length; \
1138  AddBitcodeToModule(export_module, export_module##_length, module, symbolTable, warnings);
1139 
1140 #define EXPORT_MODULE(export_module) \
1141  extern unsigned char export_module[]; \
1142  extern int export_module##_length; \
1143  AddBitcodeToModule(export_module, export_module##_length, module, symbolTable, true);
1144 
1145  // Add the definitions from the compiled builtins.c file.
1146  // When compiling for "generic" target family, data layout warnings for
1147  // "builtins_bitcode_c" have to be switched off: its DL is incompatible
1148  // with the DL of "generic". Anyway, AddBitcodeToModule() corrects this
1149  // automatically if DLs differ (by copying module`s DL to export`s DL).
1150  if (runtime32) {
1151  EXPORT_MODULE_COND_WARN(builtins_bitcode_c_32, warn);
1152  } else {
1153  EXPORT_MODULE_COND_WARN(builtins_bitcode_c_64, warn);
1154  }
1155 
1156  // Next, add the target's custom implementations of the various needed
1157  // builtin functions (e.g. __masked_store_32(), etc).
1158  switch (g->target->getISA()) {
1159 #ifdef ISPC_NVPTX_ENABLED
1160  case Target::NVPTX: {
1161  if (runtime32) {
1162  fprintf(stderr, "Unfortunatly 32bit targets are not supported at the moment .. \n");
1163  assert(0);
1164  } else {
1165  EXPORT_MODULE(builtins_bitcode_nvptx_64bit);
1166  }
1167  break;
1168  };
1169 #endif /* ISPC_NVPTX_ENABLED */
1170 
1171 #ifdef ISPC_ARM_ENABLED
1172  case Target::NEON8: {
1173  if (runtime32) {
1174  EXPORT_MODULE(builtins_bitcode_neon_8_32bit);
1175  } else {
1176  EXPORT_MODULE(builtins_bitcode_neon_8_64bit);
1177  }
1178  break;
1179  }
1180  case Target::NEON16: {
1181  if (runtime32) {
1182  EXPORT_MODULE(builtins_bitcode_neon_16_32bit);
1183  } else {
1184  EXPORT_MODULE(builtins_bitcode_neon_16_64bit);
1185  }
1186  break;
1187  }
1188  case Target::NEON32: {
1189  if (runtime32) {
1190  EXPORT_MODULE(builtins_bitcode_neon_32_32bit);
1191  } else {
1192  EXPORT_MODULE(builtins_bitcode_neon_32_64bit);
1193  }
1194  break;
1195  }
1196 #endif
1197  case Target::SSE2: {
1198  switch (g->target->getVectorWidth()) {
1199  case 4:
1200  if (runtime32) {
1201  EXPORT_MODULE(builtins_bitcode_sse2_32bit);
1202  } else {
1203  EXPORT_MODULE(builtins_bitcode_sse2_64bit);
1204  }
1205  break;
1206  case 8:
1207  if (runtime32) {
1208  EXPORT_MODULE(builtins_bitcode_sse2_x2_32bit);
1209  } else {
1210  EXPORT_MODULE(builtins_bitcode_sse2_x2_64bit);
1211  }
1212  break;
1213  default:
1214  FATAL("logic error in DefineStdlib");
1215  }
1216  break;
1217  }
1218  case Target::SSE4: {
1219  switch (g->target->getVectorWidth()) {
1220  case 4:
1221  if (runtime32) {
1222  EXPORT_MODULE(builtins_bitcode_sse4_32bit);
1223  } else {
1224  EXPORT_MODULE(builtins_bitcode_sse4_64bit);
1225  }
1226  break;
1227  case 8:
1228  if (runtime32) {
1229  if (g->target->getMaskBitCount() == 16) {
1230  EXPORT_MODULE(builtins_bitcode_sse4_16_32bit);
1231  } else {
1232  Assert(g->target->getMaskBitCount() == 32);
1233  EXPORT_MODULE(builtins_bitcode_sse4_x2_32bit);
1234  }
1235  } else {
1236  if (g->target->getMaskBitCount() == 16) {
1237  EXPORT_MODULE(builtins_bitcode_sse4_16_64bit);
1238  } else {
1239  Assert(g->target->getMaskBitCount() == 32);
1240  EXPORT_MODULE(builtins_bitcode_sse4_x2_64bit);
1241  }
1242  }
1243  break;
1244  case 16:
1245  Assert(g->target->getMaskBitCount() == 8);
1246  if (runtime32) {
1247  EXPORT_MODULE(builtins_bitcode_sse4_8_32bit);
1248  } else {
1249  EXPORT_MODULE(builtins_bitcode_sse4_8_64bit);
1250  }
1251  break;
1252  default:
1253  FATAL("logic error in DefineStdlib");
1254  }
1255  break;
1256  }
1257  case Target::AVX: {
1258  switch (g->target->getVectorWidth()) {
1259  case 4:
1260  if (g->target->getDataTypeWidth() == 32) {
1261  // Note here that for avx1-i32x4 we are using bitcode file for
1262  // sse4-i32x4. This is intentional and good enough.
1263  // AVX target implies appropriate target-feature attrbute,
1264  // which forces LLVM to generate AVX code, even for SSE4
1265  // intrinsics. Except that the only "missing" feature in sse4
1266  // target is implemenation of __masked_[store|load]_[i32|i64]
1267  // using maskmov instruction. But it's not very popular
1268  // intrinsics, so we assume the implementation to be good
1269  // enough at the moment.
1270  if (runtime32) {
1271  EXPORT_MODULE(builtins_bitcode_sse4_32bit);
1272  } else {
1273  EXPORT_MODULE(builtins_bitcode_sse4_64bit);
1274  }
1275  } else if (g->target->getDataTypeWidth() == 64) {
1276  if (runtime32) {
1277  EXPORT_MODULE(builtins_bitcode_avx1_i64x4_32bit);
1278  } else {
1279  EXPORT_MODULE(builtins_bitcode_avx1_i64x4_64bit);
1280  }
1281  } else {
1282  FATAL("logic error in DefineStdlib");
1283  }
1284  break;
1285  case 8:
1286  if (runtime32) {
1287  EXPORT_MODULE(builtins_bitcode_avx1_32bit);
1288  } else {
1289  EXPORT_MODULE(builtins_bitcode_avx1_64bit);
1290  }
1291  break;
1292  case 16:
1293  if (runtime32) {
1294  EXPORT_MODULE(builtins_bitcode_avx1_x2_32bit);
1295  } else {
1296  EXPORT_MODULE(builtins_bitcode_avx1_x2_64bit);
1297  }
1298  break;
1299  default:
1300  FATAL("logic error in DefineStdlib");
1301  }
1302  break;
1303  }
1304  case Target::AVX11: {
1305  switch (g->target->getVectorWidth()) {
1306  case 4:
1307  if (runtime32) {
1308  EXPORT_MODULE(builtins_bitcode_avx11_i64x4_32bit);
1309  } else {
1310  EXPORT_MODULE(builtins_bitcode_avx11_i64x4_64bit);
1311  }
1312  break;
1313  case 8:
1314  if (runtime32) {
1315  EXPORT_MODULE(builtins_bitcode_avx11_32bit);
1316  } else {
1317  EXPORT_MODULE(builtins_bitcode_avx11_64bit);
1318  }
1319  break;
1320  case 16:
1321  if (runtime32) {
1322  EXPORT_MODULE(builtins_bitcode_avx11_x2_32bit);
1323  } else {
1324  EXPORT_MODULE(builtins_bitcode_avx11_x2_64bit);
1325  }
1326  break;
1327  default:
1328  FATAL("logic error in DefineStdlib");
1329  }
1330  break;
1331  }
1332  case Target::AVX2: {
1333  switch (g->target->getVectorWidth()) {
1334  case 4:
1335  if (runtime32) {
1336  EXPORT_MODULE(builtins_bitcode_avx2_i64x4_32bit);
1337  } else {
1338  EXPORT_MODULE(builtins_bitcode_avx2_i64x4_64bit);
1339  }
1340  break;
1341  case 8:
1342  if (runtime32) {
1343  EXPORT_MODULE(builtins_bitcode_avx2_32bit);
1344  } else {
1345  EXPORT_MODULE(builtins_bitcode_avx2_64bit);
1346  }
1347  break;
1348  case 16:
1349  if (runtime32) {
1350  EXPORT_MODULE(builtins_bitcode_avx2_x2_32bit);
1351  } else {
1352  EXPORT_MODULE(builtins_bitcode_avx2_x2_64bit);
1353  }
1354  break;
1355  default:
1356  FATAL("logic error in DefineStdlib");
1357  }
1358  break;
1359  }
1360 #if ISPC_LLVM_VERSION >= ISPC_LLVM_3_7 // LLVM 3.7+
1361  case Target::KNL_AVX512: {
1362  switch (g->target->getVectorWidth()) {
1363  case 16:
1364  if (runtime32) {
1365  EXPORT_MODULE(builtins_bitcode_knl_32bit);
1366  } else {
1367  EXPORT_MODULE(builtins_bitcode_knl_64bit);
1368  }
1369  break;
1370  default:
1371  FATAL("logic error in DefineStdlib");
1372  }
1373  break;
1374  }
1375 #endif
1376 #if ISPC_LLVM_VERSION >= ISPC_LLVM_3_8 // LLVM 3.8+
1377  case Target::SKX_AVX512: {
1378  switch (g->target->getVectorWidth()) {
1379  case 8:
1380  if (runtime32) {
1381  EXPORT_MODULE(builtins_bitcode_skx_8_32bit);
1382  } else {
1383  EXPORT_MODULE(builtins_bitcode_skx_8_64bit);
1384  }
1385  break;
1386  case 16:
1387  if (runtime32) {
1388  EXPORT_MODULE(builtins_bitcode_skx_32bit);
1389  } else {
1390  EXPORT_MODULE(builtins_bitcode_skx_64bit);
1391  }
1392  break;
1393  default:
1394  FATAL("logic error in DefineStdlib");
1395  }
1396  break;
1397  }
1398 #endif
1399  case Target::GENERIC: {
1400  switch (g->target->getVectorWidth()) {
1401  case 4:
1402  if (runtime32) {
1403  EXPORT_MODULE(builtins_bitcode_generic_4_32bit);
1404  } else {
1405  EXPORT_MODULE(builtins_bitcode_generic_4_64bit);
1406  }
1407  break;
1408  case 8:
1409  if (runtime32) {
1410  EXPORT_MODULE(builtins_bitcode_generic_8_32bit);
1411  } else {
1412  EXPORT_MODULE(builtins_bitcode_generic_8_64bit);
1413  }
1414  break;
1415  case 16:
1416  if (runtime32) {
1417  EXPORT_MODULE(builtins_bitcode_generic_16_32bit);
1418  } else {
1419  EXPORT_MODULE(builtins_bitcode_generic_16_64bit);
1420  }
1421  break;
1422  case 32:
1423  if (runtime32) {
1424  EXPORT_MODULE(builtins_bitcode_generic_32_32bit);
1425  } else {
1426  EXPORT_MODULE(builtins_bitcode_generic_32_64bit);
1427  }
1428  break;
1429  case 64:
1430  if (runtime32) {
1431  EXPORT_MODULE(builtins_bitcode_generic_64_32bit);
1432  } else {
1433  EXPORT_MODULE(builtins_bitcode_generic_64_64bit);
1434  }
1435  break;
1436  case 1:
1437  if (runtime32) {
1438  EXPORT_MODULE(builtins_bitcode_generic_1_32bit);
1439  } else {
1440  EXPORT_MODULE(builtins_bitcode_generic_1_64bit);
1441  }
1442  break;
1443  default:
1444  FATAL("logic error in DefineStdlib");
1445  }
1446  break;
1447  }
1448  default:
1449  FATAL("logic error");
1450  }
1451 
1452  // define the 'programCount' builtin variable
1453 #ifdef ISPC_NVPTX_ENABLED
1454  if (g->target->getISA() == Target::NVPTX) {
1455  lDefineConstantInt("programCount", 32, module, symbolTable, debug_symbols);
1456  } else {
1457 #endif /* ISPC_NVPTX_ENABLED */
1458  lDefineConstantInt("programCount", g->target->getVectorWidth(), module, symbolTable, debug_symbols);
1459 #ifdef ISPC_NVPTX_ENABLED
1460  }
1461 #endif /* ISPC_NVPTX_ENABLED */
1462 
1463  // define the 'programIndex' builtin
1464  lDefineProgramIndex(module, symbolTable, debug_symbols);
1465 
1466  // Define __math_lib stuff. This is used by stdlib.ispc, for example, to
1467  // figure out which math routines to end up calling...
1468  lDefineConstantInt("__math_lib", (int)g->mathLib, module, symbolTable, debug_symbols);
1469  lDefineConstantInt("__math_lib_ispc", (int)Globals::Math_ISPC, module, symbolTable, debug_symbols);
1470  lDefineConstantInt("__math_lib_ispc_fast", (int)Globals::Math_ISPCFast, module, symbolTable, debug_symbols);
1471  lDefineConstantInt("__math_lib_svml", (int)Globals::Math_SVML, module, symbolTable, debug_symbols);
1472  lDefineConstantInt("__math_lib_system", (int)Globals::Math_System, module, symbolTable, debug_symbols);
1473  lDefineConstantIntFunc("__fast_masked_vload", (int)g->opt.fastMaskedVload, module, symbolTable, debug_symbols);
1474 
1475  lDefineConstantInt("__have_native_half", g->target->hasHalf(), module, symbolTable, debug_symbols);
1476  lDefineConstantInt("__have_native_rand", g->target->hasRand(), module, symbolTable, debug_symbols);
1477  lDefineConstantInt("__have_native_transcendentals", g->target->hasTranscendentals(), module, symbolTable,
1478  debug_symbols);
1479  lDefineConstantInt("__have_native_trigonometry", g->target->hasTrigonometry(), module, symbolTable, debug_symbols);
1480  lDefineConstantInt("__have_native_rsqrtd", g->target->hasRsqrtd(), module, symbolTable, debug_symbols);
1481  lDefineConstantInt("__have_native_rcpd", g->target->hasRcpd(), module, symbolTable, debug_symbols);
1482 
1483 #ifdef ISPC_NVPTX_ENABLED
1484  lDefineConstantInt("__is_nvptx_target", (int)(g->target->getISA() == Target::NVPTX), module, symbolTable,
1485  debug_symbols);
1486 #else
1487  lDefineConstantInt("__is_nvptx_target", (int)0, module, symbolTable, debug_symbols);
1488 #endif /* ISPC_NVPTX_ENABLED */
1489 
1490  if (g->forceAlignment != -1) {
1491  llvm::GlobalVariable *alignment = module->getGlobalVariable("memory_alignment", true);
1492  alignment->setInitializer(LLVMInt32(g->forceAlignment));
1493  }
1494 
1495  // LLVM 3.6 is only because it was not tested with earlier versions.
1496 #if ISPC_LLVM_VERSION >= ISPC_LLVM_3_6 // LLVM 3.6+
1497  if (g->generateDebuggingSymbols) {
1498  emitLLVMUsed(*module, debug_symbols);
1499  }
1500 #endif
1501 
1502  if (includeStdlibISPC) {
1503  // If the user wants the standard library to be included, parse the
1504  // serialized version of the stdlib.ispc file to get its
1505  // definitions added.
1506  extern char stdlib_mask1_code[], stdlib_mask8_code[];
1507  extern char stdlib_mask16_code[], stdlib_mask32_code[], stdlib_mask64_code[];
1508  if (g->target->getISA() == Target::GENERIC && g->target->getVectorWidth() == 1) { // 1 wide uses 32 stdlib
1509  yy_scan_string(stdlib_mask32_code);
1510  } else {
1511  switch (g->target->getMaskBitCount()) {
1512  case 1:
1513  yy_scan_string(stdlib_mask1_code);
1514  break;
1515  case 8:
1516  yy_scan_string(stdlib_mask8_code);
1517  break;
1518  case 16:
1519  yy_scan_string(stdlib_mask16_code);
1520  break;
1521  case 32:
1522  yy_scan_string(stdlib_mask32_code);
1523  break;
1524  case 64:
1525  yy_scan_string(stdlib_mask64_code);
1526  break;
1527  default:
1528  FATAL("Unhandled mask bit size for stdlib.ispc");
1529  }
1530  }
1531  yyparse();
1532  }
1533 }
llvm::Value * storagePtr
Definition: sym.h:71
static const AtomicType * VaryingInt32
Definition: type.h:335
static llvm::Type * FloatType
Definition: llvmutil.h:79
static bool lCreateISPCSymbol(llvm::Function *func, SymbolTable *symbolTable)
Definition: builtins.cpp:183
void AddBitcodeToModule(const unsigned char *bitcode, int length, llvm::Module *module, SymbolTable *symbolTable, bool warn)
Definition: builtins.cpp:825
static const AtomicType * VaryingInt16
Definition: type.h:334
llvm::Function * function
Definition: sym.h:75
static llvm::Type * Int32VectorPointerType
Definition: llvmutil.h:102
void DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *module, bool includeStdlibISPC)
Definition: builtins.cpp:1127
#define EXPORT_MODULE(export_module)
Opt opt
Definition: ispc.h:535
Declaration of the FunctionEmitContext class
bool AddFunction(Symbol *symbol)
Definition: sym.cpp:126
static void lDefineConstantInt(const char *name, int val, llvm::Module *module, SymbolTable *symbolTable, std::vector< llvm::Constant *> &dbg_sym)
Definition: builtins.cpp:964
static const AtomicType * VaryingUInt64
Definition: type.h:341
static llvm::Type * DoubleType
Definition: llvmutil.h:80
Module * m
Definition: ispc.cpp:102
static void lCheckModuleIntrinsics(llvm::Module *module)
Definition: builtins.cpp:283
Target * target
Definition: ispc.h:537
bool AddVariable(Symbol *symbol)
Definition: sym.cpp:85
virtual llvm::DIType GetDIType(llvm::DIDescriptor scope) const =0
static const AtomicType * VaryingDouble
Definition: type.h:342
Expression representing a compile-time constant value.
Definition: expr.h:362
static llvm::Type * BoolType
Definition: llvmutil.h:73
Symbol table that holds all known symbols during parsing and compilation.
Definition: sym.h:117
static void lDefineConstantIntFunc(const char *name, int val, llvm::Module *module, SymbolTable *symbolTable, std::vector< llvm::Constant *> &dbg_sym)
Definition: builtins.cpp:1025
llvm::Constant * LLVMInt32Vector(int32_t i)
Definition: llvmutil.cpp:308
static llvm::VectorType * Int32VectorType
Definition: llvmutil.h:95
int getMaskBitCount() const
Definition: ispc.h:278
static const AtomicType * UniformUInt32
Definition: type.h:338
static llvm::Type * FloatVectorPointerType
Definition: llvmutil.h:104
int getDataTypeWidth() const
Definition: ispc.h:270
Declarations of functions related to builtins and the standard library.
bool hasHalf() const
Definition: ispc.h:280
static llvm::Type * Int8PointerType
Definition: llvmutil.h:82
static llvm::Type * Int32PointerType
Definition: llvmutil.h:84
std::string name
Definition: sym.h:70
static llvm::Type * Int16VectorPointerType
Definition: llvmutil.h:101
static llvm::Type * Int16Type
Definition: llvmutil.h:76
static llvm::Type * DoubleVectorPointerType
Definition: llvmutil.h:105
static const AtomicType * UniformUInt16
Definition: type.h:337
static void lSetInternalFunctions(llvm::Module *module)
Definition: builtins.cpp:320
static PointerType * GetUniform(const Type *t, bool isSlice=false)
Definition: type.cpp:899
#define Assert(expr)
Definition: ispc.h:161
ConstExpr * constValue
Definition: sym.h:86
header file with declarations for symbol and symbol table classes.
static const AtomicType * UniformBool
Definition: type.h:332
static llvm::Type * VoidType
Definition: llvmutil.h:70
llvm::ConstantInt * LLVMInt32(int32_t i)
Definition: llvmutil.cpp:228
static void lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable, std::vector< llvm::Constant *> &dbg_sym)
Definition: builtins.cpp:1046
llvm::Module * module
Definition: module.h:155
static llvm::Type * Int8VectorPointerType
Definition: llvmutil.h:100
Globals * g
Definition: ispc.cpp:101
static const AtomicType * UniformUInt64
Definition: type.h:341
static llvm::VectorType * Int8VectorType
Definition: llvmutil.h:93
void Error(SourcePos p, const char *format,...) PRINTF_FUNC
Definition: util.cpp:351
bool VerifyDataLayoutCompatibility(const std::string &module_dl, const std::string &lib_dl)
Definition: util.cpp:565
static llvm::VectorType * FloatVectorType
Definition: llvmutil.h:97
static llvm::Type * Int64Type
Definition: llvmutil.h:78
static llvm::Type * Int8Type
Definition: llvmutil.h:75
static llvm::VectorType * Int64VectorType
Definition: llvmutil.h:96
Header file with declarations for various LLVM utility stuff.
static llvm::Type * Int64PointerType
Definition: llvmutil.h:85
bool hasRcpd() const
Definition: ispc.h:294
static llvm::Type * FloatPointerType
Definition: llvmutil.h:86
static void lAddModuleSymbols(llvm::Module *module, SymbolTable *symbolTable)
Definition: builtins.cpp:260
bool hasRand() const
Definition: ispc.h:282
Representation of a range of positions in a source file.
Definition: ispc.h:129
static llvm::Type * Int16PointerType
Definition: llvmutil.h:83
bool generateDebuggingSymbols
Definition: ispc.h:607
static const AtomicType * VaryingBool
Definition: type.h:332
bool hasTranscendentals() const
Definition: ispc.h:288
bool fastMaskedVload
Definition: ispc.h:435
const char * name
Definition: ispc.h:132
void Warning(SourcePos p, const char *format,...) PRINTF_FUNC
Definition: util.cpp:375
static const AtomicType * VaryingInt64
Definition: type.h:340
#define EXPORT_MODULE_COND_WARN(export_module, warnings)
int getVectorWidth() const
Definition: ispc.h:272
#define FATAL(message)
Definition: util.h:112
int yyparse()
static const AtomicType * UniformUInt8
Definition: type.h:336
static llvm::Type * Int64VectorPointerType
Definition: llvmutil.h:103
static llvm::Type * Int32Type
Definition: llvmutil.h:77
MathLib mathLib
Definition: ispc.h:542
static llvm::Type * DoublePointerType
Definition: llvmutil.h:87
#define ISPC_MAX_NVEC
Definition: ispc.h:69
static bool Equal(const Type *a, const Type *b)
Definition: type.cpp:3114
static const AtomicType * VaryingUInt16
Definition: type.h:337
bool hasTrigonometry() const
Definition: ispc.h:290
static const AtomicType * VaryingInt8
Definition: type.h:333
static const AtomicType * UniformFloat
Definition: type.h:339
ISA getISA() const
Definition: ispc.h:256
static const AtomicType * UniformInt32
Definition: type.h:335
Type representing a function (return type + argument types)
Definition: type.h:858
Representation of a program symbol.
Definition: sym.h:63
Interface class that defines the type abstraction.
Definition: type.h:95
static const AtomicType * UniformDouble
Definition: type.h:342
Expr abstract base class and expression implementations.
static const AtomicType * Void
Definition: type.h:343
static llvm::VectorType * MaskType
Definition: llvmutil.h:89
int forceAlignment
Definition: ispc.h:648
yy_buffer_state * yy_scan_string(const char *)
static llvm::VectorType * DoubleVectorType
Definition: llvmutil.h:98
bool hasRsqrtd() const
Definition: ispc.h:292
static llvm::VectorType * Int16VectorType
Definition: llvmutil.h:94
static const AtomicType * VaryingUInt8
Definition: type.h:336
bool is32Bit() const
Definition: ispc.h:262
Declaration of the Module class, which is the ispc-side representation of the results of compiling a ...
static const AtomicType * UniformInt64
Definition: type.h:340
llvm::LLVMContext * ctx
Definition: ispc.h:632
static const AtomicType * UniformInt16
Definition: type.h:334
const Type * type
Definition: sym.h:83
llvm::DIBuilder * diBuilder
Definition: module.h:158
std::string GetString() const
Definition: type.cpp:2568
void Debug(SourcePos p, const char *format,...) PRINTF_FUNC
Definition: util.cpp:363
static const Type * lLLVMTypeToISPCType(const llvm::Type *t, bool intAsUnsigned)
Definition: builtins.cpp:98
static const AtomicType * VaryingUInt32
Definition: type.h:338
static const AtomicType * VaryingFloat
Definition: type.h:339
static void lCreateSymbol(const std::string &name, const Type *returnType, llvm::SmallVector< const Type *, 8 > &argTypes, const llvm::FunctionType *ftype, llvm::Function *func, SymbolTable *symbolTable)
Definition: builtins.cpp:165
static const AtomicType * UniformInt8
Definition: type.h:333
File with declarations for classes related to type representation.