Intel SPMD Program Compiler  1.9.2
type.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2010-2015, 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 type.cpp
35  @brief Definitions for classes related to type representation
36 */
37 
38 #include "type.h"
39 #include "expr.h"
40 #include "sym.h"
41 #include "llvmutil.h"
42 #include "module.h"
43 
44 #include <stdio.h>
45 #include <map>
46 #if ISPC_LLVM_VERSION == ISPC_LLVM_3_2
47  #include <llvm/Value.h>
48  #include <llvm/Module.h>
49 #else
50  #include <llvm/IR/Value.h>
51  #include <llvm/IR/Module.h>
52 #endif
53 #if ISPC_LLVM_VERSION >= ISPC_LLVM_3_5 // LLVM 3.5+
54  #include <llvm/IR/DebugInfo.h>
55  #include <llvm/IR/DIBuilder.h>
56 #else
57  #include <llvm/DebugInfo.h>
58  #include <llvm/DIBuilder.h>
59 #endif
60 #if ISPC_LLVM_VERSION >= ISPC_LLVM_5_0 // LLVM 5.0+
61  #include <llvm/BinaryFormat/Dwarf.h>
62 #else // LLVM up to 4.x
63  #include <llvm/Support/Dwarf.h>
64 #endif
65 
66 
67 /** Utility routine used in code that prints out declarations; returns true
68  if the given name should be printed, false otherwise. This allows us
69  to omit the names for various internal things (whose names start with
70  double underscores) and emit anonymous declarations for them instead.
71  */
72 
73 static bool
74 lShouldPrintName(const std::string &name) {
75  if (name.size() == 0)
76  return false;
77  else if (name[0] != '_' && name[0] != '$')
78  return true;
79  else
80  return (name.size() == 1) || (name[1] != '_');
81 }
82 
83 
84 /** Utility routine to create a llvm array type of the given number of
85  the given element type. */
86 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
87 static llvm::DIType lCreateDIArray(llvm::DIType eltType, int count) {
88 #else // LLVM 3.7++
89 static llvm::DIType *lCreateDIArray(llvm::DIType *eltType, int count) {
90 #endif
91 
92 #if ISPC_LLVM_VERSION == ISPC_LLVM_3_2
93  int lowerBound = 0, upperBound = count-1;
94 
95  if (count == 0) {
96  // unsized array -> indicate with low > high
97  lowerBound = 1;
98  upperBound = 0;
99  }
100 
101  llvm::Value *sub = m->diBuilder->getOrCreateSubrange(lowerBound, upperBound);
102 #elif ISPC_LLVM_VERSION <= ISPC_LLVM_3_5
103  llvm::Value *sub = m->diBuilder->getOrCreateSubrange(0, count);
104 #endif
105 
106 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_5
107  std::vector<llvm::Value *> subs;
108 #else // LLVM 3.6++
109  llvm::Metadata *sub = m->diBuilder->getOrCreateSubrange(0, count);
110  std::vector<llvm::Metadata *> subs;
111 #endif
112  subs.push_back(sub);
113 
114 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
115  llvm::DIArray subArray = m->diBuilder->getOrCreateArray(subs);
116  uint64_t size = eltType.getSizeInBits() * count;
117  uint64_t align = eltType.getAlignInBits();
118 #else // LLVM 3.7++
119  llvm::DINodeArray subArray = m->diBuilder->getOrCreateArray(subs);
120  uint64_t size = eltType->getSizeInBits() * count;
121  uint64_t align = eltType->getAlignInBits();
122 #endif
123 
124  return m->diBuilder->createArrayType(size, align, eltType, subArray);
125 }
126 
127 
128 ///////////////////////////////////////////////////////////////////////////
129 // Variability
130 
131 std::string
133  switch (type) {
134  case Uniform: return "uniform";
135  case Varying: return "varying";
136  case SOA: {
137  char buf[32];
138  sprintf(buf, "soa<%d>", soaWidth);
139  return buf;
140  }
141  case Unbound: return "/*unbound*/";
142  default:
143  FATAL("Unhandled variability");
144  return "";
145  }
146 }
147 
148 
149 std::string
151  switch (type) {
152  case Uniform:
153  return "un";
154  case Varying:
155  return "vy";
156  case SOA: {
157  char buf[32];
158  sprintf(buf, "soa<%d>", soaWidth);
159  return buf;
160  }
161  case Unbound:
162  FATAL("Unbound unexpected in Variability::MangleString()");
163  default:
164  FATAL("Unhandled variability");
165  return "";
166  }
167 }
168 
169 ///////////////////////////////////////////////////////////////////////////
170 // AtomicType
171 
217  new AtomicType(TYPE_VOID, Variability::Uniform, false);
218 
219 
221  : Type(ATOMIC_TYPE), basicType(bt), variability(v), isConst(ic) {
222  asOtherConstType = NULL;
223  asUniformType = asVaryingType = NULL;
224 }
225 
226 
229  return variability;
230 }
231 
232 
233 bool
235  return (CastType<PointerType>(this) != NULL);
236 }
237 
238 
239 bool
241  return (CastType<ArrayType>(this) != NULL);
242 }
243 
244 bool
246  return (CastType<ReferenceType>(this) != NULL);
247 }
248 
249 bool
251  return EqualIgnoringConst(this, AtomicType::Void);
252 }
253 
254 bool
256  return (basicType == TYPE_FLOAT || basicType == TYPE_DOUBLE);
257 }
258 
259 bool
261  return (basicType == TYPE_INT8 || basicType == TYPE_UINT8 ||
265 }
266 
267 
268 bool
270  return (basicType == TYPE_UINT8 || basicType == TYPE_UINT16 ||
272 }
273 
274 
275 bool
277  return basicType == TYPE_BOOL;
278 }
279 
280 
281 bool
283  return isConst;
284 }
285 
286 
287 const AtomicType *
289  if (IsUnsignedType() == true)
290  return this;
291 
292  if (IsIntType() == false)
293  return NULL;
294 
295  switch (basicType) {
296  case TYPE_INT8:
298  case TYPE_INT16:
300  case TYPE_INT32:
302  case TYPE_INT64:
304  default:
305  FATAL("Unexpected basicType in GetAsUnsignedType()");
306  return NULL;
307  }
308 }
309 
310 
311 const AtomicType *
313  if (isConst == true)
314  return this;
315 
316  if (asOtherConstType == NULL) {
319  }
320  return asOtherConstType;
321 }
322 
323 
324 const AtomicType *
326  if (isConst == false)
327  return this;
328 
329  if (asOtherConstType == NULL) {
332  }
333  return asOtherConstType;
334 }
335 
336 
337 const AtomicType *
339  return this;
340 }
341 
342 
343 const AtomicType *
347  return this;
348 
349  if (asVaryingType == NULL) {
353  }
354  return asVaryingType;
355 }
356 
357 
358 const AtomicType *
362  return this;
363 
364  if (asUniformType == NULL) {
368  }
369  return asUniformType;
370 }
371 
372 
373 const AtomicType *
377  return this;
379 }
380 
381 
382 const AtomicType *
383 AtomicType::GetAsSOAType(int width) const {
386  return this;
388 }
389 
390 
391 const AtomicType *
395  return this;
396  return new AtomicType(basicType, v, isConst);
397 }
398 
399 
400 std::string
402  std::string ret;
403  if (isConst) ret += "const ";
404  if (basicType != TYPE_VOID) {
405  ret += variability.GetString();
406  ret += " ";
407  }
408 
409  switch (basicType) {
410  case TYPE_VOID: ret += "void"; break;
411  case TYPE_BOOL: ret += "bool"; break;
412  case TYPE_INT8: ret += "int8"; break;
413  case TYPE_UINT8: ret += "unsigned int8"; break;
414  case TYPE_INT16: ret += "int16"; break;
415  case TYPE_UINT16: ret += "unsigned int16"; break;
416  case TYPE_INT32: ret += "int32"; break;
417  case TYPE_UINT32: ret += "unsigned int32"; break;
418  case TYPE_FLOAT: ret += "float"; break;
419  case TYPE_INT64: ret += "int64"; break;
420  case TYPE_UINT64: ret += "unsigned int64"; break;
421  case TYPE_DOUBLE: ret += "double"; break;
422  default: FATAL("Logic error in AtomicType::GetString()");
423  }
424  return ret;
425 }
426 
427 
428 std::string
430  std::string ret;
431  if (isConst) ret += "C";
432  ret += variability.MangleString();
433 
434  switch (basicType) {
435  case TYPE_VOID: ret += "v"; break;
436  case TYPE_BOOL: ret += "b"; break;
437  case TYPE_INT8: ret += "t"; break;
438  case TYPE_UINT8: ret += "T"; break;
439  case TYPE_INT16: ret += "s"; break;
440  case TYPE_UINT16: ret += "S"; break;
441  case TYPE_INT32: ret += "i"; break;
442  case TYPE_UINT32: ret += "u"; break;
443  case TYPE_FLOAT: ret += "f"; break;
444  case TYPE_INT64: ret += "I"; break;
445  case TYPE_UINT64: ret += "U"; break;
446  case TYPE_DOUBLE: ret += "d"; break;
447  default: FATAL("Logic error in AtomicType::Mangle()");
448  }
449  return ret;
450 }
451 
452 
453 std::string
454 AtomicType::GetCDeclaration(const std::string &name) const {
455  std::string ret;
457  Assert(m->errorCount > 0);
458  return ret;
459  }
460  if (isConst) ret += "const ";
461 
462  switch (basicType) {
463  case TYPE_VOID: ret += "void"; break;
464  case TYPE_BOOL: ret += "bool"; break;
465  case TYPE_INT8: ret += "int8_t"; break;
466  case TYPE_UINT8: ret += "uint8_t"; break;
467  case TYPE_INT16: ret += "int16_t"; break;
468  case TYPE_UINT16: ret += "uint16_t"; break;
469  case TYPE_INT32: ret += "int32_t"; break;
470  case TYPE_UINT32: ret += "uint32_t"; break;
471  case TYPE_FLOAT: ret += "float"; break;
472  case TYPE_INT64: ret += "int64_t"; break;
473  case TYPE_UINT64: ret += "uint64_t"; break;
474  case TYPE_DOUBLE: ret += "double"; break;
475  default: FATAL("Logic error in AtomicType::GetCDeclaration()");
476  }
477 
478  if (lShouldPrintName(name)) {
479  ret += " ";
480  ret += name;
481  }
482 
483  if (variability == Variability::SOA) {
484  char buf[32];
485  sprintf(buf, "[%d]", variability.soaWidth);
486  ret += buf;
487  }
488 
489  return ret;
490 }
491 
492 
493 llvm::Type *
494 AtomicType::LLVMType(llvm::LLVMContext *ctx) const {
496  bool isUniform = (variability == Variability::Uniform);
497  bool isVarying = (variability == Variability::Varying);
498 
499  if (isUniform || isVarying) {
500  switch (basicType) {
501  case TYPE_VOID:
502  return llvm::Type::getVoidTy(*ctx);
503  case TYPE_BOOL:
504  return isUniform ? LLVMTypes::BoolType : LLVMTypes::BoolVectorType;
505  case TYPE_INT8:
506  case TYPE_UINT8:
507  return isUniform ? LLVMTypes::Int8Type : LLVMTypes::Int8VectorType;
508  case TYPE_INT16:
509  case TYPE_UINT16:
511  case TYPE_INT32:
512  case TYPE_UINT32:
514  case TYPE_FLOAT:
516  case TYPE_INT64:
517  case TYPE_UINT64:
519  case TYPE_DOUBLE:
521  default:
522  FATAL("logic error in AtomicType::LLVMType");
523  return NULL;
524  }
525  }
526  else {
528  return at.LLVMType(ctx);
529  }
530 }
531 
532 
533 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
534 llvm::DIType AtomicType::GetDIType(llvm::DIDescriptor scope) const {
535 #else //LLVM 3.7++
536 llvm::DIType *AtomicType::GetDIType(llvm::DIScope *scope) const {
537 #endif
539 
541  switch (basicType) {
542  case TYPE_VOID:
543 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
544  return llvm::DIType();
545 #else //LLVM 3.7++
546  return NULL;
547 #endif
548 
549 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_9
550  case TYPE_BOOL:
551  return m->diBuilder->createBasicType("bool", 32 /* size */, 32 /* align */,
552  llvm::dwarf::DW_ATE_unsigned);
553  break;
554  case TYPE_INT8:
555  return m->diBuilder->createBasicType("int8", 8 /* size */, 8 /* align */,
556  llvm::dwarf::DW_ATE_signed);
557  break;
558  case TYPE_UINT8:
559  return m->diBuilder->createBasicType("uint8", 8 /* size */, 8 /* align */,
560  llvm::dwarf::DW_ATE_unsigned);
561  break;
562  case TYPE_INT16:
563  return m->diBuilder->createBasicType("int16", 16 /* size */, 16 /* align */,
564  llvm::dwarf::DW_ATE_signed);
565  break;
566  case TYPE_UINT16:
567  return m->diBuilder->createBasicType("uint16", 16 /* size */, 16 /* align */,
568  llvm::dwarf::DW_ATE_unsigned);
569  break;
570  case TYPE_INT32:
571  return m->diBuilder->createBasicType("int32", 32 /* size */, 32 /* align */,
572  llvm::dwarf::DW_ATE_signed);
573  break;
574  case TYPE_UINT32:
575  return m->diBuilder->createBasicType("uint32", 32 /* size */, 32 /* align */,
576  llvm::dwarf::DW_ATE_unsigned);
577  break;
578  case TYPE_FLOAT:
579  return m->diBuilder->createBasicType("float", 32 /* size */, 32 /* align */,
580  llvm::dwarf::DW_ATE_float);
581  break;
582  case TYPE_DOUBLE:
583  return m->diBuilder->createBasicType("double", 64 /* size */, 64 /* align */,
584  llvm::dwarf::DW_ATE_float);
585  break;
586  case TYPE_INT64:
587  return m->diBuilder->createBasicType("int64", 64 /* size */, 64 /* align */,
588  llvm::dwarf::DW_ATE_signed);
589  break;
590  case TYPE_UINT64:
591  return m->diBuilder->createBasicType("uint64", 64 /* size */, 64 /* align */,
592  llvm::dwarf::DW_ATE_unsigned);
593  break;
594 #else // LLVM 4.0+
595  case TYPE_BOOL:
596  return m->diBuilder->createBasicType("bool", 32 /* size */,
597  llvm::dwarf::DW_ATE_unsigned);
598  break;
599  case TYPE_INT8:
600  return m->diBuilder->createBasicType("int8", 8 /* size */,
601  llvm::dwarf::DW_ATE_signed);
602  break;
603  case TYPE_UINT8:
604  return m->diBuilder->createBasicType("uint8", 8 /* size */,
605  llvm::dwarf::DW_ATE_unsigned);
606  break;
607  case TYPE_INT16:
608  return m->diBuilder->createBasicType("int16", 16 /* size */,
609  llvm::dwarf::DW_ATE_signed);
610  break;
611  case TYPE_UINT16:
612  return m->diBuilder->createBasicType("uint16", 16 /* size */,
613  llvm::dwarf::DW_ATE_unsigned);
614  break;
615  case TYPE_INT32:
616  return m->diBuilder->createBasicType("int32", 32 /* size */,
617  llvm::dwarf::DW_ATE_signed);
618  break;
619  case TYPE_UINT32:
620  return m->diBuilder->createBasicType("uint32", 32 /* size */,
621  llvm::dwarf::DW_ATE_unsigned);
622  break;
623  case TYPE_FLOAT:
624  return m->diBuilder->createBasicType("float", 32 /* size */,
625  llvm::dwarf::DW_ATE_float);
626  break;
627  case TYPE_DOUBLE:
628  return m->diBuilder->createBasicType("double", 64 /* size */,
629  llvm::dwarf::DW_ATE_float);
630  break;
631  case TYPE_INT64:
632  return m->diBuilder->createBasicType("int64", 64 /* size */,
633  llvm::dwarf::DW_ATE_signed);
634  break;
635  case TYPE_UINT64:
636  return m->diBuilder->createBasicType("uint64", 64 /* size */,
637  llvm::dwarf::DW_ATE_unsigned);
638  break;
639 #endif
640 
641  default:
642  FATAL("unhandled basic type in AtomicType::GetDIType()");
643 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
644  return llvm::DIType();
645 #else //LLVM 3.7+
646  return NULL;
647 #endif
648  }
649  }
650  else if (variability == Variability::Varying) {
651 #if ISPC_LLVM_VERSION == ISPC_LLVM_3_2
652  llvm::Value *sub = m->diBuilder->getOrCreateSubrange(0, g->target->getVectorWidth()-1);
653 #elif ISPC_LLVM_VERSION > ISPC_VERSION_3_2 && ISPC_LLVM_VERSION <= ISPC_LLVM_3_5
654  llvm::Value *sub = m->diBuilder->getOrCreateSubrange(0, g->target->getVectorWidth());
655 #else // LLVM 3.6+
656  llvm::Metadata *sub = m->diBuilder->getOrCreateSubrange(0, g->target->getVectorWidth());
657 #endif
658 #if ISPC_LLVM_VERSION > ISPC_VERSION_3_2 && ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
659  llvm::DIArray subArray = m->diBuilder->getOrCreateArray(sub);
660  llvm::DIType unifType = GetAsUniformType()->GetDIType(scope);
661  uint64_t size = unifType.getSizeInBits() * g->target->getVectorWidth();
662  uint64_t align = unifType.getAlignInBits() * g->target->getVectorWidth();
663 #else // LLVM 3.7+
664  llvm::DINodeArray subArray = m->diBuilder->getOrCreateArray(sub);
665  llvm::DIType *unifType = GetAsUniformType()->GetDIType(scope);
666  uint64_t size = unifType->getSizeInBits() * g->target->getVectorWidth();
667  uint64_t align = unifType->getAlignInBits()* g->target->getVectorWidth();
668 #endif
669  return m->diBuilder->createVectorType(size, align, unifType, subArray);
670  }
671  else {
674  return at.GetDIType(scope);
675  }
676 }
677 
678 
679 ///////////////////////////////////////////////////////////////////////////
680 // EnumType
681 
683  : Type(ENUM_TYPE), pos(p) {
684  // name = "/* (anonymous) */";
685  isConst = false;
687 }
688 
689 
690 EnumType::EnumType(const char *n, SourcePos p)
691  : Type(ENUM_TYPE), pos(p), name(n) {
692  isConst = false;
694 }
695 
696 
699  return variability;
700 }
701 
702 
703 bool
705  return false;
706 }
707 
708 
709 bool
711  return false;
712 }
713 
714 
715 bool
717  return true;
718 }
719 
720 
721 bool
723  return true;
724 }
725 
726 
727 bool
729  return isConst;
730 }
731 
732 
733 const EnumType *
735  return this;
736 }
737 
738 
739 const EnumType *
741  if (IsUniformType())
742  return this;
743  else {
744  EnumType *enumType = new EnumType(*this);
745  enumType->variability = Variability::Uniform;
746  return enumType;
747  }
748 }
749 
750 
751 const EnumType *
754  return this;
755  else {
756  EnumType *enumType = new EnumType(*this);
757  enumType->variability = v;
758  return enumType;
759  }
760 }
761 
762 
763 const EnumType *
765  if (IsVaryingType())
766  return this;
767  else {
768  EnumType *enumType = new EnumType(*this);
770  return enumType;
771  }
772 }
773 
774 
775 const EnumType *
777  if (HasUnboundVariability())
778  return this;
779  else {
780  EnumType *enumType = new EnumType(*this);
782  return enumType;
783  }
784 }
785 
786 
787 const EnumType *
788 EnumType::GetAsSOAType(int width) const {
789  if (GetSOAWidth() == width)
790  return this;
791  else {
792  EnumType *enumType = new EnumType(*this);
793  enumType->variability = Variability(Variability::SOA, width);
794  return enumType;
795  }
796 }
797 
798 
799 const EnumType *
801  if (isConst)
802  return this;
803  else {
804  EnumType *enumType = new EnumType(*this);
805  enumType->isConst = true;
806  return enumType;
807  }
808 }
809 
810 
811 const EnumType *
813  if (!isConst)
814  return this;
815  else {
816  EnumType *enumType = new EnumType(*this);
817  enumType->isConst = false;
818  return enumType;
819  }
820 }
821 
822 
823 std::string
825  std::string ret;
826  if (isConst) ret += "const ";
827  ret += variability.GetString();
828 
829  ret += " enum ";
830  if (name.size())
831  ret += name;
832  return ret;
833 }
834 
835 
836 std::string
839 
840  std::string ret;
841  if (isConst) ret += "C";
842  ret += variability.MangleString();
843 // ret += std::string("enum[") + name + std::string("]");
844  ret += std::string("enum_5B_") + name + std::string("_5D_");
845  return ret;
846 }
847 
848 
849 std::string
850 EnumType::GetCDeclaration(const std::string &varName) const {
852  Assert(m->errorCount > 0);
853  return "";
854  }
855 
856  std::string ret;
857  if (isConst) ret += "const ";
858  ret += "enum";
859  if (name.size())
860  ret += std::string(" ") + name;
861 
862  if (lShouldPrintName(varName)) {
863  ret += " ";
864  ret += varName;
865  }
866 
867  if (variability == Variability::SOA ||
869  int vWidth = (variability == Variability::Varying) ?
870  g->target->getVectorWidth() :
872  char buf[32];
873  sprintf(buf, "[%d]", vWidth);
874  ret += buf;
875  }
876 
877  return ret;
878 }
879 
880 
881 llvm::Type *
882 EnumType::LLVMType(llvm::LLVMContext *ctx) const {
884 
885  switch (variability.type) {
887  return LLVMTypes::Int32Type;
890  case Variability::SOA: {
891  ArrayType at(AtomicType::UniformInt32, variability.soaWidth);
892  return at.LLVMType(ctx);
893  }
894  default:
895  FATAL("Unexpected variability in EnumType::LLVMType()");
896  return NULL;
897  }
898 }
899 
900 
901 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
902 llvm::DIType EnumType::GetDIType(llvm::DIDescriptor scope) const {
903 #else // LLVM 3.7+
904 llvm::DIType *EnumType::GetDIType(llvm::DIScope *scope) const {
905 #endif
906 
907 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_5
908  std::vector<llvm::Value *> enumeratorDescriptors;
909 #else // LLVM 3.6+
910  std::vector<llvm::Metadata *> enumeratorDescriptors;
911 #endif
912  for (unsigned int i = 0; i < enumerators.size(); ++i) {
913  unsigned int enumeratorValue;
914  Assert(enumerators[i]->constValue != NULL);
915  int count = enumerators[i]->constValue->GetValues(&enumeratorValue);
916  Assert(count == 1);
917 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_5
918  llvm::Value *descriptor =
919 #else // LLVM 3.6+
920  llvm::Metadata *descriptor =
921 #endif
922  m->diBuilder->createEnumerator(enumerators[i]->name, enumeratorValue);
923  enumeratorDescriptors.push_back(descriptor);
924  }
925 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
926  llvm::DIArray elementArray =
927  m->diBuilder->getOrCreateArray(enumeratorDescriptors);
928  llvm::DIFile diFile = pos.GetDIFile();
929  llvm::DIType diType =
930  m->diBuilder->createEnumerationType(diFile, name, diFile, pos.first_line,
931  32 /* size in bits */,
932  32 /* align in bits */,
933  elementArray, llvm::DIType());
934 #else // LLVM 3.7+
935  llvm::DINodeArray elementArray =
936  m->diBuilder->getOrCreateArray(enumeratorDescriptors);
937  llvm::DIFile *diFile = pos.GetDIFile();
938  llvm::DIType *underlyingType = AtomicType::UniformInt32->GetDIType(scope);
939  llvm::DIType *diType =
940  m->diBuilder->createEnumerationType(diFile, name, diFile, pos.first_line,
941  32 /* size in bits */,
942  32 /* align in bits */,
943  elementArray, underlyingType, name);
944 #endif
945  switch (variability.type) {
947  return diType;
948  case Variability::Varying: {
949 #if ISPC_LLVM_VERSION == ISPC_LLVM_3_2
950  llvm::Value *sub = m->diBuilder->getOrCreateSubrange(0, g->target->getVectorWidth()-1);
951 #elif ISPC_LLVM_VERSION <= ISPC_LLVM_3_5
952  llvm::Value *sub = m->diBuilder->getOrCreateSubrange(0, g->target->getVectorWidth());
953 #else // LLVM 3.6++
954  llvm::Metadata *sub = m->diBuilder->getOrCreateSubrange(0, g->target->getVectorWidth());
955 #endif
956 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
957  llvm::DIArray subArray = m->diBuilder->getOrCreateArray(sub);
958  uint64_t size = diType.getSizeInBits() * g->target->getVectorWidth();
959  uint64_t align = diType.getAlignInBits() * g->target->getVectorWidth();
960 #elif ISPC_LLVM_VERSION >= ISPC_LLVM_3_7 // LLVM 3.7+
961  llvm::DINodeArray subArray = m->diBuilder->getOrCreateArray(sub);
962  //llvm::DebugNodeArray subArray = m->diBuilder->getOrCreateArray(sub);
963  uint64_t size = diType->getSizeInBits() * g->target->getVectorWidth();
964  uint64_t align = diType->getAlignInBits()* g->target->getVectorWidth();
965 #endif
966  return m->diBuilder->createVectorType(size, align, diType, subArray);
967  }
968  case Variability::SOA: {
969  return lCreateDIArray(diType, variability.soaWidth);
970  }
971  default:
972  FATAL("Unexpected variability in EnumType::GetDIType()");
973 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
974  return llvm::DIType();
975 #else //LLVM 3.7++
976  return NULL;
977 #endif
978  }
979 }
980 
981 
982 void
983 EnumType::SetEnumerators(const std::vector<Symbol *> &e) {
984  enumerators = e;
985 }
986 
987 
988 int
990  return (int)enumerators.size();
991 }
992 
993 
994 const Symbol *
996  return enumerators[i];
997 }
998 
999 
1000 ///////////////////////////////////////////////////////////////////////////
1001 // PointerType
1002 
1004  new PointerType(AtomicType::Void, Variability(Variability::Uniform), false);
1005 
1006 
1007 PointerType::PointerType(const Type *t, Variability v, bool ic, bool is,
1008  bool fr)
1009  : Type(POINTER_TYPE), variability(v), isConst(ic), isSlice(is), isFrozen(fr) {
1010  baseType = t;
1011 }
1012 
1013 
1014 PointerType *
1015 PointerType::GetUniform(const Type *t, bool is) {
1016  return new PointerType(t, Variability(Variability::Uniform), false, is);
1017 }
1018 
1019 
1020 PointerType *
1022  return new PointerType(t, Variability(Variability::Varying), false);
1023 }
1024 
1025 
1026 bool
1030 }
1031 
1032 
1035  return variability;
1036 }
1037 
1038 
1039 bool
1041  return false;
1042 }
1043 
1044 
1045 bool
1047  return false;
1048 }
1049 
1050 
1051 bool
1053  return false;
1054 }
1055 
1056 
1057 bool
1059  return false;
1060 }
1061 
1062 
1063 bool
1065  return isConst;
1066 }
1067 
1068 
1069 const Type *
1071  return baseType;
1072 }
1073 
1074 
1075 const PointerType *
1078  return this;
1079  else
1082 }
1083 
1084 
1085 const PointerType *
1088  return this;
1089  else
1092 }
1093 
1094 
1095 const PointerType *
1098  return this;
1099  else
1102 }
1103 
1104 
1105 const PointerType *
1106 PointerType::GetAsSOAType(int width) const {
1107  if (GetSOAWidth() == width)
1108  return this;
1109  else
1110  return new PointerType(baseType, Variability(Variability::SOA, width),
1112 }
1113 
1114 
1115 const PointerType *
1117  if (isSlice)
1118  return this;
1119  return new PointerType(baseType, variability, isConst, true);
1120 }
1121 
1122 
1123 const PointerType *
1125  if (isSlice == false)
1126  return this;
1127  return new PointerType(baseType, variability, isConst, false);
1128 }
1129 
1130 
1131 const PointerType *
1133  if (isFrozen)
1134  return this;
1135  return new PointerType(baseType, variability, isConst, true, true);
1136 }
1137 
1138 
1139 const PointerType *
1141  if (baseType == NULL) {
1142  Assert(m->errorCount > 0);
1143  return NULL;
1144  }
1145 
1147  Variability ptrVariability = (variability == Variability::Unbound) ? v :
1148  variability;
1149  const Type *resolvedBaseType =
1151  return new PointerType(resolvedBaseType, ptrVariability, isConst, isSlice,
1152  isFrozen);
1153 }
1154 
1155 
1156 const PointerType *
1158  if (isConst == true)
1159  return this;
1160  else
1161  return new PointerType(baseType, variability, true, isSlice);
1162 }
1163 
1164 
1165 const PointerType *
1167  if (isConst == false)
1168  return this;
1169  else
1170  return new PointerType(baseType, variability, false, isSlice);
1171 }
1172 
1173 
1174 std::string
1176  if (baseType == NULL) {
1177  Assert(m->errorCount > 0);
1178  return "";
1179  }
1180 
1181  std::string ret = baseType->GetString();
1182 
1183  ret += std::string(" * ");
1184  if (isConst) ret += "const ";
1185  if (isSlice) ret += "slice ";
1186  if (isFrozen) ret += "/*frozen*/ ";
1187  ret += variability.GetString();
1188 
1189  return ret;
1190 }
1191 
1192 
1193 std::string
1196  if (baseType == NULL) {
1197  Assert(m->errorCount > 0);
1198  return "";
1199  }
1200 
1201  std::string ret = variability.MangleString() + std::string("_3C_"); // <
1202  if (isSlice || isFrozen) ret += "-";
1203  if (isSlice) ret += "s";
1204  if (isFrozen) ret += "f";
1205  if (isSlice || isFrozen) ret += "-";
1206  return ret + baseType->Mangle() + std::string("_3E_"); // >
1207 }
1208 
1209 
1210 std::string
1211 PointerType::GetCDeclaration(const std::string &name) const {
1212  if (isSlice ||
1214  Assert(m->errorCount > 0);
1215  return "";
1216  }
1217 
1218  if (baseType == NULL) {
1219  Assert(m->errorCount > 0);
1220  return "";
1221  }
1222 
1223  std::string ret = baseType->GetCDeclaration("");
1224 
1225  bool baseIsBasicVarying = (IsBasicType(baseType)) && (baseType->IsVaryingType());
1226 
1227  if (baseIsBasicVarying) ret += std::string("(");
1228  ret += std::string(" *");
1229  if (isConst) ret += " const";
1230  ret += std::string(" ");
1231  ret += name;
1232  if (baseIsBasicVarying) ret += std::string(")");
1233 
1234  if (variability == Variability::SOA) {
1235  char buf[32];
1236  sprintf(buf, "[%d]", variability.soaWidth);
1237  ret += buf;
1238  }
1239  if (baseIsBasicVarying) {
1240  int vWidth = g->target->getVectorWidth();
1241  char buf[32];
1242  sprintf(buf, "[%d]", vWidth);
1243  ret += buf;
1244  }
1245 
1246  return ret;
1247 }
1248 
1249 
1250 llvm::Type *
1251 PointerType::LLVMType(llvm::LLVMContext *ctx) const {
1252  if (baseType == NULL) {
1253  Assert(m->errorCount > 0);
1254  return NULL;
1255  }
1256 
1257  if (isSlice) {
1258  llvm::Type *types[2];
1259  types[0] = GetAsNonSlice()->LLVMType(ctx);
1260 
1261  switch (variability.type) {
1262  case Variability::Uniform:
1263  types[1] = LLVMTypes::Int32Type;
1264  break;
1265  case Variability::Varying:
1266  types[1] = LLVMTypes::Int32VectorType;
1267  break;
1268  case Variability::SOA:
1269  types[1] = llvm::ArrayType::get(LLVMTypes::Int32Type,
1271  break;
1272  default:
1273  FATAL("unexpected variability for slice pointer in "
1274  "PointerType::LLVMType");
1275  }
1276 
1277  llvm::ArrayRef<llvm::Type *> typesArrayRef =
1278  llvm::ArrayRef<llvm::Type *>(types, 2);
1279  return llvm::StructType::get(*g->ctx, typesArrayRef);
1280  }
1281 
1282  switch (variability.type) {
1283  case Variability::Uniform: {
1284  llvm::Type *ptype = NULL;
1285  const FunctionType *ftype = CastType<FunctionType>(baseType);
1286  if (ftype != NULL)
1287  ptype = llvm::PointerType::get(ftype->LLVMFunctionType(ctx), 0);
1288  else {
1289  if (baseType->IsVoidType())
1291  else
1292  ptype = llvm::PointerType::get(baseType->LLVMType(ctx), 0);
1293  }
1294  return ptype;
1295  }
1296  case Variability::Varying:
1297  // always the same, since we currently use int vectors for varying
1298  // pointers
1300  case Variability::SOA: {
1302  return at.LLVMType(ctx);
1303  }
1304  default:
1305  FATAL("Unexpected variability in PointerType::LLVMType()");
1306  return NULL;
1307  }
1308 }
1309 
1310 
1311 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
1312 llvm::DIType PointerType::GetDIType(llvm::DIDescriptor scope) const {
1313  if (baseType == NULL) {
1314  Assert(m->errorCount > 0);
1315  return llvm::DIType();
1316  }
1317  llvm::DIType diTargetType = baseType->GetDIType(scope);
1318 #else //LLVM 3.7++
1319 llvm::DIType *PointerType::GetDIType(llvm::DIScope *scope) const {
1320  if (baseType == NULL) {
1321  Assert(m->errorCount > 0);
1322  return NULL;
1323  }
1324  llvm::DIType *diTargetType = baseType->GetDIType(scope);
1325 #endif
1326  int bitsSize = g->target->is32Bit() ? 32 : 64;
1327  int ptrAlignBits = bitsSize;
1328  switch (variability.type) {
1329  case Variability::Uniform:
1330  return m->diBuilder->createPointerType(diTargetType, bitsSize,
1331  ptrAlignBits);
1332  case Variability::Varying: {
1333  // emit them as an array of pointers
1334 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
1335  llvm::DIType eltType =
1336 #else //LLVM 3.7++
1337  llvm::DIDerivedType *eltType =
1338 #endif
1339  m->diBuilder->createPointerType(diTargetType, bitsSize, ptrAlignBits);
1340  return lCreateDIArray(eltType, g->target->getVectorWidth());
1341  }
1342  case Variability::SOA: {
1344  return at.GetDIType(scope);
1345  }
1346  default:
1347  FATAL("Unexpected variability in PointerType::GetDIType()");
1348 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
1349  return llvm::DIType();
1350 #else //LLVM 3.7++
1351  return NULL;
1352 #endif
1353  }
1354 }
1355 
1356 
1357 ///////////////////////////////////////////////////////////////////////////
1358 // SequentialType
1359 
1360 const Type *SequentialType::GetElementType(int index) const {
1361  return GetElementType();
1362 }
1363 
1364 
1365 ///////////////////////////////////////////////////////////////////////////
1366 // ArrayType
1367 
1368 ArrayType::ArrayType(const Type *c, int a)
1369  : SequentialType(ARRAY_TYPE), child(c), numElements(a) {
1370  // 0 -> unsized array.
1371  Assert(numElements >= 0);
1372  Assert(c->IsVoidType() == false);
1373 }
1374 
1375 
1376 llvm::ArrayType *
1377 ArrayType::LLVMType(llvm::LLVMContext *ctx) const {
1378  if (child == NULL) {
1379  Assert(m->errorCount > 0);
1380  return NULL;
1381  }
1382 
1383  llvm::Type *ct = child->LLVMType(ctx);
1384  if (ct == NULL) {
1385  Assert(m->errorCount > 0);
1386  return NULL;
1387  }
1388  return llvm::ArrayType::get(ct, numElements);
1389 }
1390 
1391 
1395 }
1396 
1397 
1398 bool
1400  return false;
1401 }
1402 
1403 
1404 bool
1406  return false;
1407 }
1408 
1409 
1410 bool
1412  return false;
1413 }
1414 
1415 
1416 bool
1418  return false;
1419 }
1420 
1421 
1422 bool
1424  return child ? child->IsConstType() : false;
1425 }
1426 
1427 
1428 const Type *
1430  const Type *type = child;
1431  const ArrayType *at = CastType<ArrayType>(type);
1432  // Keep walking until we reach a child that isn't itself an array
1433  while (at) {
1434  type = at->child;
1435  at = CastType<ArrayType>(type);
1436  }
1437  return type;
1438 }
1439 
1440 
1441 const ArrayType *
1443  if (child == NULL) {
1444  Assert(m->errorCount > 0);
1445  return NULL;
1446  }
1447  return new ArrayType(child->GetAsVaryingType(), numElements);
1448 }
1449 
1450 
1451 const ArrayType *
1453  if (child == NULL) {
1454  Assert(m->errorCount > 0);
1455  return NULL;
1456  }
1457  return new ArrayType(child->GetAsUniformType(), numElements);
1458 }
1459 
1460 
1461 const ArrayType *
1463  if (child == NULL) {
1464  Assert(m->errorCount > 0);
1465  return NULL;
1466  }
1468 }
1469 
1470 
1471 const ArrayType *
1472 ArrayType::GetAsSOAType(int width) const {
1473  if (child == NULL) {
1474  Assert(m->errorCount > 0);
1475  return NULL;
1476  }
1477  return new ArrayType(child->GetAsSOAType(width), numElements);
1478 }
1479 
1480 
1481 const ArrayType *
1483  if (child == NULL) {
1484  Assert(m->errorCount > 0);
1485  return NULL;
1486  }
1488 }
1489 
1490 
1491 const ArrayType *
1493  if (child == NULL) {
1494  Assert(m->errorCount > 0);
1495  return NULL;
1496  }
1497  return new ArrayType(child->GetAsUnsignedType(), numElements);
1498 }
1499 
1500 
1501 const ArrayType *
1503  if (child == NULL) {
1504  Assert(m->errorCount > 0);
1505  return NULL;
1506  }
1507  return new ArrayType(child->GetAsConstType(), numElements);
1508 }
1509 
1510 
1511 const ArrayType *
1513  if (child == NULL) {
1514  Assert(m->errorCount > 0);
1515  return NULL;
1516  }
1517  return new ArrayType(child->GetAsNonConstType(), numElements);
1518 }
1519 
1520 
1521 int
1523  return numElements;
1524 }
1525 
1526 
1527 const Type *
1529  return child;
1530 }
1531 
1532 
1533 std::string
1535  const Type *base = GetBaseType();
1536  if (base == NULL) {
1537  Assert(m->errorCount > 0);
1538  return "";
1539  }
1540  std::string s = base->GetString();
1541 
1542  const ArrayType *at = this;
1543  // Walk through this and any children arrays and print all of their
1544  // dimensions
1545  while (at) {
1546  char buf[16];
1547  if (at->numElements > 0)
1548  sprintf(buf, "%d", at->numElements);
1549  else
1550  buf[0] = '\0';
1551  s += std::string("[") + std::string(buf) + std::string("]");
1552  at = CastType<ArrayType>(at->child);
1553  }
1554  return s;
1555 }
1556 
1557 
1558 std::string
1560  if (child == NULL) {
1561  Assert(m->errorCount > 0);
1562  return "(error)";
1563  }
1564  std::string s = child->Mangle();
1565  char buf[16];
1566  if (numElements > 0)
1567  sprintf(buf, "%d", numElements);
1568  else
1569  buf[0] = '\0';
1570 // return s + "[" + buf + "]";
1571  return s + "_5B_" + buf + "_5D_";
1572 }
1573 
1574 
1575 std::string
1576 ArrayType::GetCDeclaration(const std::string &name) const {
1577  const Type *base = GetBaseType();
1578  if (base == NULL) {
1579  Assert(m->errorCount > 0);
1580  return "";
1581  }
1582 
1583  int soaWidth = base->GetSOAWidth();
1584  int vWidth = (base->IsVaryingType()) ? g->target->getVectorWidth() : 0;
1585  base = base->GetAsUniformType();
1586 
1587  std::string s = base->GetCDeclaration(name);
1588 
1589  const ArrayType *at = this;
1590  while (at) {
1591  char buf[16];
1592  if (at->numElements > 0)
1593  sprintf(buf, "%d", at->numElements);
1594  else
1595  buf[0] = '\0';
1596  s += std::string("[") + std::string(buf) + std::string("]");
1597  at = CastType<ArrayType>(at->child);
1598  }
1599 
1600  if (soaWidth > 0) {
1601  char buf[16];
1602  sprintf(buf, "[%d]", soaWidth);
1603  s += buf;
1604  }
1605 
1606  if (vWidth > 0) {
1607  char buf[16];
1608  sprintf(buf, "[%d]", vWidth);
1609  s += buf;
1610  }
1611 
1612  return s;
1613 }
1614 
1615 
1616 int
1618  const ArrayType *ct = CastType<ArrayType>(child);
1619  if (ct != NULL)
1620  return numElements * ct->TotalElementCount();
1621  else
1622  return numElements;
1623 }
1624 
1625 
1626 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
1627 llvm::DIType ArrayType::GetDIType(llvm::DIDescriptor scope) const {
1628  if (child == NULL) {
1629  Assert(m->errorCount > 0);
1630  return llvm::DIType();
1631  }
1632  llvm::DIType eltType = child->GetDIType(scope);
1633 #else //LLVM 3.7++
1634 llvm::DIType *ArrayType::GetDIType(llvm::DIScope *scope) const {
1635  if (child == NULL) {
1636  Assert(m->errorCount > 0);
1637  return NULL;
1638  }
1639  llvm::DIType *eltType = child->GetDIType(scope);
1640 #endif
1641  return lCreateDIArray(eltType, numElements);
1642 }
1643 
1644 
1645 ArrayType *
1647  Assert(numElements == 0);
1648  return new ArrayType(child, sz);
1649 }
1650 
1651 
1652 const Type *
1653 ArrayType::SizeUnsizedArrays(const Type *type, Expr *initExpr) {
1654  const ArrayType *at = CastType<ArrayType>(type);
1655  if (at == NULL)
1656  return type;
1657 
1658  ExprList *exprList = llvm::dyn_cast_or_null<ExprList>(initExpr);
1659  if (exprList == NULL || exprList->exprs.size() == 0)
1660  return type;
1661 
1662  // If the current dimension is unsized, then size it according to the
1663  // length of the expression list
1664  if (at->GetElementCount() == 0) {
1665  type = at->GetSizedArray(exprList->exprs.size());
1666  at = CastType<ArrayType>(type);
1667  }
1668 
1669  // Is there another nested level of expression lists? If not, bail out
1670  // now. Otherwise we'll use the first one to size the next dimension
1671  // (after checking below that it has the same length as all of the
1672  // other ones.
1673  ExprList *nextList = llvm::dyn_cast_or_null<ExprList>(exprList->exprs[0]);
1674  if (nextList == NULL)
1675  return type;
1676 
1677  const Type *nextType = at->GetElementType();
1678  const ArrayType *nextArrayType = CastType<ArrayType>(nextType);
1679  if (nextArrayType != NULL && nextArrayType->GetElementCount() == 0) {
1680  // If the recursive call to SizeUnsizedArrays at the bottom of the
1681  // function is going to size an unsized dimension, make sure that
1682  // all of the sub-expression lists are the same length--i.e. issue
1683  // an error if we have something like
1684  // int x[][] = { { 1 }, { 1, 2, 3, 4 } };
1685  unsigned int nextSize = nextList->exprs.size();
1686  for (unsigned int i = 1; i < exprList->exprs.size(); ++i) {
1687  if (exprList->exprs[i] == NULL) {
1688  // We should have seen an error earlier in this case.
1689  Assert(m->errorCount > 0);
1690  continue;
1691  }
1692 
1693  ExprList *el = llvm::dyn_cast_or_null<ExprList>(exprList->exprs[i]);
1694  if (el == NULL || el->exprs.size() != nextSize) {
1695  Error(Union(exprList->exprs[0]->pos, exprList->exprs[i]->pos),
1696  "Inconsistent initializer expression list lengths "
1697  "make it impossible to size unsized array dimensions.");
1698  return NULL;
1699  }
1700  }
1701  }
1702 
1703  // Recursively call SizeUnsizedArrays() to get the child type for the
1704  // array that we were able to size here.
1705  return new ArrayType(SizeUnsizedArrays(at->GetElementType(), nextList),
1706  at->GetElementCount());
1707 }
1708 
1709 
1710 ///////////////////////////////////////////////////////////////////////////
1711 // VectorType
1712 
1714  : SequentialType(VECTOR_TYPE), base(b), numElements(a) {
1715  Assert(numElements > 0);
1716  Assert(base != NULL);
1717 }
1718 
1719 
1722  return base->GetVariability();
1723 }
1724 
1725 
1726 bool
1728  return base->IsFloatType();
1729 }
1730 
1731 
1732 bool
1734  return base->IsIntType();
1735 }
1736 
1737 
1738 bool
1740  return base->IsUnsignedType();
1741 }
1742 
1743 
1744 bool
1746  return base->IsBoolType();
1747 }
1748 
1749 
1750 bool
1752  return base->IsConstType();
1753 }
1754 
1755 
1756 const Type *
1758  return base;
1759 }
1760 
1761 
1762 const VectorType *
1764  return new VectorType(base->GetAsVaryingType(), numElements);
1765 }
1766 
1767 
1768 const VectorType *
1770  return new VectorType(base->GetAsUniformType(), numElements);
1771 }
1772 
1773 
1774 const VectorType *
1777 }
1778 
1779 
1780 const VectorType *
1781 VectorType::GetAsSOAType(int width) const {
1782  return new VectorType(base->GetAsSOAType(width), numElements);
1783 }
1784 
1785 
1786 const VectorType *
1789 }
1790 
1791 
1792 const VectorType *
1794  if (base == NULL) {
1795  Assert(m->errorCount > 0);
1796  return NULL;
1797  }
1798  return new VectorType(base->GetAsUnsignedType(), numElements);
1799 }
1800 
1801 
1802 const VectorType *
1804  return new VectorType(base->GetAsConstType(), numElements);
1805 }
1806 
1807 
1808 const VectorType *
1810  return new VectorType(base->GetAsNonConstType(), numElements);
1811 }
1812 
1813 
1814 std::string
1816  std::string s = base->GetString();
1817  char buf[16];
1818  sprintf(buf, "<%d>", numElements);
1819  return s + std::string(buf);
1820 }
1821 
1822 
1823 std::string
1825  std::string s = base->Mangle();
1826  char buf[16];
1827  sprintf(buf, "_3C_%d_3E_", numElements); // "<%d>"
1828  return s + std::string(buf);
1829 }
1830 
1831 
1832 std::string
1833 VectorType::GetCDeclaration(const std::string &name) const {
1834  std::string s = base->GetCDeclaration("");
1835  char buf[16];
1836  sprintf(buf, "%d", numElements);
1837  return s + std::string(buf) + " " + name;
1838 }
1839 
1840 
1841 int
1843  return numElements;
1844 }
1845 
1846 
1847 const AtomicType *
1849  return base;
1850 }
1851 
1852 
1853 llvm::Type *
1854 VectorType::LLVMType(llvm::LLVMContext *ctx) const {
1855  if (base == NULL) {
1856  Assert(m->errorCount > 0);
1857  return NULL;
1858  }
1859 
1860  llvm::Type *bt = base->LLVMType(ctx);
1861  if (!bt)
1862  return NULL;
1863 
1864  if (base->IsUniformType())
1865  // vectors of uniform types are laid out across LLVM vectors, with
1866  // the llvm vector size set to be a multiple of the machine's
1867  // natural vector size (e.g. 4 on SSE). This is a roundabout way
1868  // of ensuring that LLVM lays them out into machine vector
1869  // registers so that e.g. if we want to add two uniform 4 float
1870  // vectors, that is turned into a single addps on SSE.
1871  return llvm::VectorType::get(bt, getVectorMemoryCount());
1872  else if (base->IsVaryingType())
1873  // varying types are already laid out to fill HW vector registers,
1874  // so a vector type here is just expanded out as an llvm array.
1875  return llvm::ArrayType::get(bt, getVectorMemoryCount());
1876  else if (base->IsSOAType())
1877  return llvm::ArrayType::get(bt, numElements);
1878  else {
1879  FATAL("Unexpected variability in VectorType::LLVMType()");
1880  return NULL;
1881  }
1882 }
1883 
1884 
1885 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
1886 llvm::DIType VectorType::GetDIType(llvm::DIDescriptor scope) const {
1887  llvm::DIType eltType = base->GetDIType(scope);
1888 #else //LLVM 3.7++
1889 llvm::DIType *VectorType::GetDIType(llvm::DIScope *scope) const {
1890  llvm::DIType *eltType = base->GetDIType(scope);
1891 #endif
1892 #if ISPC_LLVM_VERSION == ISPC_LLVM_3_2
1893  llvm::Value *sub = m->diBuilder->getOrCreateSubrange(0, numElements-1);
1894 #elif ISPC_LLVM_VERSION <= ISPC_LLVM_3_5
1895  llvm::Value *sub = m->diBuilder->getOrCreateSubrange(0, numElements);
1896 #else // LLVM 3.6++
1897  llvm::Metadata *sub = m->diBuilder->getOrCreateSubrange(0, numElements);
1898 #endif
1899 
1900  // vectors of varying types are already naturally aligned to the
1901  // machine's vector width, but arrays of uniform types need to be
1902  // explicitly aligned to the machines natural vector alignment.
1903 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
1904  llvm::DIArray subArray = m->diBuilder->getOrCreateArray(sub);
1905  uint64_t sizeBits = eltType.getSizeInBits() * numElements;
1906  uint64_t align = eltType.getAlignInBits();
1907 #else // LLVM 3.7++
1908  llvm::DINodeArray subArray = m->diBuilder->getOrCreateArray(sub);
1909  uint64_t sizeBits = eltType->getSizeInBits() * numElements;
1910  uint64_t align = eltType->getAlignInBits();
1911 #endif
1912 
1913  if (IsUniformType())
1914  align = 4 * g->target->getNativeVectorWidth();
1915 
1916  if (IsUniformType() || IsVaryingType())
1917  return m->diBuilder->createVectorType(sizeBits, align, eltType, subArray);
1918  else if (IsSOAType()) {
1919  ArrayType at(base, numElements);
1920  return at.GetDIType(scope);
1921  }
1922  else {
1923  FATAL("Unexpected variability in VectorType::GetDIType()");
1924 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
1925  return llvm::DIType();
1926 #else // LLVM 3.7++
1927  return NULL;
1928 #endif
1929  }
1930 }
1931 
1932 
1933 int
1935  if (base->IsVaryingType())
1936  return numElements;
1937  else if (base->IsUniformType()) {
1938  int nativeWidth = g->target->getNativeVectorWidth();
1942  // target.getNativeVectorWidth() should be in terms of 32-bit
1943  // values, so for the 64-bit guys, it takes half as many of
1944  // them to fill the native width
1945  nativeWidth /= 2;
1946  // and now round up the element count to be a multiple of
1947  // nativeWidth
1948  return (numElements + (nativeWidth - 1)) & ~(nativeWidth-1);
1949  }
1950  else if (base->IsSOAType()) {
1951  FATAL("VectorType SOA getVectorMemoryCount");
1952  return -1;
1953  }
1954  else {
1955  FATAL("Unexpected variability in VectorType::getVectorMemoryCount()");
1956  return -1;
1957  }
1958 }
1959 
1960 
1961 ///////////////////////////////////////////////////////////////////////////
1962 // StructType
1963 
1964 // We maintain a map from struct names to LLVM struct types so that we can
1965 // uniquely get the llvm::StructType * for a given ispc struct type. Note
1966 // that we need to mangle the name a bit so that we can e.g. differentiate
1967 // between the uniform and varying variants of a given struct type. This
1968 // is handled by lMangleStructName() below.
1969 static std::map<std::string, llvm::StructType *> lStructTypeMap;
1970 
1971 /** Using a struct's name, its variability, and the vector width for the
1972  current compilation target, this function generates a string that
1973  encodes that full structure type, for use in the lStructTypeMap. Note
1974  that the vector width is needed in order to differentiate between
1975  'varying' structs with different compilation targets, which have
1976  different memory layouts...
1977  */
1978 static std::string
1979 lMangleStructName(const std::string &name, Variability variability) {
1980  char buf[32];
1981  std::string n;
1982 
1983  // Encode vector width
1984  sprintf(buf, "v%d", g->target->getVectorWidth());
1985  n += buf;
1986 
1987  // Variability
1988  switch (variability.type) {
1989  case Variability::Uniform:
1990  n += "_uniform_";
1991  break;
1992  case Variability::Varying:
1993  n += "_varying_";
1994  break;
1995  case Variability::SOA:
1996  sprintf(buf, "_soa%d_", variability.soaWidth);
1997  n += buf;
1998  break;
1999  default:
2000  FATAL("Unexpected variability in lMangleStructName()");
2001  }
2002 
2003  // And stuff the name at the end....
2004  n += name;
2005  return n;
2006 }
2007 
2008 
2009 StructType::StructType(const std::string &n, const llvm::SmallVector<const Type *, 8> &elts,
2010  const llvm::SmallVector<std::string, 8> &en,
2011  const llvm::SmallVector<SourcePos, 8> &ep,
2012  bool ic, Variability v, SourcePos p)
2013  : CollectionType(STRUCT_TYPE), name(n), elementTypes(elts), elementNames(en),
2014  elementPositions(ep), variability(v), isConst(ic), pos(p) {
2015  oppositeConstStructType = NULL;
2016  finalElementTypes.resize(elts.size(), NULL);
2017 
2019  // For structs with non-unbound variability, we'll create the
2020  // correspoing LLVM struct type now, if one hasn't been made
2021  // already.
2022 
2023  // Create a unique anonymous struct name if we have an anonymous
2024  // struct (name == ""), or if we are creating a derived type from
2025  // an anonymous struct (e.g. the varying variant--name == '$').
2026  if (name == "" || name[0] == '$') {
2027  char buf[16];
2028  static int count = 0;
2029  sprintf(buf, "$anon%d", count);
2030  name = buf;
2031  ++count;
2032  }
2033 
2034  // If a non-opaque LLVM struct for this type has already been
2035  // created, we're done. For an opaque struct type, we'll override
2036  // the old definition now that we have a full definition.
2037  std::string mname = lMangleStructName(name, variability);
2038  if (lStructTypeMap.find(mname) != lStructTypeMap.end() &&
2039  lStructTypeMap[mname]->isOpaque() == false)
2040  return;
2041 
2042  // Actually make the LLVM struct
2043  std::vector<llvm::Type *> elementTypes;
2044  int nElements = GetElementCount();
2045  if (nElements == 0) {
2046  elementTypes.push_back(LLVMTypes::Int8Type);
2047  }
2048  else {
2049  for (int i = 0; i < nElements; ++i) {
2050  const Type *type = GetElementType(i);
2051  if (type == NULL) {
2052  Assert(m->errorCount > 0);
2053  return;
2054  }
2055  else if (CastType<FunctionType>(type) != NULL) {
2056  Error(elementPositions[i], "Method declarations are not "
2057  "supported.");
2058  return;
2059  }
2060  else
2061  elementTypes.push_back(type->LLVMType(g->ctx));
2062  }
2063  }
2064 
2065  if (lStructTypeMap.find(mname) == lStructTypeMap.end()) {
2066  // New struct definition
2067  llvm::StructType *st =
2068  llvm::StructType::create(*g->ctx, elementTypes, mname);
2069  lStructTypeMap[mname] = st;
2070  }
2071  else {
2072  // Definition for what was before just a declaration
2073  lStructTypeMap[mname]->setBody(elementTypes);
2074  }
2075  }
2076 }
2077 
2078 const std::string
2080  // only return mangled name for varying structs for backwards
2081  // compatibility...
2082 
2085  }
2086  else {
2087  return GetStructName();
2088  }
2089 }
2090 
2093  return variability;
2094 }
2095 
2096 
2097 bool
2099  return false;
2100 }
2101 
2102 
2103 bool
2105  return false;
2106 }
2107 
2108 
2109 bool
2111  return false;
2112 }
2113 
2114 
2115 bool
2117  return false;
2118 }
2119 
2120 
2121 bool
2123  return isConst;
2124 }
2125 
2126 
2127 bool
2129  for (int i = 0; i < GetElementCount(); i++) {
2130  const Type *t = GetElementType(i);
2131  const UndefinedStructType *ust = CastType<UndefinedStructType>(t);
2132  if (ust != NULL) {
2133  return false;
2134  }
2135  const StructType *st = CastType<StructType>(t);
2136  if (st != NULL) {
2137  if (!st->IsDefined()) {
2138  return false;
2139  }
2140  }
2141  }
2142  return true;
2143 }
2144 
2145 
2146 const Type *
2148  return this;
2149 }
2150 
2151 
2152 const StructType *
2154  if (IsVaryingType())
2155  return this;
2156  else
2159 }
2160 
2161 
2162 const StructType *
2164  if (IsUniformType())
2165  return this;
2166  else
2169 }
2170 
2171 
2172 const StructType *
2174  if (HasUnboundVariability())
2175  return this;
2176  else
2179 }
2180 
2181 
2182 const StructType *
2183 StructType::GetAsSOAType(int width) const {
2184  if (GetSOAWidth() == width)
2185  return this;
2186 
2187  if (checkIfCanBeSOA(this) == false)
2188  return NULL;
2189 
2192 }
2193 
2194 
2195 const StructType *
2198 
2200  return this;
2201 
2202  // We don't resolve the members here but leave them unbound, so that if
2203  // resolve to varying but later want to get the uniform version of this
2204  // type, for example, then we still have the information around about
2205  // which element types were originally unbound...
2207  isConst, v, pos);
2208 }
2209 
2210 
2211 const StructType *
2213  if (isConst == true)
2214  return this;
2215  else if (oppositeConstStructType != NULL)
2216  return oppositeConstStructType;
2217  else {
2220  true, variability, pos);
2222  return oppositeConstStructType;
2223  }
2224 }
2225 
2226 
2227 const StructType *
2229  if (isConst == false)
2230  return this;
2231  else if (oppositeConstStructType != NULL)
2232  return oppositeConstStructType;
2233  else {
2236  false, variability, pos);
2238  return oppositeConstStructType;
2239  }
2240 }
2241 
2242 
2243 std::string
2245  std::string ret;
2246  if (isConst)
2247  ret += "const ";
2248  ret += variability.GetString();
2249  ret += " ";
2250 
2251  if (name[0] == '$') {
2252  // Print the whole anonymous struct declaration
2253  ret += std::string("struct { ") + name;
2254  for (unsigned int i = 0; i < elementTypes.size(); ++i) {
2255  ret += elementTypes[i]->GetString();
2256  ret += " ";
2257  ret += elementNames[i];
2258  ret += "; ";
2259  }
2260  ret += "}";
2261  }
2262  else {
2263  ret += "struct ";
2264  ret += name;
2265  }
2266 
2267  return ret;
2268 }
2269 
2270 
2271 /** Mangle a struct name for use in function name mangling. */
2272 static std::string
2273 lMangleStruct(Variability variability, bool isConst, const std::string &name) {
2274  Assert(variability != Variability::Unbound);
2275 
2276  std::string ret;
2277 // ret += "s[";
2278  ret += "s_5B_";
2279  if (isConst)
2280  ret += "_c_";
2281  ret += variability.MangleString();
2282 
2283 // ret += name + std::string("]");
2284  ret += name + std::string("_5D_");
2285  return ret;
2286 }
2287 
2288 
2289 std::string
2292 }
2293 
2294 
2295 std::string
2296 StructType::GetCDeclaration(const std::string &n) const {
2297  std::string ret;
2298  if (isConst) ret += "const ";
2299  ret += std::string("struct ") + GetCStructName();
2300  if (lShouldPrintName(n)) {
2301  ret += std::string(" ") + n;
2302 
2303  if (variability.soaWidth > 0) {
2304  char buf[32];
2305  // This has to match the naming scheme used in lEmitStructDecls()
2306  // in module.cpp
2307  sprintf(buf, "_SOA%d", variability.soaWidth);
2308  ret += buf;
2309  }
2310  }
2311 
2312  return ret;
2313 }
2314 
2315 
2316 llvm::Type *
2317 StructType::LLVMType(llvm::LLVMContext *ctx) const {
2319  std::string mname = lMangleStructName(name, variability);
2320  if (lStructTypeMap.find(mname) == lStructTypeMap.end()) {
2321  Assert(m->errorCount > 0);
2322  return NULL;
2323  }
2324  return lStructTypeMap[mname];
2325 }
2326 
2327 
2328 // Versioning of this function becomes really messy, so versioning the whole function.
2329 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_9
2330 
2331 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
2332 llvm::DIType StructType::GetDIType(llvm::DIDescriptor scope) const {
2333 #else //LLVM 3.7++
2334 llvm::DIType *StructType::GetDIType(llvm::DIScope *scope) const {
2335 #endif
2336  uint64_t currentSize = 0, align = 0;
2337 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_5
2338  std::vector<llvm::Value *> elementLLVMTypes;
2339 #else // LLVM 3.6++
2340  std::vector<llvm::Metadata *> elementLLVMTypes;
2341 #endif
2342  // Walk through the elements of the struct; for each one figure out its
2343  // alignment and size, using that to figure out its offset w.r.t. the
2344  // start of the structure.
2345  for (unsigned int i = 0; i < elementTypes.size(); ++i) {
2346 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
2347  llvm::DIType eltType = GetElementType(i)->GetDIType(scope);
2348  uint64_t eltAlign = eltType.getAlignInBits();
2349  uint64_t eltSize = eltType.getSizeInBits();
2350 #else // LLVM 3.7+
2351  llvm::DIType *eltType = GetElementType(i)->GetDIType(scope);
2352  uint64_t eltAlign = eltType->getAlignInBits();
2353  uint64_t eltSize = eltType->getSizeInBits();
2354 #endif
2355  Assert(eltAlign != 0);
2356 
2357  // The alignment for the entire structure is the maximum of the
2358  // required alignments of its elements
2359  align = std::max(align, eltAlign);
2360 
2361  // Move the current size forward if needed so that the current
2362  // element starts at an offset that's the correct alignment.
2363  if (currentSize > 0 && (currentSize % eltAlign))
2364  currentSize += eltAlign - (currentSize % eltAlign);
2365  Assert((currentSize == 0) || (currentSize % eltAlign) == 0);
2366 
2367  int line = elementPositions[i].first_line;
2368 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
2369  llvm::DIFile diFile = elementPositions[i].GetDIFile();
2370  llvm::DIType fieldType =
2371 #else // LLVM 3.7++
2372  llvm::DIFile *diFile = elementPositions[i].GetDIFile();
2373  llvm::DIDerivedType *fieldType =
2374 #endif
2375  m->diBuilder->createMemberType(scope, elementNames[i], diFile,
2376  line, eltSize, eltAlign,
2377  currentSize, 0, eltType);
2378  elementLLVMTypes.push_back(fieldType);
2379 
2380  currentSize += eltSize;
2381  }
2382 
2383  // Round up the struct's entire size so that it's a multiple of the
2384  // required alignment that we figured out along the way...
2385  if (currentSize > 0 && (currentSize % align))
2386  currentSize += align - (currentSize % align);
2387 
2388 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
2389  llvm::DIArray elements = m->diBuilder->getOrCreateArray(elementLLVMTypes);
2390  llvm::DIFile diFile = pos.GetDIFile();
2391 #else // LLVM 3.7++
2392  llvm::DINodeArray elements = m->diBuilder->getOrCreateArray(elementLLVMTypes);
2393  llvm::DIFile *diFile = pos.GetDIFile();
2394 #endif
2395  return m->diBuilder->createStructType(
2396  diFile,
2397  name,
2398  diFile,
2399  pos.first_line, // Line number
2400  currentSize, // Size in bits
2401  align, // Alignment in bits
2402  0, // Flags
2403 #if ISPC_LLVM_VERSION >= ISPC_LLVM_3_3 && ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
2404  llvm::DIType(), // DerivedFrom
2405 #elif ISPC_LLVM_VERSION >= ISPC_LLVM_3_7 // LLVM 3.7++
2406  NULL,
2407 #endif
2408  elements);
2409 }
2410 
2411 #else // LLVM 4.0+
2412 
2413 llvm::DIType *StructType::GetDIType(llvm::DIScope *scope) const {
2414  llvm::Type *llvm_type = LLVMType(g->ctx);
2415  auto& dataLayout = m->module->getDataLayout();
2416  auto layout = dataLayout.getStructLayout(llvm::dyn_cast_or_null<llvm::StructType>(llvm_type));
2417  std::vector<llvm::Metadata *> elementLLVMTypes;
2418  // Walk through the elements of the struct; for each one figure out its
2419  // alignment and size, using that to figure out its offset w.r.t. the
2420  // start of the structure.
2421  for (unsigned int i = 0; i < elementTypes.size(); ++i) {
2422  llvm::DIType *eltType = GetElementType(i)->GetDIType(scope);
2423  uint64_t eltSize = eltType->getSizeInBits();
2424 
2425  auto llvmType = GetElementType(i)->LLVMType(g->ctx);
2426  uint64_t eltAlign = dataLayout.getABITypeAlignment(llvmType) * 8;
2427  Assert(eltAlign != 0);
2428 
2429  auto eltOffset = layout->getElementOffsetInBits(i);
2430 
2431  int line = elementPositions[i].first_line;
2432  llvm::DIFile *diFile = elementPositions[i].GetDIFile();
2433  llvm::DIDerivedType *fieldType =
2434  m->diBuilder->createMemberType(scope, elementNames[i], diFile,
2435  line, eltSize, eltAlign,
2436  eltOffset, llvm::DINode::FlagZero, eltType);
2437  elementLLVMTypes.push_back(fieldType);
2438  }
2439 
2440  llvm::DINodeArray elements = m->diBuilder->getOrCreateArray(elementLLVMTypes);
2441  llvm::DIFile *diFile = pos.GetDIFile();
2442  return m->diBuilder->createStructType(
2443  diFile,
2444  name,
2445  diFile,
2446  pos.first_line, // Line number
2447  layout->getSizeInBits(), // Size in bits
2448  layout->getAlignment() * 8, // Alignment in bits
2449  llvm::DINode::FlagZero, // Flags
2450  NULL,
2451  elements);
2452 }
2453 
2454 #endif
2455 
2456 
2457 
2458 
2459 const Type *
2462  Assert(i < (int)elementTypes.size());
2463 
2464  if (finalElementTypes[i] == NULL) {
2465  const Type *type = elementTypes[i];
2466  if (type == NULL) {
2467  Assert(m->errorCount > 0);
2468  return NULL;
2469  }
2470 
2471  // If the element has unbound variability, resolve its variability to
2472  // the struct type's variability
2473  type = type ->ResolveUnboundVariability(variability);
2474  if (isConst)
2475  type = type->GetAsConstType();
2476  finalElementTypes[i] = type;
2477  }
2478 
2479  return finalElementTypes[i];
2480 }
2481 
2482 
2483 const Type *
2484 StructType::GetElementType(const std::string &n) const {
2485  for (unsigned int i = 0; i < elementNames.size(); ++i)
2486  if (elementNames[i] == n)
2487  return GetElementType(i);
2488  return NULL;
2489 }
2490 
2491 
2492 int
2493 StructType::GetElementNumber(const std::string &n) const {
2494  for (unsigned int i = 0; i < elementNames.size(); ++i)
2495  if (elementNames[i] == n)
2496  return i;
2497  return -1;
2498 }
2499 
2500 
2501 bool
2503  bool ok = true;
2504  for (int i = 0; i < (int)st->elementTypes.size(); ++i) {
2505  const Type *eltType = st->elementTypes[i];
2506  const StructType *childStructType = CastType<StructType>(eltType);
2507 
2508  if (childStructType != NULL)
2509  ok &= checkIfCanBeSOA(childStructType);
2510  else if (eltType->HasUnboundVariability() == false) {
2511  Error(st->elementPositions[i], "Unable to apply SOA conversion to "
2512  "struct due to \"%s\" member \"%s\" with bound \"%s\" "
2513  "variability.", eltType->GetString().c_str(),
2514  st->elementNames[i].c_str(),
2515  eltType->IsUniformType() ? "uniform" : "varying");
2516  ok = false;
2517  }
2518  else if (CastType<ReferenceType>(eltType)) {
2519  Error(st->elementPositions[i], "Unable to apply SOA conversion to "
2520  "struct due to member \"%s\" with reference type \"%s\".",
2521  st->elementNames[i].c_str(), eltType->GetString().c_str());
2522  ok = false;
2523  }
2524  }
2525  return ok;
2526 }
2527 
2528 
2529 ///////////////////////////////////////////////////////////////////////////
2530 // UndefinedStructType
2531 
2533  const Variability var, bool ic,
2534  SourcePos p)
2535  : Type(UNDEFINED_STRUCT_TYPE), name(n), variability(var), isConst(ic), pos(p) {
2536  Assert(name != "");
2538  // Create a new opaque LLVM struct type for this struct name
2539  std::string mname = lMangleStructName(name, variability);
2540  if (lStructTypeMap.find(mname) == lStructTypeMap.end())
2541  lStructTypeMap[mname] = llvm::StructType::create(*g->ctx, mname);
2542  }
2543 }
2544 
2545 
2548  return variability;
2549 }
2550 
2551 
2552 bool
2554  return false;
2555 }
2556 
2557 
2558 bool
2560  return false;
2561 }
2562 
2563 
2564 bool
2566  return false;
2567 }
2568 
2569 
2570 bool
2572  return false;
2573 }
2574 
2575 
2576 bool
2578  return isConst;
2579 }
2580 
2581 
2582 const Type *
2584  return this;
2585 }
2586 
2587 
2588 const UndefinedStructType *
2591  return this;
2593 }
2594 
2595 
2596 const UndefinedStructType *
2599  return this;
2601 }
2602 
2603 
2604 const UndefinedStructType *
2607  return this;
2609 }
2610 
2611 
2612 const UndefinedStructType *
2614  FATAL("UndefinedStructType::GetAsSOAType() shouldn't be called.");
2615  return NULL;
2616 }
2617 
2618 
2619 const UndefinedStructType *
2622  return this;
2623  return new UndefinedStructType(name, v, isConst, pos);
2624 }
2625 
2626 
2627 const UndefinedStructType *
2629  if (isConst)
2630  return this;
2631  return new UndefinedStructType(name, variability, true, pos);
2632 }
2633 
2634 
2635 const UndefinedStructType *
2637  if (isConst == false)
2638  return this;
2639  return new UndefinedStructType(name, variability, false, pos);
2640 }
2641 
2642 
2643 std::string
2645  std::string ret;
2646  if (isConst) ret += "const ";
2647  ret += variability.GetString();
2648  ret += " struct ";
2649  ret += name;
2650  return ret;
2651 }
2652 
2653 
2654 std::string
2657 }
2658 
2659 
2660 std::string
2661 UndefinedStructType::GetCDeclaration(const std::string &n) const {
2662  std::string ret;
2663  if (isConst) ret += "const ";
2664  ret += std::string("struct ") + name;
2665  if (lShouldPrintName(n))
2666  ret += std::string(" ") + n;
2667  return ret;
2668 }
2669 
2670 
2671 llvm::Type *
2672 UndefinedStructType::LLVMType(llvm::LLVMContext *ctx) const {
2674  std::string mname = lMangleStructName(name, variability);
2675  if (lStructTypeMap.find(mname) == lStructTypeMap.end()) {
2676  Assert(m->errorCount > 0);
2677  return NULL;
2678  }
2679  return lStructTypeMap[mname];
2680 }
2681 
2682 
2683 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
2684 llvm::DIType UndefinedStructType::GetDIType(llvm::DIDescriptor scope) const {
2685  llvm::DIFile diFile = pos.GetDIFile();
2686  llvm::DIArray elements;
2687 #else //LLVM 3.7++
2688 llvm::DIType *UndefinedStructType::GetDIType(llvm::DIScope *scope) const {
2689  llvm::DIFile *diFile = pos.GetDIFile();
2690  llvm::DINodeArray elements;
2691 #endif
2692  return m->diBuilder->createStructType(
2693  diFile,
2694  name,
2695  diFile,
2696  pos.first_line, // Line number
2697  0, // Size
2698  0, // Align
2699 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_9
2700  0, // Flags
2701 #else // LLVM 4.0+
2702  llvm::DINode::FlagZero, // Flags
2703 #endif
2704 #if ISPC_LLVM_VERSION >= ISPC_LLVM_3_3 && ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
2705  llvm::DIType(), // DerivedFrom
2706 #elif ISPC_LLVM_VERSION >= ISPC_LLVM_3_7 // LLVM 3.7+
2707  NULL,
2708 #endif
2709  elements);
2710 }
2711 
2712 
2713 ///////////////////////////////////////////////////////////////////////////
2714 // ReferenceType
2715 
2717  : Type(REFERENCE_TYPE), targetType(t) {
2718  asOtherConstType = NULL;
2719 }
2720 
2721 
2724  if (targetType == NULL) {
2725  Assert(m->errorCount > 0);
2727  }
2728  return targetType->GetVariability();
2729 }
2730 
2731 
2732 bool
2734  if (targetType == NULL) {
2735  Assert(m->errorCount > 0);
2736  return false;
2737  }
2738  return targetType->IsBoolType();
2739 }
2740 
2741 
2742 bool
2744  if (targetType == NULL) {
2745  Assert(m->errorCount > 0);
2746  return false;
2747  }
2748  return targetType->IsFloatType();
2749 }
2750 
2751 
2752 bool
2754  if (targetType == NULL) {
2755  Assert(m->errorCount > 0);
2756  return false;
2757  }
2758  return targetType->IsIntType();
2759 }
2760 
2761 
2762 bool
2764  if (targetType == NULL) {
2765  Assert(m->errorCount > 0);
2766  return false;
2767  }
2768  return targetType->IsUnsignedType();
2769 }
2770 
2771 
2772 bool
2774  if (targetType == NULL) {
2775  Assert(m->errorCount > 0);
2776  return false;
2777  }
2778  return targetType->IsConstType();
2779 }
2780 
2781 
2782 const Type *
2784  return targetType;
2785 }
2786 
2787 
2788 const Type *
2790  if (targetType == NULL) {
2791  Assert(m->errorCount > 0);
2792  return NULL;
2793  }
2794  return targetType->GetBaseType();
2795 }
2796 
2797 
2798 const ReferenceType *
2800  if (targetType == NULL) {
2801  Assert(m->errorCount > 0);
2802  return NULL;
2803  }
2804  if (IsVaryingType())
2805  return this;
2806  return new ReferenceType(targetType->GetAsVaryingType());
2807 }
2808 
2809 
2810 const ReferenceType *
2812  if (targetType == NULL) {
2813  Assert(m->errorCount > 0);
2814  return NULL;
2815  }
2816  if (IsUniformType())
2817  return this;
2818  return new ReferenceType(targetType->GetAsUniformType());
2819 }
2820 
2821 
2822 const ReferenceType *
2824  if (targetType == NULL) {
2825  Assert(m->errorCount > 0);
2826  return NULL;
2827  }
2828  if (HasUnboundVariability())
2829  return this;
2831 }
2832 
2833 
2834 const Type *
2836  // FIXME: is this right?
2837  return new ArrayType(this, width);
2838 }
2839 
2840 
2841 const ReferenceType *
2843  if (targetType == NULL) {
2844  Assert(m->errorCount > 0);
2845  return NULL;
2846  }
2848 }
2849 
2850 
2851 const ReferenceType *
2853  if (targetType == NULL) {
2854  Assert(m->errorCount > 0);
2855  return NULL;
2856  }
2857  if (IsConstType())
2858  return this;
2859 
2860  if (asOtherConstType == NULL) {
2863  }
2864  return asOtherConstType;
2865 }
2866 
2867 
2868 const ReferenceType *
2870  if (targetType == NULL) {
2871  Assert(m->errorCount > 0);
2872  return NULL;
2873  }
2874  if (!IsConstType())
2875  return this;
2876 
2877  if (asOtherConstType == NULL) {
2880  }
2881  return asOtherConstType;
2882 }
2883 
2884 
2885 std::string
2887  if (targetType == NULL) {
2888  Assert(m->errorCount > 0);
2889  return "";
2890  }
2891 
2892  std::string ret = targetType->GetString();
2893 
2894  ret += std::string(" &");
2895  return ret;
2896 }
2897 
2898 
2899 std::string
2901  if (targetType == NULL) {
2902  Assert(m->errorCount > 0);
2903  return "";
2904  }
2905  std::string ret;
2906  ret += std::string("REF") + targetType->Mangle();
2907  return ret;
2908 }
2909 
2910 
2911 std::string
2912 ReferenceType::GetCDeclaration(const std::string &name) const {
2913  if (targetType == NULL) {
2914  Assert(m->errorCount > 0);
2915  return "";
2916  }
2917 
2918  const ArrayType *at = CastType<ArrayType>(targetType);
2919  if (at != NULL) {
2920  if (at->GetElementCount() == 0) {
2921  // emit unsized arrays as pointers to the base type..
2922  std::string ret;
2923  ret += at->GetElementType()->GetAsNonConstType()->GetCDeclaration("") +
2924  std::string(" *");
2925  if (lShouldPrintName(name))
2926  ret += name;
2927  return ret;
2928  }
2929  else
2930  // otherwise forget about the reference part if it's an
2931  // array since C already passes arrays by reference...
2932  return targetType->GetCDeclaration(name);
2933  }
2934  else {
2935  std::string ret;
2936  ret += targetType->GetCDeclaration("") + std::string(" &");
2937  if (lShouldPrintName(name))
2938  ret += name;
2939  return ret;
2940  }
2941 }
2942 
2943 
2944 llvm::Type *
2945 ReferenceType::LLVMType(llvm::LLVMContext *ctx) const {
2946  if (targetType == NULL) {
2947  Assert(m->errorCount > 0);
2948  return NULL;
2949  }
2950 
2951  llvm::Type *t = targetType->LLVMType(ctx);
2952  if (t == NULL) {
2953  Assert(m->errorCount > 0);
2954  return NULL;
2955  }
2956 
2957  return llvm::PointerType::get(t, 0);
2958 }
2959 
2960 
2961 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
2962 llvm::DIType ReferenceType::GetDIType(llvm::DIDescriptor scope) const {
2963  if (targetType == NULL) {
2964  Assert(m->errorCount > 0);
2965  return llvm::DIType();
2966  }
2967  llvm::DIType diTargetType = targetType->GetDIType(scope);
2968 #else //LLVM 3.7++
2969 llvm::DIType *ReferenceType::GetDIType(llvm::DIScope *scope) const {
2970  if (targetType == NULL) {
2971  Assert(m->errorCount > 0);
2972  return NULL;
2973  }
2974  llvm::DIType *diTargetType = targetType->GetDIType(scope);
2975 #endif
2976  return m->diBuilder->createReferenceType(llvm::dwarf::DW_TAG_reference_type,
2977  diTargetType);
2978 }
2979 
2980 
2981 ///////////////////////////////////////////////////////////////////////////
2982 // FunctionType
2983 
2985  const llvm::SmallVector<const Type *, 8> &a,
2986  SourcePos p)
2987  : Type(FUNCTION_TYPE), isTask(false), isExported(false), isExternC(false),
2988  isUnmasked(false), returnType(r), paramTypes(a),
2989  paramNames(llvm::SmallVector<std::string, 8>(a.size(), "")),
2990  paramDefaults(llvm::SmallVector<Expr *, 8>(a.size(), NULL)),
2991  paramPositions(llvm::SmallVector<SourcePos, 8>(a.size(), p)) {
2992  Assert(returnType != NULL);
2993  isSafe = false;
2994  costOverride = -1;
2995 }
2996 
2997 
2999  const llvm::SmallVector<const Type *, 8> &a,
3000  const llvm::SmallVector<std::string, 8> &an,
3001  const llvm::SmallVector<Expr *, 8> &ad,
3002  const llvm::SmallVector<SourcePos, 8> &ap,
3003  bool it, bool is, bool ec, bool ium)
3004  : Type(FUNCTION_TYPE), isTask(it), isExported(is), isExternC(ec),
3005  isUnmasked(ium), returnType(r), paramTypes(a), paramNames(an),
3006  paramDefaults(ad), paramPositions(ap) {
3007  Assert(paramTypes.size() == paramNames.size() &&
3008  paramNames.size() == paramDefaults.size() &&
3009  paramDefaults.size() == paramPositions.size());
3010  Assert(returnType != NULL);
3011  isSafe = false;
3012  costOverride = -1;
3013 }
3014 
3015 
3019 }
3020 
3021 
3022 bool
3024  return false;
3025 }
3026 
3027 
3028 bool
3030  return false;
3031 }
3032 
3033 
3034 bool
3036  return false;
3037 }
3038 
3039 
3040 bool
3042  return false;
3043 }
3044 
3045 
3046 bool
3048  return false;
3049 }
3050 
3051 
3052 const Type *
3054  FATAL("FunctionType::GetBaseType() shouldn't be called");
3055  return NULL;
3056 }
3057 
3058 
3059 const Type *
3061  FATAL("FunctionType::GetAsVaryingType shouldn't be called");
3062  return NULL;
3063 }
3064 
3065 
3066 const Type *
3068  FATAL("FunctionType::GetAsUniformType shouldn't be called");
3069  return NULL;
3070 }
3071 
3072 
3073 const Type *
3075  FATAL("FunctionType::GetAsUnboundVariabilityType shouldn't be called");
3076  return NULL;
3077 }
3078 
3079 
3080 const Type *
3081 FunctionType::GetAsSOAType(int width) const {
3082  FATAL("FunctionType::GetAsSOAType() shouldn't be called");
3083  return NULL;
3084 }
3085 
3086 
3087 const FunctionType *
3089  if (returnType == NULL) {
3090  Assert(m->errorCount > 0);
3091  return NULL;
3092  }
3093  const Type *rt = returnType->ResolveUnboundVariability(v);
3094 
3095  llvm::SmallVector<const Type *, 8> pt;
3096  for (unsigned int i = 0; i < paramTypes.size(); ++i) {
3097  if (paramTypes[i] == NULL) {
3098  Assert(m->errorCount > 0);
3099  return NULL;
3100  }
3101  pt.push_back(paramTypes[i]->ResolveUnboundVariability(v));
3102  }
3103 
3104  FunctionType *ret = new FunctionType(rt, pt, paramNames, paramDefaults,
3107  ret->isSafe = isSafe;
3108  ret->costOverride = costOverride;
3109 
3110  return ret;
3111 }
3112 
3113 
3114 const Type *
3116  return this;
3117 }
3118 
3119 
3120 const Type *
3122  return this;
3123 }
3124 
3125 
3126 std::string
3128  std::string ret = GetReturnTypeString();
3129  ret += "(";
3130  for (unsigned int i = 0; i < paramTypes.size(); ++i) {
3131  if (paramTypes[i] == NULL)
3132  ret += "/* ERROR */";
3133  else
3134  ret += paramTypes[i]->GetString();
3135 
3136  if (i != paramTypes.size() - 1)
3137  ret += ", ";
3138  }
3139  ret += ")";
3140  return ret;
3141 }
3142 
3143 
3144 std::string
3146  std::string ret = "___";
3147  if (isUnmasked)
3148  ret += "UM_";
3149 
3150  for (unsigned int i = 0; i < paramTypes.size(); ++i)
3151  if (paramTypes[i] == NULL)
3152  Assert(m->errorCount > 0);
3153  else
3154  ret += paramTypes[i]->Mangle();
3155 
3156  return ret;
3157 }
3158 
3159 
3160 std::string
3161 FunctionType::GetCDeclaration(const std::string &fname) const {
3162  std::string ret;
3163  ret += returnType->GetCDeclaration("");
3164  ret += " ";
3165  ret += fname;
3166  ret += "(";
3167  for (unsigned int i = 0; i < paramTypes.size(); ++i) {
3168  const Type *type = paramTypes[i];
3169 
3170  // Convert pointers to arrays to unsized arrays, which are more clear
3171  // to print out for multidimensional arrays (i.e. "float foo[][4] "
3172  // versus "float (foo *)[4]").
3173  const PointerType *pt = CastType<PointerType>(type);
3174  if (pt != NULL &&
3175  CastType<ArrayType>(pt->GetBaseType()) != NULL) {
3176  type = new ArrayType(pt->GetBaseType(), 0);
3177  }
3178 
3179  if (paramNames[i] != "")
3180  ret += type->GetCDeclaration(paramNames[i]);
3181  else
3182  ret += type->GetString();
3183  if (i != paramTypes.size() - 1)
3184  ret += ", ";
3185  }
3186  ret += ")";
3187  return ret;
3188 }
3189 
3190 
3191 std::string
3192 FunctionType::GetCDeclarationForDispatch(const std::string &fname) const {
3193  std::string ret;
3194  ret += returnType->GetCDeclaration("");
3195  ret += " ";
3196  ret += fname;
3197  ret += "(";
3198  for (unsigned int i = 0; i < paramTypes.size(); ++i) {
3199  const Type *type = paramTypes[i];
3200 
3201  // Convert pointers to arrays to unsized arrays, which are more clear
3202  // to print out for multidimensional arrays (i.e. "float foo[][4] "
3203  // versus "float (foo *)[4]").
3204  const PointerType *pt = CastType<PointerType>(type);
3205  if (pt != NULL &&
3206  CastType<ArrayType>(pt->GetBaseType()) != NULL) {
3207  type = new ArrayType(pt->GetBaseType(), 0);
3208  }
3209 
3210  // Change pointers to varying thingies to void *
3211  if (pt != NULL && pt->GetBaseType()->IsVaryingType()) {
3213 
3214  if (paramNames[i] != "")
3215  ret += t->GetCDeclaration(paramNames[i]);
3216  else
3217  ret += t->GetString();
3218  }
3219  else {
3220  if (paramNames[i] != "")
3221  ret += type->GetCDeclaration(paramNames[i]);
3222  else
3223  ret += type->GetString();
3224  }
3225  if (i != paramTypes.size() - 1)
3226  ret += ", ";
3227  }
3228  ret += ")";
3229  return ret;
3230 }
3231 
3232 
3233 llvm::Type *
3234 FunctionType::LLVMType(llvm::LLVMContext *ctx) const {
3235  FATAL("FunctionType::LLVMType() shouldn't be called");
3236  return NULL;
3237 }
3238 
3239 
3240 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
3241 llvm::DIType FunctionType::GetDIType(llvm::DIDescriptor scope) const {
3242 #else //LLVM 3.7++
3243 llvm::DIType *FunctionType::GetDIType(llvm::DIScope *scope) const {
3244 #endif
3245 
3246 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_5
3247  std::vector<llvm::Value *> retArgTypes;
3248 #else // LLVM 3.6++
3249  std::vector<llvm::Metadata *> retArgTypes;
3250 #endif
3251  retArgTypes.push_back(returnType->GetDIType(scope));
3252  for (int i = 0; i < GetNumParameters(); ++i) {
3253  const Type *t = GetParameterType(i);
3254  if (t == NULL)
3255 
3256 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_3
3257  return llvm::DIType();
3258 #elif ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
3259  return llvm::DICompositeType();
3260 #else // LLVM 3.7++
3261  return NULL;
3262 #endif
3263  retArgTypes.push_back(t->GetDIType(scope));
3264  }
3265 #if ISPC_LLVM_VERSION <= ISPC_LLVM_3_5
3266  llvm::DIArray retArgTypesArray =
3267  m->diBuilder->getOrCreateArray(llvm::ArrayRef<llvm::Value *>(retArgTypes));
3268  llvm::DIType diType =
3269  // FIXME: DIFile
3270  m->diBuilder->createSubroutineType(llvm::DIFile(), retArgTypesArray);
3271 #elif ISPC_LLVM_VERSION == ISPC_LLVM_3_6
3272  llvm::DITypeArray retArgTypesArray =
3273  m->diBuilder->getOrCreateTypeArray(retArgTypes);
3274  llvm::DIType diType =
3275  // FIXME: DIFile
3276  m->diBuilder->createSubroutineType(llvm::DIFile(), retArgTypesArray);
3277 #elif ISPC_LLVM_VERSION == ISPC_LLVM_3_7 // LLVM 3.7
3278  llvm::DITypeRefArray retArgTypesArray =
3279  m->diBuilder->getOrCreateTypeArray(retArgTypes);
3280  llvm::DIType *diType =
3281  m->diBuilder->createSubroutineType(NULL, retArgTypesArray);
3282 #else // LLVM 3.8+
3283  llvm::DITypeRefArray retArgTypesArray =
3284  m->diBuilder->getOrCreateTypeArray(retArgTypes);
3285  llvm::DIType *diType =
3286  m->diBuilder->createSubroutineType(retArgTypesArray);
3287 #endif
3288  return diType;
3289 }
3290 
3291 
3292 const std::string
3294  if (returnType == NULL)
3295  return "/* ERROR */";
3296 
3297  std::string ret;
3298  if (isTask)
3299  ret += "task ";
3300  if (isExported)
3301  ret += "export ";
3302  if (isExternC)
3303  ret += "extern \"C\" ";
3304  if (isUnmasked)
3305  ret += "unmasked ";
3306  if (isSafe)
3307  ret += "/*safe*/ ";
3308  if (costOverride > 0) {
3309  char buf[32];
3310  sprintf(buf, "/*cost=%d*/ ", costOverride);
3311  ret += buf;
3312  }
3313 
3314  return ret + returnType->GetString();
3315 }
3316 
3317 
3318 llvm::FunctionType *
3319 FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const {
3320  if (isTask == true)
3321  Assert(removeMask == false);
3322 
3323  // Get the LLVM Type *s for the function arguments
3324  std::vector<llvm::Type *> llvmArgTypes;
3325  for (unsigned int i = 0; i < paramTypes.size(); ++i) {
3326  if (paramTypes[i] == NULL) {
3327  Assert(m->errorCount > 0);
3328  return NULL;
3329  }
3330  Assert(paramTypes[i]->IsVoidType() == false);
3331 
3332  llvm::Type *t = paramTypes[i]->LLVMType(ctx);
3333  if (t == NULL) {
3334  Assert(m->errorCount > 0);
3335  return NULL;
3336  }
3337  llvmArgTypes.push_back(t);
3338  }
3339 
3340  // And add the function mask, if asked for
3341  if (!(removeMask || isUnmasked))
3342  llvmArgTypes.push_back(LLVMTypes::MaskType);
3343 
3344  std::vector<llvm::Type *> callTypes;
3345  if (isTask
3346 #ifdef ISPC_NVPTX_ENABLED
3347  && (g->target->getISA() != Target::NVPTX)
3348 #endif
3349  ){
3350  // Tasks take three arguments: a pointer to a struct that holds the
3351  // actual task arguments, the thread index, and the total number of
3352  // threads the tasks system has running. (Task arguments are
3353  // marshalled in a struct so that it's easy to allocate space to
3354  // hold them until the task actually runs.)
3355  llvm::Type *st = llvm::StructType::get(*ctx, llvmArgTypes);
3356  callTypes.push_back(llvm::PointerType::getUnqual(st));
3357  callTypes.push_back(LLVMTypes::Int32Type); // threadIndex
3358  callTypes.push_back(LLVMTypes::Int32Type); // threadCount
3359  callTypes.push_back(LLVMTypes::Int32Type); // taskIndex
3360  callTypes.push_back(LLVMTypes::Int32Type); // taskCount
3361  callTypes.push_back(LLVMTypes::Int32Type); // taskIndex0
3362  callTypes.push_back(LLVMTypes::Int32Type); // taskIndex1
3363  callTypes.push_back(LLVMTypes::Int32Type); // taskIndex2
3364  callTypes.push_back(LLVMTypes::Int32Type); // taskCount0
3365  callTypes.push_back(LLVMTypes::Int32Type); // taskCount1
3366  callTypes.push_back(LLVMTypes::Int32Type); // taskCount2
3367  }
3368  else
3369  // Otherwise we already have the types of the arguments
3370  callTypes = llvmArgTypes;
3371 
3372  if (returnType == NULL) {
3373  Assert(m->errorCount > 0);
3374  return NULL;
3375  }
3376 
3377  llvm::Type *llvmReturnType = returnType->LLVMType(g->ctx);
3378  if (llvmReturnType == NULL)
3379  return NULL;
3380 
3381  return llvm::FunctionType::get(llvmReturnType, callTypes, false);
3382 }
3383 
3384 
3385 const Type *
3387  Assert(i < (int)paramTypes.size());
3388  return paramTypes[i];
3389 }
3390 
3391 
3392 Expr *
3394  Assert(i < (int)paramDefaults.size());
3395  return paramDefaults[i];
3396 }
3397 
3398 
3399 const SourcePos &
3401  Assert(i < (int)paramPositions.size());
3402  return paramPositions[i];
3403 }
3404 
3405 
3406 const std::string &
3408  Assert(i < (int)paramNames.size());
3409  return paramNames[i];
3410 }
3411 
3412 
3413 ///////////////////////////////////////////////////////////////////////////
3414 // Type
3415 
3416 const Type *
3418  // only ReferenceType needs to override this method
3419  return this;
3420 }
3421 
3422 
3423 const Type *
3425  // For many types, this doesn't make any sesne
3426  return NULL;
3427 }
3428 
3429 
3430 /** Given an atomic or vector type, return a vector type of the given
3431  vecSize. Issue an error if given a vector type that isn't already that
3432  size.
3433  */
3434 static const Type *
3435 lVectorConvert(const Type *type, SourcePos pos, const char *reason, int vecSize) {
3436  const VectorType *vt = CastType<VectorType>(type);
3437  if (vt) {
3438  if (vt->GetElementCount() != vecSize) {
3439  Error(pos, "Implicit conversion between from vector type "
3440  "\"%s\" to vector type of length %d for %s is not possible.",
3441  type->GetString().c_str(), vecSize, reason);
3442  return NULL;
3443  }
3444  return vt;
3445  }
3446  else {
3447  const AtomicType *at = CastType<AtomicType>(type);
3448  if (!at) {
3449  Error(pos, "Non-atomic type \"%s\" can't be converted to vector type "
3450  "for %s.", type->GetString().c_str(), reason);
3451  return NULL;
3452  }
3453  return new VectorType(at, vecSize);
3454  }
3455 }
3456 
3457 
3458 const Type *
3459 Type::MoreGeneralType(const Type *t0, const Type *t1, SourcePos pos, const char *reason,
3460  bool forceVarying, int vecSize) {
3461  Assert(reason != NULL);
3462 
3463  // First, if one or both types are function types, convert them to
3464  // pointer to function types and then try again.
3465  if (CastType<FunctionType>(t0) || CastType<FunctionType>(t1)) {
3466  if (CastType<FunctionType>(t0))
3467  t0 = PointerType::GetUniform(t0);
3468  if (CastType<FunctionType>(t1))
3469  t1 = PointerType::GetUniform(t1);
3470  return MoreGeneralType(t0, t1, pos, reason, forceVarying, vecSize);
3471  }
3472 
3473  // First, if we need to go varying, promote both of the types to be
3474  // varying.
3475  if (t0->IsVaryingType() || t1->IsVaryingType() || forceVarying) {
3476  t0 = t0->GetAsVaryingType();
3477  t1 = t1->GetAsVaryingType();
3478  }
3479 
3480  // And similarly, promote them both to vectors if the caller requested
3481  // a particular vector size
3482  if (vecSize > 0) {
3483  t0 = lVectorConvert(t0, pos, reason, vecSize);
3484  t1 = lVectorConvert(t1, pos, reason, vecSize);
3485  if (!t0 || !t1)
3486  return NULL;
3487  }
3488 
3489  // Are they both the same type? If so, we're done, QED.
3490  if (Type::Equal(t0, t1))
3491  return t0;
3492 
3493  // If they're function types, it's hopeless if they didn't match in the
3494  // Type::Equal() call above. Fail here so that we don't get into
3495  // trouble calling GetAsConstType()...
3496  if (CastType<FunctionType>(t0) || CastType<FunctionType>(t1)) {
3497  Error(pos, "Incompatible function types \"%s\" and \"%s\" in %s.",
3498  t0->GetString().c_str(), t1->GetString().c_str(), reason);
3499  return NULL;
3500  }
3501 
3502  // Not the same types, but only a const/non-const difference? Return
3503  // the non-const type as the more general one.
3504  if (Type::EqualIgnoringConst(t0, t1))
3505  return t0->GetAsNonConstType();
3506 
3507  const PointerType *pt0 = CastType<PointerType>(t0);
3508  const PointerType *pt1 = CastType<PointerType>(t1);
3509  if (pt0 != NULL && pt1 != NULL) {
3510  if (PointerType::IsVoidPointer(pt0))
3511  return pt1;
3512  else if (PointerType::IsVoidPointer(pt1))
3513  return pt0;
3514  else {
3515  Error(pos, "Conversion between incompatible pointer types \"%s\" "
3516  "and \"%s\" isn't possible.", t0->GetString().c_str(),
3517  t1->GetString().c_str());
3518  return NULL;
3519  }
3520  }
3521 
3522  const VectorType *vt0 = CastType<VectorType>(t0);
3523  const VectorType *vt1 = CastType<VectorType>(t1);
3524  if (vt0 && vt1) {
3525  // both are vectors; convert their base types and make a new vector
3526  // type, as long as their lengths match
3527  if (vt0->GetElementCount() != vt1->GetElementCount()) {
3528  Error(pos, "Implicit conversion between differently sized vector types "
3529  "(%s, %s) for %s is not possible.", t0->GetString().c_str(),
3530  t1->GetString().c_str(), reason);
3531  return NULL;
3532  }
3533  const Type *t = MoreGeneralType(vt0->GetElementType(), vt1->GetElementType(),
3534  pos, reason, forceVarying);
3535  if (!t)
3536  return NULL;
3537 
3538  // The 'more general' version of the two vector element types must
3539  // be an AtomicType (that's all that vectors can hold...)
3540  const AtomicType *at = CastType<AtomicType>(t);
3541  Assert(at != NULL);
3542 
3543  return new VectorType(at, vt0->GetElementCount());
3544  }
3545  else if (vt0) {
3546  // If one type is a vector type but the other isn't, see if we can
3547  // promote the other one to a vector type. This will fail and
3548  // return NULL if t1 is e.g. an array type and it's illegal to have
3549  // a vector of it..
3550  const Type *t = MoreGeneralType(vt0->GetElementType(), t1, pos,
3551  reason, forceVarying);
3552  if (!t)
3553  return NULL;
3554 
3555  const AtomicType *at = CastType<AtomicType>(t);
3556  Assert(at != NULL);
3557  return new VectorType(at, vt0->GetElementCount());
3558  }
3559  else if (vt1) {
3560  // As in the above case, see if we can promote t0 to make a vector
3561  // that matches vt1.
3562  const Type *t = MoreGeneralType(t0, vt1->GetElementType(), pos,
3563  reason, forceVarying);
3564  if (!t)
3565  return NULL;
3566 
3567  const AtomicType *at = CastType<AtomicType>(t);
3568  Assert(at != NULL);
3569  return new VectorType(at, vt1->GetElementCount());
3570  }
3571 
3572  // TODO: what do we need to do about references here, if anything??
3573 
3574  const AtomicType *at0 = CastType<AtomicType>(t0->GetReferenceTarget());
3575  const AtomicType *at1 = CastType<AtomicType>(t1->GetReferenceTarget());
3576 
3577  const EnumType *et0 = CastType<EnumType>(t0->GetReferenceTarget());
3578  const EnumType *et1 = CastType<EnumType>(t1->GetReferenceTarget());
3579  if (et0 != NULL && et1 != NULL) {
3580  // Two different enum types -> make them uint32s...
3581  Assert(et0->IsVaryingType() == et1->IsVaryingType());
3582  return et0->IsVaryingType() ? AtomicType::VaryingUInt32 :
3584  }
3585  else if (et0 != NULL) {
3586  if (at1 != NULL)
3587  // Enum type and atomic type -> convert the enum to the atomic type
3588  // TODO: should we return uint32 here, unless the atomic type is
3589  // a 64-bit atomic type, in which case we return that?
3590  return at1;
3591  else {
3592  Error(pos, "Implicit conversion from enum type \"%s\" to "
3593  "non-atomic type \"%s\" for %s not possible.",
3594  t0->GetString().c_str(), t1->GetString().c_str(), reason);
3595  return NULL;
3596  }
3597  }
3598  else if (et1 != NULL) {
3599  if (at0 != NULL)
3600  // Enum type and atomic type; see TODO above here as well...
3601  return at0;
3602  else {
3603  Error(pos, "Implicit conversion from enum type \"%s\" to "
3604  "non-atomic type \"%s\" for %s not possible.",
3605  t1->GetString().c_str(), t0->GetString().c_str(), reason);
3606  return NULL;
3607  }
3608  }
3609 
3610  // Now all we can do is promote atomic types...
3611  if (at0 == NULL || at1 == NULL) {
3612  Assert(reason != NULL);
3613  Error(pos, "Implicit conversion from type \"%s\" to \"%s\" for %s not possible.",
3614  t0->GetString().c_str(), t1->GetString().c_str(), reason);
3615  return NULL;
3616  }
3617 
3618  // Finally, to determine which of the two atomic types is more general,
3619  // use the ordering of entries in the AtomicType::BasicType enumerator.
3620  return (int(at0->basicType) >= int(at1->basicType)) ? at0 : at1;
3621 }
3622 
3623 
3624 bool
3625 Type::IsBasicType(const Type *type) {
3626  return (CastType<AtomicType>(type) != NULL ||
3627  CastType<EnumType>(type) != NULL ||
3628  CastType<PointerType>(type) != NULL);
3629 }
3630 
3631 
3632 static bool
3633 lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
3634  if (a == NULL || b == NULL)
3635  return false;
3636 
3637  if (ignoreConst == false &&
3638  a->IsConstType() != b->IsConstType())
3639  return false;
3640 
3641  const AtomicType *ata = CastType<AtomicType>(a);
3642  const AtomicType *atb = CastType<AtomicType>(b);
3643  if (ata != NULL && atb != NULL) {
3644  return ((ata->basicType == atb->basicType) &&
3645  (ata->GetVariability() == atb->GetVariability()));
3646  }
3647 
3648  // For all of the other types, we need to see if we have the same two
3649  // general types. If so, then we dig into the details of the type and
3650  // see if all of the relevant bits are equal...
3651  const EnumType *eta = CastType<EnumType>(a);
3652  const EnumType *etb = CastType<EnumType>(b);
3653  if (eta != NULL && etb != NULL)
3654  // Kind of goofy, but this sufficies to check
3655  return (eta->pos == etb->pos &&
3656  eta->GetVariability() == etb->GetVariability());
3657 
3658  const ArrayType *arta = CastType<ArrayType>(a);
3659  const ArrayType *artb = CastType<ArrayType>(b);
3660  if (arta != NULL && artb != NULL)
3661  return (arta->GetElementCount() == artb->GetElementCount() &&
3662  lCheckTypeEquality(arta->GetElementType(), artb->GetElementType(),
3663  ignoreConst));
3664 
3665  const VectorType *vta = CastType<VectorType>(a);
3666  const VectorType *vtb = CastType<VectorType>(b);
3667  if (vta != NULL && vtb != NULL)
3668  return (vta->GetElementCount() == vtb->GetElementCount() &&
3669  lCheckTypeEquality(vta->GetElementType(), vtb->GetElementType(),
3670  ignoreConst));
3671 
3672  const StructType *sta = CastType<StructType>(a);
3673  const StructType *stb = CastType<StructType>(b);
3674  const UndefinedStructType *usta = CastType<UndefinedStructType>(a);
3675  const UndefinedStructType *ustb = CastType<UndefinedStructType>(b);
3676  if ((sta != NULL || usta != NULL) && (stb != NULL || ustb != NULL)) {
3677  // Report both defuned and undefined structs as equal if their
3678  // names are the same.
3679  if (a->GetVariability() != b->GetVariability())
3680  return false;
3681 
3682  const std::string &namea = sta ? sta->GetStructName() :
3683  usta->GetStructName();
3684  const std::string &nameb = stb ? stb->GetStructName() :
3685  ustb->GetStructName();
3686  return (namea == nameb);
3687  }
3688 
3689  const PointerType *pta = CastType<PointerType>(a);
3690  const PointerType *ptb = CastType<PointerType>(b);
3691  if (pta != NULL && ptb != NULL)
3692  return (pta->IsUniformType() == ptb->IsUniformType() &&
3693  pta->IsSlice() == ptb->IsSlice() &&
3694  pta->IsFrozenSlice() == ptb->IsFrozenSlice() &&
3696  ignoreConst));
3697 
3698  const ReferenceType *rta = CastType<ReferenceType>(a);
3699  const ReferenceType *rtb = CastType<ReferenceType>(b);
3700  if (rta != NULL && rtb != NULL)
3701  return (lCheckTypeEquality(rta->GetReferenceTarget(),
3702  rtb->GetReferenceTarget(), ignoreConst));
3703 
3704  const FunctionType *fta = CastType<FunctionType>(a);
3705  const FunctionType *ftb = CastType<FunctionType>(b);
3706  if (fta != NULL && ftb != NULL) {
3707  // Both the return types and all of the argument types must match
3708  // for function types to match
3709  if (!lCheckTypeEquality(fta->GetReturnType(), ftb->GetReturnType(),
3710  ignoreConst))
3711  return false;
3712 
3713  if (fta->isTask != ftb->isTask ||
3714  fta->isExported != ftb->isExported ||
3715  fta->isExternC != ftb->isExternC ||
3716  fta->isUnmasked != ftb->isUnmasked)
3717  return false;
3718 
3719  if (fta->GetNumParameters() != ftb->GetNumParameters())
3720  return false;
3721 
3722  for (int i = 0; i < fta->GetNumParameters(); ++i)
3723  if (!lCheckTypeEquality(fta->GetParameterType(i),
3724  ftb->GetParameterType(i), ignoreConst))
3725  return false;
3726 
3727  return true;
3728  }
3729 
3730  return false;
3731 }
3732 
3733 
3734 bool
3735 Type::Equal(const Type *a, const Type *b) {
3736  return lCheckTypeEquality(a, b, false);
3737 }
3738 
3739 
3740 bool
3741 Type::EqualIgnoringConst(const Type *a, const Type *b) {
3742  return lCheckTypeEquality(a, b, true);
3743 }
bool IsVoidType() const
Definition: type.cpp:250
static const AtomicType * VaryingInt32
Definition: type.h:349
llvm::SmallVector< Expr *, 8 > paramDefaults
Definition: type.h:976
static llvm::Type * FloatType
Definition: llvmutil.h:80
const AtomicType * GetAsUnsignedType() const
Definition: type.cpp:288
bool IsVaryingType() const
Definition: type.h:150
Expr * GetParameterDefault(int i) const
Definition: type.cpp:3393
bool IsUnsignedType() const
Definition: type.cpp:1739
std::string GetString() const
Definition: type.cpp:2244
bool IsUnsignedType() const
Definition: type.cpp:722
const StructType * oppositeConstStructType
Definition: type.h:777
virtual ArrayType * GetSizedArray(int length) const
Definition: type.cpp:1646
const std::string GetReturnTypeString() const
Definition: type.cpp:3293
static const AtomicType * VaryingInt16
Definition: type.h:348
llvm::Type * LLVMType(llvm::LLVMContext *ctx) const
Definition: type.cpp:2945
static bool lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst)
Definition: type.cpp:3633
EnumType(SourcePos pos)
Definition: type.cpp:682
bool IsFloatType() const
Definition: type.cpp:3023
Variability GetVariability() const
Definition: type.cpp:228
const VectorType * GetAsNonConstType() const
Definition: type.cpp:1809
Variability GetVariability() const
Definition: type.cpp:698
const UndefinedStructType * GetAsSOAType(int width) const
Definition: type.cpp:2613
int GetElementCount() const
Definition: type.cpp:1522
llvm::DIType GetDIType(llvm::DIDescriptor scope) const
Definition: type.cpp:1886
const ReferenceType * GetAsVaryingType() const
Definition: type.cpp:2799
virtual Variability GetVariability() const =0
std::string GetString() const
Definition: type.cpp:3127
const Type * GetAsVaryingType() const
Definition: type.cpp:3060
const EnumType * GetAsUniformType() const
Definition: type.cpp:740
llvm::DIType GetDIType(llvm::DIDescriptor scope) const
Definition: type.cpp:1627
bool IsConstType() const
Definition: type.cpp:1751
std::string GetCDeclaration(const std::string &name) const
Definition: type.cpp:1833
const bool isConst
Definition: type.h:826
const ArrayType * GetAsUnsignedType() const
Definition: type.cpp:1492
int GetEnumeratorCount() const
Definition: type.cpp:989
Definition: ispc.h:74
llvm::DIType GetDIType(llvm::DIDescriptor scope) const
Definition: type.cpp:2332
const PointerType * GetAsConstType() const
Definition: type.cpp:1157
llvm::Type * LLVMType(llvm::LLVMContext *ctx) const
Definition: type.cpp:494
const AtomicType * GetAsConstType() const
Definition: type.cpp:312
const std::string GetCStructName() const
Definition: type.cpp:2079
const Type * GetAsUniformType() const
Definition: type.cpp:3067
static const AtomicType * VaryingUInt64
Definition: type.h:355
static llvm::Type * DoubleType
Definition: llvmutil.h:81
const UndefinedStructType * GetAsConstType() const
Definition: type.cpp:2628
std::string GetCDeclaration(const std::string &name) const
Definition: type.cpp:1211
bool IsIntType() const
Definition: type.cpp:1052
int TotalElementCount() const
Definition: type.cpp:1617
const bool isConst
Definition: type.h:361
static PointerType * Void
Definition: type.h:494
const ArrayType * GetAsUnboundVariabilityType() const
Definition: type.cpp:1462
bool IsIntType() const
Definition: type.cpp:3029
bool IsFrozenSlice() const
Definition: type.h:468
bool IsArrayType() const
Definition: type.cpp:240
bool IsIntType() const
Definition: type.cpp:2565
int getVectorWidth() const
Definition: ispc.h:285
Module * m
Definition: ispc.cpp:93
llvm::DIType GetDIType(llvm::DIDescriptor scope) const
Definition: type.cpp:3241
virtual bool IsUnsignedType() const =0
virtual const Type * GetAsUnboundVariabilityType() const =0
const VectorType * GetAsSOAType(int width) const
Definition: type.cpp:1781
int first_line
Definition: ispc.h:141
Target * target
Definition: ispc.h:549
static llvm::VectorType * VoidPointerVectorType
Definition: llvmutil.h:108
llvm::DIType GetDIType(llvm::DIDescriptor scope) const
Definition: type.cpp:2962
static llvm::VectorType * BoolVectorType
Definition: llvmutil.h:92
bool HasUnboundVariability() const
Definition: type.h:164
bool IsUnsignedType() const
Definition: type.cpp:3041
const EnumType * GetAsSOAType(int width) const
Definition: type.cpp:788
static const AtomicType * VaryingDouble
Definition: type.h:356
Abstract base class for types that represent sequences.
Definition: type.h:531
bool IsBoolType() const
Definition: type.cpp:2733
const PointerType * GetAsNonSlice() const
Definition: type.cpp:1124
static llvm::Type * BoolType
Definition: llvmutil.h:74
bool IsConstType() const
Definition: type.cpp:2122
bool IsUnsignedType() const
Definition: type.cpp:269
int GetElementNumber(const std::string &name) const
Definition: type.cpp:2493
const EnumType * GetAsNonConstType() const
Definition: type.cpp:812
#define Assert(expr)
Definition: ispc.h:172
static std::string lMangleStruct(Variability variability, bool isConst, const std::string &name)
Definition: type.cpp:2273
std::string GetString() const
Definition: type.cpp:401
static std::string lMangleStructName(const std::string &name, Variability variability)
Definition: type.cpp:1979
Variability variability
Definition: type.h:420
PointerType(const Type *t, Variability v, bool isConst, bool isSlice=false, bool frozen=false)
Definition: type.cpp:1007
bool IsDefined() const
Definition: type.cpp:2128
const Type * GetBaseType() const
Definition: type.cpp:1429
std::string Mangle() const
Definition: type.cpp:1559
const std::string name
Definition: type.h:419
bool IsBoolType() const
Definition: type.cpp:2553
llvm::FunctionType * LLVMFunctionType(llvm::LLVMContext *ctx, bool disableMask=false) const
Definition: type.cpp:3319
bool IsPointerType() const
Definition: type.cpp:234
static llvm::VectorType * Int32VectorType
Definition: llvmutil.h:96
bool IsConstType() const
Definition: type.cpp:2577
static const AtomicType * UniformUInt32
Definition: type.h:352
std::string GetCDeclaration(const std::string &name) const
Definition: type.cpp:454
int soaWidth
Definition: type.h:77
const Type * GetElementType(const std::string &name) const
Definition: type.cpp:2484
Variability GetVariability() const
Definition: type.cpp:1393
static PointerType * GetVarying(const Type *t)
Definition: type.cpp:1021
const PointerType * GetAsVaryingType() const
Definition: type.cpp:1076
std::string Mangle() const
Definition: type.cpp:2290
const EnumType * GetAsConstType() const
Definition: type.cpp:800
virtual const Type * GetAsUniformType() const =0
std::string GetCDeclaration(const std::string &name) const
Definition: type.cpp:2912
const Variability variability
Definition: type.h:771
static std::map< std::string, llvm::StructType * > lStructTypeMap
Definition: type.cpp:1969
const StructType * GetAsUnboundVariabilityType() const
Definition: type.cpp:2173
A list of expressions.
Definition: expr.h:252
virtual const Type * GetElementType() const =0
Type implementation for pointers to other types.
Definition: type.h:446
Variability GetVariability() const
Definition: type.cpp:2547
bool IsFloatType() const
Definition: type.cpp:1399
const int numElements
Definition: type.h:624
bool IsUnsignedType() const
Definition: type.cpp:2116
static llvm::Type * Int16Type
Definition: llvmutil.h:77
UndefinedStructType(const std::string &name, const Variability variability, bool isConst, SourcePos pos)
Definition: type.cpp:2532
bool IsUnsignedType() const
Definition: type.cpp:1058
Variability GetVariability() const
Definition: type.cpp:1721
const Type * GetBaseType() const
Definition: type.cpp:2583
bool IsFloatType() const
Definition: type.cpp:255
virtual std::string GetString() const =0
bool IsUnsignedType() const
Definition: type.cpp:1411
virtual std::string Mangle() const =0
const Variability variability
Definition: type.h:825
const ReferenceType * GetAsNonConstType() const
Definition: type.cpp:2869
Variability GetVariability() const
Definition: type.cpp:3017
const llvm::SmallVector< std::string, 8 > paramNames
Definition: type.h:973
const VectorType * ResolveUnboundVariability(Variability v) const
Definition: type.cpp:1787
static const AtomicType * UniformUInt16
Definition: type.h:351
const Type * GetReferenceTarget() const
Definition: type.cpp:2783
const UndefinedStructType * GetAsUnboundVariabilityType() const
Definition: type.cpp:2605
int GetSOAWidth() const
Definition: type.h:160
static PointerType * GetUniform(const Type *t, bool isSlice=false)
Definition: type.cpp:1015
const PointerType * GetAsSOAType(int width) const
Definition: type.cpp:1106
const StructType * ResolveUnboundVariability(Variability v) const
Definition: type.cpp:2196
const ArrayType * GetAsNonConstType() const
Definition: type.cpp:1512
bool IsIntType() const
Definition: type.cpp:1405
const StructType * GetAsNonConstType() const
Definition: type.cpp:2228
header file with declarations for symbol and symbol table classes.
static const AtomicType * UniformBool
Definition: type.h:346
const ArrayType * GetAsVaryingType() const
Definition: type.cpp:1442
bool IsBoolType() const
Definition: type.cpp:1417
int costOverride
Definition: type.h:965
Type representing a reference to another (non-reference) type.
Definition: type.h:833
std::string GetString() const
Definition: type.cpp:1534
static llvm::DIType lCreateDIArray(llvm::DIType eltType, int count)
Definition: type.cpp:87
const UndefinedStructType * ResolveUnboundVariability(Variability v) const
Definition: type.cpp:2620
const Type * baseType
Definition: type.h:500
bool IsBoolType() const
Definition: type.cpp:3035
llvm::Module * module
Definition: module.h:158
const AtomicType * GetAsUniformType() const
Definition: type.cpp:359
VectorType(const AtomicType *base, int size)
Definition: type.cpp:1713
static bool IsVoidPointer(const Type *t)
Definition: type.cpp:1027
const llvm::SmallVector< std::string, 8 > elementNames
Definition: type.h:767
int getVectorMemoryCount() const
Definition: type.cpp:1934
const ArrayType * GetAsUniformType() const
Definition: type.cpp:1452
std::vector< Symbol * > enumerators
Definition: type.h:422
Globals * g
Definition: ispc.cpp:92
const EnumType * GetBaseType() const
Definition: type.cpp:734
bool IsFloatType() const
Definition: type.cpp:2743
static const AtomicType * UniformUInt64
Definition: type.h:355
bool IsUniformType() const
Definition: type.h:145
bool IsBoolType() const
Definition: type.cpp:2098
llvm::DIType GetDIType(llvm::DIDescriptor scope) const
Definition: type.cpp:902
static llvm::VectorType * Int8VectorType
Definition: llvmutil.h:94
const Type * GetAsNonConstType() const
Definition: type.cpp:3121
bool IsIntType() const
Definition: type.cpp:260
std::string GetCDeclaration(const std::string &name) const
Definition: type.cpp:850
const std::string & GetParameterName(int i) const
Definition: type.cpp:3407
AtomicType(BasicType basicType, Variability v, bool isConst)
Definition: type.cpp:220
const bool isExternC
Definition: type.h:952
const UndefinedStructType * GetAsVaryingType() const
Definition: type.cpp:2589
bool IsConstType() const
Definition: type.cpp:282
void Error(SourcePos p, const char *format,...) PRINTF_FUNC
Definition: util.cpp:385
const llvm::SmallVector< SourcePos, 8 > elementPositions
Definition: type.h:770
virtual bool IsConstType() const =0
const Type * GetAsSOAType(int width) const
Definition: type.cpp:2835
llvm::SmallVector< const Type *, 8 > finalElementTypes
Definition: type.h:775
Definition: type.h:85
std::string GetCDeclaration(const std::string &name) const
Definition: type.cpp:2661
const EnumType * ResolveUnboundVariability(Variability v) const
Definition: type.cpp:752
static bool checkIfCanBeSOA(const StructType *st)
Definition: type.cpp:2502
llvm::Type * LLVMType(llvm::LLVMContext *ctx) const
Definition: type.cpp:1854
static llvm::VectorType * FloatVectorType
Definition: llvmutil.h:98
bool IsSlice() const
Definition: type.h:467
const VectorType * GetAsVaryingType() const
Definition: type.cpp:1763
virtual bool IsBoolType() const =0
const AtomicType * GetBaseType() const
Definition: type.cpp:338
virtual std::string GetCDeclaration(const std::string &name) const =0
static llvm::Type * Int64Type
Definition: llvmutil.h:79
std::string GetString() const
Definition: type.cpp:824
const SourcePos pos
Definition: type.h:416
static llvm::Type * Int8Type
Definition: llvmutil.h:76
static const Type * MoreGeneralType(const Type *type0, const Type *type1, SourcePos pos, const char *reason, bool forceVarying=false, int vecSize=0)
Definition: type.cpp:3459
const StructType * GetAsUniformType() const
Definition: type.cpp:2163
Representation of a structure holding a number of members.
Definition: type.h:691
virtual llvm::DIType GetDIType(llvm::DIDescriptor scope) const =0
const AtomicType * ResolveUnboundVariability(Variability v) const
Definition: type.cpp:392
const StructType * GetAsConstType() const
Definition: type.cpp:2212
SourcePos Union(const SourcePos &p1, const SourcePos &p2)
Definition: ispc.cpp:1616
std::string Mangle() const
Definition: type.cpp:3145
bool IsFloatType() const
Definition: type.cpp:1046
static llvm::VectorType * Int64VectorType
Definition: llvmutil.h:97
Header file with declarations for various LLVM utility stuff.
llvm::ArrayType * LLVMType(llvm::LLVMContext *ctx) const
Definition: type.cpp:1377
const PointerType * GetAsNonConstType() const
Definition: type.cpp:1166
virtual bool IsIntType() const =0
const EnumType * GetAsVaryingType() const
Definition: type.cpp:764
std::string GetCDeclaration(const std::string &name) const
Definition: type.cpp:2296
const AtomicType *const base
Definition: type.h:678
const Type * GetParameterType(int i) const
Definition: type.cpp:3386
const AtomicType * asVaryingType
Definition: type.h:364
ISA getISA() const
Definition: ispc.h:269
virtual const Type * GetAsConstType() const =0
static bool IsBasicType(const Type *type)
Definition: type.cpp:3625
const VectorType * GetAsUniformType() const
Definition: type.cpp:1769
bool IsBoolType() const
Definition: type.cpp:1040
const StructType * GetAsVaryingType() const
Definition: type.cpp:2153
std::string name
Definition: type.h:755
AtomicType represents basic types like floats, ints, etc.
Definition: type.h:292
const Type *const returnType
Definition: type.h:968
const bool isConst
Definition: type.h:498
Representation of a range of positions in a source file.
Definition: ispc.h:136
const ArrayType * GetAsSOAType(int width) const
Definition: type.cpp:1472
int GetElementCount() const
Definition: type.cpp:1842
Type implementation for enumerated types.
Definition: type.h:370
static const AtomicType * VaryingBool
Definition: type.h:346
Abstract base class for types that represent collections of other types.
Definition: type.h:510
std::string GetCDeclarationForDispatch(const std::string &fname) const
Definition: type.cpp:3192
const Type * GetAsSOAType(int width) const
Definition: type.cpp:3081
ArrayType(const Type *elementType, int numElements)
Definition: type.cpp:1368
const AtomicType * asOtherConstType
Definition: type.h:364
llvm::Type * LLVMType(llvm::LLVMContext *ctx) const
Definition: type.cpp:3234
std::string GetString() const
Definition: type.cpp:132
bool isConst
Definition: type.h:421
const BasicType basicType
Definition: type.h:344
std::string Mangle() const
Definition: type.cpp:1824
bool IsFloatType() const
Definition: type.cpp:2559
const PointerType * GetAsSlice() const
Definition: type.cpp:1116
static llvm::PointerType * VoidPointerType
Definition: llvmutil.h:72
const Type *const targetType
Definition: type.h:868
static const AtomicType * VaryingInt64
Definition: type.h:354
bool IsConstType() const
Definition: type.cpp:3047
bool IsIntType() const
Definition: type.cpp:716
const Type * GetBaseType() const
Definition: type.cpp:1070
std::string MangleString() const
Definition: type.cpp:150
virtual bool IsFloatType() const =0
const SourcePos pos
Definition: type.h:773
int getNativeVectorWidth() const
Definition: ispc.h:279
llvm::DIType GetDIType(llvm::DIDescriptor scope) const
Definition: type.cpp:534
ReferenceType(const Type *targetType)
Definition: type.cpp:2716
const Type * GetReturnType() const
Definition: type.h:925
bool IsBoolType() const
Definition: type.cpp:1745
std::string Mangle() const
Definition: type.cpp:2655
#define FATAL(message)
Definition: util.h:113
const int numElements
Definition: type.h:680
const llvm::SmallVector< const Type *, 8 > elementTypes
Definition: type.h:766
const Variability variability
Definition: type.h:360
virtual llvm::Type * LLVMType(llvm::LLVMContext *ctx) const =0
A (short) vector of atomic types.
Definition: type.h:639
const FunctionType * ResolveUnboundVariability(Variability v) const
Definition: type.cpp:3088
const Type * GetBaseType() const
Definition: type.cpp:1757
bool IsConstType() const
Definition: type.cpp:728
const AtomicType * GetElementType() const
Definition: type.cpp:1848
bool IsUnsignedType() const
Definition: type.cpp:2763
static const AtomicType * UniformUInt8
Definition: type.h:350
static const Type * lVectorConvert(const Type *type, SourcePos pos, const char *reason, int vecSize)
Definition: type.cpp:3435
const UndefinedStructType * GetAsUniformType() const
Definition: type.cpp:2597
static llvm::Type * Int32Type
Definition: llvmutil.h:78
Variability GetVariability() const
Definition: type.cpp:1034
const VectorType * GetAsUnboundVariabilityType() const
Definition: type.cpp:1775
const bool isSlice
Definition: type.h:499
const Symbol * GetEnumerator(int i) const
Definition: type.cpp:995
const llvm::SmallVector< SourcePos, 8 > paramPositions
Definition: type.h:981
void SetEnumerators(const std::vector< Symbol * > &enumerators)
Definition: type.cpp:983
bool IsConstType() const
Definition: type.cpp:2773
const std::string & GetStructName() const
Definition: type.h:749
static bool Equal(const Type *a, const Type *b)
Definition: type.cpp:3735
static const AtomicType * VaryingUInt16
Definition: type.h:351
const bool isTask
Definition: type.h:944
llvm::DIFile GetDIFile() const
Definition: ispc.cpp:1585
virtual const Type * GetAsVaryingType() const =0
std::vector< Expr * > exprs
Definition: expr.h:270
const PointerType * GetAsUnboundVariabilityType() const
Definition: type.cpp:1096
const ArrayType * ResolveUnboundVariability(Variability v) const
Definition: type.cpp:1482
const Type *const child
Definition: type.h:622
const AtomicType * GetAsUnboundVariabilityType() const
Definition: type.cpp:374
std::string Mangle() const
Definition: type.cpp:837
const StructType * GetAsSOAType(int width) const
Definition: type.cpp:2183
const Type * GetBaseType() const
Definition: type.cpp:2147
static const AtomicType * UniformFloat
Definition: type.h:353
static const AtomicType * VaryingInt8
Definition: type.h:347
BasicType
Definition: type.h:328
const UndefinedStructType * GetAsNonConstType() const
Definition: type.cpp:2636
llvm::Type * LLVMType(llvm::LLVMContext *ctx) const
Definition: type.cpp:882
const AtomicType * GetAsVaryingType() const
Definition: type.cpp:344
bool IsIntType() const
Definition: type.cpp:2110
static const AtomicType * UniformInt32
Definition: type.h:349
std::string GetString() const
Definition: type.cpp:1175
const PointerType * GetAsUniformType() const
Definition: type.cpp:1086
bool IsFloatType() const
Definition: type.cpp:1727
Type representing a function (return type + argument types)
Definition: type.h:884
Representation of a program symbol.
Definition: sym.h:63
std::string GetString() const
Definition: type.cpp:1815
const llvm::SmallVector< const Type *, 8 > paramTypes
Definition: type.h:972
llvm::Type * LLVMType(llvm::LLVMContext *ctx) const
Definition: type.cpp:2672
Interface class that defines the type abstraction.
Definition: type.h:101
static const AtomicType * UniformDouble
Definition: type.h:356
const bool isFrozen
Definition: type.h:499
Expr abstract base class and expression implementations.
llvm::Type * LLVMType(llvm::LLVMContext *ctx) const
Definition: type.cpp:1251
static const AtomicType * Void
Definition: type.h:357
static llvm::VectorType * MaskType
Definition: llvmutil.h:90
const bool isUnmasked
Definition: type.h:957
const SourcePos pos
Definition: type.h:827
virtual const Type * GetBaseType() const =0
const Type * GetAsUnboundVariabilityType() const
Definition: type.cpp:3074
const Type * GetBaseType() const
Definition: type.cpp:3053
std::string GetCDeclaration(const std::string &fname) const
Definition: type.cpp:3161
const AtomicType * asUniformType
Definition: type.h:364
StructType(const std::string &name, const llvm::SmallVector< const Type *, 8 > &elts, const llvm::SmallVector< std::string, 8 > &eltNames, const llvm::SmallVector< SourcePos, 8 > &eltPositions, bool isConst, Variability variability, SourcePos pos)
Definition: type.cpp:2009
bool IsReferenceType() const
Definition: type.cpp:245
Expr is the abstract base class that defines the interface that all expression types must implement...
Definition: expr.h:48
bool IsUnsignedType() const
Definition: type.cpp:2571
const AtomicType * GetAsSOAType(int width) const
Definition: type.cpp:383
static llvm::VectorType * DoubleVectorType
Definition: llvmutil.h:99
virtual const Type * GetAsNonConstType() const =0
bool IsIntType() const
Definition: type.cpp:2753
llvm::Type * LLVMType(llvm::LLVMContext *ctx) const
Definition: type.cpp:2317
std::string GetString() const
Definition: type.cpp:2886
virtual const Type * GetAsSOAType(int width) const =0
static const Type * SizeUnsizedArrays(const Type *type, Expr *initExpr)
Definition: type.cpp:1653
VarType type
Definition: type.h:76
const SourcePos & GetParameterSourcePos(int i) const
Definition: type.cpp:3400
static llvm::VectorType * Int16VectorType
Definition: llvmutil.h:95
static bool lShouldPrintName(const std::string &name)
Definition: type.cpp:74
const AtomicType * GetAsNonConstType() const
Definition: type.cpp:325
bool IsConstType() const
Definition: type.cpp:1423
const std::string name
Definition: type.h:824
bool isSafe
Definition: type.h:961
std::string GetString() const
Definition: type.cpp:2644
const bool isExported
Definition: type.h:948
static const AtomicType * VaryingUInt8
Definition: type.h:350
const Type * GetElementType() const
Definition: type.cpp:1528
bool IsConstType() const
Definition: type.cpp:1064
FunctionType(const Type *returnType, const llvm::SmallVector< const Type *, 8 > &argTypes, SourcePos pos)
Definition: type.cpp:2984
bool IsFloatType() const
Definition: type.cpp:2104
bool IsBoolType() const
Definition: type.cpp:276
virtual const Type * GetAsUnsignedType() const
Definition: type.cpp:3424
Declaration of the Module class, which is the ispc-side representation of the results of compiling a ...
static const AtomicType * UniformInt64
Definition: type.h:354
int errorCount
Definition: module.h:151
const VectorType * GetAsConstType() const
Definition: type.cpp:1803
llvm::LLVMContext * ctx
Definition: ispc.h:638
static const AtomicType * UniformInt16
Definition: type.h:348
const ReferenceType * ResolveUnboundVariability(Variability v) const
Definition: type.cpp:2842
bool IsBoolType() const
Definition: type.cpp:704
Variability GetVariability() const
Definition: type.cpp:2723
llvm::DIBuilder * diBuilder
Definition: module.h:161
bool IsFloatType() const
Definition: type.cpp:710
const ReferenceType * GetAsUniformType() const
Definition: type.cpp:2811
const Type * GetBaseType() const
Definition: type.cpp:2789
static bool EqualIgnoringConst(const Type *a, const Type *b)
Definition: type.cpp:3741
virtual const Type * GetReferenceTarget() const
Definition: type.cpp:3417
bool IsSOAType() const
Definition: type.h:156
const ReferenceType * asOtherConstType
Definition: type.h:869
llvm::DIType GetDIType(llvm::DIDescriptor scope) const
Definition: type.cpp:1312
const Type * GetAsConstType() const
Definition: type.cpp:3115
const PointerType * GetAsFrozenSlice() const
Definition: type.cpp:1132
bool is32Bit() const
Definition: ispc.h:275
const ArrayType * GetAsConstType() const
Definition: type.cpp:1502
Variability GetVariability() const
Definition: type.cpp:2092
llvm::DIType GetDIType(llvm::DIDescriptor scope) const
Definition: type.cpp:2684
std::string Mangle() const
Definition: type.cpp:429
static const AtomicType * VaryingUInt32
Definition: type.h:352
std::string Mangle() const
Definition: type.cpp:1194
int GetNumParameters() const
Definition: type.h:936
bool IsIntType() const
Definition: type.cpp:1733
static const AtomicType * VaryingFloat
Definition: type.h:353
std::string GetCDeclaration(const std::string &name) const
Definition: type.cpp:1576
virtual const Type * ResolveUnboundVariability(Variability v) const =0
static const AtomicType * UniformInt8
Definition: type.h:347
int GetElementCount() const
Definition: type.h:744
const PointerType * ResolveUnboundVariability(Variability v) const
Definition: type.cpp:1140
File with declarations for classes related to type representation.
std::string Mangle() const
Definition: type.cpp:2900
const bool isConst
Definition: type.h:772
const ReferenceType * GetAsConstType() const
Definition: type.cpp:2852
const ReferenceType * GetAsUnboundVariabilityType() const
Definition: type.cpp:2823
const EnumType * GetAsUnboundVariabilityType() const
Definition: type.cpp:776
One-dimensional array type.
Definition: type.h:555
const VectorType * GetAsUnsignedType() const
Definition: type.cpp:1793
const Variability variability
Definition: type.h:497