1 /*
2   Copyright (c) 2010-2021, 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 
47 #include <llvm/BinaryFormat/Dwarf.h>
48 #include <llvm/IR/DIBuilder.h>
49 #include <llvm/IR/DebugInfo.h>
50 #include <llvm/IR/Module.h>
51 #include <llvm/IR/Value.h>
52 #include <llvm/Support/MathExtras.h>
53 
54 using namespace ispc;
55 
56 /** Utility routine used in code that prints out declarations; returns true
57     if the given name should be printed, false otherwise.  This allows us
58     to omit the names for various internal things (whose names start with
59     double underscores) and emit anonymous declarations for them instead.
60  */
61 
lShouldPrintName(const std::string & name)62 static bool lShouldPrintName(const std::string &name) {
63     if (name.size() == 0)
64         return false;
65     else if (name[0] != '_' && name[0] != '$')
66         return true;
67     else
68         return (name.size() == 1) || (name[1] != '_');
69 }
70 
71 /** Utility routine to create a llvm array type of the given number of
72     the given element type. */
lCreateDIArray(llvm::DIType * eltType,int count)73 static llvm::DIType *lCreateDIArray(llvm::DIType *eltType, int count) {
74 
75     llvm::Metadata *sub = m->diBuilder->getOrCreateSubrange(0, count);
76     std::vector<llvm::Metadata *> subs;
77     subs.push_back(sub);
78     llvm::DINodeArray subArray = m->diBuilder->getOrCreateArray(subs);
79     uint64_t size = eltType->getSizeInBits() * count;
80     uint64_t align = eltType->getAlignInBits();
81 
82     return m->diBuilder->createArrayType(size, align, eltType, subArray);
83 }
84 
85 ///////////////////////////////////////////////////////////////////////////
86 // Variability
87 
GetString() const88 std::string Variability::GetString() const {
89     switch (type) {
90     case Uniform:
91         return "uniform";
92     case Varying:
93         return "varying";
94     case SOA: {
95         char buf[32];
96         snprintf(buf, sizeof(buf), "soa<%d>", soaWidth);
97         return std::string(buf);
98     }
99     case Unbound:
100         return "/*unbound*/";
101     default:
102         FATAL("Unhandled variability");
103         return "";
104     }
105 }
106 
MangleString() const107 std::string Variability::MangleString() const {
108     switch (type) {
109     case Uniform:
110         return "un";
111     case Varying:
112         return "vy";
113     case SOA: {
114         char buf[32];
115         snprintf(buf, sizeof(buf), "soa<%d>", soaWidth);
116         return std::string(buf);
117     }
118     case Unbound:
119         FATAL("Unbound unexpected in Variability::MangleString()");
120     default:
121         FATAL("Unhandled variability");
122         return "";
123     }
124 }
125 
126 ///////////////////////////////////////////////////////////////////////////
127 // Type
LLVMStorageType(llvm::LLVMContext * ctx) const128 llvm::Type *Type::LLVMStorageType(llvm::LLVMContext *ctx) const { return LLVMType(ctx); }
129 ///////////////////////////////////////////////////////////////////////////
130 // AtomicType
131 
132 const AtomicType *AtomicType::UniformBool = new AtomicType(AtomicType::TYPE_BOOL, Variability::Uniform, false);
133 const AtomicType *AtomicType::VaryingBool = new AtomicType(AtomicType::TYPE_BOOL, Variability::Varying, false);
134 const AtomicType *AtomicType::UniformInt8 = new AtomicType(AtomicType::TYPE_INT8, Variability::Uniform, false);
135 const AtomicType *AtomicType::VaryingInt8 = new AtomicType(AtomicType::TYPE_INT8, Variability::Varying, false);
136 const AtomicType *AtomicType::UniformUInt8 = new AtomicType(AtomicType::TYPE_UINT8, Variability::Uniform, false);
137 const AtomicType *AtomicType::VaryingUInt8 = new AtomicType(AtomicType::TYPE_UINT8, Variability::Varying, false);
138 const AtomicType *AtomicType::UniformInt16 = new AtomicType(AtomicType::TYPE_INT16, Variability::Uniform, false);
139 const AtomicType *AtomicType::VaryingInt16 = new AtomicType(AtomicType::TYPE_INT16, Variability::Varying, false);
140 const AtomicType *AtomicType::UniformUInt16 = new AtomicType(AtomicType::TYPE_UINT16, Variability::Uniform, false);
141 const AtomicType *AtomicType::VaryingUInt16 = new AtomicType(AtomicType::TYPE_UINT16, Variability::Varying, false);
142 const AtomicType *AtomicType::UniformInt32 = new AtomicType(AtomicType::TYPE_INT32, Variability::Uniform, false);
143 const AtomicType *AtomicType::VaryingInt32 = new AtomicType(AtomicType::TYPE_INT32, Variability::Varying, false);
144 const AtomicType *AtomicType::UniformUInt32 = new AtomicType(AtomicType::TYPE_UINT32, Variability::Uniform, false);
145 const AtomicType *AtomicType::VaryingUInt32 = new AtomicType(AtomicType::TYPE_UINT32, Variability::Varying, false);
146 const AtomicType *AtomicType::UniformFloat = new AtomicType(AtomicType::TYPE_FLOAT, Variability::Uniform, false);
147 const AtomicType *AtomicType::VaryingFloat = new AtomicType(AtomicType::TYPE_FLOAT, Variability::Varying, false);
148 const AtomicType *AtomicType::UniformInt64 = new AtomicType(AtomicType::TYPE_INT64, Variability::Uniform, false);
149 const AtomicType *AtomicType::VaryingInt64 = new AtomicType(AtomicType::TYPE_INT64, Variability::Varying, false);
150 const AtomicType *AtomicType::UniformUInt64 = new AtomicType(AtomicType::TYPE_UINT64, Variability::Uniform, false);
151 const AtomicType *AtomicType::VaryingUInt64 = new AtomicType(AtomicType::TYPE_UINT64, Variability::Varying, false);
152 const AtomicType *AtomicType::UniformDouble = new AtomicType(AtomicType::TYPE_DOUBLE, Variability::Uniform, false);
153 const AtomicType *AtomicType::VaryingDouble = new AtomicType(AtomicType::TYPE_DOUBLE, Variability::Varying, false);
154 const AtomicType *AtomicType::Void = new AtomicType(TYPE_VOID, Variability::Uniform, false);
155 
AtomicType(BasicType bt,Variability v,bool ic)156 AtomicType::AtomicType(BasicType bt, Variability v, bool ic)
157     : Type(ATOMIC_TYPE), basicType(bt), variability(v), isConst(ic) {
158     asOtherConstType = NULL;
159     asUniformType = asVaryingType = NULL;
160 }
161 
GetVariability() const162 Variability AtomicType::GetVariability() const { return variability; }
163 
IsPointerType() const164 bool Type::IsPointerType() const { return (CastType<PointerType>(this) != NULL); }
165 
IsArrayType() const166 bool Type::IsArrayType() const { return (CastType<ArrayType>(this) != NULL); }
167 
IsReferenceType() const168 bool Type::IsReferenceType() const { return (CastType<ReferenceType>(this) != NULL); }
169 
IsVoidType() const170 bool Type::IsVoidType() const { return EqualIgnoringConst(this, AtomicType::Void); }
171 
IsFloatType() const172 bool AtomicType::IsFloatType() const { return (basicType == TYPE_FLOAT || basicType == TYPE_DOUBLE); }
173 
IsIntType() const174 bool AtomicType::IsIntType() const {
175     return (basicType == TYPE_INT8 || basicType == TYPE_UINT8 || basicType == TYPE_INT16 || basicType == TYPE_UINT16 ||
176             basicType == TYPE_INT32 || basicType == TYPE_UINT32 || basicType == TYPE_INT64 || basicType == TYPE_UINT64);
177 }
178 
IsUnsignedType() const179 bool AtomicType::IsUnsignedType() const {
180     return (basicType == TYPE_BOOL || basicType == TYPE_UINT8 || basicType == TYPE_UINT16 || basicType == TYPE_UINT32 ||
181             basicType == TYPE_UINT64);
182 }
183 
IsBoolType() const184 bool AtomicType::IsBoolType() const { return basicType == TYPE_BOOL; }
185 
IsConstType() const186 bool AtomicType::IsConstType() const { return isConst; }
187 
GetAsUnsignedType() const188 const AtomicType *AtomicType::GetAsUnsignedType() const {
189     if (IsUnsignedType() == true)
190         return this;
191 
192     if (IsIntType() == false)
193         return NULL;
194 
195     switch (basicType) {
196     case TYPE_INT8:
197         return new AtomicType(TYPE_UINT8, variability, isConst);
198     case TYPE_INT16:
199         return new AtomicType(TYPE_UINT16, variability, isConst);
200     case TYPE_INT32:
201         return new AtomicType(TYPE_UINT32, variability, isConst);
202     case TYPE_INT64:
203         return new AtomicType(TYPE_UINT64, variability, isConst);
204     default:
205         FATAL("Unexpected basicType in GetAsUnsignedType()");
206         return NULL;
207     }
208 }
209 
GetAsConstType() const210 const AtomicType *AtomicType::GetAsConstType() const {
211     if (isConst == true)
212         return this;
213 
214     if (asOtherConstType == NULL) {
215         asOtherConstType = new AtomicType(basicType, variability, true);
216         asOtherConstType->asOtherConstType = this;
217     }
218     return asOtherConstType;
219 }
220 
GetAsNonConstType() const221 const AtomicType *AtomicType::GetAsNonConstType() const {
222     if (isConst == false)
223         return this;
224 
225     if (asOtherConstType == NULL) {
226         asOtherConstType = new AtomicType(basicType, variability, false);
227         asOtherConstType->asOtherConstType = this;
228     }
229     return asOtherConstType;
230 }
231 
GetBaseType() const232 const AtomicType *AtomicType::GetBaseType() const { return this; }
233 
GetAsVaryingType() const234 const AtomicType *AtomicType::GetAsVaryingType() const {
235     Assert(basicType != TYPE_VOID);
236     if (variability == Variability::Varying)
237         return this;
238 
239     if (asVaryingType == NULL) {
240         asVaryingType = new AtomicType(basicType, Variability::Varying, isConst);
241         if (variability == Variability::Uniform)
242             asVaryingType->asUniformType = this;
243     }
244     return asVaryingType;
245 }
246 
GetAsUniformType() const247 const AtomicType *AtomicType::GetAsUniformType() const {
248     Assert(basicType != TYPE_VOID);
249     if (variability == Variability::Uniform)
250         return this;
251 
252     if (asUniformType == NULL) {
253         asUniformType = new AtomicType(basicType, Variability::Uniform, isConst);
254         if (variability == Variability::Varying)
255             asUniformType->asVaryingType = this;
256     }
257     return asUniformType;
258 }
259 
GetAsUnboundVariabilityType() const260 const AtomicType *AtomicType::GetAsUnboundVariabilityType() const {
261     Assert(basicType != TYPE_VOID);
262     if (variability == Variability::Unbound)
263         return this;
264     return new AtomicType(basicType, Variability::Unbound, isConst);
265 }
266 
GetAsSOAType(int width) const267 const AtomicType *AtomicType::GetAsSOAType(int width) const {
268     Assert(basicType != TYPE_VOID);
269     if (variability == Variability(Variability::SOA, width))
270         return this;
271     return new AtomicType(basicType, Variability(Variability::SOA, width), isConst);
272 }
273 
ResolveUnboundVariability(Variability v) const274 const AtomicType *AtomicType::ResolveUnboundVariability(Variability v) const {
275     Assert(v != Variability::Unbound);
276     if (variability != Variability::Unbound)
277         return this;
278     return new AtomicType(basicType, v, isConst);
279 }
280 
GetString() const281 std::string AtomicType::GetString() const {
282     std::string ret;
283     if (isConst)
284         ret += "const ";
285     if (basicType != TYPE_VOID) {
286         ret += variability.GetString();
287         ret += " ";
288     }
289 
290     switch (basicType) {
291     case TYPE_VOID:
292         ret += "void";
293         break;
294     case TYPE_BOOL:
295         ret += "bool";
296         break;
297     case TYPE_INT8:
298         ret += "int8";
299         break;
300     case TYPE_UINT8:
301         ret += "unsigned int8";
302         break;
303     case TYPE_INT16:
304         ret += "int16";
305         break;
306     case TYPE_UINT16:
307         ret += "unsigned int16";
308         break;
309     case TYPE_INT32:
310         ret += "int32";
311         break;
312     case TYPE_UINT32:
313         ret += "unsigned int32";
314         break;
315     case TYPE_FLOAT:
316         ret += "float";
317         break;
318     case TYPE_INT64:
319         ret += "int64";
320         break;
321     case TYPE_UINT64:
322         ret += "unsigned int64";
323         break;
324     case TYPE_DOUBLE:
325         ret += "double";
326         break;
327     default:
328         FATAL("Logic error in AtomicType::GetString()");
329     }
330     return ret;
331 }
332 
Mangle() const333 std::string AtomicType::Mangle() const {
334     std::string ret;
335     if (isConst)
336         ret += "C";
337     ret += variability.MangleString();
338 
339     switch (basicType) {
340     case TYPE_VOID:
341         ret += "v";
342         break;
343     case TYPE_BOOL:
344         ret += "b";
345         break;
346     case TYPE_INT8:
347         ret += "t";
348         break;
349     case TYPE_UINT8:
350         ret += "T";
351         break;
352     case TYPE_INT16:
353         ret += "s";
354         break;
355     case TYPE_UINT16:
356         ret += "S";
357         break;
358     case TYPE_INT32:
359         ret += "i";
360         break;
361     case TYPE_UINT32:
362         ret += "u";
363         break;
364     case TYPE_FLOAT:
365         ret += "f";
366         break;
367     case TYPE_INT64:
368         ret += "I";
369         break;
370     case TYPE_UINT64:
371         ret += "U";
372         break;
373     case TYPE_DOUBLE:
374         ret += "d";
375         break;
376     default:
377         FATAL("Logic error in AtomicType::Mangle()");
378     }
379     return ret;
380 }
381 
GetCDeclaration(const std::string & name) const382 std::string AtomicType::GetCDeclaration(const std::string &name) const {
383     std::string ret;
384     if (variability == Variability::Unbound) {
385         Assert(m->errorCount > 0);
386         return ret;
387     }
388     if (isConst)
389         ret += "const ";
390 
391     switch (basicType) {
392     case TYPE_VOID:
393         ret += "void";
394         break;
395     case TYPE_BOOL:
396         ret += "bool";
397         break;
398     case TYPE_INT8:
399         ret += "int8_t";
400         break;
401     case TYPE_UINT8:
402         ret += "uint8_t";
403         break;
404     case TYPE_INT16:
405         ret += "int16_t";
406         break;
407     case TYPE_UINT16:
408         ret += "uint16_t";
409         break;
410     case TYPE_INT32:
411         ret += "int32_t";
412         break;
413     case TYPE_UINT32:
414         ret += "uint32_t";
415         break;
416     case TYPE_FLOAT:
417         ret += "float";
418         break;
419     case TYPE_INT64:
420         ret += "int64_t";
421         break;
422     case TYPE_UINT64:
423         ret += "uint64_t";
424         break;
425     case TYPE_DOUBLE:
426         ret += "double";
427         break;
428     default:
429         FATAL("Logic error in AtomicType::GetCDeclaration()");
430     }
431 
432     if (lShouldPrintName(name)) {
433         ret += " ";
434         ret += name;
435     }
436 
437     if (variability == Variability::SOA) {
438         char buf[32];
439         snprintf(buf, sizeof(buf), "[%d]", variability.soaWidth);
440         ret += buf;
441     }
442 
443     return ret;
444 }
445 
lGetAtomicLLVMType(llvm::LLVMContext * ctx,const AtomicType * aType,bool isStorageType)446 static llvm::Type *lGetAtomicLLVMType(llvm::LLVMContext *ctx, const AtomicType *aType, bool isStorageType) {
447     Variability variability = aType->GetVariability();
448     AtomicType::BasicType basicType = aType->basicType;
449     Assert(variability.type != Variability::Unbound);
450     bool isUniform = (variability == Variability::Uniform);
451     bool isVarying = (variability == Variability::Varying);
452 
453     if (isUniform || isVarying) {
454         switch (basicType) {
455         case AtomicType::TYPE_VOID:
456             return llvm::Type::getVoidTy(*ctx);
457         case AtomicType::TYPE_BOOL:
458             if (isStorageType)
459                 return isUniform ? LLVMTypes::BoolStorageType : LLVMTypes::BoolVectorStorageType;
460             else
461                 return isUniform ? LLVMTypes::BoolType : LLVMTypes::BoolVectorType;
462         case AtomicType::TYPE_INT8:
463         case AtomicType::TYPE_UINT8:
464             return isUniform ? LLVMTypes::Int8Type : LLVMTypes::Int8VectorType;
465         case AtomicType::TYPE_INT16:
466         case AtomicType::TYPE_UINT16:
467             return isUniform ? LLVMTypes::Int16Type : LLVMTypes::Int16VectorType;
468         case AtomicType::TYPE_INT32:
469         case AtomicType::TYPE_UINT32:
470             return isUniform ? LLVMTypes::Int32Type : LLVMTypes::Int32VectorType;
471         case AtomicType::TYPE_FLOAT:
472             return isUniform ? LLVMTypes::FloatType : LLVMTypes::FloatVectorType;
473         case AtomicType::TYPE_INT64:
474         case AtomicType::TYPE_UINT64:
475             return isUniform ? LLVMTypes::Int64Type : LLVMTypes::Int64VectorType;
476         case AtomicType::TYPE_DOUBLE:
477             return isUniform ? LLVMTypes::DoubleType : LLVMTypes::DoubleVectorType;
478         default:
479             FATAL("logic error in lGetAtomicLLVMType");
480             return NULL;
481         }
482     } else {
483         ArrayType at(aType->GetAsUniformType(), variability.soaWidth);
484         return at.LLVMType(ctx);
485     }
486 }
487 
LLVMStorageType(llvm::LLVMContext * ctx) const488 llvm::Type *AtomicType::LLVMStorageType(llvm::LLVMContext *ctx) const { return lGetAtomicLLVMType(ctx, this, true); }
LLVMType(llvm::LLVMContext * ctx) const489 llvm::Type *AtomicType::LLVMType(llvm::LLVMContext *ctx) const { return lGetAtomicLLVMType(ctx, this, false); }
490 
GetDIType(llvm::DIScope * scope) const491 llvm::DIType *AtomicType::GetDIType(llvm::DIScope *scope) const {
492     Assert(variability.type != Variability::Unbound);
493 
494     if (variability.type == Variability::Uniform) {
495         switch (basicType) {
496         case TYPE_VOID:
497             return NULL;
498 
499         case TYPE_BOOL:
500             return m->diBuilder->createBasicType("bool", 32 /* size */, llvm::dwarf::DW_ATE_unsigned);
501             break;
502         case TYPE_INT8:
503             return m->diBuilder->createBasicType("int8", 8 /* size */, llvm::dwarf::DW_ATE_signed);
504             break;
505         case TYPE_UINT8:
506             return m->diBuilder->createBasicType("uint8", 8 /* size */, llvm::dwarf::DW_ATE_unsigned);
507             break;
508         case TYPE_INT16:
509             return m->diBuilder->createBasicType("int16", 16 /* size */, llvm::dwarf::DW_ATE_signed);
510             break;
511         case TYPE_UINT16:
512             return m->diBuilder->createBasicType("uint16", 16 /* size */, llvm::dwarf::DW_ATE_unsigned);
513             break;
514         case TYPE_INT32:
515             return m->diBuilder->createBasicType("int32", 32 /* size */, llvm::dwarf::DW_ATE_signed);
516             break;
517         case TYPE_UINT32:
518             return m->diBuilder->createBasicType("uint32", 32 /* size */, llvm::dwarf::DW_ATE_unsigned);
519             break;
520         case TYPE_FLOAT:
521             return m->diBuilder->createBasicType("float", 32 /* size */, llvm::dwarf::DW_ATE_float);
522             break;
523         case TYPE_DOUBLE:
524             return m->diBuilder->createBasicType("double", 64 /* size */, llvm::dwarf::DW_ATE_float);
525             break;
526         case TYPE_INT64:
527             return m->diBuilder->createBasicType("int64", 64 /* size */, llvm::dwarf::DW_ATE_signed);
528             break;
529         case TYPE_UINT64:
530             return m->diBuilder->createBasicType("uint64", 64 /* size */, llvm::dwarf::DW_ATE_unsigned);
531             break;
532 
533         default:
534             FATAL("unhandled basic type in AtomicType::GetDIType()");
535 
536             return NULL;
537         }
538     } else if (variability == Variability::Varying) {
539 
540         llvm::Metadata *sub = m->diBuilder->getOrCreateSubrange(0, g->target->getVectorWidth());
541 
542         llvm::DINodeArray subArray = m->diBuilder->getOrCreateArray(sub);
543         llvm::DIType *unifType = GetAsUniformType()->GetDIType(scope);
544         uint64_t size = unifType->getSizeInBits() * g->target->getVectorWidth();
545         uint64_t align = unifType->getAlignInBits() * g->target->getVectorWidth();
546         return m->diBuilder->createVectorType(size, align, unifType, subArray);
547     } else {
548         Assert(variability == Variability::SOA);
549         ArrayType at(GetAsUniformType(), variability.soaWidth);
550         return at.GetDIType(scope);
551     }
552 }
553 
554 ///////////////////////////////////////////////////////////////////////////
555 // EnumType
556 
EnumType(SourcePos p)557 EnumType::EnumType(SourcePos p) : Type(ENUM_TYPE), pos(p) {
558     //    name = "/* (anonymous) */";
559     isConst = false;
560     variability = Variability(Variability::Unbound);
561 }
562 
EnumType(const char * n,SourcePos p)563 EnumType::EnumType(const char *n, SourcePos p) : Type(ENUM_TYPE), pos(p), name(n) {
564     isConst = false;
565     variability = Variability(Variability::Unbound);
566 }
567 
GetVariability() const568 Variability EnumType::GetVariability() const { return variability; }
569 
IsBoolType() const570 bool EnumType::IsBoolType() const { return false; }
571 
IsFloatType() const572 bool EnumType::IsFloatType() const { return false; }
573 
IsIntType() const574 bool EnumType::IsIntType() const { return true; }
575 
IsUnsignedType() const576 bool EnumType::IsUnsignedType() const { return true; }
577 
IsConstType() const578 bool EnumType::IsConstType() const { return isConst; }
579 
GetBaseType() const580 const EnumType *EnumType::GetBaseType() const { return this; }
581 
GetAsUniformType() const582 const EnumType *EnumType::GetAsUniformType() const {
583     if (IsUniformType())
584         return this;
585     else {
586         EnumType *enumType = new EnumType(*this);
587         enumType->variability = Variability::Uniform;
588         return enumType;
589     }
590 }
591 
ResolveUnboundVariability(Variability v) const592 const EnumType *EnumType::ResolveUnboundVariability(Variability v) const {
593     if (variability != Variability::Unbound)
594         return this;
595     else {
596         EnumType *enumType = new EnumType(*this);
597         enumType->variability = v;
598         return enumType;
599     }
600 }
601 
GetAsVaryingType() const602 const EnumType *EnumType::GetAsVaryingType() const {
603     if (IsVaryingType())
604         return this;
605     else {
606         EnumType *enumType = new EnumType(*this);
607         enumType->variability = Variability(Variability::Varying);
608         return enumType;
609     }
610 }
611 
GetAsUnboundVariabilityType() const612 const EnumType *EnumType::GetAsUnboundVariabilityType() const {
613     if (HasUnboundVariability())
614         return this;
615     else {
616         EnumType *enumType = new EnumType(*this);
617         enumType->variability = Variability(Variability::Unbound);
618         return enumType;
619     }
620 }
621 
GetAsSOAType(int width) const622 const EnumType *EnumType::GetAsSOAType(int width) const {
623     if (GetSOAWidth() == width)
624         return this;
625     else {
626         EnumType *enumType = new EnumType(*this);
627         enumType->variability = Variability(Variability::SOA, width);
628         return enumType;
629     }
630 }
631 
GetAsConstType() const632 const EnumType *EnumType::GetAsConstType() const {
633     if (isConst)
634         return this;
635     else {
636         EnumType *enumType = new EnumType(*this);
637         enumType->isConst = true;
638         return enumType;
639     }
640 }
641 
GetAsNonConstType() const642 const EnumType *EnumType::GetAsNonConstType() const {
643     if (!isConst)
644         return this;
645     else {
646         EnumType *enumType = new EnumType(*this);
647         enumType->isConst = false;
648         return enumType;
649     }
650 }
651 
GetString() const652 std::string EnumType::GetString() const {
653     std::string ret;
654     if (isConst)
655         ret += "const ";
656     ret += variability.GetString();
657 
658     ret += " enum ";
659     if (name.size())
660         ret += name;
661     return ret;
662 }
663 
Mangle() const664 std::string EnumType::Mangle() const {
665     Assert(variability != Variability::Unbound);
666 
667     std::string ret;
668     if (isConst)
669         ret += "C";
670     ret += variability.MangleString();
671     //    ret += std::string("enum[") + name + std::string("]");
672     ret += std::string("enum_5B_") + name + std::string("_5D_");
673     return ret;
674 }
675 
GetCDeclaration(const std::string & varName) const676 std::string EnumType::GetCDeclaration(const std::string &varName) const {
677     if (variability == Variability::Unbound) {
678         Assert(m->errorCount > 0);
679         return "";
680     }
681 
682     std::string ret;
683     if (isConst)
684         ret += "const ";
685     ret += "enum";
686     if (name.size())
687         ret += std::string(" ") + name;
688 
689     if (lShouldPrintName(varName)) {
690         ret += " ";
691         ret += varName;
692     }
693 
694     if (variability == Variability::SOA || variability == Variability::Varying) {
695         int vWidth = (variability == Variability::Varying) ? g->target->getVectorWidth() : variability.soaWidth;
696         char buf[32];
697         snprintf(buf, sizeof(buf), "[%d]", vWidth);
698         ret += buf;
699     }
700 
701     return ret;
702 }
703 
LLVMType(llvm::LLVMContext * ctx) const704 llvm::Type *EnumType::LLVMType(llvm::LLVMContext *ctx) const {
705     Assert(variability != Variability::Unbound);
706 
707     switch (variability.type) {
708     case Variability::Uniform:
709         return LLVMTypes::Int32Type;
710     case Variability::Varying:
711         return LLVMTypes::Int32VectorType;
712     case Variability::SOA: {
713         ArrayType at(AtomicType::UniformInt32, variability.soaWidth);
714         return at.LLVMType(ctx);
715     }
716     default:
717         FATAL("Unexpected variability in EnumType::LLVMType()");
718         return NULL;
719     }
720 }
721 
GetDIType(llvm::DIScope * scope) const722 llvm::DIType *EnumType::GetDIType(llvm::DIScope *scope) const {
723 
724     std::vector<llvm::Metadata *> enumeratorDescriptors;
725     for (unsigned int i = 0; i < enumerators.size(); ++i) {
726         unsigned int enumeratorValue;
727         Assert(enumerators[i]->constValue != NULL);
728         int count = enumerators[i]->constValue->GetValues(&enumeratorValue);
729         Assert(count == 1);
730 
731         llvm::Metadata *descriptor = m->diBuilder->createEnumerator(enumerators[i]->name, enumeratorValue);
732         enumeratorDescriptors.push_back(descriptor);
733     }
734 
735     llvm::DINodeArray elementArray = m->diBuilder->getOrCreateArray(enumeratorDescriptors);
736     llvm::DIFile *diFile = pos.GetDIFile();
737     llvm::DINamespace *diSpace = pos.GetDINamespace();
738     llvm::DIType *underlyingType = AtomicType::UniformInt32->GetDIType(scope);
739     llvm::DIType *diType =
740         m->diBuilder->createEnumerationType(diSpace, GetString(), diFile, pos.first_line, 32 /* size in bits */,
741                                             32 /* align in bits */, elementArray, underlyingType, name);
742     switch (variability.type) {
743     case Variability::Uniform:
744         return diType;
745     case Variability::Varying: {
746         llvm::Metadata *sub = m->diBuilder->getOrCreateSubrange(0, g->target->getVectorWidth());
747 
748         llvm::DINodeArray subArray = m->diBuilder->getOrCreateArray(sub);
749         // llvm::DebugNodeArray subArray = m->diBuilder->getOrCreateArray(sub);
750         uint64_t size = diType->getSizeInBits() * g->target->getVectorWidth();
751         uint64_t align = diType->getAlignInBits() * g->target->getVectorWidth();
752         return m->diBuilder->createVectorType(size, align, diType, subArray);
753     }
754     case Variability::SOA: {
755         return lCreateDIArray(diType, variability.soaWidth);
756     }
757     default:
758         FATAL("Unexpected variability in EnumType::GetDIType()");
759         return NULL;
760     }
761 }
762 
SetEnumerators(const std::vector<Symbol * > & e)763 void EnumType::SetEnumerators(const std::vector<Symbol *> &e) { enumerators = e; }
764 
GetEnumeratorCount() const765 int EnumType::GetEnumeratorCount() const { return (int)enumerators.size(); }
766 
GetEnumerator(int i) const767 const Symbol *EnumType::GetEnumerator(int i) const { return enumerators[i]; }
768 
769 ///////////////////////////////////////////////////////////////////////////
770 // PointerType
771 
772 PointerType *PointerType::Void = new PointerType(AtomicType::Void, Variability(Variability::Uniform), false);
773 
PointerType(const Type * t,Variability v,bool ic,bool is,bool fr)774 PointerType::PointerType(const Type *t, Variability v, bool ic, bool is, bool fr)
775     : Type(POINTER_TYPE), variability(v), isConst(ic), isSlice(is), isFrozen(fr) {
776     baseType = t;
777 }
778 
GetUniform(const Type * t,bool is)779 PointerType *PointerType::GetUniform(const Type *t, bool is) {
780     return new PointerType(t, Variability(Variability::Uniform), false, is);
781 }
782 
GetVarying(const Type * t)783 PointerType *PointerType::GetVarying(const Type *t) {
784     return new PointerType(t, Variability(Variability::Varying), false);
785 }
786 
IsVoidPointer(const Type * t)787 bool PointerType::IsVoidPointer(const Type *t) {
788     return Type::EqualIgnoringConst(t->GetAsUniformType(), PointerType::Void);
789 }
790 
GetVariability() const791 Variability PointerType::GetVariability() const { return variability; }
792 
IsBoolType() const793 bool PointerType::IsBoolType() const { return false; }
794 
IsFloatType() const795 bool PointerType::IsFloatType() const { return false; }
796 
IsIntType() const797 bool PointerType::IsIntType() const { return false; }
798 
IsUnsignedType() const799 bool PointerType::IsUnsignedType() const { return false; }
800 
IsConstType() const801 bool PointerType::IsConstType() const { return isConst; }
802 
GetBaseType() const803 const Type *PointerType::GetBaseType() const { return baseType; }
804 
GetAsVaryingType() const805 const PointerType *PointerType::GetAsVaryingType() const {
806     if (variability == Variability::Varying)
807         return this;
808     else
809         return new PointerType(baseType, Variability(Variability::Varying), isConst, isSlice, isFrozen);
810 }
811 
GetAsUniformType() const812 const PointerType *PointerType::GetAsUniformType() const {
813     if (variability == Variability::Uniform)
814         return this;
815     else
816         return new PointerType(baseType, Variability(Variability::Uniform), isConst, isSlice, isFrozen);
817 }
818 
GetAsUnboundVariabilityType() const819 const PointerType *PointerType::GetAsUnboundVariabilityType() const {
820     if (variability == Variability::Unbound)
821         return this;
822     else
823         return new PointerType(baseType, Variability(Variability::Unbound), isConst, isSlice, isFrozen);
824 }
825 
GetAsSOAType(int width) const826 const PointerType *PointerType::GetAsSOAType(int width) const {
827     if (GetSOAWidth() == width)
828         return this;
829     else
830         return new PointerType(baseType, Variability(Variability::SOA, width), isConst, isSlice, isFrozen);
831 }
832 
GetAsSlice() const833 const PointerType *PointerType::GetAsSlice() const {
834     if (isSlice)
835         return this;
836     return new PointerType(baseType, variability, isConst, true);
837 }
838 
GetAsNonSlice() const839 const PointerType *PointerType::GetAsNonSlice() const {
840     if (isSlice == false)
841         return this;
842     return new PointerType(baseType, variability, isConst, false);
843 }
844 
GetAsFrozenSlice() const845 const PointerType *PointerType::GetAsFrozenSlice() const {
846     if (isFrozen)
847         return this;
848     return new PointerType(baseType, variability, isConst, true, true);
849 }
850 
ResolveUnboundVariability(Variability v) const851 const PointerType *PointerType::ResolveUnboundVariability(Variability v) const {
852     if (baseType == NULL) {
853         Assert(m->errorCount > 0);
854         return NULL;
855     }
856 
857     Assert(v != Variability::Unbound);
858     Variability ptrVariability = (variability == Variability::Unbound) ? v : variability;
859     const Type *resolvedBaseType = baseType->ResolveUnboundVariability(Variability::Uniform);
860     return new PointerType(resolvedBaseType, ptrVariability, isConst, isSlice, isFrozen);
861 }
862 
GetAsConstType() const863 const PointerType *PointerType::GetAsConstType() const {
864     if (isConst == true)
865         return this;
866     else
867         return new PointerType(baseType, variability, true, isSlice);
868 }
869 
GetAsNonConstType() const870 const PointerType *PointerType::GetAsNonConstType() const {
871     if (isConst == false)
872         return this;
873     else
874         return new PointerType(baseType, variability, false, isSlice);
875 }
876 
GetString() const877 std::string PointerType::GetString() const {
878     if (baseType == NULL) {
879         Assert(m->errorCount > 0);
880         return "";
881     }
882 
883     std::string ret = baseType->GetString();
884 
885     ret += std::string(" * ");
886     if (isConst)
887         ret += "const ";
888     if (isSlice)
889         ret += "slice ";
890     if (isFrozen)
891         ret += "/*frozen*/ ";
892     ret += variability.GetString();
893 
894     return ret;
895 }
896 
Mangle() const897 std::string PointerType::Mangle() const {
898     Assert(variability != Variability::Unbound);
899     if (baseType == NULL) {
900         Assert(m->errorCount > 0);
901         return "";
902     }
903 
904     std::string ret = variability.MangleString() + std::string("_3C_"); // <
905     if (isSlice || isFrozen)
906         ret += "-";
907     if (isSlice)
908         ret += "s";
909     if (isFrozen)
910         ret += "f";
911     if (isSlice || isFrozen)
912         ret += "-";
913     return ret + baseType->Mangle() + std::string("_3E_"); // >
914 }
915 
GetCDeclaration(const std::string & name) const916 std::string PointerType::GetCDeclaration(const std::string &name) const {
917     if (isSlice || (variability == Variability::Unbound)) {
918         Assert(m->errorCount > 0);
919         return "";
920     }
921 
922     if (baseType == NULL) {
923         Assert(m->errorCount > 0);
924         return "";
925     }
926 
927     bool baseIsBasicVarying = (IsBasicType(baseType)) && (baseType->IsVaryingType());
928     bool baseIsFunction = (CastType<FunctionType>(baseType) != NULL);
929 
930     std::string tempName;
931     if (baseIsBasicVarying || baseIsFunction)
932         tempName += std::string("(");
933     tempName += std::string(" *");
934     if (isConst)
935         tempName += " const";
936     tempName += std::string(" ");
937     tempName += name;
938     if (baseIsBasicVarying || baseIsFunction)
939         tempName += std::string(")");
940 
941     std::string ret;
942     if (!baseIsFunction) {
943         ret = baseType->GetCDeclaration("");
944         ret += tempName;
945     } else {
946         ret += baseType->GetCDeclaration(tempName);
947     }
948     if (variability == Variability::SOA) {
949         char buf[32];
950         snprintf(buf, sizeof(buf), "[%d]", variability.soaWidth);
951         ret += buf;
952     }
953     if (baseIsBasicVarying) {
954         int vWidth = g->target->getVectorWidth();
955         char buf[32];
956         snprintf(buf, sizeof(buf), "[%d]", vWidth);
957         ret += buf;
958     }
959 
960     return ret;
961 }
962 
LLVMType(llvm::LLVMContext * ctx) const963 llvm::Type *PointerType::LLVMType(llvm::LLVMContext *ctx) const {
964     if (baseType == NULL) {
965         Assert(m->errorCount > 0);
966         return NULL;
967     }
968 
969     if (isSlice) {
970         llvm::Type *types[2];
971         types[0] = GetAsNonSlice()->LLVMStorageType(ctx);
972 
973         switch (variability.type) {
974         case Variability::Uniform:
975             types[1] = LLVMTypes::Int32Type;
976             break;
977         case Variability::Varying:
978             types[1] = LLVMTypes::Int32VectorType;
979             break;
980         case Variability::SOA:
981             types[1] = llvm::ArrayType::get(LLVMTypes::Int32Type, variability.soaWidth);
982             break;
983         default:
984             FATAL("unexpected variability for slice pointer in "
985                   "PointerType::LLVMType");
986         }
987 
988         llvm::ArrayRef<llvm::Type *> typesArrayRef = llvm::ArrayRef<llvm::Type *>(types, 2);
989         return llvm::StructType::get(*g->ctx, typesArrayRef);
990     }
991 
992     switch (variability.type) {
993     case Variability::Uniform: {
994         llvm::Type *ptype = NULL;
995         const FunctionType *ftype = CastType<FunctionType>(baseType);
996         if (ftype != NULL)
997             ptype = llvm::PointerType::get(ftype->LLVMFunctionType(ctx), 0);
998         else {
999             if (baseType->IsVoidType())
1000                 ptype = LLVMTypes::VoidPointerType;
1001             else
1002                 ptype = llvm::PointerType::get(baseType->LLVMStorageType(ctx), 0);
1003         }
1004         return ptype;
1005     }
1006     case Variability::Varying:
1007         // always the same, since we currently use int vectors for varying
1008         // pointers
1009         return LLVMTypes::VoidPointerVectorType;
1010     case Variability::SOA: {
1011         ArrayType at(GetAsUniformType(), variability.soaWidth);
1012         return at.LLVMType(ctx);
1013     }
1014     default:
1015         FATAL("Unexpected variability in PointerType::LLVMType()");
1016         return NULL;
1017     }
1018 }
1019 
GetDIType(llvm::DIScope * scope) const1020 llvm::DIType *PointerType::GetDIType(llvm::DIScope *scope) const {
1021     if (baseType == NULL) {
1022         Assert(m->errorCount > 0);
1023         return NULL;
1024     }
1025     llvm::DIType *diTargetType = baseType->GetDIType(scope);
1026     int bitsSize = g->target->is32Bit() ? 32 : 64;
1027     int ptrAlignBits = bitsSize;
1028     switch (variability.type) {
1029     case Variability::Uniform:
1030         return m->diBuilder->createPointerType(diTargetType, bitsSize, ptrAlignBits);
1031     case Variability::Varying: {
1032         // emit them as an array of pointers
1033         llvm::DIDerivedType *eltType = m->diBuilder->createPointerType(diTargetType, bitsSize, ptrAlignBits);
1034         return lCreateDIArray(eltType, g->target->getVectorWidth());
1035     }
1036     case Variability::SOA: {
1037         ArrayType at(GetAsUniformType(), variability.soaWidth);
1038         return at.GetDIType(scope);
1039     }
1040     default:
1041         FATAL("Unexpected variability in PointerType::GetDIType()");
1042         return NULL;
1043     }
1044 }
1045 
1046 ///////////////////////////////////////////////////////////////////////////
1047 // SequentialType
1048 
GetElementType(int index) const1049 const Type *SequentialType::GetElementType(int index) const { return GetElementType(); }
1050 
1051 ///////////////////////////////////////////////////////////////////////////
1052 // ArrayType
1053 
ArrayType(const Type * c,int a)1054 ArrayType::ArrayType(const Type *c, int a) : SequentialType(ARRAY_TYPE), child(c), numElements(a) {
1055     // 0 -> unsized array.
1056     Assert(numElements >= 0);
1057     Assert(c->IsVoidType() == false);
1058 }
1059 
LLVMType(llvm::LLVMContext * ctx) const1060 llvm::ArrayType *ArrayType::LLVMType(llvm::LLVMContext *ctx) const {
1061     if (child == NULL) {
1062         Assert(m->errorCount > 0);
1063         return NULL;
1064     }
1065 
1066     llvm::Type *ct = child->LLVMStorageType(ctx);
1067     if (ct == NULL) {
1068         Assert(m->errorCount > 0);
1069         return NULL;
1070     }
1071     return llvm::ArrayType::get(ct, numElements);
1072 }
1073 
GetVariability() const1074 Variability ArrayType::GetVariability() const {
1075     return child ? child->GetVariability() : Variability(Variability::Uniform);
1076 }
1077 
IsFloatType() const1078 bool ArrayType::IsFloatType() const { return false; }
1079 
IsIntType() const1080 bool ArrayType::IsIntType() const { return false; }
1081 
IsUnsignedType() const1082 bool ArrayType::IsUnsignedType() const { return false; }
1083 
IsBoolType() const1084 bool ArrayType::IsBoolType() const { return false; }
1085 
IsConstType() const1086 bool ArrayType::IsConstType() const { return child ? child->IsConstType() : false; }
1087 
GetBaseType() const1088 const Type *ArrayType::GetBaseType() const {
1089     const Type *type = child;
1090     const ArrayType *at = CastType<ArrayType>(type);
1091     // Keep walking until we reach a child that isn't itself an array
1092     while (at) {
1093         type = at->child;
1094         at = CastType<ArrayType>(type);
1095     }
1096     return type;
1097 }
1098 
GetAsVaryingType() const1099 const ArrayType *ArrayType::GetAsVaryingType() const {
1100     if (child == NULL) {
1101         Assert(m->errorCount > 0);
1102         return NULL;
1103     }
1104     return new ArrayType(child->GetAsVaryingType(), numElements);
1105 }
1106 
GetAsUniformType() const1107 const ArrayType *ArrayType::GetAsUniformType() const {
1108     if (child == NULL) {
1109         Assert(m->errorCount > 0);
1110         return NULL;
1111     }
1112     return new ArrayType(child->GetAsUniformType(), numElements);
1113 }
1114 
GetAsUnboundVariabilityType() const1115 const ArrayType *ArrayType::GetAsUnboundVariabilityType() const {
1116     if (child == NULL) {
1117         Assert(m->errorCount > 0);
1118         return NULL;
1119     }
1120     return new ArrayType(child->GetAsUnboundVariabilityType(), numElements);
1121 }
1122 
GetAsSOAType(int width) const1123 const ArrayType *ArrayType::GetAsSOAType(int width) const {
1124     if (child == NULL) {
1125         Assert(m->errorCount > 0);
1126         return NULL;
1127     }
1128     return new ArrayType(child->GetAsSOAType(width), numElements);
1129 }
1130 
ResolveUnboundVariability(Variability v) const1131 const ArrayType *ArrayType::ResolveUnboundVariability(Variability v) const {
1132     if (child == NULL) {
1133         Assert(m->errorCount > 0);
1134         return NULL;
1135     }
1136     return new ArrayType(child->ResolveUnboundVariability(v), numElements);
1137 }
1138 
GetAsUnsignedType() const1139 const ArrayType *ArrayType::GetAsUnsignedType() const {
1140     if (child == NULL) {
1141         Assert(m->errorCount > 0);
1142         return NULL;
1143     }
1144     return new ArrayType(child->GetAsUnsignedType(), numElements);
1145 }
1146 
GetAsConstType() const1147 const ArrayType *ArrayType::GetAsConstType() const {
1148     if (child == NULL) {
1149         Assert(m->errorCount > 0);
1150         return NULL;
1151     }
1152     return new ArrayType(child->GetAsConstType(), numElements);
1153 }
1154 
GetAsNonConstType() const1155 const ArrayType *ArrayType::GetAsNonConstType() const {
1156     if (child == NULL) {
1157         Assert(m->errorCount > 0);
1158         return NULL;
1159     }
1160     return new ArrayType(child->GetAsNonConstType(), numElements);
1161 }
1162 
GetElementCount() const1163 int ArrayType::GetElementCount() const { return numElements; }
1164 
GetElementType() const1165 const Type *ArrayType::GetElementType() const { return child; }
1166 
GetString() const1167 std::string ArrayType::GetString() const {
1168     const Type *base = GetBaseType();
1169     if (base == NULL) {
1170         Assert(m->errorCount > 0);
1171         return "";
1172     }
1173     std::string s = base->GetString();
1174 
1175     const ArrayType *at = this;
1176     Assert(at);
1177     // Walk through this and any children arrays and print all of their
1178     // dimensions
1179     while (at) {
1180         char buf[16];
1181         if (at->numElements > 0)
1182             snprintf(buf, sizeof(buf), "%d", at->numElements);
1183         else
1184             buf[0] = '\0';
1185         s += std::string("[") + std::string(buf) + std::string("]");
1186         at = CastType<ArrayType>(at->child);
1187     }
1188     return s;
1189 }
1190 
Mangle() const1191 std::string ArrayType::Mangle() const {
1192     if (child == NULL) {
1193         Assert(m->errorCount > 0);
1194         return "(error)";
1195     }
1196     std::string s = child->Mangle();
1197     char buf[16];
1198     if (numElements > 0)
1199         snprintf(buf, sizeof(buf), "%d", numElements);
1200     else
1201         buf[0] = '\0';
1202     //    return s + "[" + buf + "]";
1203     return s + "_5B_" + buf + "_5D_";
1204 }
1205 
GetCDeclaration(const std::string & name) const1206 std::string ArrayType::GetCDeclaration(const std::string &name) const {
1207     const Type *base = GetBaseType();
1208     if (base == NULL) {
1209         Assert(m->errorCount > 0);
1210         return "";
1211     }
1212 
1213     int soaWidth = base->GetSOAWidth();
1214     int vWidth = (base->IsVaryingType()) ? g->target->getVectorWidth() : 0;
1215     base = base->GetAsUniformType();
1216 
1217     std::string s = base->GetCDeclaration(name);
1218 
1219     const ArrayType *at = this;
1220     Assert(at);
1221     while (at) {
1222         char buf[16];
1223         if (at->numElements > 0)
1224             snprintf(buf, sizeof(buf), "%d", at->numElements);
1225         else
1226             buf[0] = '\0';
1227         s += std::string("[") + std::string(buf) + std::string("]");
1228         at = CastType<ArrayType>(at->child);
1229     }
1230 
1231     if (soaWidth > 0) {
1232         char buf[16];
1233         snprintf(buf, sizeof(buf), "[%d]", soaWidth);
1234         s += buf;
1235     }
1236 
1237     if (vWidth > 0) {
1238         char buf[16];
1239         snprintf(buf, sizeof(buf), "[%d]", vWidth);
1240         s += buf;
1241     }
1242 
1243     return s;
1244 }
1245 
TotalElementCount() const1246 int ArrayType::TotalElementCount() const {
1247     const ArrayType *ct = CastType<ArrayType>(child);
1248     if (ct != NULL)
1249         return numElements * ct->TotalElementCount();
1250     else
1251         return numElements;
1252 }
1253 
GetDIType(llvm::DIScope * scope) const1254 llvm::DIType *ArrayType::GetDIType(llvm::DIScope *scope) const {
1255     if (child == NULL) {
1256         Assert(m->errorCount > 0);
1257         return NULL;
1258     }
1259     llvm::DIType *eltType = child->GetDIType(scope);
1260     return lCreateDIArray(eltType, numElements);
1261 }
1262 
GetSizedArray(int sz) const1263 ArrayType *ArrayType::GetSizedArray(int sz) const {
1264     Assert(numElements == 0);
1265     return new ArrayType(child, sz);
1266 }
1267 
SizeUnsizedArrays(const Type * type,Expr * initExpr)1268 const Type *ArrayType::SizeUnsizedArrays(const Type *type, Expr *initExpr) {
1269     const ArrayType *at = CastType<ArrayType>(type);
1270     if (at == NULL)
1271         return type;
1272 
1273     ExprList *exprList = llvm::dyn_cast_or_null<ExprList>(initExpr);
1274     if (exprList == NULL || exprList->exprs.size() == 0)
1275         return type;
1276 
1277     // If the current dimension is unsized, then size it according to the
1278     // length of the expression list
1279     if (at->GetElementCount() == 0) {
1280         type = at->GetSizedArray(exprList->exprs.size());
1281         at = CastType<ArrayType>(type);
1282     }
1283 
1284     // Is there another nested level of expression lists?  If not, bail out
1285     // now.  Otherwise we'll use the first one to size the next dimension
1286     // (after checking below that it has the same length as all of the
1287     // other ones.
1288     ExprList *nextList = llvm::dyn_cast_or_null<ExprList>(exprList->exprs[0]);
1289     if (nextList == NULL)
1290         return type;
1291 
1292     const Type *nextType = at->GetElementType();
1293     const ArrayType *nextArrayType = CastType<ArrayType>(nextType);
1294     if (nextArrayType != NULL && nextArrayType->GetElementCount() == 0) {
1295         // If the recursive call to SizeUnsizedArrays at the bottom of the
1296         // function is going to size an unsized dimension, make sure that
1297         // all of the sub-expression lists are the same length--i.e. issue
1298         // an error if we have something like
1299         // int x[][] = { { 1 }, { 1, 2, 3, 4 } };
1300         unsigned int nextSize = nextList->exprs.size();
1301         for (unsigned int i = 1; i < exprList->exprs.size(); ++i) {
1302             if (exprList->exprs[i] == NULL) {
1303                 // We should have seen an error earlier in this case.
1304                 Assert(m->errorCount > 0);
1305                 continue;
1306             }
1307 
1308             ExprList *el = llvm::dyn_cast_or_null<ExprList>(exprList->exprs[i]);
1309             if (el == NULL || el->exprs.size() != nextSize) {
1310                 Error(Union(exprList->exprs[0]->pos, exprList->exprs[i]->pos),
1311                       "Inconsistent initializer expression list lengths "
1312                       "make it impossible to size unsized array dimensions.");
1313                 return NULL;
1314             }
1315         }
1316     }
1317 
1318     // Recursively call SizeUnsizedArrays() to get the child type for the
1319     // array that we were able to size here.
1320     return new ArrayType(SizeUnsizedArrays(at->GetElementType(), nextList), at->GetElementCount());
1321 }
1322 
1323 ///////////////////////////////////////////////////////////////////////////
1324 // VectorType
1325 
VectorType(const AtomicType * b,int a)1326 VectorType::VectorType(const AtomicType *b, int a) : SequentialType(VECTOR_TYPE), base(b), numElements(a) {
1327     Assert(numElements > 0);
1328     Assert(base != NULL);
1329 }
1330 
GetVariability() const1331 Variability VectorType::GetVariability() const { return base->GetVariability(); }
1332 
IsFloatType() const1333 bool VectorType::IsFloatType() const { return base->IsFloatType(); }
1334 
IsIntType() const1335 bool VectorType::IsIntType() const { return base->IsIntType(); }
1336 
IsUnsignedType() const1337 bool VectorType::IsUnsignedType() const { return base->IsUnsignedType(); }
1338 
IsBoolType() const1339 bool VectorType::IsBoolType() const { return base->IsBoolType(); }
1340 
IsConstType() const1341 bool VectorType::IsConstType() const { return base->IsConstType(); }
1342 
GetBaseType() const1343 const Type *VectorType::GetBaseType() const { return base; }
1344 
GetAsVaryingType() const1345 const VectorType *VectorType::GetAsVaryingType() const { return new VectorType(base->GetAsVaryingType(), numElements); }
1346 
GetAsUniformType() const1347 const VectorType *VectorType::GetAsUniformType() const { return new VectorType(base->GetAsUniformType(), numElements); }
1348 
GetAsUnboundVariabilityType() const1349 const VectorType *VectorType::GetAsUnboundVariabilityType() const {
1350     return new VectorType(base->GetAsUnboundVariabilityType(), numElements);
1351 }
1352 
GetAsSOAType(int width) const1353 const VectorType *VectorType::GetAsSOAType(int width) const {
1354     return new VectorType(base->GetAsSOAType(width), numElements);
1355 }
1356 
ResolveUnboundVariability(Variability v) const1357 const VectorType *VectorType::ResolveUnboundVariability(Variability v) const {
1358     return new VectorType(base->ResolveUnboundVariability(v), numElements);
1359 }
1360 
GetAsUnsignedType() const1361 const VectorType *VectorType::GetAsUnsignedType() const {
1362     if (base == NULL) {
1363         Assert(m->errorCount > 0);
1364         return NULL;
1365     }
1366     return new VectorType(base->GetAsUnsignedType(), numElements);
1367 }
1368 
GetAsConstType() const1369 const VectorType *VectorType::GetAsConstType() const { return new VectorType(base->GetAsConstType(), numElements); }
1370 
GetAsNonConstType() const1371 const VectorType *VectorType::GetAsNonConstType() const {
1372     return new VectorType(base->GetAsNonConstType(), numElements);
1373 }
1374 
GetString() const1375 std::string VectorType::GetString() const {
1376     std::string s = base->GetString();
1377     char buf[16];
1378     snprintf(buf, sizeof(buf), "<%d>", numElements);
1379     return s + std::string(buf);
1380 }
1381 
Mangle() const1382 std::string VectorType::Mangle() const {
1383     std::string s = base->Mangle();
1384     char buf[16];
1385     snprintf(buf, sizeof(buf), "_3C_%d_3E_", numElements); // "<%d>"
1386     return s + std::string(buf);
1387 }
1388 
GetCDeclaration(const std::string & name) const1389 std::string VectorType::GetCDeclaration(const std::string &name) const {
1390     std::string s = base->GetCDeclaration("");
1391     char buf[16];
1392     snprintf(buf, sizeof(buf), "%d", numElements);
1393     return s + std::string(buf) + "  " + name;
1394 }
1395 
GetElementCount() const1396 int VectorType::GetElementCount() const { return numElements; }
1397 
GetElementType() const1398 const AtomicType *VectorType::GetElementType() const { return base; }
1399 
lGetVectorLLVMType(llvm::LLVMContext * ctx,const VectorType * vType,bool isStorage)1400 static llvm::Type *lGetVectorLLVMType(llvm::LLVMContext *ctx, const VectorType *vType, bool isStorage) {
1401 
1402     const Type *base = vType->GetBaseType();
1403     int numElements = vType->GetElementCount();
1404 
1405     if (base == NULL) {
1406         Assert(m->errorCount > 0);
1407         return NULL;
1408     }
1409 
1410     llvm::Type *bt;
1411     // Non-uniform vector types are represented in IR as an array.
1412     // So, creating them with base as storage type similar to arrays.
1413     if (isStorage || !base->IsUniformType())
1414         bt = base->LLVMStorageType(ctx);
1415     else
1416         bt = base->LLVMType(ctx);
1417     if (!bt)
1418         return NULL;
1419 
1420     if (base->IsUniformType())
1421         // Vectors of uniform types are laid out across LLVM vectors, with
1422         // the llvm vector size set to be a power of 2 bits in size but not less then 128 bit.
1423         // This is a roundabout way of ensuring that LLVM lays
1424         // them out into machine vector registers for the specified target
1425         // so that e.g. if we want to add two uniform 4 float
1426         // vectors, that is turned into a single addps on SSE.
1427         return LLVMVECTOR::get(bt, vType->getVectorMemoryCount());
1428     else if (base->IsVaryingType())
1429         // varying types are already laid out to fill HW vector registers,
1430         // so a vector type here is just expanded out as an llvm array.
1431         return llvm::ArrayType::get(bt, vType->getVectorMemoryCount());
1432     else if (base->IsSOAType())
1433         return llvm::ArrayType::get(bt, numElements);
1434     else {
1435         FATAL("Unexpected variability in lGetVectorLLVMType()");
1436         return NULL;
1437     }
1438 }
1439 
LLVMStorageType(llvm::LLVMContext * ctx) const1440 llvm::Type *VectorType::LLVMStorageType(llvm::LLVMContext *ctx) const { return lGetVectorLLVMType(ctx, this, true); }
1441 
LLVMType(llvm::LLVMContext * ctx) const1442 llvm::Type *VectorType::LLVMType(llvm::LLVMContext *ctx) const { return lGetVectorLLVMType(ctx, this, false); }
1443 
GetDIType(llvm::DIScope * scope) const1444 llvm::DIType *VectorType::GetDIType(llvm::DIScope *scope) const {
1445     llvm::DIType *eltType = base->GetDIType(scope);
1446 
1447     llvm::Metadata *sub = m->diBuilder->getOrCreateSubrange(0, numElements);
1448 
1449     // vectors of varying types are already naturally aligned to the
1450     // machine's vector width, but arrays of uniform types need to be
1451     // explicitly aligned to the machines natural vector alignment.
1452 
1453     llvm::DINodeArray subArray = m->diBuilder->getOrCreateArray(sub);
1454     uint64_t sizeBits = eltType->getSizeInBits() * numElements;
1455     uint64_t align = eltType->getAlignInBits();
1456 
1457     if (IsUniformType()) {
1458         llvm::Type *ty = this->LLVMType(g->ctx);
1459         align = g->target->getDataLayout()->getABITypeAlignment(ty);
1460     }
1461 
1462     if (IsUniformType() || IsVaryingType())
1463         return m->diBuilder->createVectorType(sizeBits, align, eltType, subArray);
1464     else if (IsSOAType()) {
1465         ArrayType at(base, numElements);
1466         return at.GetDIType(scope);
1467     } else {
1468         FATAL("Unexpected variability in VectorType::GetDIType()");
1469         return NULL;
1470     }
1471 }
1472 
getVectorMemoryCount() const1473 int VectorType::getVectorMemoryCount() const {
1474     if (base->IsVaryingType())
1475         return numElements;
1476     else if (base->IsUniformType()) {
1477         // Round up the element count to power of 2 bits in size but not less then 128 bit in total vector size
1478         // where one element size is data type width in bits.
1479         // This strategy was chosen by the following reasons:
1480         // 1. We need to return the same number of vector elements regardless the element size for correct work of the
1481         // language.
1482         // 2. Using next power of two, but not less than 128 bit in total vector size ensures that machine vector
1483         // registers are used. It generally leads to better performance. This strategy also matches OpenCL short
1484         // vectors.
1485         // 3. Using data type width of the target to determine element size makes optimization trade off.
1486         int nextPow2 = llvm::NextPowerOf2(numElements - 1);
1487         return (nextPow2 * g->target->getDataTypeWidth() < 128) ? (128 / g->target->getDataTypeWidth()) : nextPow2;
1488     } else if (base->IsSOAType()) {
1489         FATAL("VectorType SOA getVectorMemoryCount");
1490         return -1;
1491     } else {
1492         FATAL("Unexpected variability in VectorType::getVectorMemoryCount()");
1493         return -1;
1494     }
1495 }
1496 
1497 ///////////////////////////////////////////////////////////////////////////
1498 // StructType
1499 
1500 // We maintain a map from struct names to LLVM struct types so that we can
1501 // uniquely get the llvm::StructType * for a given ispc struct type.  Note
1502 // that we need to mangle the name a bit so that we can e.g. differentiate
1503 // between the uniform and varying variants of a given struct type.  This
1504 // is handled by lMangleStructName() below.
1505 static std::map<std::string, llvm::StructType *> lStructTypeMap;
1506 
1507 /** Using a struct's name, its variability, and the vector width for the
1508     current compilation target, this function generates a string that
1509     encodes that full structure type, for use in the lStructTypeMap.  Note
1510     that the vector width is needed in order to differentiate between
1511     'varying' structs with different compilation targets, which have
1512     different memory layouts...
1513  */
lMangleStructName(const std::string & name,Variability variability)1514 static std::string lMangleStructName(const std::string &name, Variability variability) {
1515     char buf[32];
1516     std::string n;
1517 
1518     // Encode vector width
1519     snprintf(buf, sizeof(buf), "v%d", g->target->getVectorWidth());
1520 
1521     n += buf;
1522 
1523     // Variability
1524     switch (variability.type) {
1525     case Variability::Uniform:
1526         n += "_uniform_";
1527         break;
1528     case Variability::Varying:
1529         n += "_varying_";
1530         break;
1531     case Variability::SOA:
1532         snprintf(buf, sizeof(buf), "_soa%d_", variability.soaWidth);
1533         n += buf;
1534         break;
1535     default:
1536         FATAL("Unexpected variability in lMangleStructName()");
1537     }
1538 
1539     // And stuff the name at the end....
1540     n += name;
1541     return n;
1542 }
1543 
StructType(const std::string & n,const llvm::SmallVector<const Type *,8> & elts,const llvm::SmallVector<std::string,8> & en,const llvm::SmallVector<SourcePos,8> & ep,bool ic,Variability v,bool ia,SourcePos p)1544 StructType::StructType(const std::string &n, const llvm::SmallVector<const Type *, 8> &elts,
1545                        const llvm::SmallVector<std::string, 8> &en, const llvm::SmallVector<SourcePos, 8> &ep, bool ic,
1546                        Variability v, bool ia, SourcePos p)
1547     : CollectionType(STRUCT_TYPE), name(n), elementTypes(elts), elementNames(en), elementPositions(ep), variability(v),
1548       isConst(ic), isAnonymous(ia), pos(p) {
1549     oppositeConstStructType = NULL;
1550     finalElementTypes.resize(elts.size(), NULL);
1551 
1552     static int count = 0;
1553     if (variability != Variability::Unbound) {
1554         // For structs with non-unbound variability, we'll create the
1555         // correspoing LLVM struct type now, if one hasn't been made
1556         // already.
1557 
1558         // Create a unique anonymous struct name if we have an anonymous
1559         // struct (name == "").
1560         if (name == "") {
1561             char buf[16];
1562             snprintf(buf, sizeof(buf), "$anon%d", count);
1563             name = std::string(buf);
1564             ++count;
1565         }
1566 
1567         // If a non-opaque LLVM struct for this type has already been
1568         // created, we're done.  For an opaque struct type, we'll override
1569         // the old definition now that we have a full definition.
1570         std::string mname = lMangleStructName(name, variability);
1571         if (lStructTypeMap.find(mname) != lStructTypeMap.end() && lStructTypeMap[mname]->isOpaque() == false)
1572             return;
1573 
1574         // Actually make the LLVM struct
1575         std::vector<llvm::Type *> elementTypes;
1576         int nElements = GetElementCount();
1577         if (nElements == 0) {
1578             elementTypes.push_back(LLVMTypes::Int8Type);
1579         } else {
1580             for (int i = 0; i < nElements; ++i) {
1581                 const Type *type = GetElementType(i);
1582                 if (type == NULL) {
1583                     Assert(m->errorCount > 0);
1584                     return;
1585                 } else if (CastType<FunctionType>(type) != NULL) {
1586                     Error(elementPositions[i], "Method declarations are not "
1587                                                "supported.");
1588                     return;
1589                 } else
1590                     elementTypes.push_back(type->LLVMStorageType(g->ctx));
1591             }
1592         }
1593 
1594         if (lStructTypeMap.find(mname) == lStructTypeMap.end()) {
1595             // New struct definition
1596             llvm::StructType *st = llvm::StructType::create(*g->ctx, elementTypes, mname);
1597             lStructTypeMap[mname] = st;
1598         } else {
1599             // Definition for what was before just a declaration
1600             lStructTypeMap[mname]->setBody(elementTypes);
1601         }
1602     }
1603     // Create a unique anonymous struct name if we have an anonymous struct (name == "")
1604     // Ensuring struct is created with a name, prevents each use of original
1605     // struct from having different names causing type match errors.
1606     if (name == "") {
1607         char buf[16];
1608         snprintf(buf, sizeof(buf), "$anon%d", count);
1609         name = std::string(buf);
1610         ++count;
1611     }
1612 }
1613 
GetCStructName() const1614 const std::string StructType::GetCStructName() const {
1615     // only return mangled name for varying structs for backwards
1616     // compatibility...
1617 
1618     if (variability == Variability::Varying) {
1619         return lMangleStructName(name, variability);
1620     } else {
1621         return GetStructName();
1622     }
1623 }
1624 
GetVariability() const1625 Variability StructType::GetVariability() const { return variability; }
1626 
IsBoolType() const1627 bool StructType::IsBoolType() const { return false; }
1628 
IsFloatType() const1629 bool StructType::IsFloatType() const { return false; }
1630 
IsIntType() const1631 bool StructType::IsIntType() const { return false; }
1632 
IsUnsignedType() const1633 bool StructType::IsUnsignedType() const { return false; }
1634 
IsConstType() const1635 bool StructType::IsConstType() const { return isConst; }
1636 
IsDefined() const1637 bool StructType::IsDefined() const {
1638     for (int i = 0; i < GetElementCount(); i++) {
1639         const Type *t = GetElementType(i);
1640         const UndefinedStructType *ust = CastType<UndefinedStructType>(t);
1641         if (ust != NULL) {
1642             return false;
1643         }
1644         const StructType *st = CastType<StructType>(t);
1645         if (st != NULL) {
1646             if (!st->IsDefined()) {
1647                 return false;
1648             }
1649         }
1650     }
1651     return true;
1652 }
1653 
GetBaseType() const1654 const Type *StructType::GetBaseType() const { return this; }
1655 
GetAsVaryingType() const1656 const StructType *StructType::GetAsVaryingType() const {
1657     if (IsVaryingType())
1658         return this;
1659     else
1660         return new StructType(name, elementTypes, elementNames, elementPositions, isConst,
1661                               Variability(Variability::Varying), isAnonymous, pos);
1662 }
1663 
GetAsUniformType() const1664 const StructType *StructType::GetAsUniformType() const {
1665     if (IsUniformType())
1666         return this;
1667     else
1668         return new StructType(name, elementTypes, elementNames, elementPositions, isConst,
1669                               Variability(Variability::Uniform), isAnonymous, pos);
1670 }
1671 
GetAsUnboundVariabilityType() const1672 const StructType *StructType::GetAsUnboundVariabilityType() const {
1673     if (HasUnboundVariability())
1674         return this;
1675     else
1676         return new StructType(name, elementTypes, elementNames, elementPositions, isConst,
1677                               Variability(Variability::Unbound), isAnonymous, pos);
1678 }
1679 
GetAsSOAType(int width) const1680 const StructType *StructType::GetAsSOAType(int width) const {
1681     if (GetSOAWidth() == width)
1682         return this;
1683 
1684     if (checkIfCanBeSOA(this) == false)
1685         return NULL;
1686 
1687     return new StructType(name, elementTypes, elementNames, elementPositions, isConst,
1688                           Variability(Variability::SOA, width), isAnonymous, pos);
1689 }
1690 
ResolveUnboundVariability(Variability v) const1691 const StructType *StructType::ResolveUnboundVariability(Variability v) const {
1692     Assert(v != Variability::Unbound);
1693 
1694     if (variability != Variability::Unbound)
1695         return this;
1696 
1697     // We don't resolve the members here but leave them unbound, so that if
1698     // resolve to varying but later want to get the uniform version of this
1699     // type, for example, then we still have the information around about
1700     // which element types were originally unbound...
1701     return new StructType(name, elementTypes, elementNames, elementPositions, isConst, v, isAnonymous, pos);
1702 }
1703 
GetAsConstType() const1704 const StructType *StructType::GetAsConstType() const {
1705     if (isConst == true)
1706         return this;
1707     else if (oppositeConstStructType != NULL)
1708         return oppositeConstStructType;
1709     else {
1710         oppositeConstStructType =
1711             new StructType(name, elementTypes, elementNames, elementPositions, true, variability, isAnonymous, pos);
1712         oppositeConstStructType->oppositeConstStructType = this;
1713         return oppositeConstStructType;
1714     }
1715 }
1716 
GetAsNonConstType() const1717 const StructType *StructType::GetAsNonConstType() const {
1718     if (isConst == false)
1719         return this;
1720     else if (oppositeConstStructType != NULL)
1721         return oppositeConstStructType;
1722     else {
1723         oppositeConstStructType =
1724             new StructType(name, elementTypes, elementNames, elementPositions, false, variability, isAnonymous, pos);
1725         oppositeConstStructType->oppositeConstStructType = this;
1726         return oppositeConstStructType;
1727     }
1728 }
1729 
GetString() const1730 std::string StructType::GetString() const {
1731     std::string ret;
1732     if (isConst)
1733         ret += "const ";
1734     ret += variability.GetString();
1735     ret += " struct ";
1736 
1737     if (isAnonymous) {
1738         // Print the whole anonymous struct declaration
1739         ret += name + std::string(" { ");
1740         for (unsigned int i = 0; i < elementTypes.size(); ++i) {
1741             ret += elementTypes[i]->GetString();
1742             ret += " ";
1743             ret += elementNames[i];
1744             ret += "; ";
1745         }
1746         ret += "}";
1747     } else {
1748         ret += name;
1749     }
1750 
1751     return ret;
1752 }
1753 
1754 /** Mangle a struct name for use in function name mangling. */
lMangleStruct(Variability variability,bool isConst,const std::string & name)1755 static std::string lMangleStruct(Variability variability, bool isConst, const std::string &name) {
1756     Assert(variability != Variability::Unbound);
1757 
1758     std::string ret;
1759     //    ret += "s[";
1760     ret += "s_5B_";
1761     if (isConst)
1762         ret += "_c_";
1763     ret += variability.MangleString();
1764 
1765     //    ret += name + std::string("]");
1766     ret += name + std::string("_5D_");
1767     return ret;
1768 }
1769 
Mangle() const1770 std::string StructType::Mangle() const { return lMangleStruct(variability, isConst, name); }
1771 
GetCDeclaration(const std::string & n) const1772 std::string StructType::GetCDeclaration(const std::string &n) const {
1773     std::string ret;
1774     if (isConst)
1775         ret += "const ";
1776     ret += std::string("struct ") + GetCStructName();
1777 
1778     // Add _SOA<SOAWIDTH> to end of struct name.
1779     if (variability.soaWidth > 0) {
1780         char buf[32];
1781         // This has to match the naming scheme used in lEmitStructDecls()
1782         // in module.cpp
1783         snprintf(buf, sizeof(buf), "_SOA%d", variability.soaWidth);
1784         ret += buf;
1785     }
1786 
1787     if (lShouldPrintName(n)) {
1788         ret += std::string(" ") + n;
1789     }
1790 
1791     return ret;
1792 }
1793 
LLVMType(llvm::LLVMContext * ctx) const1794 llvm::Type *StructType::LLVMType(llvm::LLVMContext *ctx) const {
1795     Assert(variability != Variability::Unbound);
1796     std::string mname = lMangleStructName(name, variability);
1797     if (lStructTypeMap.find(mname) == lStructTypeMap.end()) {
1798         Assert(m->errorCount > 0);
1799         return NULL;
1800     }
1801     return lStructTypeMap[mname];
1802 }
1803 
1804 // Versioning of this function becomes really messy, so versioning the whole function.
GetDIType(llvm::DIScope * scope) const1805 llvm::DIType *StructType::GetDIType(llvm::DIScope *scope) const {
1806     llvm::Type *llvm_type = LLVMStorageType(g->ctx);
1807     auto &dataLayout = m->module->getDataLayout();
1808     auto layout = dataLayout.getStructLayout(llvm::dyn_cast_or_null<llvm::StructType>(llvm_type));
1809     std::vector<llvm::Metadata *> elementLLVMTypes;
1810     // Walk through the elements of the struct; for each one figure out its
1811     // alignment and size, using that to figure out its offset w.r.t. the
1812     // start of the structure.
1813     for (unsigned int i = 0; i < elementTypes.size(); ++i) {
1814         llvm::DIType *eltType = GetElementType(i)->GetDIType(scope);
1815         uint64_t eltSize = eltType->getSizeInBits();
1816 
1817         auto llvmType = GetElementType(i)->LLVMStorageType(g->ctx);
1818         uint64_t eltAlign = dataLayout.getABITypeAlignment(llvmType) * 8;
1819         Assert(eltAlign != 0);
1820 
1821         auto eltOffset = layout->getElementOffsetInBits(i);
1822 
1823         int line = elementPositions[i].first_line;
1824         llvm::DIFile *diFile = elementPositions[i].GetDIFile();
1825         llvm::DIDerivedType *fieldType = m->diBuilder->createMemberType(
1826             scope, elementNames[i], diFile, line, eltSize, eltAlign, eltOffset, llvm::DINode::FlagZero, eltType);
1827         elementLLVMTypes.push_back(fieldType);
1828     }
1829 
1830     llvm::DINodeArray elements = m->diBuilder->getOrCreateArray(elementLLVMTypes);
1831     llvm::DIFile *diFile = pos.GetDIFile();
1832     llvm::DINamespace *diSpace = pos.GetDINamespace();
1833     return m->diBuilder->createStructType(diSpace, GetString(), diFile,
1834                                           pos.first_line,                     // Line number
1835                                           layout->getSizeInBits(),            // Size in bits
1836                                           layout->getAlignment().value() * 8, // Alignment in bits
1837                                           llvm::DINode::FlagZero,             // Flags
1838                                           NULL, elements);
1839 }
1840 
GetElementType(int i) const1841 const Type *StructType::GetElementType(int i) const {
1842     Assert(variability != Variability::Unbound);
1843     Assert(i < (int)elementTypes.size());
1844 
1845     if (finalElementTypes[i] == NULL) {
1846         const Type *type = elementTypes[i];
1847         if (type == NULL) {
1848             Assert(m->errorCount > 0);
1849             return NULL;
1850         }
1851 
1852         // If the element has unbound variability, resolve its variability to
1853         // the struct type's variability
1854         type = type->ResolveUnboundVariability(variability);
1855         if (isConst)
1856             type = type->GetAsConstType();
1857         finalElementTypes[i] = type;
1858     }
1859 
1860     return finalElementTypes[i];
1861 }
1862 
GetElementType(const std::string & n) const1863 const Type *StructType::GetElementType(const std::string &n) const {
1864     for (unsigned int i = 0; i < elementNames.size(); ++i)
1865         if (elementNames[i] == n)
1866             return GetElementType(i);
1867     return NULL;
1868 }
1869 
GetElementNumber(const std::string & n) const1870 int StructType::GetElementNumber(const std::string &n) const {
1871     for (unsigned int i = 0; i < elementNames.size(); ++i)
1872         if (elementNames[i] == n)
1873             return i;
1874     return -1;
1875 }
1876 
checkIfCanBeSOA(const StructType * st)1877 bool StructType::checkIfCanBeSOA(const StructType *st) {
1878     bool ok = true;
1879     for (int i = 0; i < (int)st->elementTypes.size(); ++i) {
1880         const Type *eltType = st->elementTypes[i];
1881         const StructType *childStructType = CastType<StructType>(eltType);
1882 
1883         if (childStructType != NULL)
1884             ok &= checkIfCanBeSOA(childStructType);
1885         else if (eltType->HasUnboundVariability() == false) {
1886             Error(st->elementPositions[i],
1887                   "Unable to apply SOA conversion to "
1888                   "struct due to \"%s\" member \"%s\" with bound \"%s\" "
1889                   "variability.",
1890                   eltType->GetString().c_str(), st->elementNames[i].c_str(),
1891                   eltType->IsUniformType() ? "uniform" : "varying");
1892             ok = false;
1893         } else if (CastType<ReferenceType>(eltType)) {
1894             Error(st->elementPositions[i],
1895                   "Unable to apply SOA conversion to "
1896                   "struct due to member \"%s\" with reference type \"%s\".",
1897                   st->elementNames[i].c_str(), eltType->GetString().c_str());
1898             ok = false;
1899         }
1900     }
1901     return ok;
1902 }
1903 
1904 ///////////////////////////////////////////////////////////////////////////
1905 // UndefinedStructType
1906 
UndefinedStructType(const std::string & n,const Variability var,bool ic,SourcePos p)1907 UndefinedStructType::UndefinedStructType(const std::string &n, const Variability var, bool ic, SourcePos p)
1908     : Type(UNDEFINED_STRUCT_TYPE), name(n), variability(var), isConst(ic), pos(p) {
1909     Assert(name != "");
1910     if (variability != Variability::Unbound) {
1911         // Create a new opaque LLVM struct type for this struct name
1912         std::string mname = lMangleStructName(name, variability);
1913         if (lStructTypeMap.find(mname) == lStructTypeMap.end())
1914             lStructTypeMap[mname] = llvm::StructType::create(*g->ctx, mname);
1915     }
1916 }
1917 
GetVariability() const1918 Variability UndefinedStructType::GetVariability() const { return variability; }
1919 
IsBoolType() const1920 bool UndefinedStructType::IsBoolType() const { return false; }
1921 
IsFloatType() const1922 bool UndefinedStructType::IsFloatType() const { return false; }
1923 
IsIntType() const1924 bool UndefinedStructType::IsIntType() const { return false; }
1925 
IsUnsignedType() const1926 bool UndefinedStructType::IsUnsignedType() const { return false; }
1927 
IsConstType() const1928 bool UndefinedStructType::IsConstType() const { return isConst; }
1929 
GetBaseType() const1930 const Type *UndefinedStructType::GetBaseType() const { return this; }
1931 
GetAsVaryingType() const1932 const UndefinedStructType *UndefinedStructType::GetAsVaryingType() const {
1933     if (variability == Variability::Varying)
1934         return this;
1935     return new UndefinedStructType(name, Variability::Varying, isConst, pos);
1936 }
1937 
GetAsUniformType() const1938 const UndefinedStructType *UndefinedStructType::GetAsUniformType() const {
1939     if (variability == Variability::Uniform)
1940         return this;
1941     return new UndefinedStructType(name, Variability::Uniform, isConst, pos);
1942 }
1943 
GetAsUnboundVariabilityType() const1944 const UndefinedStructType *UndefinedStructType::GetAsUnboundVariabilityType() const {
1945     if (variability == Variability::Unbound)
1946         return this;
1947     return new UndefinedStructType(name, Variability::Unbound, isConst, pos);
1948 }
1949 
GetAsSOAType(int width) const1950 const UndefinedStructType *UndefinedStructType::GetAsSOAType(int width) const {
1951     FATAL("UndefinedStructType::GetAsSOAType() shouldn't be called.");
1952     return NULL;
1953 }
1954 
ResolveUnboundVariability(Variability v) const1955 const UndefinedStructType *UndefinedStructType::ResolveUnboundVariability(Variability v) const {
1956     if (variability != Variability::Unbound)
1957         return this;
1958     return new UndefinedStructType(name, v, isConst, pos);
1959 }
1960 
GetAsConstType() const1961 const UndefinedStructType *UndefinedStructType::GetAsConstType() const {
1962     if (isConst)
1963         return this;
1964     return new UndefinedStructType(name, variability, true, pos);
1965 }
1966 
GetAsNonConstType() const1967 const UndefinedStructType *UndefinedStructType::GetAsNonConstType() const {
1968     if (isConst == false)
1969         return this;
1970     return new UndefinedStructType(name, variability, false, pos);
1971 }
1972 
GetString() const1973 std::string UndefinedStructType::GetString() const {
1974     std::string ret;
1975     if (isConst)
1976         ret += "const ";
1977     ret += variability.GetString();
1978     ret += " struct ";
1979     ret += name;
1980     return ret;
1981 }
1982 
Mangle() const1983 std::string UndefinedStructType::Mangle() const { return lMangleStruct(variability, isConst, name); }
1984 
GetCDeclaration(const std::string & n) const1985 std::string UndefinedStructType::GetCDeclaration(const std::string &n) const {
1986     std::string ret;
1987     if (isConst)
1988         ret += "const ";
1989     ret += std::string("struct ") + name;
1990     if (lShouldPrintName(n))
1991         ret += std::string(" ") + n;
1992     return ret;
1993 }
1994 
LLVMType(llvm::LLVMContext * ctx) const1995 llvm::Type *UndefinedStructType::LLVMType(llvm::LLVMContext *ctx) const {
1996     Assert(variability != Variability::Unbound);
1997     std::string mname = lMangleStructName(name, variability);
1998     if (lStructTypeMap.find(mname) == lStructTypeMap.end()) {
1999         Assert(m->errorCount > 0);
2000         return NULL;
2001     }
2002     return lStructTypeMap[mname];
2003 }
2004 
GetDIType(llvm::DIScope * scope) const2005 llvm::DIType *UndefinedStructType::GetDIType(llvm::DIScope *scope) const {
2006     llvm::DIFile *diFile = pos.GetDIFile();
2007     llvm::DINamespace *diSpace = pos.GetDINamespace();
2008     llvm::DINodeArray elements;
2009     return m->diBuilder->createStructType(diSpace, GetString(), diFile,
2010                                           pos.first_line,         // Line number
2011                                           0,                      // Size
2012                                           0,                      // Align
2013                                           llvm::DINode::FlagZero, // Flags
2014                                           NULL, elements);
2015 }
2016 
2017 ///////////////////////////////////////////////////////////////////////////
2018 // ReferenceType
2019 
ReferenceType(const Type * t)2020 ReferenceType::ReferenceType(const Type *t) : Type(REFERENCE_TYPE), targetType(t) { asOtherConstType = NULL; }
2021 
GetVariability() const2022 Variability ReferenceType::GetVariability() const {
2023     if (targetType == NULL) {
2024         Assert(m->errorCount > 0);
2025         return Variability(Variability::Unbound);
2026     }
2027     return targetType->GetVariability();
2028 }
2029 
IsBoolType() const2030 bool ReferenceType::IsBoolType() const {
2031     if (targetType == NULL) {
2032         Assert(m->errorCount > 0);
2033         return false;
2034     }
2035     return targetType->IsBoolType();
2036 }
2037 
IsFloatType() const2038 bool ReferenceType::IsFloatType() const {
2039     if (targetType == NULL) {
2040         Assert(m->errorCount > 0);
2041         return false;
2042     }
2043     return targetType->IsFloatType();
2044 }
2045 
IsIntType() const2046 bool ReferenceType::IsIntType() const {
2047     if (targetType == NULL) {
2048         Assert(m->errorCount > 0);
2049         return false;
2050     }
2051     return targetType->IsIntType();
2052 }
2053 
IsUnsignedType() const2054 bool ReferenceType::IsUnsignedType() const {
2055     if (targetType == NULL) {
2056         Assert(m->errorCount > 0);
2057         return false;
2058     }
2059     return targetType->IsUnsignedType();
2060 }
2061 
IsConstType() const2062 bool ReferenceType::IsConstType() const {
2063     if (targetType == NULL) {
2064         Assert(m->errorCount > 0);
2065         return false;
2066     }
2067     return targetType->IsConstType();
2068 }
2069 
GetReferenceTarget() const2070 const Type *ReferenceType::GetReferenceTarget() const { return targetType; }
2071 
GetBaseType() const2072 const Type *ReferenceType::GetBaseType() const {
2073     if (targetType == NULL) {
2074         Assert(m->errorCount > 0);
2075         return NULL;
2076     }
2077     return targetType->GetBaseType();
2078 }
2079 
GetAsVaryingType() const2080 const ReferenceType *ReferenceType::GetAsVaryingType() const {
2081     if (targetType == NULL) {
2082         Assert(m->errorCount > 0);
2083         return NULL;
2084     }
2085     if (IsVaryingType())
2086         return this;
2087     return new ReferenceType(targetType->GetAsVaryingType());
2088 }
2089 
GetAsUniformType() const2090 const ReferenceType *ReferenceType::GetAsUniformType() const {
2091     if (targetType == NULL) {
2092         Assert(m->errorCount > 0);
2093         return NULL;
2094     }
2095     if (IsUniformType())
2096         return this;
2097     return new ReferenceType(targetType->GetAsUniformType());
2098 }
2099 
GetAsUnboundVariabilityType() const2100 const ReferenceType *ReferenceType::GetAsUnboundVariabilityType() const {
2101     if (targetType == NULL) {
2102         Assert(m->errorCount > 0);
2103         return NULL;
2104     }
2105     if (HasUnboundVariability())
2106         return this;
2107     return new ReferenceType(targetType->GetAsUnboundVariabilityType());
2108 }
2109 
GetAsSOAType(int width) const2110 const Type *ReferenceType::GetAsSOAType(int width) const {
2111     // FIXME: is this right?
2112     return new ArrayType(this, width);
2113 }
2114 
ResolveUnboundVariability(Variability v) const2115 const ReferenceType *ReferenceType::ResolveUnboundVariability(Variability v) const {
2116     if (targetType == NULL) {
2117         Assert(m->errorCount > 0);
2118         return NULL;
2119     }
2120     return new ReferenceType(targetType->ResolveUnboundVariability(v));
2121 }
2122 
GetAsConstType() const2123 const ReferenceType *ReferenceType::GetAsConstType() const {
2124     if (targetType == NULL) {
2125         Assert(m->errorCount > 0);
2126         return NULL;
2127     }
2128     if (IsConstType())
2129         return this;
2130 
2131     if (asOtherConstType == NULL) {
2132         asOtherConstType = new ReferenceType(targetType->GetAsConstType());
2133         asOtherConstType->asOtherConstType = this;
2134     }
2135     return asOtherConstType;
2136 }
2137 
GetAsNonConstType() const2138 const ReferenceType *ReferenceType::GetAsNonConstType() const {
2139     if (targetType == NULL) {
2140         Assert(m->errorCount > 0);
2141         return NULL;
2142     }
2143     if (!IsConstType())
2144         return this;
2145 
2146     if (asOtherConstType == NULL) {
2147         asOtherConstType = new ReferenceType(targetType->GetAsNonConstType());
2148         asOtherConstType->asOtherConstType = this;
2149     }
2150     return asOtherConstType;
2151 }
2152 
GetString() const2153 std::string ReferenceType::GetString() const {
2154     if (targetType == NULL) {
2155         Assert(m->errorCount > 0);
2156         return "";
2157     }
2158 
2159     std::string ret = targetType->GetString();
2160 
2161     ret += std::string(" &");
2162     return ret;
2163 }
2164 
Mangle() const2165 std::string ReferenceType::Mangle() const {
2166     if (targetType == NULL) {
2167         Assert(m->errorCount > 0);
2168         return "";
2169     }
2170     std::string ret;
2171     ret += std::string("REF") + targetType->Mangle();
2172     return ret;
2173 }
2174 
GetCDeclaration(const std::string & name) const2175 std::string ReferenceType::GetCDeclaration(const std::string &name) const {
2176     if (targetType == NULL) {
2177         Assert(m->errorCount > 0);
2178         return "";
2179     }
2180 
2181     const ArrayType *at = CastType<ArrayType>(targetType);
2182     if (at != NULL) {
2183         if (at->GetElementCount() == 0) {
2184             // emit unsized arrays as pointers to the base type..
2185             std::string ret;
2186             ret += at->GetElementType()->GetAsNonConstType()->GetCDeclaration("") + std::string(" *");
2187             if (lShouldPrintName(name))
2188                 ret += name;
2189             return ret;
2190         } else
2191             // otherwise forget about the reference part if it's an
2192             // array since C already passes arrays by reference...
2193             return targetType->GetCDeclaration(name);
2194     } else {
2195         std::string ret;
2196         ret += targetType->GetCDeclaration("") + std::string(" &");
2197         if (lShouldPrintName(name))
2198             ret += name;
2199         return ret;
2200     }
2201 }
2202 
LLVMType(llvm::LLVMContext * ctx) const2203 llvm::Type *ReferenceType::LLVMType(llvm::LLVMContext *ctx) const {
2204     if (targetType == NULL) {
2205         Assert(m->errorCount > 0);
2206         return NULL;
2207     }
2208 
2209     llvm::Type *t = targetType->LLVMStorageType(ctx);
2210     if (t == NULL) {
2211         Assert(m->errorCount > 0);
2212         return NULL;
2213     }
2214 
2215     return llvm::PointerType::get(t, 0);
2216 }
2217 
GetDIType(llvm::DIScope * scope) const2218 llvm::DIType *ReferenceType::GetDIType(llvm::DIScope *scope) const {
2219     if (targetType == NULL) {
2220         Assert(m->errorCount > 0);
2221         return NULL;
2222     }
2223     llvm::DIType *diTargetType = targetType->GetDIType(scope);
2224     return m->diBuilder->createReferenceType(llvm::dwarf::DW_TAG_reference_type, diTargetType);
2225 }
2226 
2227 ///////////////////////////////////////////////////////////////////////////
2228 // FunctionType
2229 
FunctionType(const Type * r,const llvm::SmallVector<const Type *,8> & a,SourcePos p)2230 FunctionType::FunctionType(const Type *r, const llvm::SmallVector<const Type *, 8> &a, SourcePos p)
2231     : Type(FUNCTION_TYPE), isTask(false), isExported(false), isExternC(false), isUnmasked(false), returnType(r),
2232       paramTypes(a), paramNames(llvm::SmallVector<std::string, 8>(a.size(), "")),
2233       paramDefaults(llvm::SmallVector<Expr *, 8>(a.size(), NULL)),
2234       paramPositions(llvm::SmallVector<SourcePos, 8>(a.size(), p)) {
2235     Assert(returnType != NULL);
2236     isSafe = false;
2237     costOverride = -1;
2238 }
2239 
FunctionType(const Type * r,const llvm::SmallVector<const Type *,8> & a,const llvm::SmallVector<std::string,8> & an,const llvm::SmallVector<Expr *,8> & ad,const llvm::SmallVector<SourcePos,8> & ap,bool it,bool is,bool ec,bool ium)2240 FunctionType::FunctionType(const Type *r, const llvm::SmallVector<const Type *, 8> &a,
2241                            const llvm::SmallVector<std::string, 8> &an, const llvm::SmallVector<Expr *, 8> &ad,
2242                            const llvm::SmallVector<SourcePos, 8> &ap, bool it, bool is, bool ec, bool ium)
2243     : Type(FUNCTION_TYPE), isTask(it), isExported(is), isExternC(ec), isUnmasked(ium), returnType(r), paramTypes(a),
2244       paramNames(an), paramDefaults(ad), paramPositions(ap) {
2245     Assert(paramTypes.size() == paramNames.size() && paramNames.size() == paramDefaults.size() &&
2246            paramDefaults.size() == paramPositions.size());
2247     Assert(returnType != NULL);
2248     isSafe = false;
2249     costOverride = -1;
2250 }
2251 
GetVariability() const2252 Variability FunctionType::GetVariability() const { return Variability(Variability::Uniform); }
2253 
IsFloatType() const2254 bool FunctionType::IsFloatType() const { return false; }
2255 
IsIntType() const2256 bool FunctionType::IsIntType() const { return false; }
2257 
IsBoolType() const2258 bool FunctionType::IsBoolType() const { return false; }
2259 
IsUnsignedType() const2260 bool FunctionType::IsUnsignedType() const { return false; }
2261 
IsConstType() const2262 bool FunctionType::IsConstType() const { return false; }
2263 
GetBaseType() const2264 const Type *FunctionType::GetBaseType() const {
2265     FATAL("FunctionType::GetBaseType() shouldn't be called");
2266     return NULL;
2267 }
2268 
GetAsVaryingType() const2269 const Type *FunctionType::GetAsVaryingType() const {
2270     FATAL("FunctionType::GetAsVaryingType shouldn't be called");
2271     return NULL;
2272 }
2273 
GetAsUniformType() const2274 const Type *FunctionType::GetAsUniformType() const {
2275     FATAL("FunctionType::GetAsUniformType shouldn't be called");
2276     return NULL;
2277 }
2278 
GetAsUnboundVariabilityType() const2279 const Type *FunctionType::GetAsUnboundVariabilityType() const {
2280     FATAL("FunctionType::GetAsUnboundVariabilityType shouldn't be called");
2281     return NULL;
2282 }
2283 
GetAsSOAType(int width) const2284 const Type *FunctionType::GetAsSOAType(int width) const {
2285     FATAL("FunctionType::GetAsSOAType() shouldn't be called");
2286     return NULL;
2287 }
2288 
ResolveUnboundVariability(Variability v) const2289 const FunctionType *FunctionType::ResolveUnboundVariability(Variability v) const {
2290     if (returnType == NULL) {
2291         Assert(m->errorCount > 0);
2292         return NULL;
2293     }
2294     const Type *rt = returnType->ResolveUnboundVariability(v);
2295 
2296     llvm::SmallVector<const Type *, 8> pt;
2297     for (unsigned int i = 0; i < paramTypes.size(); ++i) {
2298         if (paramTypes[i] == NULL) {
2299             Assert(m->errorCount > 0);
2300             return NULL;
2301         }
2302         pt.push_back(paramTypes[i]->ResolveUnboundVariability(v));
2303     }
2304 
2305     FunctionType *ret =
2306         new FunctionType(rt, pt, paramNames, paramDefaults, paramPositions, isTask, isExported, isExternC, isUnmasked);
2307     ret->isSafe = isSafe;
2308     ret->costOverride = costOverride;
2309 
2310     return ret;
2311 }
2312 
GetAsConstType() const2313 const Type *FunctionType::GetAsConstType() const { return this; }
2314 
GetAsNonConstType() const2315 const Type *FunctionType::GetAsNonConstType() const { return this; }
2316 
GetString() const2317 std::string FunctionType::GetString() const {
2318     std::string ret = GetReturnTypeString();
2319     ret += "(";
2320     for (unsigned int i = 0; i < paramTypes.size(); ++i) {
2321         if (paramTypes[i] == NULL)
2322             ret += "/* ERROR */";
2323         else
2324             ret += paramTypes[i]->GetString();
2325 
2326         if (i != paramTypes.size() - 1)
2327             ret += ", ";
2328     }
2329     ret += ")";
2330     return ret;
2331 }
2332 
Mangle() const2333 std::string FunctionType::Mangle() const {
2334     std::string ret = "___";
2335     if (isUnmasked)
2336         ret += "UM_";
2337 
2338     for (unsigned int i = 0; i < paramTypes.size(); ++i)
2339         if (paramTypes[i] == NULL)
2340             Assert(m->errorCount > 0);
2341         else
2342             ret += paramTypes[i]->Mangle();
2343 
2344     return ret;
2345 }
2346 
GetCDeclaration(const std::string & fname) const2347 std::string FunctionType::GetCDeclaration(const std::string &fname) const {
2348     std::string ret;
2349     ret += returnType->GetCDeclaration("");
2350     ret += " ";
2351     ret += fname;
2352     ret += "(";
2353     for (unsigned int i = 0; i < paramTypes.size(); ++i) {
2354         const Type *type = paramTypes[i];
2355 
2356         // Convert pointers to arrays to unsized arrays, which are more clear
2357         // to print out for multidimensional arrays (i.e. "float foo[][4] "
2358         // versus "float (foo *)[4]").
2359         const PointerType *pt = CastType<PointerType>(type);
2360         if (pt != NULL && CastType<ArrayType>(pt->GetBaseType()) != NULL) {
2361             type = new ArrayType(pt->GetBaseType(), 0);
2362         }
2363 
2364         if (paramNames[i] != "")
2365             ret += type->GetCDeclaration(paramNames[i]);
2366         else
2367             ret += type->GetString();
2368         if (i != paramTypes.size() - 1)
2369             ret += ", ";
2370     }
2371     ret += ")";
2372     return ret;
2373 }
2374 
GetCDeclarationForDispatch(const std::string & fname) const2375 std::string FunctionType::GetCDeclarationForDispatch(const std::string &fname) const {
2376     std::string ret;
2377     ret += returnType->GetCDeclaration("");
2378     ret += " ";
2379     ret += fname;
2380     ret += "(";
2381     for (unsigned int i = 0; i < paramTypes.size(); ++i) {
2382         const Type *type = paramTypes[i];
2383 
2384         // Convert pointers to arrays to unsized arrays, which are more clear
2385         // to print out for multidimensional arrays (i.e. "float foo[][4] "
2386         // versus "float (foo *)[4]").
2387         const PointerType *pt = CastType<PointerType>(type);
2388         if (pt != NULL && CastType<ArrayType>(pt->GetBaseType()) != NULL) {
2389             type = new ArrayType(pt->GetBaseType(), 0);
2390         }
2391 
2392         // Change pointers to varying thingies to void *
2393         if (pt != NULL && pt->GetBaseType()->IsVaryingType()) {
2394             PointerType *t = PointerType::Void;
2395 
2396             if (paramNames[i] != "")
2397                 ret += t->GetCDeclaration(paramNames[i]);
2398             else
2399                 ret += t->GetString();
2400         } else {
2401             if (paramNames[i] != "")
2402                 ret += type->GetCDeclaration(paramNames[i]);
2403             else
2404                 ret += type->GetString();
2405         }
2406         if (i != paramTypes.size() - 1)
2407             ret += ", ";
2408     }
2409     ret += ")";
2410     return ret;
2411 }
2412 
LLVMType(llvm::LLVMContext * ctx) const2413 llvm::Type *FunctionType::LLVMType(llvm::LLVMContext *ctx) const {
2414     FATAL("FunctionType::LLVMType() shouldn't be called");
2415     return NULL;
2416 }
2417 
GetDIType(llvm::DIScope * scope) const2418 llvm::DIType *FunctionType::GetDIType(llvm::DIScope *scope) const {
2419 
2420     std::vector<llvm::Metadata *> retArgTypes;
2421     retArgTypes.push_back(returnType->GetDIType(scope));
2422     for (int i = 0; i < GetNumParameters(); ++i) {
2423         const Type *t = GetParameterType(i);
2424         if (t == NULL)
2425 
2426             return NULL;
2427         retArgTypes.push_back(t->GetDIType(scope));
2428     }
2429 
2430     llvm::DITypeRefArray retArgTypesArray = m->diBuilder->getOrCreateTypeArray(retArgTypes);
2431     llvm::DIType *diType = m->diBuilder->createSubroutineType(retArgTypesArray);
2432     return diType;
2433 }
2434 
GetReturnTypeString() const2435 const std::string FunctionType::GetReturnTypeString() const {
2436     if (returnType == NULL)
2437         return "/* ERROR */";
2438 
2439     std::string ret;
2440     if (isTask)
2441         ret += "task ";
2442     if (isExported)
2443         ret += "export ";
2444     if (isExternC)
2445         ret += "extern \"C\" ";
2446     if (isUnmasked)
2447         ret += "unmasked ";
2448     if (isSafe)
2449         ret += "/*safe*/ ";
2450     if (costOverride > 0) {
2451         char buf[32];
2452         snprintf(buf, sizeof(buf), "/*cost=%d*/ ", costOverride);
2453         ret += buf;
2454     }
2455 
2456     return ret + returnType->GetString();
2457 }
2458 
LLVMFunctionType(llvm::LLVMContext * ctx,bool removeMask) const2459 llvm::FunctionType *FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const {
2460     if (!g->target->isGenXTarget() && isTask == true) {
2461         Assert(removeMask == false);
2462     }
2463 
2464     // Get the LLVM Type *s for the function arguments
2465     std::vector<llvm::Type *> llvmArgTypes;
2466     for (unsigned int i = 0; i < paramTypes.size(); ++i) {
2467         if (paramTypes[i] == NULL) {
2468             Assert(m->errorCount > 0);
2469             return NULL;
2470         }
2471         Assert(paramTypes[i]->IsVoidType() == false);
2472 
2473         const Type *argType = paramTypes[i];
2474         llvm::Type *t = argType->LLVMType(ctx);
2475         if (t == NULL) {
2476             Assert(m->errorCount > 0);
2477             return NULL;
2478         }
2479         llvmArgTypes.push_back(t);
2480     }
2481 
2482     // And add the function mask, if asked for
2483     if (!(removeMask || isUnmasked || (g->target->isGenXTarget() && isTask))) {
2484         llvmArgTypes.push_back(LLVMTypes::MaskType);
2485     }
2486 
2487     std::vector<llvm::Type *> callTypes;
2488     if (isTask && (!g->target->isGenXTarget())) {
2489         // Tasks take three arguments: a pointer to a struct that holds the
2490         // actual task arguments, the thread index, and the total number of
2491         // threads the tasks system has running.  (Task arguments are
2492         // marshalled in a struct so that it's easy to allocate space to
2493         // hold them until the task actually runs.)
2494         llvm::Type *st = llvm::StructType::get(*ctx, llvmArgTypes);
2495         callTypes.push_back(llvm::PointerType::getUnqual(st));
2496         callTypes.push_back(LLVMTypes::Int32Type); // threadIndex
2497         callTypes.push_back(LLVMTypes::Int32Type); // threadCount
2498         callTypes.push_back(LLVMTypes::Int32Type); // taskIndex
2499         callTypes.push_back(LLVMTypes::Int32Type); // taskCount
2500         callTypes.push_back(LLVMTypes::Int32Type); // taskIndex0
2501         callTypes.push_back(LLVMTypes::Int32Type); // taskIndex1
2502         callTypes.push_back(LLVMTypes::Int32Type); // taskIndex2
2503         callTypes.push_back(LLVMTypes::Int32Type); // taskCount0
2504         callTypes.push_back(LLVMTypes::Int32Type); // taskCount1
2505         callTypes.push_back(LLVMTypes::Int32Type); // taskCount2
2506     } else {
2507         // Otherwise we already have the types of the arguments
2508         callTypes = llvmArgTypes;
2509     }
2510 
2511     if (returnType == NULL) {
2512         Assert(m->errorCount > 0);
2513         return NULL;
2514     }
2515 
2516     const Type *retType = returnType;
2517 
2518     llvm::Type *llvmReturnType = retType->LLVMType(g->ctx);
2519     if (llvmReturnType == NULL)
2520         return NULL;
2521     return llvm::FunctionType::get(llvmReturnType, callTypes, false);
2522 }
2523 
GetParameterType(int i) const2524 const Type *FunctionType::GetParameterType(int i) const {
2525     Assert(i < (int)paramTypes.size());
2526     return paramTypes[i];
2527 }
2528 
GetParameterDefault(int i) const2529 Expr *FunctionType::GetParameterDefault(int i) const {
2530     Assert(i < (int)paramDefaults.size());
2531     return paramDefaults[i];
2532 }
2533 
GetParameterSourcePos(int i) const2534 const SourcePos &FunctionType::GetParameterSourcePos(int i) const {
2535     Assert(i < (int)paramPositions.size());
2536     return paramPositions[i];
2537 }
2538 
GetParameterName(int i) const2539 const std::string &FunctionType::GetParameterName(int i) const {
2540     Assert(i < (int)paramNames.size());
2541     return paramNames[i];
2542 }
2543 
2544 ///////////////////////////////////////////////////////////////////////////
2545 // Type
2546 
GetReferenceTarget() const2547 const Type *Type::GetReferenceTarget() const {
2548     // only ReferenceType needs to override this method
2549     return this;
2550 }
2551 
GetAsUnsignedType() const2552 const Type *Type::GetAsUnsignedType() const {
2553     // For many types, this doesn't make any sesne
2554     return NULL;
2555 }
2556 
2557 /** Given an atomic or vector type, return a vector type of the given
2558     vecSize.  Issue an error if given a vector type that isn't already that
2559     size.
2560  */
lVectorConvert(const Type * type,SourcePos pos,const char * reason,int vecSize)2561 static const Type *lVectorConvert(const Type *type, SourcePos pos, const char *reason, int vecSize) {
2562     const VectorType *vt = CastType<VectorType>(type);
2563     if (vt) {
2564         if (vt->GetElementCount() != vecSize) {
2565             Error(pos,
2566                   "Implicit conversion between from vector type "
2567                   "\"%s\" to vector type of length %d for %s is not possible.",
2568                   type->GetString().c_str(), vecSize, reason);
2569             return NULL;
2570         }
2571         return vt;
2572     } else {
2573         const AtomicType *at = CastType<AtomicType>(type);
2574         if (!at) {
2575             Error(pos,
2576                   "Non-atomic type \"%s\" can't be converted to vector type "
2577                   "for %s.",
2578                   type->GetString().c_str(), reason);
2579             return NULL;
2580         }
2581         return new VectorType(at, vecSize);
2582     }
2583 }
2584 
MoreGeneralType(const Type * t0,const Type * t1,SourcePos pos,const char * reason,bool forceVarying,int vecSize)2585 const Type *Type::MoreGeneralType(const Type *t0, const Type *t1, SourcePos pos, const char *reason, bool forceVarying,
2586                                   int vecSize) {
2587     Assert(reason != NULL);
2588 
2589     // First, if one or both types are function types, convert them to
2590     // pointer to function types and then try again.
2591     if (CastType<FunctionType>(t0) || CastType<FunctionType>(t1)) {
2592         if (CastType<FunctionType>(t0))
2593             t0 = PointerType::GetUniform(t0);
2594         if (CastType<FunctionType>(t1))
2595             t1 = PointerType::GetUniform(t1);
2596         return MoreGeneralType(t0, t1, pos, reason, forceVarying, vecSize);
2597     }
2598 
2599     // First, if we need to go varying, promote both of the types to be
2600     // varying.
2601     if (t0->IsVaryingType() || t1->IsVaryingType() || forceVarying) {
2602         t0 = t0->GetAsVaryingType();
2603         t1 = t1->GetAsVaryingType();
2604     }
2605 
2606     // And similarly, promote them both to vectors if the caller requested
2607     // a particular vector size
2608     if (vecSize > 0) {
2609         t0 = lVectorConvert(t0, pos, reason, vecSize);
2610         t1 = lVectorConvert(t1, pos, reason, vecSize);
2611         if (!t0 || !t1)
2612             return NULL;
2613     }
2614 
2615     // Are they both the same type?  If so, we're done, QED.
2616     if (Type::Equal(t0, t1))
2617         return t0;
2618 
2619     // If they're function types, it's hopeless if they didn't match in the
2620     // Type::Equal() call above.  Fail here so that we don't get into
2621     // trouble calling GetAsConstType()...
2622     if (CastType<FunctionType>(t0) || CastType<FunctionType>(t1)) {
2623         Error(pos, "Incompatible function types \"%s\" and \"%s\" in %s.", t0->GetString().c_str(),
2624               t1->GetString().c_str(), reason);
2625         return NULL;
2626     }
2627 
2628     // Not the same types, but only a const/non-const difference?  Return
2629     // the non-const type as the more general one.
2630     if (Type::EqualIgnoringConst(t0, t1))
2631         return t0->GetAsNonConstType();
2632 
2633     const PointerType *pt0 = CastType<PointerType>(t0);
2634     const PointerType *pt1 = CastType<PointerType>(t1);
2635     if (pt0 != NULL && pt1 != NULL) {
2636         if (PointerType::IsVoidPointer(pt0))
2637             return pt1;
2638         else if (PointerType::IsVoidPointer(pt1))
2639             return pt0;
2640         else {
2641             Error(pos,
2642                   "Conversion between incompatible pointer types \"%s\" "
2643                   "and \"%s\" isn't possible.",
2644                   t0->GetString().c_str(), t1->GetString().c_str());
2645             return NULL;
2646         }
2647     }
2648 
2649     const VectorType *vt0 = CastType<VectorType>(t0->GetReferenceTarget());
2650     const VectorType *vt1 = CastType<VectorType>(t1->GetReferenceTarget());
2651     if (vt0 && vt1) {
2652         // both are vectors; convert their base types and make a new vector
2653         // type, as long as their lengths match
2654         if (vt0->GetElementCount() != vt1->GetElementCount()) {
2655             Error(pos,
2656                   "Implicit conversion between differently sized vector types "
2657                   "(%s, %s) for %s is not possible.",
2658                   t0->GetString().c_str(), t1->GetString().c_str(), reason);
2659             return NULL;
2660         }
2661         const Type *t = MoreGeneralType(vt0->GetElementType(), vt1->GetElementType(), pos, reason, forceVarying);
2662         if (!t)
2663             return NULL;
2664 
2665         // The 'more general' version of the two vector element types must
2666         // be an AtomicType (that's all that vectors can hold...)
2667         const AtomicType *at = CastType<AtomicType>(t);
2668         Assert(at != NULL);
2669 
2670         return new VectorType(at, vt0->GetElementCount());
2671     } else if (vt0) {
2672         // If one type is a vector type but the other isn't, see if we can
2673         // promote the other one to a vector type.  This will fail and
2674         // return NULL if t1 is e.g. an array type and it's illegal to have
2675         // a vector of it..
2676         const Type *t = MoreGeneralType(vt0->GetElementType(), t1, pos, reason, forceVarying);
2677         if (!t)
2678             return NULL;
2679 
2680         const AtomicType *at = CastType<AtomicType>(t);
2681         Assert(at != NULL);
2682         return new VectorType(at, vt0->GetElementCount());
2683     } else if (vt1) {
2684         // As in the above case, see if we can promote t0 to make a vector
2685         // that matches vt1.
2686         const Type *t = MoreGeneralType(t0, vt1->GetElementType(), pos, reason, forceVarying);
2687         if (!t)
2688             return NULL;
2689 
2690         const AtomicType *at = CastType<AtomicType>(t);
2691         Assert(at != NULL);
2692         return new VectorType(at, vt1->GetElementCount());
2693     }
2694 
2695     // TODO: what do we need to do about references here, if anything??
2696 
2697     const AtomicType *at0 = CastType<AtomicType>(t0->GetReferenceTarget());
2698     const AtomicType *at1 = CastType<AtomicType>(t1->GetReferenceTarget());
2699 
2700     const EnumType *et0 = CastType<EnumType>(t0->GetReferenceTarget());
2701     const EnumType *et1 = CastType<EnumType>(t1->GetReferenceTarget());
2702     if (et0 != NULL && et1 != NULL) {
2703         // Two different enum types -> make them uint32s...
2704         Assert(et0->IsVaryingType() == et1->IsVaryingType());
2705         return et0->IsVaryingType() ? AtomicType::VaryingUInt32 : AtomicType::UniformUInt32;
2706     } else if (et0 != NULL) {
2707         if (at1 != NULL)
2708             // Enum type and atomic type -> convert the enum to the atomic type
2709             // TODO: should we return uint32 here, unless the atomic type is
2710             // a 64-bit atomic type, in which case we return that?
2711             return at1;
2712         else {
2713             Error(pos,
2714                   "Implicit conversion from enum type \"%s\" to "
2715                   "non-atomic type \"%s\" for %s not possible.",
2716                   t0->GetString().c_str(), t1->GetString().c_str(), reason);
2717             return NULL;
2718         }
2719     } else if (et1 != NULL) {
2720         if (at0 != NULL)
2721             // Enum type and atomic type; see TODO above here as well...
2722             return at0;
2723         else {
2724             Error(pos,
2725                   "Implicit conversion from enum type \"%s\" to "
2726                   "non-atomic type \"%s\" for %s not possible.",
2727                   t1->GetString().c_str(), t0->GetString().c_str(), reason);
2728             return NULL;
2729         }
2730     }
2731 
2732     // Now all we can do is promote atomic types...
2733     if (at0 == NULL || at1 == NULL) {
2734         Assert(reason != NULL);
2735         Error(pos, "Implicit conversion from type \"%s\" to \"%s\" for %s not possible.", t0->GetString().c_str(),
2736               t1->GetString().c_str(), reason);
2737         return NULL;
2738     }
2739 
2740     // Finally, to determine which of the two atomic types is more general,
2741     // use the ordering of entries in the AtomicType::BasicType enumerator.
2742     return (int(at0->basicType) >= int(at1->basicType)) ? at0 : at1;
2743 }
2744 
IsBasicType(const Type * type)2745 bool Type::IsBasicType(const Type *type) {
2746     return (CastType<AtomicType>(type) != NULL || CastType<EnumType>(type) != NULL ||
2747             CastType<PointerType>(type) != NULL);
2748 }
2749 
lCheckTypeEquality(const Type * a,const Type * b,bool ignoreConst)2750 static bool lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
2751     if (a == NULL || b == NULL)
2752         return false;
2753 
2754     if (ignoreConst == false && a->IsConstType() != b->IsConstType())
2755         return false;
2756 
2757     const AtomicType *ata = CastType<AtomicType>(a);
2758     const AtomicType *atb = CastType<AtomicType>(b);
2759     if (ata != NULL && atb != NULL) {
2760         return ((ata->basicType == atb->basicType) && (ata->GetVariability() == atb->GetVariability()));
2761     }
2762 
2763     // For all of the other types, we need to see if we have the same two
2764     // general types.  If so, then we dig into the details of the type and
2765     // see if all of the relevant bits are equal...
2766     const EnumType *eta = CastType<EnumType>(a);
2767     const EnumType *etb = CastType<EnumType>(b);
2768     if (eta != NULL && etb != NULL)
2769         // Kind of goofy, but this sufficies to check
2770         return (eta->pos == etb->pos && eta->GetVariability() == etb->GetVariability());
2771 
2772     const ArrayType *arta = CastType<ArrayType>(a);
2773     const ArrayType *artb = CastType<ArrayType>(b);
2774     if (arta != NULL && artb != NULL)
2775         return (arta->GetElementCount() == artb->GetElementCount() &&
2776                 lCheckTypeEquality(arta->GetElementType(), artb->GetElementType(), ignoreConst));
2777 
2778     const VectorType *vta = CastType<VectorType>(a);
2779     const VectorType *vtb = CastType<VectorType>(b);
2780     if (vta != NULL && vtb != NULL)
2781         return (vta->GetElementCount() == vtb->GetElementCount() &&
2782                 lCheckTypeEquality(vta->GetElementType(), vtb->GetElementType(), ignoreConst));
2783 
2784     const StructType *sta = CastType<StructType>(a);
2785     const StructType *stb = CastType<StructType>(b);
2786     const UndefinedStructType *usta = CastType<UndefinedStructType>(a);
2787     const UndefinedStructType *ustb = CastType<UndefinedStructType>(b);
2788     if ((sta != NULL || usta != NULL) && (stb != NULL || ustb != NULL)) {
2789         // Report both defuned and undefined structs as equal if their
2790         // names are the same.
2791         if (a->GetVariability() != b->GetVariability())
2792             return false;
2793 
2794         const std::string &namea = sta ? sta->GetStructName() : usta->GetStructName();
2795         const std::string &nameb = stb ? stb->GetStructName() : ustb->GetStructName();
2796         return (namea == nameb);
2797     }
2798 
2799     const PointerType *pta = CastType<PointerType>(a);
2800     const PointerType *ptb = CastType<PointerType>(b);
2801     if (pta != NULL && ptb != NULL)
2802         return (pta->IsUniformType() == ptb->IsUniformType() && pta->IsSlice() == ptb->IsSlice() &&
2803                 pta->IsFrozenSlice() == ptb->IsFrozenSlice() &&
2804                 lCheckTypeEquality(pta->GetBaseType(), ptb->GetBaseType(), ignoreConst));
2805 
2806     const ReferenceType *rta = CastType<ReferenceType>(a);
2807     const ReferenceType *rtb = CastType<ReferenceType>(b);
2808     if (rta != NULL && rtb != NULL)
2809         return (lCheckTypeEquality(rta->GetReferenceTarget(), rtb->GetReferenceTarget(), ignoreConst));
2810 
2811     const FunctionType *fta = CastType<FunctionType>(a);
2812     const FunctionType *ftb = CastType<FunctionType>(b);
2813     if (fta != NULL && ftb != NULL) {
2814         // Both the return types and all of the argument types must match
2815         // for function types to match
2816         if (!lCheckTypeEquality(fta->GetReturnType(), ftb->GetReturnType(), ignoreConst))
2817             return false;
2818 
2819         if (fta->isTask != ftb->isTask || fta->isExported != ftb->isExported || fta->isExternC != ftb->isExternC ||
2820             fta->isUnmasked != ftb->isUnmasked)
2821             return false;
2822 
2823         if (fta->GetNumParameters() != ftb->GetNumParameters())
2824             return false;
2825 
2826         for (int i = 0; i < fta->GetNumParameters(); ++i)
2827             if (!lCheckTypeEquality(fta->GetParameterType(i), ftb->GetParameterType(i), ignoreConst))
2828                 return false;
2829 
2830         return true;
2831     }
2832 
2833     return false;
2834 }
2835 
Equal(const Type * a,const Type * b)2836 bool Type::Equal(const Type *a, const Type *b) { return lCheckTypeEquality(a, b, false); }
2837 
EqualIgnoringConst(const Type * a,const Type * b)2838 bool Type::EqualIgnoringConst(const Type *a, const Type *b) { return lCheckTypeEquality(a, b, true); }
2839