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