Intel® Implicit SPMD Program Compiler (Intel® ISPC)  1.13.0
builtins.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 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 
51 #include <llvm/ADT/Triple.h>
52 #include <llvm/Bitcode/BitcodeReader.h>
53 #include <llvm/IR/Attributes.h>
54 #include <llvm/IR/DerivedTypes.h>
55 #include <llvm/IR/Instructions.h>
56 #include <llvm/IR/Intrinsics.h>
57 #include <llvm/IR/LLVMContext.h>
58 #include <llvm/IR/Module.h>
59 #include <llvm/IR/Type.h>
60 #include <llvm/Linker/Linker.h>
61 #include <llvm/Support/MemoryBuffer.h>
62 #include <llvm/Target/TargetMachine.h>
63 
64 extern int yyparse();
65 struct yy_buffer_state;
66 extern yy_buffer_state *yy_scan_string(const char *);
67 
68 /** Given an LLVM type, try to find the equivalent ispc type. Note that
69  this is an under-constrained problem due to LLVM's type representations
70  carrying less information than ispc's. (For example, LLVM doesn't
71  distinguish between signed and unsigned integers in its types.)
72 
73  Because this function is only used for generating ispc declarations of
74  functions defined in LLVM bitcode in the builtins-*.ll files, in practice
75  we can get enough of what we need for the relevant cases to make things
76  work, partially with the help of the intAsUnsigned parameter, which
77  indicates whether LLVM integer types should be treated as being signed
78  or unsigned.
79 
80  */
81 static const Type *lLLVMTypeToISPCType(const llvm::Type *t, bool intAsUnsigned) {
82  if (t == LLVMTypes::VoidType)
83  return AtomicType::Void;
84 
85  // uniform
86  else if (t == LLVMTypes::BoolType)
88  else if (t == LLVMTypes::Int8Type)
89  return intAsUnsigned ? AtomicType::UniformUInt8 : AtomicType::UniformInt8;
90  else if (t == LLVMTypes::Int16Type)
91  return intAsUnsigned ? AtomicType::UniformUInt16 : AtomicType::UniformInt16;
92  else if (t == LLVMTypes::Int32Type)
93  return intAsUnsigned ? AtomicType::UniformUInt32 : AtomicType::UniformInt32;
94  else if (t == LLVMTypes::FloatType)
96  else if (t == LLVMTypes::DoubleType)
98  else if (t == LLVMTypes::Int64Type)
99  return intAsUnsigned ? AtomicType::UniformUInt64 : AtomicType::UniformInt64;
100 
101  // varying
102  if (t == LLVMTypes::Int8VectorType)
103  return intAsUnsigned ? AtomicType::VaryingUInt8 : AtomicType::VaryingInt8;
104  else if (t == LLVMTypes::Int16VectorType)
105  return intAsUnsigned ? AtomicType::VaryingUInt16 : AtomicType::VaryingInt16;
106  else if (t == LLVMTypes::Int32VectorType)
107  return intAsUnsigned ? AtomicType::VaryingUInt32 : AtomicType::VaryingInt32;
108  else if (t == LLVMTypes::FloatVectorType)
110  else if (t == LLVMTypes::DoubleVectorType)
112  else if (t == LLVMTypes::Int64VectorType)
113  return intAsUnsigned ? AtomicType::VaryingUInt64 : AtomicType::VaryingInt64;
114  else if (t == LLVMTypes::MaskType)
116 
117  // pointers to uniform
118  else if (t == LLVMTypes::Int8PointerType)
120  else if (t == LLVMTypes::Int16PointerType)
122  else if (t == LLVMTypes::Int32PointerType)
124  else if (t == LLVMTypes::Int64PointerType)
126  else if (t == LLVMTypes::FloatPointerType)
128  else if (t == LLVMTypes::DoublePointerType)
130 
131  // pointers to varying
132  else if (t == LLVMTypes::Int8VectorPointerType)
134  else if (t == LLVMTypes::Int16VectorPointerType)
136  else if (t == LLVMTypes::Int32VectorPointerType)
138  else if (t == LLVMTypes::Int64VectorPointerType)
140  else if (t == LLVMTypes::FloatVectorPointerType)
144 
145  return NULL;
146 }
147 
148 static void lCreateSymbol(const std::string &name, const Type *returnType, llvm::SmallVector<const Type *, 8> &argTypes,
149  const llvm::FunctionType *ftype, llvm::Function *func, SymbolTable *symbolTable) {
150  SourcePos noPos;
151  noPos.name = "__stdlib";
152 
153  FunctionType *funcType = new FunctionType(returnType, argTypes, noPos);
154 
155  Debug(noPos, "Created builtin symbol \"%s\" [%s]\n", name.c_str(), funcType->GetString().c_str());
156 
157  Symbol *sym = new Symbol(name, noPos, funcType);
158  sym->function = func;
159  symbolTable->AddFunction(sym);
160 }
161 
162 /** Given an LLVM function declaration, synthesize the equivalent ispc
163  symbol for the function (if possible). Returns true on success, false
164  on failure.
165  */
166 static bool lCreateISPCSymbol(llvm::Function *func, SymbolTable *symbolTable) {
167  SourcePos noPos;
168  noPos.name = "__stdlib";
169 
170  const llvm::FunctionType *ftype = func->getFunctionType();
171  std::string name = std::string(func->getName());
172 
173  if (name.size() < 3 || name[0] != '_' || name[1] != '_')
174  return false;
175 
176  Debug(SourcePos(), "Attempting to create ispc symbol for function \"%s\".", name.c_str());
177 
178  // An unfortunate hack: we want this builtin function to have the
179  // signature "int __sext_varying_bool(bool)", but the ispc function
180  // symbol creation code below assumes that any LLVM vector of i32s is a
181  // varying int32. Here, we need that to be interpreted as a varying
182  // bool, so just have a one-off override for that one...
183  if (g->target->getMaskBitCount() != 1 && name == "__sext_varying_bool") {
184  const Type *returnType = AtomicType::VaryingInt32;
185  llvm::SmallVector<const Type *, 8> argTypes;
186  argTypes.push_back(AtomicType::VaryingBool);
187 
188  FunctionType *funcType = new FunctionType(returnType, argTypes, noPos);
189 
190  Symbol *sym = new Symbol(name, noPos, funcType);
191  sym->function = func;
192  symbolTable->AddFunction(sym);
193  return true;
194  }
195 
196  // If the function has any parameters with integer types, we'll make
197  // two Symbols for two overloaded versions of the function, one with
198  // all of the integer types treated as signed integers and one with all
199  // of them treated as unsigned.
200  for (int i = 0; i < 2; ++i) {
201  bool intAsUnsigned = (i == 1);
202 
203  const Type *returnType = lLLVMTypeToISPCType(ftype->getReturnType(), intAsUnsigned);
204  if (returnType == NULL) {
205  Debug(SourcePos(),
206  "Failed: return type not representable for "
207  "builtin %s.",
208  name.c_str());
209  // return type not representable in ispc -> not callable from ispc
210  return false;
211  }
212 
213  // Iterate over the arguments and try to find their equivalent ispc
214  // types. Track if any of the arguments has an integer type.
215  bool anyIntArgs = false;
216  llvm::SmallVector<const Type *, 8> argTypes;
217  for (unsigned int j = 0; j < ftype->getNumParams(); ++j) {
218  const llvm::Type *llvmArgType = ftype->getParamType(j);
219  const Type *type = lLLVMTypeToISPCType(llvmArgType, intAsUnsigned);
220  if (type == NULL) {
221  Debug(SourcePos(),
222  "Failed: type of parameter %d not "
223  "representable for builtin %s",
224  j, name.c_str());
225  return false;
226  }
227  anyIntArgs |= (Type::Equal(type, lLLVMTypeToISPCType(llvmArgType, !intAsUnsigned)) == false);
228  argTypes.push_back(type);
229  }
230 
231  // Always create the symbol the first time through, in particular
232  // so that we get symbols for things with no integer types!
233  if (i == 0 || anyIntArgs == true)
234  lCreateSymbol(name, returnType, argTypes, ftype, func, symbolTable);
235  }
236 
237  return true;
238 }
239 
240 /** Given an LLVM module, create ispc symbols for the functions in the
241  module.
242  */
243 static void lAddModuleSymbols(llvm::Module *module, SymbolTable *symbolTable) {
244 #if 0
245  // FIXME: handle globals?
246  Assert(module->global_empty());
247 #endif
248 
249  llvm::Module::iterator iter;
250  for (iter = module->begin(); iter != module->end(); ++iter) {
251  llvm::Function *func = &*iter;
252  lCreateISPCSymbol(func, symbolTable);
253  }
254 }
255 
256 /** In many of the builtins-*.ll files, we have declarations of various LLVM
257  intrinsics that are then used in the implementation of various target-
258  specific functions. This function loops over all of the intrinsic
259  declarations and makes sure that the signature we have in our .ll file
260  matches the signature of the actual intrinsic.
261 */
262 static void lCheckModuleIntrinsics(llvm::Module *module) {
263  llvm::Module::iterator iter;
264  for (iter = module->begin(); iter != module->end(); ++iter) {
265  llvm::Function *func = &*iter;
266  if (!func->isIntrinsic())
267  continue;
268 
269  const std::string funcName = func->getName().str();
270  // Work around http://llvm.org/bugs/show_bug.cgi?id=10438; only
271  // check the llvm.x86.* intrinsics for now...
272  if (!strncmp(funcName.c_str(), "llvm.x86.", 9)) {
273  llvm::Intrinsic::ID id = (llvm::Intrinsic::ID)func->getIntrinsicID();
274  if (id == 0) {
275  std::string error_message = "Intrinsic is not found: ";
276  error_message += funcName;
277  FATAL(error_message.c_str());
278  }
279  llvm::Type *intrinsicType = llvm::Intrinsic::getType(*g->ctx, id);
280  intrinsicType = llvm::PointerType::get(intrinsicType, 0);
281  Assert(func->getType() == intrinsicType);
282  }
283  }
284 }
285 
286 /** We'd like to have all of these functions declared as 'internal' in
287  their respective bitcode files so that if they aren't needed by the
288  user's program they are elimiated from the final output. However, if
289  we do so, then they aren't brought in by the LinkModules() call below
290  since they aren't yet used by anything in the module they're being
291  linked with (in LLVM 3.1, at least).
292 
293  Therefore, we don't declare them as internal when we first define them,
294  but instead mark them as internal after they've been linked in. This
295  is admittedly a kludge.
296  */
297 static void lSetInternalFunctions(llvm::Module *module) {
298  // clang-format off
299  const char *names[] = {
300  "__add_float",
301  "__add_int32",
302  "__add_uniform_double",
303  "__add_uniform_int32",
304  "__add_uniform_int64",
305  "__add_varying_double",
306  "__add_varying_int32",
307  "__add_varying_int64",
308  "__all",
309  "__any",
310  "__aos_to_soa3_double",
311  "__aos_to_soa3_double1",
312  "__aos_to_soa3_double16",
313  "__aos_to_soa3_double32",
314  "__aos_to_soa3_double4",
315  "__aos_to_soa3_double64",
316  "__aos_to_soa3_double8",
317  "__aos_to_soa3_float",
318  "__aos_to_soa3_float1",
319  "__aos_to_soa3_float16",
320  "__aos_to_soa3_float32",
321  "__aos_to_soa3_float4",
322  "__aos_to_soa3_float64",
323  "__aos_to_soa3_float8",
324  "__aos_to_soa4_double",
325  "__aos_to_soa4_double1",
326  "__aos_to_soa4_double16",
327  "__aos_to_soa4_double32",
328  "__aos_to_soa4_double4",
329  "__aos_to_soa4_double64",
330  "__aos_to_soa4_double8",
331  "__aos_to_soa4_float",
332  "__aos_to_soa4_float1",
333  "__aos_to_soa4_float16",
334  "__aos_to_soa4_float32",
335  "__aos_to_soa4_float4",
336  "__aos_to_soa4_float64",
337  "__aos_to_soa4_float8",
338  "__atomic_add_int32_global",
339  "__atomic_add_int64_global",
340  "__atomic_add_uniform_int32_global",
341  "__atomic_add_uniform_int64_global",
342  "__atomic_and_int32_global",
343  "__atomic_and_int64_global",
344  "__atomic_and_uniform_int32_global",
345  "__atomic_and_uniform_int64_global",
346  "__atomic_compare_exchange_double_global",
347  "__atomic_compare_exchange_float_global",
348  "__atomic_compare_exchange_int32_global",
349  "__atomic_compare_exchange_int64_global",
350  "__atomic_compare_exchange_uniform_double_global",
351  "__atomic_compare_exchange_uniform_float_global",
352  "__atomic_compare_exchange_uniform_int32_global",
353  "__atomic_compare_exchange_uniform_int64_global",
354  "__atomic_max_uniform_int32_global",
355  "__atomic_max_uniform_int64_global",
356  "__atomic_min_uniform_int32_global",
357  "__atomic_min_uniform_int64_global",
358  "__atomic_or_int32_global",
359  "__atomic_or_int64_global",
360  "__atomic_or_uniform_int32_global",
361  "__atomic_or_uniform_int64_global",
362  "__atomic_sub_int32_global",
363  "__atomic_sub_int64_global",
364  "__atomic_sub_uniform_int32_global",
365  "__atomic_sub_uniform_int64_global",
366  "__atomic_swap_double_global",
367  "__atomic_swap_float_global",
368  "__atomic_swap_int32_global",
369  "__atomic_swap_int64_global",
370  "__atomic_swap_uniform_double_global",
371  "__atomic_swap_uniform_float_global",
372  "__atomic_swap_uniform_int32_global",
373  "__atomic_swap_uniform_int64_global",
374  "__atomic_umax_uniform_uint32_global",
375  "__atomic_umax_uniform_uint64_global",
376  "__atomic_umin_uniform_uint32_global",
377  "__atomic_umin_uniform_uint64_global",
378  "__atomic_xor_int32_global",
379  "__atomic_xor_int64_global",
380  "__atomic_xor_uniform_int32_global",
381  "__atomic_xor_uniform_int64_global",
382  "__broadcast_double",
383  "__broadcast_float",
384  "__broadcast_i16",
385  "__broadcast_i32",
386  "__broadcast_i64",
387  "__broadcast_i8",
388  "__cast_mask_to_i1",
389  "__cast_mask_to_i8",
390  "__cast_mask_to_i16",
391  "__ceil_uniform_double",
392  "__ceil_uniform_float",
393  "__ceil_varying_double",
394  "__ceil_varying_float",
395  "__clock",
396  "__count_trailing_zeros_i32",
397  "__count_trailing_zeros_i64",
398  "__count_leading_zeros_i32",
399  "__count_leading_zeros_i64",
400  "__delete_uniform_32rt",
401  "__delete_uniform_64rt",
402  "__delete_varying_32rt",
403  "__delete_varying_64rt",
404  "__do_assert_uniform",
405  "__do_assert_varying",
406  "__do_print",
407  "__doublebits_uniform_int64",
408  "__doublebits_varying_int64",
409  "__exclusive_scan_add_double",
410  "__exclusive_scan_add_float",
411  "__exclusive_scan_add_i32",
412  "__exclusive_scan_add_i64",
413  "__exclusive_scan_and_i32",
414  "__exclusive_scan_and_i64",
415  "__exclusive_scan_or_i32",
416  "__exclusive_scan_or_i64",
417  "__extract_bool",
418  "__extract_int16",
419  "__extract_int32",
420  "__extract_int64",
421  "__extract_int8",
422  "__extract_mask_low",
423  "__extract_mask_hi",
424  "__fastmath",
425  "__float_to_half_uniform",
426  "__float_to_half_varying",
427  "__floatbits_uniform_int32",
428  "__floatbits_varying_int32",
429  "__floor_uniform_double",
430  "__floor_uniform_float",
431  "__floor_varying_double",
432  "__floor_varying_float",
433  "__get_system_isa",
434  "__half_to_float_uniform",
435  "__half_to_float_varying",
436  "__insert_bool",
437  "__insert_int16",
438  "__insert_int32",
439  "__insert_int64",
440  "__insert_int8",
441  "__intbits_uniform_double",
442  "__intbits_uniform_float",
443  "__intbits_varying_double",
444  "__intbits_varying_float",
445  "__max_uniform_double",
446  "__max_uniform_float",
447  "__max_uniform_int32",
448  "__max_uniform_int64",
449  "__max_uniform_uint32",
450  "__max_uniform_uint64",
451  "__max_varying_double",
452  "__max_varying_float",
453  "__max_varying_int32",
454  "__max_varying_int64",
455  "__max_varying_uint32",
456  "__max_varying_uint64",
457  "__memory_barrier",
458  "__memcpy32",
459  "__memcpy64",
460  "__memmove32",
461  "__memmove64",
462  "__memset32",
463  "__memset64",
464  "__min_uniform_double",
465  "__min_uniform_float",
466  "__min_uniform_int32",
467  "__min_uniform_int64",
468  "__min_uniform_uint32",
469  "__min_uniform_uint64",
470  "__min_varying_double",
471  "__min_varying_float",
472  "__min_varying_int32",
473  "__min_varying_int64",
474  "__min_varying_uint32",
475  "__min_varying_uint64",
476  "__movmsk",
477  "__new_uniform_32rt",
478  "__new_uniform_64rt",
479  "__new_varying32_32rt",
480  "__new_varying32_64rt",
481  "__new_varying64_64rt",
482  "__none",
483  "__num_cores",
484  "__packed_load_active",
485  "__packed_store_active",
486  "__packed_store_active2",
487  "__padds_vi8",
488  "__padds_vi16",
489  "__paddus_vi8",
490  "__paddus_vi16",
491  "__popcnt_int32",
492  "__popcnt_int64",
493  "__prefetch_read_uniform_1",
494  "__prefetch_read_uniform_2",
495  "__prefetch_read_uniform_3",
496  "__prefetch_read_uniform_nt",
497  "__pseudo_prefetch_read_varying_1",
498  "__pseudo_prefetch_read_varying_2",
499  "__pseudo_prefetch_read_varying_3",
500  "__pseudo_prefetch_read_varying_nt",
501  "__psubs_vi8",
502  "__psubs_vi16",
503  "__psubus_vi8",
504  "__psubus_vi16",
505  "__rcp_fast_uniform_float",
506  "__rcp_uniform_float",
507  "__rcp_fast_varying_float",
508  "__rcp_varying_float",
509  "__rcp_uniform_double",
510  "__rcp_varying_double",
511  "__rdrand_i16",
512  "__rdrand_i32",
513  "__rdrand_i64",
514  "__reduce_add_double",
515  "__reduce_add_float",
516  "__reduce_add_int8",
517  "__reduce_add_int16",
518  "__reduce_add_int32",
519  "__reduce_add_int64",
520  "__reduce_equal_double",
521  "__reduce_equal_float",
522  "__reduce_equal_int32",
523  "__reduce_equal_int64",
524  "__reduce_max_double",
525  "__reduce_max_float",
526  "__reduce_max_int32",
527  "__reduce_max_int64",
528  "__reduce_max_uint32",
529  "__reduce_max_uint64",
530  "__reduce_min_double",
531  "__reduce_min_float",
532  "__reduce_min_int32",
533  "__reduce_min_int64",
534  "__reduce_min_uint32",
535  "__reduce_min_uint64",
536  "__rotate_double",
537  "__rotate_float",
538  "__rotate_i16",
539  "__rotate_i32",
540  "__rotate_i64",
541  "__rotate_i8",
542  "__round_uniform_double",
543  "__round_uniform_float",
544  "__round_varying_double",
545  "__round_varying_float",
546  "__rsqrt_fast_varying_float",
547  "__rsqrt_uniform_float",
548  "__rsqrt_fast_uniform_float",
549  "__rsqrt_varying_float",
550  "__rsqrt_uniform_double",
551  "__rsqrt_varying_double",
552  "__set_system_isa",
553  "__sext_uniform_bool",
554  "__sext_varying_bool",
555  "__shift_double",
556  "__shift_float",
557  "__shift_i16",
558  "__shift_i32",
559  "__shift_i64",
560  "__shift_i8",
561  "__shuffle2_double",
562  "__shuffle2_float",
563  "__shuffle2_i16",
564  "__shuffle2_i32",
565  "__shuffle2_i64",
566  "__shuffle2_i8",
567  "__shuffle_double",
568  "__shuffle_float",
569  "__shuffle_i16",
570  "__shuffle_i32",
571  "__shuffle_i64",
572  "__shuffle_i8",
573  "__soa_to_aos3_double",
574  "__soa_to_aos3_double1",
575  "__soa_to_aos3_double16",
576  "__soa_to_aos3_double32",
577  "__soa_to_aos3_double4",
578  "__soa_to_aos3_double64",
579  "__soa_to_aos3_double8",
580  "__soa_to_aos3_float",
581  "__soa_to_aos3_float1",
582  "__soa_to_aos3_float16",
583  "__soa_to_aos3_float32",
584  "__soa_to_aos3_float4",
585  "__soa_to_aos3_float64",
586  "__soa_to_aos3_float8",
587  "__soa_to_aos4_double",
588  "__soa_to_aos4_double1",
589  "__soa_to_aos4_double16",
590  "__soa_to_aos4_double32",
591  "__soa_to_aos4_double4",
592  "__soa_to_aos4_double64",
593  "__soa_to_aos4_double8",
594  "__soa_to_aos4_float",
595  "__soa_to_aos4_float1",
596  "__soa_to_aos4_float16",
597  "__soa_to_aos4_float32",
598  "__soa_to_aos4_float4",
599  "__soa_to_aos4_float64",
600  "__soa_to_aos4_float8",
601  "__sqrt_uniform_double",
602  "__sqrt_uniform_float",
603  "__sqrt_varying_double",
604  "__sqrt_varying_float",
605  "__stdlib_acosf",
606  "__stdlib_asinf",
607  "__stdlib_atan",
608  "__stdlib_atan2",
609  "__stdlib_atan2f",
610  "__stdlib_atanf",
611  "__stdlib_cos",
612  "__stdlib_cosf",
613  "__stdlib_exp",
614  "__stdlib_expf",
615  "__stdlib_log",
616  "__stdlib_logf",
617  "__stdlib_pow",
618  "__stdlib_powf",
619  "__stdlib_sin",
620  "__stdlib_asin",
621  "__stdlib_sincos",
622  "__stdlib_sincosf",
623  "__stdlib_sinf",
624  "__stdlib_tan",
625  "__stdlib_tanf",
626  "__streaming_load_uniform_double",
627  "__streaming_load_uniform_float",
628  "__streaming_load_uniform_i8",
629  "__streaming_load_uniform_i16",
630  "__streaming_load_uniform_i32",
631  "__streaming_load_uniform_i64",
632  "__streaming_load_varying_double",
633  "__streaming_load_varying_float",
634  "__streaming_load_varying_i8",
635  "__streaming_load_varying_i16",
636  "__streaming_load_varying_i32",
637  "__streaming_load_varying_i64",
638  "__streaming_store_uniform_double",
639  "__streaming_store_uniform_float",
640  "__streaming_store_uniform_i8",
641  "__streaming_store_uniform_i16",
642  "__streaming_store_uniform_i32",
643  "__streaming_store_uniform_i64",
644  "__streaming_store_varying_double",
645  "__streaming_store_varying_float",
646  "__streaming_store_varying_i8",
647  "__streaming_store_varying_i16",
648  "__streaming_store_varying_i32",
649  "__streaming_store_varying_i64",
650  "__svml_sind",
651  "__svml_asind",
652  "__svml_cosd",
653  "__svml_acosd",
654  "__svml_sincosd",
655  "__svml_tand",
656  "__svml_atand",
657  "__svml_atan2d",
658  "__svml_expd",
659  "__svml_logd",
660  "__svml_powd",
661  "__svml_sinf",
662  "__svml_asinf",
663  "__svml_cosf",
664  "__svml_acosf",
665  "__svml_sincosf",
666  "__svml_tanf",
667  "__svml_atanf",
668  "__svml_atan2f",
669  "__svml_expf",
670  "__svml_logf",
671  "__svml_powf",
672  "__log_uniform_float",
673  "__log_varying_float",
674  "__exp_uniform_float",
675  "__exp_varying_float",
676  "__pow_uniform_float",
677  "__pow_varying_float",
678  "__log_uniform_double",
679  "__log_varying_double",
680  "__exp_uniform_double",
681  "__exp_varying_double",
682  "__pow_uniform_double",
683  "__pow_varying_double",
684  "__sin_varying_float",
685  "__asin_varying_float",
686  "__cos_varying_float",
687  "__acos_varying_float",
688  "__sincos_varying_float",
689  "__tan_varying_float",
690  "__atan_varying_float",
691  "__atan2_varying_float",
692  "__sin_uniform_float",
693  "__asin_uniform_float",
694  "__cos_uniform_float",
695  "__acos_uniform_float",
696  "__sincos_uniform_float",
697  "__tan_uniform_float",
698  "__atan_uniform_float",
699  "__atan2_uniform_float",
700  "__sin_varying_double",
701  "__asin_varying_double",
702  "__cos_varying_double",
703  "__acos_varying_double",
704  "__sincos_varying_double",
705  "__tan_varying_double",
706  "__atan_varying_double",
707  "__atan2_varying_double",
708  "__sin_uniform_double",
709  "__asin_uniform_double",
710  "__cos_uniform_double",
711  "__acos_uniform_double",
712  "__sincos_uniform_double",
713  "__tan_uniform_double",
714  "__atan_uniform_double",
715  "__atan2_uniform_double",
716  "__undef_uniform",
717  "__undef_varying",
718  "__vec4_add_float",
719  "__vec4_add_int32",
720  "__vselect_float",
721  "__vselect_i32",
722  "ISPCAlloc",
723  "ISPCLaunch",
724  "ISPCSync"
725  };
726  // clang-format on
727  int count = sizeof(names) / sizeof(names[0]);
728  for (int i = 0; i < count; ++i) {
729  llvm::Function *f = module->getFunction(names[i]);
730  if (f != NULL && f->empty() == false) {
731  f->setLinkage(llvm::GlobalValue::InternalLinkage);
732  // TO-DO : Revisit adding this back for ARM support.
733  // g->target->markFuncWithTargetAttr(f);
734  }
735  }
736 }
737 
738 /** This utility function takes serialized binary LLVM bitcode and adds its
739  definitions to the given module. Functions in the bitcode that can be
740  mapped to ispc functions are also added to the symbol table.
741 
742  @param lib Pointer to BitcodeLib class representing LLVM bitcode (e.g. the contents of a *.bc file)
743  @param module Module to link the bitcode into
744  @param symbolTable Symbol table to add definitions to
745  */
746 void AddBitcodeToModule(const BitcodeLib *lib, llvm::Module *module, SymbolTable *symbolTable, bool warn) {
747  llvm::StringRef sb = llvm::StringRef((const char *)lib->getLib(), lib->getSize());
748  llvm::MemoryBufferRef bcBuf = llvm::MemoryBuffer::getMemBuffer(sb)->getMemBufferRef();
749 
750  llvm::Expected<std::unique_ptr<llvm::Module>> ModuleOrErr = llvm::parseBitcodeFile(bcBuf, *g->ctx);
751  if (!ModuleOrErr) {
752  Error(SourcePos(), "Error parsing stdlib bitcode: %s", toString(ModuleOrErr.takeError()).c_str());
753  } else {
754  llvm::Module *bcModule = ModuleOrErr.get().release();
755  // FIXME: this feels like a bad idea, but the issue is that when we
756  // set the llvm::Module's target triple in the ispc Module::Module
757  // constructor, we start by calling llvm::sys::getHostTriple() (and
758  // then change the arch if needed). Somehow that ends up giving us
759  // strings like 'x86_64-apple-darwin11.0.0', while the stuff we
760  // compile to bitcode with clang has module triples like
761  // 'i386-apple-macosx10.7.0'. And then LLVM issues a warning about
762  // linking together modules with incompatible target triples..
763  llvm::Triple mTriple(m->module->getTargetTriple());
764  llvm::Triple bcTriple(bcModule->getTargetTriple());
765  Debug(SourcePos(), "module triple: %s\nbitcode triple: %s\n", mTriple.str().c_str(), bcTriple.str().c_str());
766 
767  // Disable this code for cross compilation
768 #if 0
769  {
770  Assert(bcTriple.getArch() == llvm::Triple::UnknownArch || mTriple.getArch() == bcTriple.getArch());
771  Assert(bcTriple.getVendor() == llvm::Triple::UnknownVendor ||
772  mTriple.getVendor() == bcTriple.getVendor());
773 
774  // We unconditionally set module DataLayout to library, but we must
775  // ensure that library and module DataLayouts are compatible.
776  // If they are not, we should recompile the library for problematic
777  // architecture and investigate what happened.
778  // Generally we allow library DataLayout to be subset of module
779  // DataLayout or library DataLayout to be empty.
780  if (!VerifyDataLayoutCompatibility(module->getDataLayoutStr(), bcModule->getDataLayoutStr()) && warn) {
781  Warning(SourcePos(),
782  "Module DataLayout is incompatible with "
783  "library DataLayout:\n"
784  "Module DL: %s\n"
785  "Library DL: %s\n",
786  module->getDataLayoutStr().c_str(), bcModule->getDataLayoutStr().c_str());
787  }
788  }
789 #endif
790 
791  bcModule->setTargetTriple(mTriple.str());
792  bcModule->setDataLayout(module->getDataLayout());
793 
794  // A hack to move over declaration, which have no definition.
795  // New linker is kind of smart and think it knows better what to do, so
796  // it removes unused declarations without definitions.
797  // This trick should be legal, as both modules use the same LLVMContext.
798  for (llvm::Function &f : *bcModule) {
799  if (f.isDeclaration()) {
800  // Declarations with uses will be moved by Linker.
801  if (f.getNumUses() > 0)
802  continue;
803  module->getOrInsertFunction(f.getName(), f.getFunctionType(), f.getAttributes());
804  }
805  }
806 
807  std::unique_ptr<llvm::Module> M(bcModule);
808  if (llvm::Linker::linkModules(*module, std::move(M))) {
809  Error(SourcePos(), "Error linking stdlib bitcode.");
810  }
811 
812  lSetInternalFunctions(module);
813  if (symbolTable != NULL)
814  lAddModuleSymbols(module, symbolTable);
815  lCheckModuleIntrinsics(module);
816  }
817 }
818 
819 /** Utility routine that defines a constant int32 with given value, adding
820  the symbol to both the ispc symbol table and the given LLVM module.
821  */
822 static void lDefineConstantInt(const char *name, int val, llvm::Module *module, SymbolTable *symbolTable,
823  std::vector<llvm::Constant *> &dbg_sym) {
824  Symbol *sym = new Symbol(name, SourcePos(), AtomicType::UniformInt32->GetAsConstType(), SC_STATIC);
825  sym->constValue = new ConstExpr(sym->type, val, SourcePos());
826  llvm::Type *ltype = LLVMTypes::Int32Type;
827  llvm::Constant *linit = LLVMInt32(val);
828  auto GV = new llvm::GlobalVariable(*module, ltype, true, llvm::GlobalValue::InternalLinkage, linit, name);
829  dbg_sym.push_back(GV);
830  sym->storagePtr = GV;
831  symbolTable->AddVariable(sym);
832 
833  if (m->diBuilder != NULL) {
834  llvm::DIFile *file = m->diCompileUnit->getFile();
835  llvm::DICompileUnit *cu = m->diCompileUnit;
836  llvm::DIType *diType = sym->type->GetDIType(file);
837  // FIXME? DWARF says that this (and programIndex below) should
838  // have the DW_AT_artifical attribute. It's not clear if this
839  // matters for anything though.
840  llvm::GlobalVariable *sym_GV_storagePtr = llvm::dyn_cast<llvm::GlobalVariable>(sym->storagePtr);
841  llvm::DIGlobalVariableExpression *var =
842  m->diBuilder->createGlobalVariableExpression(cu, name, name, file, 0 /* line */, diType, true /* static */);
843  sym_GV_storagePtr->addDebugInfo(var);
844  /*#if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
845  Assert(var.Verify());
846  #else // LLVM 3.7+
847  // coming soon
848  #endif*/
849  }
850 }
851 
852 static void lDefineConstantIntFunc(const char *name, int val, llvm::Module *module, SymbolTable *symbolTable,
853  std::vector<llvm::Constant *> &dbg_sym) {
854  llvm::SmallVector<const Type *, 8> args;
856  Symbol *sym = new Symbol(name, SourcePos(), ft, SC_STATIC);
857 
858  llvm::Function *func = module->getFunction(name);
859  dbg_sym.push_back(func);
860  Assert(func != NULL); // it should be declared already...
861  func->addFnAttr(llvm::Attribute::AlwaysInline);
862  llvm::BasicBlock *bblock = llvm::BasicBlock::Create(*g->ctx, "entry", func, 0);
863  llvm::ReturnInst::Create(*g->ctx, LLVMInt32(val), bblock);
864 
865  sym->function = func;
866  symbolTable->AddVariable(sym);
867 }
868 
869 static void lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable,
870  std::vector<llvm::Constant *> &dbg_sym) {
871  Symbol *sym = new Symbol("programIndex", SourcePos(), AtomicType::VaryingInt32->GetAsConstType(), SC_STATIC);
872 
873  int pi[ISPC_MAX_NVEC];
874  for (int i = 0; i < g->target->getVectorWidth(); ++i)
875  pi[i] = i;
876  sym->constValue = new ConstExpr(sym->type, pi, SourcePos());
877 
878  llvm::Type *ltype = LLVMTypes::Int32VectorType;
879  llvm::Constant *linit = LLVMInt32Vector(pi);
880 
881  auto GV =
882  new llvm::GlobalVariable(*module, ltype, true, llvm::GlobalValue::InternalLinkage, linit, sym->name.c_str());
883  dbg_sym.push_back(GV);
884  sym->storagePtr = GV;
885  symbolTable->AddVariable(sym);
886 
887  if (m->diBuilder != NULL) {
888  llvm::DIFile *file = m->diCompileUnit->getFile();
889  llvm::DICompileUnit *cu = m->diCompileUnit;
890  llvm::DIType *diType = sym->type->GetDIType(file);
891  llvm::GlobalVariable *sym_GV_storagePtr = llvm::dyn_cast<llvm::GlobalVariable>(sym->storagePtr);
892  llvm::DIGlobalVariableExpression *var = m->diBuilder->createGlobalVariableExpression(
893  cu, sym->name.c_str(), sym->name.c_str(), file, 0 /* line */, diType, false /* static */);
894  sym_GV_storagePtr->addDebugInfo(var);
895  /*#if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
896  Assert(var.Verify());
897  #else // LLVM 3.7+
898  // coming soon
899  #endif*/
900  }
901 }
902 
903 static void emitLLVMUsed(llvm::Module &module, std::vector<llvm::Constant *> &list) {
904  // Convert list to what ConstantArray needs.
905  llvm::SmallVector<llvm::Constant *, 8> UsedArray;
906  UsedArray.reserve(list.size());
907  for (auto c : list) {
908  UsedArray.push_back(llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(llvm::cast<llvm::Constant>(c),
910  }
911 
912  llvm::ArrayType *ATy = llvm::ArrayType::get(LLVMTypes::Int8PointerType, UsedArray.size());
913 
914  auto *GV = new llvm::GlobalVariable(module, ATy, false, llvm::GlobalValue::AppendingLinkage,
915  llvm::ConstantArray::get(ATy, UsedArray), "llvm.used");
916 
917  GV->setSection("llvm.metadata");
918 }
919 
920 void DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *module, bool includeStdlibISPC) {
921  // debug_symbols are symbols that supposed to be preserved in debug information.
922  // They will be referenced in llvm.used intrinsic to prevent they removal from
923  // the object file.
924  std::vector<llvm::Constant *> debug_symbols;
925  bool warn = g->target->getISA() != Target::GENERIC;
926 
927  // Add the definitions from the compiled builtins.c file.
928  // When compiling for "generic" target family, data layout warnings for
929  // "builtins_bitcode_c" have to be switched off: its DL is incompatible
930  // with the DL of "generic". Anyway, AddBitcodeToModule() corrects this
931  // automatically if DLs differ (by copying module`s DL to export`s DL).
932 
933  // Unlike regular builtins and dispatch module, which don't care about mangling of external functions,
934  // so they only differentiate Windows/Unix and 32/64 bit, builtins-c need to take care about mangling.
935  // Hence, different version for all potentially supported OSes.
937  Assert(builtins);
938  AddBitcodeToModule(builtins, module, symbolTable, warn);
939 
940  // Next, add the target's custom implementations of the various needed
941  // builtin functions (e.g. __masked_store_32(), etc).
942  const BitcodeLib *target =
944  Assert(target);
945  AddBitcodeToModule(target, module, symbolTable, true);
946 
947  // define the 'programCount' builtin variable
948  lDefineConstantInt("programCount", g->target->getVectorWidth(), module, symbolTable, debug_symbols);
949 
950  // define the 'programIndex' builtin
951  lDefineProgramIndex(module, symbolTable, debug_symbols);
952 
953  // Define __math_lib stuff. This is used by stdlib.ispc, for example, to
954  // figure out which math routines to end up calling...
955  lDefineConstantInt("__math_lib", (int)g->mathLib, module, symbolTable, debug_symbols);
956  lDefineConstantInt("__math_lib_ispc", (int)Globals::Math_ISPC, module, symbolTable, debug_symbols);
957  lDefineConstantInt("__math_lib_ispc_fast", (int)Globals::Math_ISPCFast, module, symbolTable, debug_symbols);
958  lDefineConstantInt("__math_lib_svml", (int)Globals::Math_SVML, module, symbolTable, debug_symbols);
959  lDefineConstantInt("__math_lib_system", (int)Globals::Math_System, module, symbolTable, debug_symbols);
960  lDefineConstantIntFunc("__fast_masked_vload", (int)g->opt.fastMaskedVload, module, symbolTable, debug_symbols);
961 
962  lDefineConstantInt("__have_native_half", g->target->hasHalf(), module, symbolTable, debug_symbols);
963  lDefineConstantInt("__have_native_rand", g->target->hasRand(), module, symbolTable, debug_symbols);
964  lDefineConstantInt("__have_native_transcendentals", g->target->hasTranscendentals(), module, symbolTable,
965  debug_symbols);
966  lDefineConstantInt("__have_native_trigonometry", g->target->hasTrigonometry(), module, symbolTable, debug_symbols);
967  lDefineConstantInt("__have_native_rsqrtd", g->target->hasRsqrtd(), module, symbolTable, debug_symbols);
968  lDefineConstantInt("__have_native_rcpd", g->target->hasRcpd(), module, symbolTable, debug_symbols);
969 
970  if (g->forceAlignment != -1) {
971  llvm::GlobalVariable *alignment = module->getGlobalVariable("memory_alignment", true);
972  alignment->setInitializer(LLVMInt32(g->forceAlignment));
973  }
974 
976  emitLLVMUsed(*module, debug_symbols);
977  }
978 
979  if (includeStdlibISPC) {
980  // If the user wants the standard library to be included, parse the
981  // serialized version of the stdlib.ispc file to get its
982  // definitions added.
983  extern const char stdlib_mask1_code[], stdlib_mask8_code[];
984  extern const char stdlib_mask16_code[], stdlib_mask32_code[], stdlib_mask64_code[];
985  if (g->target->getISA() == Target::GENERIC && g->target->getVectorWidth() == 1) { // 1 wide uses 32 stdlib
986  yy_scan_string(stdlib_mask32_code);
987  } else {
988  switch (g->target->getMaskBitCount()) {
989  case 1:
990  yy_scan_string(stdlib_mask1_code);
991  break;
992  case 8:
993  yy_scan_string(stdlib_mask8_code);
994  break;
995  case 16:
996  yy_scan_string(stdlib_mask16_code);
997  break;
998  case 32:
999  yy_scan_string(stdlib_mask32_code);
1000  break;
1001  case 64:
1002  yy_scan_string(stdlib_mask64_code);
1003  break;
1004  default:
1005  FATAL("Unhandled mask bit size for stdlib.ispc");
1006  }
1007  }
1008  yyparse();
1009  }
1010 }
llvm::Value * storagePtr
Definition: sym.h:70
static const AtomicType * VaryingInt32
Definition: type.h:325
static llvm::Type * FloatType
Definition: llvmutil.h:69
static bool lCreateISPCSymbol(llvm::Function *func, SymbolTable *symbolTable)
Definition: builtins.cpp:166
TargetOS target_os
Definition: ispc.h:515
static const AtomicType * VaryingInt16
Definition: type.h:324
llvm::Function * function
Definition: sym.h:74
static llvm::Type * Int32VectorPointerType
Definition: llvmutil.h:93
void DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *module, bool includeStdlibISPC)
Definition: builtins.cpp:920
Opt opt
Definition: ispc.h:509
Declaration of the FunctionEmitContext class
TargetLibRegistry * target_registry
Definition: ispc.h:506
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:822
static const AtomicType * VaryingUInt64
Definition: type.h:331
static llvm::Type * DoubleType
Definition: llvmutil.h:70
static void lCheckModuleIntrinsics(llvm::Module *module)
Definition: builtins.cpp:262
Target * target
Definition: ispc.h:512
bool AddVariable(Symbol *symbol)
Definition: sym.cpp:85
static const AtomicType * VaryingDouble
Definition: type.h:332
Expression representing a compile-time constant value.
Definition: expr.h:374
static llvm::Type * BoolType
Definition: llvmutil.h:62
Symbol table that holds all known symbols during parsing and compilation.
Definition: sym.h:116
static void lDefineConstantIntFunc(const char *name, int val, llvm::Module *module, SymbolTable *symbolTable, std::vector< llvm::Constant *> &dbg_sym)
Definition: builtins.cpp:852
const BitcodeLib * getISPCTargetLib(ISPCTarget target, TargetOS os, Arch arch) const
static llvm::VectorType * Int32VectorType
Definition: llvmutil.h:86
int getMaskBitCount() const
Definition: ispc.h:251
static const AtomicType * UniformUInt32
Definition: type.h:328
static llvm::Type * FloatVectorPointerType
Definition: llvmutil.h:95
Declarations of functions related to builtins and the standard library.
bool hasHalf() const
Definition: ispc.h:253
static llvm::Type * Int8PointerType
Definition: llvmutil.h:72
static llvm::Type * Int32PointerType
Definition: llvmutil.h:74
Module * m
Definition: ispc.cpp:73
std::string name
Definition: sym.h:69
static llvm::Type * Int16VectorPointerType
Definition: llvmutil.h:92
static llvm::Type * Int16Type
Definition: llvmutil.h:66
static llvm::Type * DoubleVectorPointerType
Definition: llvmutil.h:96
static const AtomicType * UniformUInt16
Definition: type.h:327
static void lSetInternalFunctions(llvm::Module *module)
Definition: builtins.cpp:297
static PointerType * GetUniform(const Type *t, bool isSlice=false)
Definition: type.cpp:799
ConstExpr * constValue
Definition: sym.h:85
bool VerifyDataLayoutCompatibility(const std::string &module_dl, const std::string &lib_dl)
Definition: util.cpp:568
header file with declarations for symbol and symbol table classes.
static const AtomicType * UniformBool
Definition: type.h:322
virtual llvm::DIType * GetDIType(llvm::DIScope *scope) const =0
static llvm::Type * VoidType
Definition: llvmutil.h:59
static void lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable, std::vector< llvm::Constant *> &dbg_sym)
Definition: builtins.cpp:869
llvm::Module * module
Definition: module.h:151
static llvm::Type * Int8VectorPointerType
Definition: llvmutil.h:91
static const AtomicType * UniformUInt64
Definition: type.h:331
static llvm::VectorType * Int8VectorType
Definition: llvmutil.h:84
llvm::Constant * LLVMInt32Vector(int32_t ival)
Definition: llvmutil.cpp:313
static llvm::VectorType * FloatVectorType
Definition: llvmutil.h:88
static llvm::Type * Int64Type
Definition: llvmutil.h:68
static llvm::Type * Int8Type
Definition: llvmutil.h:65
static llvm::VectorType * Int64VectorType
Definition: llvmutil.h:87
Header file with declarations for various LLVM utility stuff.
static llvm::Type * Int64PointerType
Definition: llvmutil.h:75
bool hasRcpd() const
Definition: ispc.h:267
static llvm::Type * FloatPointerType
Definition: llvmutil.h:76
static void lAddModuleSymbols(llvm::Module *module, SymbolTable *symbolTable)
Definition: builtins.cpp:243
bool hasRand() const
Definition: ispc.h:255
Representation of a range of positions in a source file.
Definition: ispc.h:123
static llvm::Type * Int16PointerType
Definition: llvmutil.h:73
bool generateDebuggingSymbols
Definition: ispc.h:588
const unsigned char * getLib() const
Definition: bitcode_lib.cpp:87
llvm::ConstantInt * LLVMInt32(int32_t ival)
Definition: llvmutil.cpp:233
static const AtomicType * VaryingBool
Definition: type.h:322
bool hasTranscendentals() const
Definition: ispc.h:261
const BitcodeLib * getBuiltinsCLib(TargetOS os, Arch arch) const
bool fastMaskedVload
Definition: ispc.h:402
const char * name
Definition: ispc.h:126
static const AtomicType * VaryingInt64
Definition: type.h:330
void Error(SourcePos p, const char *fmt,...)
Definition: util.cpp:351
int getVectorWidth() const
Definition: ispc.h:245
#define FATAL(message)
Definition: util.h:116
int yyparse()
static const AtomicType * UniformUInt8
Definition: type.h:326
static llvm::Type * Int64VectorPointerType
Definition: llvmutil.h:94
static llvm::Type * Int32Type
Definition: llvmutil.h:67
MathLib mathLib
Definition: ispc.h:520
static llvm::Type * DoublePointerType
Definition: llvmutil.h:77
#define ISPC_MAX_NVEC
Definition: ispc.h:69
Arch getArch() const
Definition: ispc.h:233
#define Assert(expr)
Definition: util.h:128
static bool Equal(const Type *a, const Type *b)
Definition: type.cpp:2853
static const AtomicType * VaryingUInt16
Definition: type.h:327
bool hasTrigonometry() const
Definition: ispc.h:263
static const AtomicType * VaryingInt8
Definition: type.h:323
static const AtomicType * UniformFloat
Definition: type.h:329
ISA getISA() const
Definition: ispc.h:231
static const AtomicType * UniformInt32
Definition: type.h:325
Type representing a function (return type + argument types)
Definition: type.h:829
Representation of a program symbol.
Definition: sym.h:62
Interface class that defines the type abstraction.
Definition: type.h:90
static const AtomicType * UniformDouble
Definition: type.h:332
Globals * g
Definition: ispc.cpp:72
Expr abstract base class and expression implementations.
static const AtomicType * Void
Definition: type.h:333
void AddBitcodeToModule(const BitcodeLib *lib, llvm::Module *module, SymbolTable *symbolTable, bool warn)
Definition: builtins.cpp:746
static llvm::VectorType * MaskType
Definition: llvmutil.h:79
llvm::DICompileUnit * diCompileUnit
Definition: module.h:156
int forceAlignment
Definition: ispc.h:627
void Debug(SourcePos p, const char *fmt,...)
Definition: util.cpp:366
ISPCTarget getISPCTarget() const
Definition: ispc.h:229
yy_buffer_state * yy_scan_string(const char *)
static llvm::VectorType * DoubleVectorType
Definition: llvmutil.h:89
bool hasRsqrtd() const
Definition: ispc.h:265
static llvm::VectorType * Int16VectorType
Definition: llvmutil.h:85
static const AtomicType * VaryingUInt8
Definition: type.h:326
Declaration of the Module class, which is the ispc-side representation of the results of compiling a ...
static const AtomicType * UniformInt64
Definition: type.h:330
llvm::LLVMContext * ctx
Definition: ispc.h:611
static void emitLLVMUsed(llvm::Module &module, std::vector< llvm::Constant *> &list)
Definition: builtins.cpp:903
static const AtomicType * UniformInt16
Definition: type.h:324
const Type * type
Definition: sym.h:82
llvm::DIBuilder * diBuilder
Definition: module.h:154
std::string GetString() const
Definition: type.cpp:2334
void Warning(SourcePos p, const char *fmt,...)
Definition: util.cpp:378
const size_t getSize() const
Definition: bitcode_lib.cpp:88
static const Type * lLLVMTypeToISPCType(const llvm::Type *t, bool intAsUnsigned)
Definition: builtins.cpp:81
static const AtomicType * VaryingUInt32
Definition: type.h:328
static const AtomicType * VaryingFloat
Definition: type.h:329
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:148
static const AtomicType * UniformInt8
Definition: type.h:323
File with declarations for classes related to type representation.