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