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