Intel SPMD Program Compiler  1.3.0
expr.cpp
Go to the documentation of this file.
00001 /*
00002   Copyright (c) 2010-2012, Intel Corporation
00003   All rights reserved.
00004 
00005   Redistribution and use in source and binary forms, with or without
00006   modification, are permitted provided that the following conditions are
00007   met:
00008 
00009     * Redistributions of source code must retain the above copyright
00010       notice, this list of conditions and the following disclaimer.
00011 
00012     * Redistributions in binary form must reproduce the above copyright
00013       notice, this list of conditions and the following disclaimer in the
00014       documentation and/or other materials provided with the distribution.
00015 
00016     * Neither the name of Intel Corporation nor the names of its
00017       contributors may be used to endorse or promote products derived from
00018       this software without specific prior written permission.
00019 
00020 
00021    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00022    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00023    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00024    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00025    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00026    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00027    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00028    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00029    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00030    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00031    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
00032 */
00033 
00034 /** @file expr.cpp
00035     @brief Implementations of expression classes
00036 */
00037 
00038 #include "expr.h"
00039 #include "ast.h"
00040 #include "type.h"
00041 #include "sym.h"
00042 #include "ctx.h"
00043 #include "module.h"
00044 #include "util.h"
00045 #include "llvmutil.h"
00046 #ifndef _MSC_VER
00047 #include <inttypes.h>
00048 #endif
00049 #ifndef PRId64
00050 #define PRId64 "lld"
00051 #endif
00052 #ifndef PRIu64
00053 #define PRIu64 "llu"
00054 #endif
00055 
00056 #include <list>
00057 #include <set>
00058 #include <stdio.h>
00059 #include <llvm/Module.h>
00060 #include <llvm/Function.h>
00061 #include <llvm/Type.h>
00062 #include <llvm/DerivedTypes.h>
00063 #include <llvm/LLVMContext.h>
00064 #include <llvm/Instructions.h>
00065 #include <llvm/CallingConv.h>
00066 #include <llvm/Target/TargetData.h>
00067 #include <llvm/Support/IRBuilder.h>
00068 #include <llvm/ExecutionEngine/GenericValue.h>
00069 #include <llvm/Support/InstIterator.h>
00070 
00071 
00072 /////////////////////////////////////////////////////////////////////////////////////
00073 // Expr
00074 
00075 llvm::Value *
00076 Expr::GetLValue(FunctionEmitContext *ctx) const {
00077     // Expressions that can't provide an lvalue can just return NULL
00078     return NULL;
00079 }
00080 
00081 
00082 const Type *
00083 Expr::GetLValueType() const {
00084     // This also only needs to be overrided by Exprs that implement the
00085     // GetLValue() method.
00086     return NULL;
00087 }
00088 
00089 
00090 llvm::Constant *
00091 Expr::GetConstant(const Type *type) const {
00092     // The default is failure; just return NULL
00093     return NULL;
00094 }
00095 
00096 
00097 Symbol *
00098 Expr::GetBaseSymbol() const {
00099     // Not all expressions can do this, so provide a generally-useful
00100     // default implementation.
00101     return NULL;
00102 }
00103 
00104 
00105 #if 0
00106 /** If a conversion from 'fromAtomicType' to 'toAtomicType' may cause lost
00107     precision, issue a warning.  Don't warn for conversions to bool and
00108     conversions between signed and unsigned integers of the same size.
00109  */
00110 static void
00111 lMaybeIssuePrecisionWarning(const AtomicType *toAtomicType, 
00112                             const AtomicType *fromAtomicType, 
00113                             SourcePos pos, const char *errorMsgBase) {
00114     switch (toAtomicType->basicType) {
00115     case AtomicType::TYPE_BOOL:
00116     case AtomicType::TYPE_INT8:
00117     case AtomicType::TYPE_UINT8:
00118     case AtomicType::TYPE_INT16:
00119     case AtomicType::TYPE_UINT16:
00120     case AtomicType::TYPE_INT32:
00121     case AtomicType::TYPE_UINT32:
00122     case AtomicType::TYPE_FLOAT:
00123     case AtomicType::TYPE_INT64:
00124     case AtomicType::TYPE_UINT64:
00125     case AtomicType::TYPE_DOUBLE:
00126         if ((int)toAtomicType->basicType < (int)fromAtomicType->basicType &&
00127             toAtomicType->basicType != AtomicType::TYPE_BOOL &&
00128             !(toAtomicType->basicType == AtomicType::TYPE_INT8 && 
00129               fromAtomicType->basicType == AtomicType::TYPE_UINT8) &&
00130             !(toAtomicType->basicType == AtomicType::TYPE_INT16 && 
00131               fromAtomicType->basicType == AtomicType::TYPE_UINT16) &&
00132             !(toAtomicType->basicType == AtomicType::TYPE_INT32 && 
00133               fromAtomicType->basicType == AtomicType::TYPE_UINT32) &&
00134             !(toAtomicType->basicType == AtomicType::TYPE_INT64 && 
00135               fromAtomicType->basicType == AtomicType::TYPE_UINT64))
00136             Warning(pos, "Conversion from type \"%s\" to type \"%s\" for %s"
00137                     " may lose information.",
00138                     fromAtomicType->GetString().c_str(), toAtomicType->GetString().c_str(),
00139                     errorMsgBase);
00140         break;
00141     default:
00142         FATAL("logic error in lMaybeIssuePrecisionWarning()");
00143     }
00144 }
00145 #endif
00146 
00147 ///////////////////////////////////////////////////////////////////////////
00148 
00149 static Expr *
00150 lArrayToPointer(Expr *expr) {
00151     AssertPos(expr->pos, expr && CastType<ArrayType>(expr->GetType()));
00152 
00153     Expr *zero = new ConstExpr(AtomicType::UniformInt32, 0, expr->pos);
00154     Expr *index = new IndexExpr(expr, zero, expr->pos);
00155     Expr *addr = new AddressOfExpr(index, expr->pos);
00156     addr = TypeCheck(addr);
00157     Assert(addr != NULL);
00158     addr = Optimize(addr);
00159     Assert(addr != NULL);
00160     return addr;
00161 }
00162 
00163 
00164 static bool
00165 lIsAllIntZeros(Expr *expr) {
00166     const Type *type = expr->GetType();
00167     if (type == NULL || type->IsIntType() == false)
00168         return false;
00169 
00170     ConstExpr *ce = dynamic_cast<ConstExpr *>(expr);
00171     if (ce == NULL)
00172         return false;
00173 
00174     uint64_t vals[ISPC_MAX_NVEC];
00175     int count = ce->AsUInt64(vals);
00176     if (count == 1) 
00177         return (vals[0] == 0);
00178     else {
00179         for (int i = 0; i < count; ++i)
00180             if (vals[i] != 0)
00181                 return false;
00182     }
00183     return true;
00184 }
00185 
00186 
00187 static bool
00188 lDoTypeConv(const Type *fromType, const Type *toType, Expr **expr,
00189             bool failureOk, const char *errorMsgBase, SourcePos pos) {
00190     /* This function is way too long and complex.  Is type conversion stuff
00191        always this messy, or can this be cleaned up somehow? */
00192     AssertPos(pos, failureOk || errorMsgBase != NULL);
00193 
00194     if (toType == NULL || fromType == NULL)
00195         return false;
00196 
00197     // The types are equal; there's nothing to do
00198     if (Type::Equal(toType, fromType))
00199         return true;
00200 
00201     if (Type::Equal(fromType, AtomicType::Void)) {
00202         if (!failureOk)
00203             Error(pos, "Can't convert from \"void\" to \"%s\" for %s.",
00204                   toType->GetString().c_str(), errorMsgBase);
00205         return false;
00206     }
00207 
00208     if (Type::Equal(toType, AtomicType::Void)) {
00209         if (!failureOk)
00210             Error(pos, "Can't convert type \"%s\" to \"void\" for %s.",
00211                   fromType->GetString().c_str(), errorMsgBase);
00212         return false;
00213     }
00214 
00215     if (CastType<FunctionType>(fromType)) {
00216         if (CastType<PointerType>(toType) != NULL) {
00217             // Convert function type to pointer to function type
00218             if (expr != NULL) {
00219                 Expr *aoe = new AddressOfExpr(*expr, (*expr)->pos);
00220                 if (lDoTypeConv(aoe->GetType(), toType, &aoe, failureOk,
00221                                 errorMsgBase, pos)) {
00222                     *expr = aoe;
00223                     return true;
00224                 }
00225             }
00226             else
00227                 return lDoTypeConv(PointerType::GetUniform(fromType), toType, NULL,
00228                                    failureOk, errorMsgBase, pos);
00229         }
00230         else {
00231             if (!failureOk)
00232                 Error(pos, "Can't convert function type \"%s\" to \"%s\" for %s.",
00233                       fromType->GetString().c_str(),
00234                       toType->GetString().c_str(), errorMsgBase);
00235             return false;
00236         }
00237     }
00238     if (CastType<FunctionType>(toType)) {
00239         if (!failureOk)
00240             Error(pos, "Can't convert from type \"%s\" to function type \"%s\" "
00241                   "for %s.", fromType->GetString().c_str(),
00242                   toType->GetString().c_str(), errorMsgBase);
00243         return false;
00244     }
00245 
00246     if ((toType->GetSOAWidth() > 0 || fromType->GetSOAWidth() > 0) &&
00247         Type::Equal(toType->GetAsUniformType(), fromType->GetAsUniformType()) &&
00248         toType->GetSOAWidth() != fromType->GetSOAWidth()) {
00249         if (!failureOk)
00250             Error(pos, "Can't convert between types \"%s\" and \"%s\" with "
00251                   "different SOA widths for %s.", fromType->GetString().c_str(),
00252                   toType->GetString().c_str(), errorMsgBase);
00253         return false;
00254     }
00255 
00256     const ArrayType *toArrayType = CastType<ArrayType>(toType);
00257     const ArrayType *fromArrayType = CastType<ArrayType>(fromType);
00258     const VectorType *toVectorType = CastType<VectorType>(toType);
00259     const VectorType *fromVectorType = CastType<VectorType>(fromType);
00260     const StructType *toStructType = CastType<StructType>(toType);
00261     const StructType *fromStructType = CastType<StructType>(fromType);
00262     const EnumType *toEnumType = CastType<EnumType>(toType);
00263     const EnumType *fromEnumType = CastType<EnumType>(fromType);
00264     const AtomicType *toAtomicType = CastType<AtomicType>(toType);
00265     const AtomicType *fromAtomicType = CastType<AtomicType>(fromType);
00266     const PointerType *fromPointerType = CastType<PointerType>(fromType);
00267     const PointerType *toPointerType = CastType<PointerType>(toType);
00268 
00269     // Do this early, since for the case of a conversion like
00270     // "float foo[10]" -> "float * uniform foo", we have what's seemingly
00271     // a varying to uniform conversion (but not really)
00272     if (fromArrayType != NULL && toPointerType != NULL) {
00273         // can convert any array to a void pointer (both uniform and
00274         // varying).
00275         if (PointerType::IsVoidPointer(toPointerType))
00276             goto typecast_ok;
00277 
00278         // array to pointer to array element type
00279         const Type *eltType = fromArrayType->GetElementType();
00280         if (toPointerType->GetBaseType()->IsConstType())
00281             eltType = eltType->GetAsConstType();
00282 
00283         PointerType pt(eltType, toPointerType->GetVariability(),
00284                        toPointerType->IsConstType());
00285         if (Type::Equal(toPointerType, &pt))
00286             goto typecast_ok;
00287         else {
00288             if (!failureOk)
00289                 Error(pos, "Can't convert from incompatible array type \"%s\" "
00290                       "to pointer type \"%s\" for %s.", 
00291                       fromType->GetString().c_str(),
00292                       toType->GetString().c_str(), errorMsgBase);
00293             return false;
00294         }
00295     }
00296 
00297     if (toType->IsUniformType() && fromType->IsVaryingType()) {
00298         if (!failureOk)
00299             Error(pos, "Can't convert from type \"%s\" to type \"%s\" for %s.",
00300                   fromType->GetString().c_str(), toType->GetString().c_str(), 
00301                   errorMsgBase);
00302         return false;
00303     }
00304 
00305     if (fromPointerType != NULL) {
00306         if (CastType<AtomicType>(toType) != NULL &&
00307             toType->IsBoolType())
00308             // Allow implicit conversion of pointers to bools
00309             goto typecast_ok;
00310 
00311         if (toArrayType != NULL &&
00312             Type::Equal(fromType->GetBaseType(), toArrayType->GetElementType())) {
00313             // Can convert pointers to arrays of the same type
00314             goto typecast_ok;
00315         }
00316         if (toPointerType == NULL) {
00317             if (!failureOk)
00318                 Error(pos, "Can't convert between from pointer type "
00319                       "\"%s\" to non-pointer type \"%s\" for %s.", 
00320                       fromType->GetString().c_str(),
00321                       toType->GetString().c_str(), errorMsgBase);
00322             return false;
00323         }
00324         else if (fromPointerType->IsSlice() == true &&
00325                  toPointerType->IsSlice() == false) {
00326             if (!failureOk)
00327                 Error(pos, "Can't convert from pointer to SOA type "
00328                       "\"%s\" to pointer to non-SOA type \"%s\" for %s.",
00329                       fromPointerType->GetAsNonSlice()->GetString().c_str(),
00330                       toType->GetString().c_str(), errorMsgBase);
00331             return false;
00332         }
00333         else if (PointerType::IsVoidPointer(toPointerType)) {
00334             // any pointer type can be converted to a void *
00335             goto typecast_ok;
00336         }
00337         else if (PointerType::IsVoidPointer(fromPointerType) &&
00338                  expr != NULL &&
00339                  dynamic_cast<NullPointerExpr *>(*expr) != NULL) {
00340             // and a NULL convert to any other pointer type
00341             goto typecast_ok;
00342         }
00343         else if (!Type::Equal(fromPointerType->GetBaseType(), 
00344                               toPointerType->GetBaseType()) &&
00345                  !Type::Equal(fromPointerType->GetBaseType()->GetAsConstType(), 
00346                               toPointerType->GetBaseType())) {
00347             if (!failureOk)
00348                 Error(pos, "Can't convert from pointer type \"%s\" to "
00349                       "incompatible pointer type \"%s\" for %s.",
00350                       fromPointerType->GetString().c_str(),
00351                       toPointerType->GetString().c_str(), errorMsgBase);
00352             return false;
00353         }
00354 
00355         if (toType->IsVaryingType() && fromType->IsUniformType())
00356             goto typecast_ok;
00357 
00358         if (toPointerType->IsSlice() == true &&
00359             fromPointerType->IsSlice() == false)
00360             goto typecast_ok;
00361 
00362         // Otherwise there's nothing to do
00363         return true;
00364     }
00365 
00366     if (toPointerType != NULL && fromAtomicType != NULL && 
00367         fromAtomicType->IsIntType() && expr != NULL &&
00368         lIsAllIntZeros(*expr)) {
00369         // We have a zero-valued integer expression, which can also be
00370         // treated as a NULL pointer that can be converted to any other
00371         // pointer type.
00372         Expr *npe = new NullPointerExpr(pos);
00373         if (lDoTypeConv(PointerType::Void, toType, &npe,
00374                         failureOk, errorMsgBase, pos)) {
00375             *expr = npe;
00376             return true;
00377         }
00378         return false;
00379     }
00380 
00381     // Need to check this early, since otherwise the [sic] "unbound"
00382     // variability of SOA struct types causes things to get messy if that
00383     // hasn't been detected...
00384     if (toStructType && fromStructType &&
00385         (toStructType->GetSOAWidth() != fromStructType->GetSOAWidth())) {
00386         if (!failureOk)
00387             Error(pos, "Can't convert between incompatible struct types \"%s\" "
00388                   "and \"%s\" for %s.", fromType->GetString().c_str(),
00389                   toType->GetString().c_str(), errorMsgBase);
00390         return false;
00391     }
00392 
00393     // Convert from type T -> const T; just return a TypeCast expr, which
00394     // can handle this
00395     if (Type::EqualIgnoringConst(toType, fromType) &&
00396         toType->IsConstType() == true &&
00397         fromType->IsConstType() == false)
00398         goto typecast_ok;
00399     
00400     if (CastType<ReferenceType>(fromType)) {
00401         if (CastType<ReferenceType>(toType)) {
00402             // Convert from a reference to a type to a const reference to a type;
00403             // this is handled by TypeCastExpr
00404             if (Type::Equal(toType->GetReferenceTarget(),
00405                             fromType->GetReferenceTarget()->GetAsConstType()))
00406                 goto typecast_ok;
00407 
00408             const ArrayType *atFrom = 
00409                 CastType<ArrayType>(fromType->GetReferenceTarget());
00410             const ArrayType *atTo = 
00411                 CastType<ArrayType>(toType->GetReferenceTarget());
00412 
00413             if (atFrom != NULL && atTo != NULL && 
00414                 Type::Equal(atFrom->GetElementType(), atTo->GetElementType())) {
00415                 goto typecast_ok;
00416             }
00417             else {
00418                 if (!failureOk)
00419                     Error(pos, "Can't convert between incompatible reference types \"%s\" "
00420                           "and \"%s\" for %s.", fromType->GetString().c_str(),
00421                           toType->GetString().c_str(), errorMsgBase);
00422                 return false;
00423             }
00424         }
00425         else {
00426             // convert from a reference T -> T
00427             if (expr != NULL) {
00428                 Expr *drExpr = new RefDerefExpr(*expr, pos);
00429                 if (lDoTypeConv(drExpr->GetType(), toType, &drExpr, failureOk, 
00430                                 errorMsgBase, pos) == true) {
00431                     *expr = drExpr;
00432                     return true;
00433                 }
00434                 return false;
00435             }
00436             else
00437                 return lDoTypeConv(fromType->GetReferenceTarget(), toType, NULL,
00438                                    failureOk, errorMsgBase, pos);
00439         }
00440     }
00441     else if (CastType<ReferenceType>(toType)) {
00442         // T -> reference T
00443         if (expr != NULL) {
00444             Expr *rExpr = new ReferenceExpr(*expr, pos);
00445             if (lDoTypeConv(rExpr->GetType(), toType, &rExpr, failureOk,
00446                             errorMsgBase, pos) == true) {
00447                 *expr = rExpr;
00448                 return true;
00449             }
00450             return false;
00451         }
00452         else {
00453             ReferenceType rt(fromType);
00454             return lDoTypeConv(&rt, toType, NULL, failureOk, errorMsgBase, pos);
00455         }
00456     }
00457     else if (Type::Equal(toType, fromType->GetAsNonConstType()))
00458         // convert: const T -> T (as long as T isn't a reference)
00459         goto typecast_ok;
00460 
00461     fromType = fromType->GetReferenceTarget();
00462     toType = toType->GetReferenceTarget();
00463     if (toArrayType && fromArrayType) {
00464         if (Type::Equal(toArrayType->GetElementType(), 
00465                         fromArrayType->GetElementType())) {
00466             // the case of different element counts should have returned
00467             // successfully earlier, yes??
00468             AssertPos(pos, toArrayType->GetElementCount() != fromArrayType->GetElementCount());
00469             goto typecast_ok;
00470         }
00471         else if (Type::Equal(toArrayType->GetElementType(), 
00472                              fromArrayType->GetElementType()->GetAsConstType())) {
00473             // T[x] -> const T[x]
00474             goto typecast_ok;
00475         }
00476         else {
00477             if (!failureOk)
00478                 Error(pos, "Array type \"%s\" can't be converted to type \"%s\" for %s.",
00479                       fromType->GetString().c_str(), toType->GetString().c_str(),
00480                       errorMsgBase);
00481             return false;
00482         }
00483     }
00484 
00485     if (toVectorType && fromVectorType) {
00486         // converting e.g. int<n> -> float<n>
00487         if (fromVectorType->GetElementCount() != toVectorType->GetElementCount()) {
00488             if (!failureOk)
00489                 Error(pos, "Can't convert between differently sized vector types "
00490                       "\"%s\" -> \"%s\" for %s.", fromType->GetString().c_str(),
00491                       toType->GetString().c_str(), errorMsgBase);
00492             return false;
00493         }
00494         goto typecast_ok;
00495     }
00496 
00497     if (toStructType && fromStructType) {
00498         if (!Type::Equal(toStructType->GetAsUniformType()->GetAsConstType(),
00499                          fromStructType->GetAsUniformType()->GetAsConstType())) {
00500             if (!failureOk)
00501                 Error(pos, "Can't convert between different struct types "
00502                       "\"%s\" and \"%s\" for %s.", fromStructType->GetString().c_str(),
00503                       toStructType->GetString().c_str(), errorMsgBase);
00504             return false;
00505         }
00506         goto typecast_ok;
00507     }
00508 
00509     if (toEnumType != NULL && fromEnumType != NULL) {
00510         // No implicit conversions between different enum types
00511         if (!Type::EqualIgnoringConst(toEnumType->GetAsUniformType(),
00512                                      fromEnumType->GetAsUniformType())) {
00513             if (!failureOk)
00514                 Error(pos, "Can't convert between different enum types "
00515                       "\"%s\" and \"%s\" for %s", fromEnumType->GetString().c_str(),
00516                       toEnumType->GetString().c_str(), errorMsgBase);
00517             return false;
00518         }
00519         goto typecast_ok;
00520     }
00521 
00522     // enum -> atomic (integer, generally...) is always ok
00523     if (fromEnumType != NULL) {
00524         AssertPos(pos, toAtomicType != NULL || toVectorType != NULL);
00525         goto typecast_ok;
00526     }
00527 
00528     // from here on out, the from type can only be atomic something or
00529     // other...
00530     if (fromAtomicType == NULL) {
00531         if (!failureOk)
00532             Error(pos, "Type conversion from \"%s\" to \"%s\" for %s is not "
00533                   "possible.", fromType->GetString().c_str(), 
00534                   toType->GetString().c_str(), errorMsgBase);
00535         return false;
00536     }
00537 
00538     // scalar -> short-vector conversions
00539     if (toVectorType != NULL &&
00540         (fromType->GetSOAWidth() == toType->GetSOAWidth()))
00541         goto typecast_ok;
00542 
00543     // ok, it better be a scalar->scalar conversion of some sort by now
00544     if (toAtomicType == NULL) {
00545         if (!failureOk)
00546             Error(pos, "Type conversion from \"%s\" to \"%s\" for %s is "
00547                   "not possible", fromType->GetString().c_str(), 
00548                   toType->GetString().c_str(), errorMsgBase);
00549         return false;
00550     }
00551 
00552     if (fromType->GetSOAWidth() != toType->GetSOAWidth()) {
00553         if (!failureOk)
00554             Error(pos, "Can't convert between types \"%s\" and \"%s\" with "
00555                   "different SOA widths for %s.", fromType->GetString().c_str(),
00556                   toType->GetString().c_str(), errorMsgBase);
00557         return false;
00558     }
00559 
00560  typecast_ok:
00561     if (expr != NULL)
00562         *expr = new TypeCastExpr(toType, *expr, pos);
00563     return true;
00564 }
00565 
00566 
00567 bool
00568 CanConvertTypes(const Type *fromType, const Type *toType, 
00569                 const char *errorMsgBase, SourcePos pos) {
00570     return lDoTypeConv(fromType, toType, NULL, errorMsgBase == NULL,
00571                        errorMsgBase, pos);
00572 }
00573 
00574 
00575 Expr *
00576 TypeConvertExpr(Expr *expr, const Type *toType, const char *errorMsgBase) {
00577     if (expr == NULL)
00578         return NULL;
00579 
00580 #if 0
00581     Debug(expr->pos, "type convert %s -> %s.", expr->GetType()->GetString().c_str(),
00582           toType->GetString().c_str());
00583 #endif
00584 
00585     const Type *fromType = expr->GetType();
00586     Expr *e = expr;
00587     if (lDoTypeConv(fromType, toType, &e, false, errorMsgBase, 
00588                     expr->pos))
00589         return e;
00590     else
00591         return NULL;
00592 }
00593 
00594 
00595 bool
00596 PossiblyResolveFunctionOverloads(Expr *expr, const Type *type) {
00597     FunctionSymbolExpr *fse = NULL;
00598     const FunctionType *funcType = NULL;
00599     if (CastType<PointerType>(type) != NULL &&
00600         (funcType = CastType<FunctionType>(type->GetBaseType())) &&
00601         (fse = dynamic_cast<FunctionSymbolExpr *>(expr)) != NULL) {
00602         // We're initializing a function pointer with a function symbol,
00603         // which in turn may represent an overloaded function.  So we need
00604         // to try to resolve the overload based on the type of the symbol
00605         // we're initializing here.
00606         std::vector<const Type *> paramTypes;
00607         for (int i = 0; i < funcType->GetNumParameters(); ++i)
00608             paramTypes.push_back(funcType->GetParameterType(i));
00609 
00610         if (fse->ResolveOverloads(expr->pos, paramTypes) == false)
00611             return false;
00612     }
00613     return true;
00614 }
00615 
00616 
00617 
00618 /** Utility routine that emits code to initialize a symbol given an
00619     initializer expression.
00620 
00621     @param ptr       Memory location of storage for the symbol's data
00622     @param symName   Name of symbol (used in error messages)
00623     @param symType   Type of variable being initialized
00624     @param initExpr  Expression for the initializer
00625     @param ctx       FunctionEmitContext to use for generating instructions
00626     @param pos       Source file position of the variable being initialized
00627 */
00628 void
00629 InitSymbol(llvm::Value *ptr, const Type *symType, Expr *initExpr, 
00630            FunctionEmitContext *ctx, SourcePos pos) {
00631     if (initExpr == NULL)
00632         // leave it uninitialized
00633         return;
00634 
00635     // See if we have a constant initializer a this point
00636     llvm::Constant *constValue = initExpr->GetConstant(symType);
00637     if (constValue != NULL) {
00638         // It'd be nice if we could just do a StoreInst(constValue, ptr)
00639         // at this point, but unfortunately that doesn't generate great
00640         // code (e.g. a bunch of scalar moves for a constant array.)  So
00641         // instead we'll make a constant static global that holds the
00642         // constant value and emit a memcpy to put its value into the
00643         // pointer we have.
00644         llvm::Type *llvmType = symType->LLVMType(g->ctx);
00645         if (llvmType == NULL) {
00646             AssertPos(pos, m->errorCount > 0);
00647             return;
00648         }
00649 
00650         if (Type::IsBasicType(symType))
00651             ctx->StoreInst(constValue, ptr);
00652         else {
00653             llvm::Value *constPtr = 
00654                 new llvm::GlobalVariable(*m->module, llvmType, true /* const */, 
00655                                          llvm::GlobalValue::InternalLinkage,
00656                                          constValue, "const_initializer");
00657             llvm::Value *size = g->target.SizeOf(llvmType, 
00658                                                  ctx->GetCurrentBasicBlock());
00659             ctx->MemcpyInst(ptr, constPtr, size);
00660         }
00661 
00662         return;
00663     }
00664 
00665     // If the initializer is a straight up expression that isn't an
00666     // ExprList, then we'll see if we can type convert it to the type of
00667     // the variable.
00668     if (dynamic_cast<ExprList *>(initExpr) == NULL) {
00669         if (PossiblyResolveFunctionOverloads(initExpr, symType) == false)
00670             return;
00671         initExpr = TypeConvertExpr(initExpr, symType, "initializer");
00672 
00673         if (initExpr == NULL)
00674             return;
00675 
00676         llvm::Value *initializerValue = initExpr->GetValue(ctx);
00677         if (initializerValue != NULL)
00678             // Bingo; store the value in the variable's storage
00679             ctx->StoreInst(initializerValue, ptr);
00680         return;
00681     }
00682 
00683     // Atomic types and enums can be initialized with { ... } initializer
00684     // expressions if they have a single element (except for SOA types,
00685     // which are handled below).
00686     if (symType->IsSOAType() == false && Type::IsBasicType(symType)) {
00687         ExprList *elist = dynamic_cast<ExprList *>(initExpr);
00688         if (elist != NULL) {
00689             if (elist->exprs.size() == 1)
00690                 InitSymbol(ptr, symType, elist->exprs[0], ctx, pos);
00691             else
00692                 Error(initExpr->pos, "Expression list initializers with "
00693                       "multiple values can't be used with type \"%s\".", 
00694                       symType->GetString().c_str());
00695         }
00696         return;
00697     }
00698 
00699     const ReferenceType *rt = CastType<ReferenceType>(symType);
00700     if (rt) {
00701         if (!Type::Equal(initExpr->GetType(), rt)) {
00702             Error(initExpr->pos, "Initializer for reference type \"%s\" must have same "
00703                   "reference type itself. \"%s\" is incompatible.", 
00704                   rt->GetString().c_str(), initExpr->GetType()->GetString().c_str());
00705             return;
00706         }
00707 
00708         llvm::Value *initializerValue = initExpr->GetValue(ctx);
00709         if (initializerValue)
00710             ctx->StoreInst(initializerValue, ptr);
00711         return;
00712     }
00713 
00714     // Handle initiailizers for SOA types as well as for structs, arrays,
00715     // and vectors.
00716     const CollectionType *collectionType = CastType<CollectionType>(symType);
00717     if (collectionType != NULL || symType->IsSOAType()) {
00718         int nElements = collectionType ? collectionType->GetElementCount() :
00719             symType->GetSOAWidth();
00720 
00721         std::string name;
00722         if (CastType<StructType>(symType) != NULL)
00723             name = "struct";
00724         else if (CastType<ArrayType>(symType) != NULL) 
00725             name = "array";
00726         else if (CastType<VectorType>(symType) != NULL) 
00727             name = "vector";
00728         else if (symType->IsSOAType())
00729             name = symType->GetVariability().GetString();
00730         else
00731             FATAL("Unexpected CollectionType in InitSymbol()");
00732 
00733         // There are two cases for initializing these types; either a
00734         // single initializer may be provided (float foo[3] = 0;), in which
00735         // case all of the elements are initialized to the given value, or
00736         // an initializer list may be provided (float foo[3] = { 1,2,3 }),
00737         // in which case the elements are initialized with the
00738         // corresponding values.
00739         ExprList *exprList = dynamic_cast<ExprList *>(initExpr);
00740         if (exprList != NULL) {
00741             // The { ... } case; make sure we have the no more expressions
00742             // in the ExprList as we have struct members
00743             int nInits = exprList->exprs.size();
00744             if (nInits > nElements) {
00745                 Error(initExpr->pos, "Initializer for %s type \"%s\" requires "
00746                       "no more than %d values; %d provided.", name.c_str(), 
00747                       symType->GetString().c_str(), nElements, nInits);
00748                 return;
00749             }
00750 
00751             // Initialize each element with the corresponding value from
00752             // the ExprList
00753             for (int i = 0; i < nElements; ++i) {
00754                 // For SOA types, the element type is the uniform variant
00755                 // of the underlying type
00756                 const Type *elementType = 
00757                     collectionType ? collectionType->GetElementType(i) : 
00758                                      symType->GetAsUniformType();
00759                 if (elementType == NULL) {
00760                     AssertPos(pos, m->errorCount > 0);
00761                     return;
00762                 }
00763 
00764                 llvm::Value *ep;
00765                 if (CastType<StructType>(symType) != NULL)
00766                     ep = ctx->AddElementOffset(ptr, i, NULL, "element");
00767                 else
00768                     ep = ctx->GetElementPtrInst(ptr, LLVMInt32(0), LLVMInt32(i), 
00769                                                 PointerType::GetUniform(elementType),
00770                                                 "gep");
00771 
00772                 if (i < nInits)
00773                     InitSymbol(ep, elementType, exprList->exprs[i], ctx, pos);
00774                 else {
00775                     // If we don't have enough initializer values, initialize the
00776                     // rest as zero.
00777                     llvm::Type *llvmType = elementType->LLVMType(g->ctx);
00778                     if (llvmType == NULL) {
00779                         AssertPos(pos, m->errorCount > 0);
00780                         return;
00781                     }
00782 
00783                     llvm::Constant *zeroInit = llvm::Constant::getNullValue(llvmType);
00784                     ctx->StoreInst(zeroInit, ep);
00785                 }
00786             }
00787         }
00788         else
00789             Error(initExpr->pos, "Can't assign type \"%s\" to \"%s\".",
00790                   initExpr->GetType()->GetString().c_str(),
00791                   collectionType->GetString().c_str());
00792         return;
00793     }
00794 
00795     FATAL("Unexpected Type in InitSymbol()");
00796 }
00797 
00798 
00799 ///////////////////////////////////////////////////////////////////////////
00800 
00801 /** Given an atomic or vector type, this returns a boolean type with the
00802     same "shape".  In other words, if the given type is a vector type of
00803     three uniform ints, the returned type is a vector type of three uniform
00804     bools. */
00805 static const Type *
00806 lMatchingBoolType(const Type *type) {
00807     bool uniformTest = type->IsUniformType();
00808     const AtomicType *boolBase = uniformTest ? AtomicType::UniformBool : 
00809                                                AtomicType::VaryingBool;
00810     const VectorType *vt = CastType<VectorType>(type);
00811     if (vt != NULL)
00812         return new VectorType(boolBase, vt->GetElementCount());
00813     else {
00814         Assert(CastType<AtomicType>(type) != NULL ||
00815                CastType<PointerType>(type) != NULL);
00816         return boolBase;
00817     }
00818 }
00819 
00820 ///////////////////////////////////////////////////////////////////////////
00821 // UnaryExpr
00822 
00823 static llvm::Constant *
00824 lLLVMConstantValue(const Type *type, llvm::LLVMContext *ctx, double value) {
00825     const AtomicType *atomicType = CastType<AtomicType>(type);
00826     const EnumType *enumType = CastType<EnumType>(type);
00827     const VectorType *vectorType = CastType<VectorType>(type);
00828     const PointerType *pointerType = CastType<PointerType>(type);
00829 
00830     // This function is only called with, and only works for atomic, enum,
00831     // and vector types.
00832     Assert(atomicType != NULL || enumType != NULL || vectorType != NULL ||
00833            pointerType != NULL);
00834 
00835     if (atomicType != NULL || enumType != NULL) {
00836         // If it's an atomic or enuemrator type, then figure out which of
00837         // the llvmutil.h functions to call to get the corresponding
00838         // constant and then call it...
00839         bool isUniform = type->IsUniformType();
00840         AtomicType::BasicType basicType = (enumType != NULL) ? 
00841             AtomicType::TYPE_UINT32 : atomicType->basicType;
00842 
00843         switch (basicType) {
00844         case AtomicType::TYPE_VOID:
00845             FATAL("can't get constant value for void type");
00846             return NULL;
00847         case AtomicType::TYPE_BOOL:
00848             if (isUniform)
00849                 return (value != 0.) ? LLVMTrue : LLVMFalse;
00850             else
00851                 return LLVMBoolVector(value != 0.);
00852         case AtomicType::TYPE_INT8: {
00853             int i = (int)value;
00854             Assert((double)i == value);
00855             return isUniform ? LLVMInt8(i) : LLVMInt8Vector(i);
00856         }
00857         case AtomicType::TYPE_UINT8: {
00858             unsigned int i = (unsigned int)value;
00859             return isUniform ? LLVMUInt8(i) : LLVMUInt8Vector(i);
00860         }
00861         case AtomicType::TYPE_INT16: {
00862             int i = (int)value;
00863             Assert((double)i == value);
00864             return isUniform ? LLVMInt16(i) : LLVMInt16Vector(i);
00865         }
00866         case AtomicType::TYPE_UINT16: {
00867             unsigned int i = (unsigned int)value;
00868             return isUniform ? LLVMUInt16(i) : LLVMUInt16Vector(i);
00869         }
00870         case AtomicType::TYPE_INT32: {
00871             int i = (int)value;
00872             Assert((double)i == value);
00873             return isUniform ? LLVMInt32(i) : LLVMInt32Vector(i);
00874         }
00875         case AtomicType::TYPE_UINT32: {
00876             unsigned int i = (unsigned int)value;
00877             return isUniform ? LLVMUInt32(i) : LLVMUInt32Vector(i);
00878         }
00879         case AtomicType::TYPE_FLOAT:
00880             return isUniform ? LLVMFloat((float)value) : 
00881                                LLVMFloatVector((float)value);
00882         case AtomicType::TYPE_UINT64: {
00883             uint64_t i = (uint64_t)value;
00884             Assert(value == (int64_t)i);
00885             return isUniform ? LLVMUInt64(i) : LLVMUInt64Vector(i);
00886         }
00887         case AtomicType::TYPE_INT64: {
00888             int64_t i = (int64_t)value;
00889             Assert((double)i == value);
00890             return isUniform ? LLVMInt64(i) : LLVMInt64Vector(i);
00891         }
00892         case AtomicType::TYPE_DOUBLE:
00893             return isUniform ? LLVMDouble(value) : LLVMDoubleVector(value);
00894         default:
00895             FATAL("logic error in lLLVMConstantValue");
00896             return NULL;
00897         }
00898     }
00899     else if (pointerType != NULL) {
00900         Assert(value == 0);
00901         if (pointerType->IsUniformType())
00902             return llvm::Constant::getNullValue(LLVMTypes::VoidPointerType);
00903         else
00904             return llvm::Constant::getNullValue(LLVMTypes::VoidPointerVectorType);
00905     }
00906     else {
00907         // For vector types, first get the LLVM constant for the basetype with
00908         // a recursive call to lLLVMConstantValue().
00909         const Type *baseType = vectorType->GetBaseType();
00910         llvm::Constant *constElement = lLLVMConstantValue(baseType, ctx, value);
00911         llvm::Type *llvmVectorType = vectorType->LLVMType(ctx);
00912 
00913         // Now create a constant version of the corresponding LLVM type that we
00914         // use to represent the VectorType.
00915         // FIXME: this is a little ugly in that the fact that ispc represents
00916         // uniform VectorTypes as LLVM VectorTypes and varying VectorTypes as
00917         // LLVM ArrayTypes leaks into the code here; it feels like this detail
00918         // should be better encapsulated?
00919         if (baseType->IsUniformType()) {
00920             llvm::VectorType *lvt = 
00921                 llvm::dyn_cast<llvm::VectorType>(llvmVectorType);
00922             Assert(lvt != NULL);
00923             std::vector<llvm::Constant *> vals;
00924             for (unsigned int i = 0; i < lvt->getNumElements(); ++i)
00925                 vals.push_back(constElement);
00926             return llvm::ConstantVector::get(vals);
00927         }
00928         else {
00929             llvm::ArrayType *lat = 
00930                 llvm::dyn_cast<llvm::ArrayType>(llvmVectorType);
00931             Assert(lat != NULL);
00932             std::vector<llvm::Constant *> vals;
00933             for (unsigned int i = 0; i < lat->getNumElements(); ++i)
00934                 vals.push_back(constElement);
00935             return llvm::ConstantArray::get(lat, vals);
00936         }
00937     }
00938 }
00939 
00940 
00941 static llvm::Value *
00942 lMaskForSymbol(Symbol *baseSym, FunctionEmitContext *ctx) {
00943     if (baseSym == NULL)
00944         return ctx->GetFullMask();
00945 
00946     if (CastType<PointerType>(baseSym->type) != NULL ||
00947         CastType<ReferenceType>(baseSym->type) != NULL)
00948         // FIXME: for pointers, we really only want to do this for
00949         // dereferencing the pointer, not for things like pointer
00950         // arithmetic, when we may be able to use the internal mask,
00951         // depending on context...
00952         return ctx->GetFullMask();
00953 
00954     llvm::Value *mask = (baseSym->parentFunction == ctx->GetFunction() && 
00955                          baseSym->storageClass != SC_STATIC) ? 
00956         ctx->GetInternalMask() : ctx->GetFullMask();
00957     return mask;
00958 }
00959 
00960 
00961 /** Store the result of an assignment to the given location. 
00962  */
00963 static void
00964 lStoreAssignResult(llvm::Value *value, llvm::Value *ptr, const Type *valueType,
00965                    const Type *ptrType, FunctionEmitContext *ctx,
00966                    Symbol *baseSym) {
00967     Assert(baseSym == NULL ||
00968            baseSym->varyingCFDepth <= ctx->VaryingCFDepth());
00969     if (!g->opt.disableMaskedStoreToStore &&
00970         !g->opt.disableMaskAllOnOptimizations &&
00971         baseSym != NULL &&
00972         baseSym->varyingCFDepth == ctx->VaryingCFDepth() &&
00973         baseSym->storageClass != SC_STATIC &&
00974         CastType<ReferenceType>(baseSym->type) == NULL &&
00975         CastType<PointerType>(baseSym->type) == NULL) {
00976         // If the variable is declared at the same varying control flow
00977         // depth as where it's being assigned, then we don't need to do any
00978         // masking but can just do the assignment as if all the lanes were
00979         // known to be on.  While this may lead to random/garbage values
00980         // written into the lanes that are off, by definition they will
00981         // never be accessed, since those lanes aren't executing, and won't
00982         // be executing at this scope or any other one before the variable
00983         // goes out of scope.
00984         ctx->StoreInst(value, ptr, LLVMMaskAllOn, valueType, ptrType);
00985     }
00986     else {
00987         ctx->StoreInst(value, ptr, lMaskForSymbol(baseSym, ctx), valueType, ptrType);
00988     }
00989 }
00990 
00991 
00992 /** Utility routine to emit code to do a {pre,post}-{inc,dec}rement of the
00993     given expresion.
00994  */
00995 static llvm::Value *
00996 lEmitPrePostIncDec(UnaryExpr::Op op, Expr *expr, SourcePos pos,
00997                    FunctionEmitContext *ctx) {
00998     const Type *type = expr->GetType();
00999     if (type == NULL)
01000         return NULL;
01001 
01002     // Get both the lvalue and the rvalue of the given expression
01003     llvm::Value *lvalue = NULL, *rvalue = NULL;
01004     const Type *lvalueType = NULL;
01005     if (CastType<ReferenceType>(type) != NULL) {
01006         lvalueType = type;
01007         type = type->GetReferenceTarget();
01008         lvalue = expr->GetValue(ctx);
01009 
01010         Expr *deref = new RefDerefExpr(expr, expr->pos);
01011         rvalue = deref->GetValue(ctx);
01012     }
01013     else {
01014         lvalue = expr->GetLValue(ctx);
01015         lvalueType = expr->GetLValueType();
01016         rvalue = expr->GetValue(ctx);
01017     }
01018 
01019     if (lvalue == NULL) {
01020         // If we can't get a lvalue, then we have an error here 
01021         const char *prepost = (op == UnaryExpr::PreInc || 
01022                                op == UnaryExpr::PreDec) ? "pre" : "post";
01023         const char *incdec = (op == UnaryExpr::PreInc || 
01024                               op == UnaryExpr::PostInc) ? "increment" : "decrement";
01025         Error(pos, "Can't %s-%s non-lvalues.", prepost, incdec);
01026         return NULL;
01027     }
01028 
01029     // Emit code to do the appropriate addition/subtraction to the
01030     // expression's old value
01031     ctx->SetDebugPos(pos);
01032     llvm::Value *binop = NULL;
01033     int delta = (op == UnaryExpr::PreInc || op == UnaryExpr::PostInc) ? 1 : -1;
01034 
01035     std::string opName = rvalue->getName().str();
01036     if (op == UnaryExpr::PreInc || op == UnaryExpr::PostInc)
01037         opName += "_plus1";
01038     else
01039         opName += "_minus1";
01040 
01041     if (CastType<PointerType>(type) != NULL) {
01042         const Type *incType = type->IsUniformType() ? AtomicType::UniformInt32 :
01043             AtomicType::VaryingInt32;
01044         llvm::Constant *dval = lLLVMConstantValue(incType, g->ctx, delta);
01045         binop = ctx->GetElementPtrInst(rvalue, dval, type, opName.c_str());
01046     }
01047     else {
01048         llvm::Constant *dval = lLLVMConstantValue(type, g->ctx, delta);
01049         if (type->IsFloatType())
01050             binop = ctx->BinaryOperator(llvm::Instruction::FAdd, rvalue, 
01051                                         dval, opName.c_str());
01052         else
01053             binop = ctx->BinaryOperator(llvm::Instruction::Add, rvalue, 
01054                                         dval, opName.c_str());
01055     }
01056 
01057     // And store the result out to the lvalue
01058     Symbol *baseSym = expr->GetBaseSymbol();
01059     lStoreAssignResult(binop, lvalue, type, lvalueType, ctx, baseSym);
01060 
01061     // And then if it's a pre increment/decrement, return the final
01062     // computed result; otherwise return the previously-grabbed expression
01063     // value.
01064     return (op == UnaryExpr::PreInc || op == UnaryExpr::PreDec) ? binop : rvalue;
01065 }
01066 
01067 
01068 
01069 /** Utility routine to emit code to negate the given expression.
01070  */
01071 static llvm::Value *
01072 lEmitNegate(Expr *arg, SourcePos pos, FunctionEmitContext *ctx) {
01073     const Type *type = arg->GetType();
01074     llvm::Value *argVal = arg->GetValue(ctx);
01075     if (type == NULL || argVal == NULL)
01076         return NULL;
01077 
01078     // Negate by subtracting from zero...
01079     llvm::Value *zero = lLLVMConstantValue(type, g->ctx, 0.);
01080     ctx->SetDebugPos(pos);
01081     if (type->IsFloatType())
01082         return ctx->BinaryOperator(llvm::Instruction::FSub, zero, argVal,
01083                                    LLVMGetName(argVal, "_negate"));
01084     else {
01085         AssertPos(pos, type->IsIntType());
01086         return ctx->BinaryOperator(llvm::Instruction::Sub, zero, argVal,
01087                                    LLVMGetName(argVal, "_negate"));
01088     }
01089 }
01090 
01091 
01092 UnaryExpr::UnaryExpr(Op o, Expr *e, SourcePos p) 
01093   : Expr(p), op(o) { 
01094     expr = e;
01095 }
01096 
01097 
01098 llvm::Value *
01099 UnaryExpr::GetValue(FunctionEmitContext *ctx) const {
01100     if (expr == NULL)
01101         return NULL;
01102 
01103     ctx->SetDebugPos(pos);
01104 
01105     switch (op) {
01106     case PreInc:
01107     case PreDec:
01108     case PostInc:
01109     case PostDec:
01110         return lEmitPrePostIncDec(op, expr, pos, ctx);
01111     case Negate:
01112         return lEmitNegate(expr, pos, ctx);
01113     case LogicalNot: {
01114         llvm::Value *argVal = expr->GetValue(ctx);
01115         return ctx->NotOperator(argVal, LLVMGetName(argVal, "_logicalnot"));
01116     }
01117     case BitNot: {
01118         llvm::Value *argVal = expr->GetValue(ctx);
01119         return ctx->NotOperator(argVal, LLVMGetName(argVal, "_bitnot"));
01120     }
01121     default:
01122         FATAL("logic error");
01123         return NULL;
01124     }
01125 }
01126 
01127 
01128 const Type *
01129 UnaryExpr::GetType() const {
01130     if (expr == NULL)
01131         return NULL;
01132 
01133     const Type *type = expr->GetType();
01134     if (type == NULL)
01135         return NULL;
01136 
01137     // For all unary expressions besides logical not, the returned type is
01138     // the same as the source type.  Logical not always returns a bool
01139     // type, with the same shape as the input type.
01140     switch (op) {
01141     case PreInc:
01142     case PreDec:
01143     case PostInc:
01144     case PostDec:
01145     case Negate:
01146     case BitNot: 
01147         return type;
01148     case LogicalNot:
01149         return lMatchingBoolType(type);
01150     default:
01151         FATAL("error");
01152         return NULL;
01153     }
01154 }
01155 
01156 
01157 Expr *
01158 UnaryExpr::Optimize() {
01159     ConstExpr *constExpr = dynamic_cast<ConstExpr *>(expr);
01160     // If the operand isn't a constant, then we can't do any optimization
01161     // here...
01162     if (constExpr == NULL)
01163         return this;
01164 
01165     const Type *type = constExpr->GetType();
01166     bool isEnumType = CastType<EnumType>(type) != NULL;
01167 
01168     const Type *baseType = type->GetAsNonConstType()->GetAsUniformType();
01169     if (Type::Equal(baseType, AtomicType::UniformInt8) ||
01170         Type::Equal(baseType, AtomicType::UniformUInt8) ||
01171         Type::Equal(baseType, AtomicType::UniformInt16) ||
01172         Type::Equal(baseType, AtomicType::UniformUInt16) ||
01173         Type::Equal(baseType, AtomicType::UniformInt64) ||
01174         Type::Equal(baseType, AtomicType::UniformUInt64))
01175         // FIXME: should handle these at some point; for now we only do
01176         // constant folding for bool, int32 and float types...
01177         return this;
01178 
01179     switch (op) {
01180     case PreInc:
01181     case PreDec:
01182     case PostInc:
01183     case PostDec:
01184         // this shouldn't happen--it's illegal to modify a contant value..
01185         // An error will be issued elsewhere...
01186         return this;
01187     case Negate: {
01188         // Since we currently only handle int32, floats, and doubles here,
01189         // it's safe to stuff whatever we have into a double, do the negate
01190         // as a double, and then return a ConstExpr with the same type as
01191         // the original...
01192         double v[ISPC_MAX_NVEC];
01193         int count = constExpr->AsDouble(v);
01194         for (int i = 0; i < count; ++i)
01195             v[i] = -v[i];
01196         return new ConstExpr(constExpr, v);
01197     }
01198     case BitNot: {
01199         if (Type::EqualIgnoringConst(type, AtomicType::UniformInt32) || 
01200             Type::EqualIgnoringConst(type, AtomicType::VaryingInt32)) {
01201             int32_t v[ISPC_MAX_NVEC];
01202             int count = constExpr->AsInt32(v);
01203             for (int i = 0; i < count; ++i)
01204                 v[i] = ~v[i];
01205             return new ConstExpr(type, v, pos);
01206         }
01207         else if (Type::EqualIgnoringConst(type, AtomicType::UniformUInt32) || 
01208                  Type::EqualIgnoringConst(type, AtomicType::VaryingUInt32) ||
01209                  isEnumType == true) {
01210             uint32_t v[ISPC_MAX_NVEC];
01211             int count = constExpr->AsUInt32(v);
01212             for (int i = 0; i < count; ++i)
01213                 v[i] = ~v[i];
01214             return new ConstExpr(type, v, pos);
01215         }
01216         else
01217             FATAL("unexpected type in UnaryExpr::Optimize() / BitNot case");
01218     }
01219     case LogicalNot: {
01220         AssertPos(pos, Type::EqualIgnoringConst(type, AtomicType::UniformBool) || 
01221                Type::EqualIgnoringConst(type, AtomicType::VaryingBool));
01222         bool v[ISPC_MAX_NVEC];
01223         int count = constExpr->AsBool(v);
01224         for (int i = 0; i < count; ++i)
01225             v[i] = !v[i];
01226         return new ConstExpr(type, v, pos);
01227     }
01228     default:
01229         FATAL("unexpected op in UnaryExpr::Optimize()");
01230         return NULL;
01231     }
01232 }
01233 
01234 
01235 Expr *
01236 UnaryExpr::TypeCheck() {
01237     const Type *type;
01238     if (expr == NULL || (type = expr->GetType()) == NULL)
01239         // something went wrong in type checking...
01240         return NULL;
01241 
01242     if (type->IsSOAType()) {
01243         Error(pos, "Can't apply unary operator to SOA type \"%s\".",
01244               type->GetString().c_str());
01245         return NULL;
01246     }
01247 
01248     if (op == PreInc || op == PreDec || op == PostInc || op == PostDec) {
01249         if (type->IsConstType()) {
01250             Error(pos, "Can't assign to type \"%s\" on left-hand side of "
01251                   "expression.", type->GetString().c_str());
01252             return NULL;
01253         }
01254 
01255         if (type->IsNumericType())
01256             return this;
01257 
01258         const PointerType *pt = CastType<PointerType>(type);
01259         if (pt == NULL) {
01260             Error(expr->pos, "Can only pre/post increment numeric and "
01261                   "pointer types, not \"%s\".", type->GetString().c_str());
01262             return NULL;
01263         }
01264 
01265         if (PointerType::IsVoidPointer(type)) {
01266             Error(expr->pos, "Illegal to pre/post increment \"%s\" type.",
01267                   type->GetString().c_str());
01268             return NULL;
01269         }
01270         if (CastType<UndefinedStructType>(pt->GetBaseType())) {
01271             Error(expr->pos, "Illegal to pre/post increment pointer to "
01272                   "undefined struct type \"%s\".", type->GetString().c_str());
01273             return NULL;
01274         }
01275 
01276         return this;
01277     }
01278 
01279     // don't do this for pre/post increment/decrement
01280     if (CastType<ReferenceType>(type)) {
01281         expr = new RefDerefExpr(expr, pos);
01282         type = expr->GetType();
01283     }
01284 
01285     if (op == Negate) {
01286         if (!type->IsNumericType()) {
01287             Error(expr->pos, "Negate not allowed for non-numeric type \"%s\".", 
01288                   type->GetString().c_str());
01289             return NULL;
01290         }
01291     }
01292     else if (op == LogicalNot) {
01293         const Type *boolType = lMatchingBoolType(type);
01294         expr = TypeConvertExpr(expr, boolType, "logical not");
01295         if (expr == NULL)
01296             return NULL;
01297     }
01298     else if (op == BitNot) {
01299         if (!type->IsIntType()) {
01300             Error(expr->pos, "~ operator can only be used with integer types, "
01301                   "not \"%s\".", type->GetString().c_str());
01302             return NULL;
01303         }
01304     }
01305     return this;
01306 }
01307 
01308 
01309 int
01310 UnaryExpr::EstimateCost() const {
01311     if (dynamic_cast<ConstExpr *>(expr) != NULL)
01312         return 0;
01313 
01314     return COST_SIMPLE_ARITH_LOGIC_OP;
01315 }
01316 
01317 
01318 void
01319 UnaryExpr::Print() const {
01320     if (!expr || !GetType())
01321         return;
01322 
01323     printf("[ %s ] (", GetType()->GetString().c_str());
01324     if (op == PreInc) printf("++");
01325     if (op == PreDec) printf("--");
01326     if (op == Negate) printf("-");
01327     if (op == LogicalNot) printf("!");
01328     if (op == BitNot) printf("~");
01329     printf("(");
01330     expr->Print();
01331     printf(")");
01332     if (op == PostInc) printf("++");
01333     if (op == PostDec) printf("--");
01334     printf(")");
01335     pos.Print();
01336 }
01337 
01338 
01339 ///////////////////////////////////////////////////////////////////////////
01340 // BinaryExpr
01341 
01342 static const char *
01343 lOpString(BinaryExpr::Op op) {
01344     switch (op) {
01345     case BinaryExpr::Add:        return "+";
01346     case BinaryExpr::Sub:        return "-";
01347     case BinaryExpr::Mul:        return "*";
01348     case BinaryExpr::Div:        return "/";
01349     case BinaryExpr::Mod:        return "%";
01350     case BinaryExpr::Shl:        return "<<";
01351     case BinaryExpr::Shr:        return ">>";
01352     case BinaryExpr::Lt:         return "<";
01353     case BinaryExpr::Gt:         return ">";
01354     case BinaryExpr::Le:         return "<=";
01355     case BinaryExpr::Ge:         return ">=";
01356     case BinaryExpr::Equal:      return "==";
01357     case BinaryExpr::NotEqual:   return "!=";
01358     case BinaryExpr::BitAnd:     return "&";
01359     case BinaryExpr::BitXor:     return "^";
01360     case BinaryExpr::BitOr:      return "|";
01361     case BinaryExpr::LogicalAnd: return "&&";
01362     case BinaryExpr::LogicalOr:  return "||";
01363     case BinaryExpr::Comma:      return ",";
01364     default:
01365         FATAL("unimplemented case in lOpString()");
01366         return "";
01367     }
01368 }
01369 
01370 
01371 /** Utility routine to emit the binary bitwise operator corresponding to
01372     the given BinaryExpr::Op. 
01373 */
01374 static llvm::Value *
01375 lEmitBinaryBitOp(BinaryExpr::Op op, llvm::Value *arg0Val,
01376                  llvm::Value *arg1Val, bool isUnsigned,
01377                  FunctionEmitContext *ctx) {
01378     llvm::Instruction::BinaryOps inst;
01379     switch (op) {
01380     case BinaryExpr::Shl:    inst = llvm::Instruction::Shl;  break;
01381     case BinaryExpr::Shr:
01382         if (isUnsigned)
01383             inst = llvm::Instruction::LShr; 
01384         else
01385             inst = llvm::Instruction::AShr; 
01386         break; 
01387     case BinaryExpr::BitAnd: inst = llvm::Instruction::And;  break;
01388     case BinaryExpr::BitXor: inst = llvm::Instruction::Xor;  break;
01389     case BinaryExpr::BitOr:  inst = llvm::Instruction::Or;   break;
01390     default:
01391         FATAL("logic error in lEmitBinaryBitOp()");
01392         return NULL;
01393     }
01394 
01395     return ctx->BinaryOperator(inst, arg0Val, arg1Val, "bitop");
01396 }
01397 
01398 
01399 static llvm::Value *
01400 lEmitBinaryPointerArith(BinaryExpr::Op op, llvm::Value *value0,
01401                         llvm::Value *value1, const Type *type0,
01402                         const Type *type1, FunctionEmitContext *ctx,
01403                         SourcePos pos) {
01404     const PointerType *ptrType = CastType<PointerType>(type0);
01405 
01406     switch (op) {
01407     case BinaryExpr::Add:
01408         // ptr + integer
01409         return ctx->GetElementPtrInst(value0, value1, ptrType, "ptrmath");
01410         break;
01411     case BinaryExpr::Sub: {
01412         if (CastType<PointerType>(type1) != NULL) {
01413             AssertPos(pos, Type::Equal(type0, type1));
01414 
01415             if (ptrType->IsSlice()) {
01416                 llvm::Value *p0 = ctx->ExtractInst(value0, 0);
01417                 llvm::Value *p1 = ctx->ExtractInst(value1, 0);
01418                 const Type *majorType = ptrType->GetAsNonSlice();
01419                 llvm::Value *majorDelta = 
01420                     lEmitBinaryPointerArith(op, p0, p1, majorType, majorType,
01421                                             ctx, pos);
01422                
01423                 int soaWidth = ptrType->GetBaseType()->GetSOAWidth();
01424                 AssertPos(pos, soaWidth > 0);
01425                 llvm::Value *soaScale = LLVMIntAsType(soaWidth, 
01426                                                       majorDelta->getType());
01427 
01428                 llvm::Value *majorScale =
01429                     ctx->BinaryOperator(llvm::Instruction::Mul, majorDelta,
01430                                         soaScale, "major_soa_scaled");
01431 
01432                 llvm::Value *m0 = ctx->ExtractInst(value0, 1);
01433                 llvm::Value *m1 = ctx->ExtractInst(value1, 1);
01434                 llvm::Value *minorDelta =
01435                     ctx->BinaryOperator(llvm::Instruction::Sub, m0, m1,
01436                                         "minor_soa_delta");
01437 
01438                 ctx->MatchIntegerTypes(&majorScale, &minorDelta);
01439                 return ctx->BinaryOperator(llvm::Instruction::Add, majorScale,
01440                                            minorDelta, "soa_ptrdiff");
01441             }
01442 
01443             // ptr - ptr
01444             if (ptrType->IsUniformType()) {
01445                 value0 = ctx->PtrToIntInst(value0);
01446                 value1 = ctx->PtrToIntInst(value1);
01447             }
01448 
01449             // Compute the difference in bytes
01450             llvm::Value *delta = 
01451                 ctx->BinaryOperator(llvm::Instruction::Sub, value0, value1,
01452                                     "ptr_diff");
01453 
01454             // Now divide by the size of the type that the pointer
01455             // points to in order to return the difference in elements.
01456             llvm::Type *llvmElementType = 
01457                 ptrType->GetBaseType()->LLVMType(g->ctx);
01458             llvm::Value *size = g->target.SizeOf(llvmElementType, 
01459                                                  ctx->GetCurrentBasicBlock());
01460             if (ptrType->IsVaryingType())
01461                 size = ctx->SmearUniform(size);
01462 
01463             if (g->target.is32Bit == false && 
01464                 g->opt.force32BitAddressing == true) {
01465                 // If we're doing 32-bit addressing math on a 64-bit
01466                 // target, then trunc the delta down to a 32-bit value.
01467                 // (Thus also matching what will be a 32-bit value
01468                 // returned from SizeOf above.)
01469                 if (ptrType->IsUniformType())
01470                     delta = ctx->TruncInst(delta, LLVMTypes::Int32Type,
01471                                            "trunc_ptr_delta");
01472                 else
01473                     delta = ctx->TruncInst(delta, LLVMTypes::Int32VectorType,
01474                                            "trunc_ptr_delta");
01475             }
01476 
01477             // And now do the actual division
01478             return ctx->BinaryOperator(llvm::Instruction::SDiv, delta, size,
01479                                        "element_diff");
01480         }
01481         else {
01482             // ptr - integer
01483             llvm::Value *zero = lLLVMConstantValue(type1, g->ctx, 0.);
01484             llvm::Value *negOffset = 
01485                 ctx->BinaryOperator(llvm::Instruction::Sub, zero, value1, 
01486                                     "negate");
01487             // Do a GEP as ptr + -integer
01488             return ctx->GetElementPtrInst(value0, negOffset, ptrType, 
01489                                           "ptrmath");
01490         }
01491     }
01492     default:
01493         FATAL("Logic error in lEmitBinaryArith() for pointer type case");
01494         return NULL;
01495     }
01496 
01497 }
01498 
01499 /** Utility routine to emit binary arithmetic operator based on the given
01500     BinaryExpr::Op.
01501 */
01502 static llvm::Value *
01503 lEmitBinaryArith(BinaryExpr::Op op, llvm::Value *value0, llvm::Value *value1,
01504                  const Type *type0, const Type *type1,
01505                  FunctionEmitContext *ctx, SourcePos pos) {
01506     const PointerType *ptrType = CastType<PointerType>(type0);
01507 
01508     if (ptrType != NULL)
01509         return lEmitBinaryPointerArith(op, value0, value1, type0, type1,
01510                                        ctx, pos);
01511     else {
01512         AssertPos(pos, Type::EqualIgnoringConst(type0, type1));
01513 
01514         llvm::Instruction::BinaryOps inst;
01515         bool isFloatOp = type0->IsFloatType();
01516         bool isUnsignedOp = type0->IsUnsignedType();
01517 
01518         const char *opName = NULL;
01519         switch (op) {
01520         case BinaryExpr::Add:
01521             opName = "add";
01522             inst = isFloatOp ? llvm::Instruction::FAdd : llvm::Instruction::Add;
01523             break;
01524         case BinaryExpr::Sub:
01525             opName = "sub";
01526             inst = isFloatOp ? llvm::Instruction::FSub : llvm::Instruction::Sub;
01527             break;
01528         case BinaryExpr::Mul:
01529             opName = "mul";
01530             inst = isFloatOp ? llvm::Instruction::FMul : llvm::Instruction::Mul;
01531             break;
01532         case BinaryExpr::Div:
01533             opName = "div";
01534             if (type0->IsVaryingType() && !isFloatOp)
01535                 PerformanceWarning(pos, "Division with varying integer types is "
01536                                    "very inefficient."); 
01537             inst = isFloatOp ? llvm::Instruction::FDiv : 
01538                 (isUnsignedOp ? llvm::Instruction::UDiv : llvm::Instruction::SDiv);
01539             break;
01540         case BinaryExpr::Mod:
01541             opName = "mod";
01542             if (type0->IsVaryingType() && !isFloatOp)
01543                 PerformanceWarning(pos, "Modulus operator with varying types is "
01544                                    "very inefficient."); 
01545             inst = isFloatOp ? llvm::Instruction::FRem : 
01546                 (isUnsignedOp ? llvm::Instruction::URem : llvm::Instruction::SRem);
01547             break;
01548         default:
01549             FATAL("Invalid op type passed to lEmitBinaryArith()");
01550             return NULL;
01551         }
01552 
01553         return ctx->BinaryOperator(inst, value0, value1, LLVMGetName(opName, value0, value1));
01554     }
01555 }
01556 
01557 
01558 /** Utility routine to emit a binary comparison operator based on the given
01559     BinaryExpr::Op.
01560  */
01561 static llvm::Value *
01562 lEmitBinaryCmp(BinaryExpr::Op op, llvm::Value *e0Val, llvm::Value *e1Val,
01563                const Type *type, FunctionEmitContext *ctx, SourcePos pos) {
01564     bool isFloatOp = type->IsFloatType();
01565     bool isUnsignedOp = type->IsUnsignedType();
01566 
01567     llvm::CmpInst::Predicate pred;
01568     const char *opName = NULL;
01569     switch (op) {
01570     case BinaryExpr::Lt:
01571         opName = "less";
01572         pred = isFloatOp ? llvm::CmpInst::FCMP_ULT : 
01573             (isUnsignedOp ? llvm::CmpInst::ICMP_ULT : llvm::CmpInst::ICMP_SLT);
01574         break;
01575     case BinaryExpr::Gt:
01576         opName = "greater";
01577         pred = isFloatOp ? llvm::CmpInst::FCMP_UGT : 
01578             (isUnsignedOp ? llvm::CmpInst::ICMP_UGT : llvm::CmpInst::ICMP_SGT);
01579         break;
01580     case BinaryExpr::Le:
01581         opName = "lessequal";
01582         pred = isFloatOp ? llvm::CmpInst::FCMP_ULE : 
01583             (isUnsignedOp ? llvm::CmpInst::ICMP_ULE : llvm::CmpInst::ICMP_SLE);
01584         break;
01585     case BinaryExpr::Ge:
01586         opName = "greaterequal";
01587         pred = isFloatOp ? llvm::CmpInst::FCMP_UGE : 
01588             (isUnsignedOp ? llvm::CmpInst::ICMP_UGE : llvm::CmpInst::ICMP_SGE);
01589         break;
01590     case BinaryExpr::Equal:
01591         opName = "equal";
01592         pred = isFloatOp ? llvm::CmpInst::FCMP_UEQ : llvm::CmpInst::ICMP_EQ;
01593         break;
01594     case BinaryExpr::NotEqual:
01595         opName = "notequal";
01596         pred = isFloatOp ? llvm::CmpInst::FCMP_UNE : llvm::CmpInst::ICMP_NE;
01597         break;
01598     default:
01599         FATAL("error in lEmitBinaryCmp()");
01600         return NULL;
01601     }
01602 
01603     llvm::Value *cmp = ctx->CmpInst(isFloatOp ? llvm::Instruction::FCmp : 
01604                                     llvm::Instruction::ICmp,
01605                                     pred, e0Val, e1Val, 
01606                                     LLVMGetName(opName, e0Val, e1Val));
01607     // This is a little ugly: CmpInst returns i1 values, but we use vectors
01608     // of i32s for varying bool values; type convert the result here if
01609     // needed.
01610     if (type->IsVaryingType())
01611         cmp = ctx->I1VecToBoolVec(cmp);
01612 
01613     return cmp;
01614 }
01615 
01616 
01617 BinaryExpr::BinaryExpr(Op o, Expr *a, Expr *b, SourcePos p) 
01618     : Expr(p), op(o) {
01619     arg0 = a;
01620     arg1 = b;
01621 }
01622 
01623 
01624 /** Emit code for a && or || logical operator.  In particular, the code
01625     here handles "short-circuit" evaluation, where the second expression
01626     isn't evaluated if the value of the first one determines the value of
01627     the result. 
01628 */ 
01629 llvm::Value *
01630 lEmitLogicalOp(BinaryExpr::Op op, Expr *arg0, Expr *arg1,
01631                FunctionEmitContext *ctx, SourcePos pos) {
01632 
01633     const Type *type0 = arg0->GetType(), *type1 = arg1->GetType();
01634     if (type0 == NULL || type1 == NULL) {
01635         AssertPos(pos, m->errorCount > 0);
01636         return NULL;
01637     }
01638 
01639     // There is overhead (branches, etc.), to short-circuiting, so if the
01640     // right side of the expression is a) relatively simple, and b) can be
01641     // safely executed with an all-off execution mask, then we just
01642     // evaluate both sides and then the logical operator in that case.
01643     // FIXME: not sure what we should do about vector types here...
01644     bool shortCircuit = (EstimateCost(arg1) > PREDICATE_SAFE_IF_STATEMENT_COST ||
01645                          SafeToRunWithMaskAllOff(arg1) == false ||
01646                          CastType<VectorType>(type0) != NULL ||
01647                          CastType<VectorType>(type1) != NULL);
01648     if (shortCircuit == false) {
01649         // If one of the operands is uniform but the other is varying,
01650         // promote the uniform one to varying
01651         if (type0->IsUniformType() && type1->IsVaryingType()) {
01652             arg0 = TypeConvertExpr(arg0, AtomicType::VaryingBool, lOpString(op));
01653             AssertPos(pos, arg0 != NULL);
01654         }
01655         if (type1->IsUniformType() && type0->IsVaryingType()) {
01656             arg1 = TypeConvertExpr(arg1, AtomicType::VaryingBool, lOpString(op));
01657             AssertPos(pos, arg1 != NULL);
01658         }
01659 
01660         llvm::Value *value0 = arg0->GetValue(ctx);
01661         llvm::Value *value1 = arg1->GetValue(ctx);
01662         if (value0 == NULL || value1 == NULL) {
01663             AssertPos(pos, m->errorCount > 0);
01664             return NULL;
01665         }
01666 
01667         if (op == BinaryExpr::LogicalAnd)
01668             return ctx->BinaryOperator(llvm::Instruction::And, value0, value1,
01669                                        "logical_and");
01670         else {
01671             AssertPos(pos, op == BinaryExpr::LogicalOr);
01672             return ctx->BinaryOperator(llvm::Instruction::Or, value0, value1, 
01673                                        "logical_or");
01674         }
01675     }
01676 
01677     // Allocate temporary storage for the return value
01678     const Type *retType = Type::MoreGeneralType(type0, type1, pos, lOpString(op));
01679     llvm::Type *llvmRetType = retType->LLVMType(g->ctx);
01680     llvm::Value *retPtr = ctx->AllocaInst(llvmRetType, "logical_op_mem");
01681 
01682     llvm::BasicBlock *bbSkipEvalValue1 = ctx->CreateBasicBlock("skip_eval_1");
01683     llvm::BasicBlock *bbEvalValue1 = ctx->CreateBasicBlock("eval_1");
01684     llvm::BasicBlock *bbLogicalDone = ctx->CreateBasicBlock("logical_op_done");
01685 
01686     // Evaluate the first operand
01687     llvm::Value *value0 = arg0->GetValue(ctx);
01688     if (value0 == NULL) {
01689         AssertPos(pos, m->errorCount > 0);
01690         return NULL;
01691     }
01692 
01693     if (type0->IsUniformType()) {
01694         // Check to see if the value of the first operand is true or false
01695         llvm::Value *value0True = 
01696             ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ,
01697                          value0, LLVMTrue);
01698 
01699         if (op == BinaryExpr::LogicalOr) {
01700             // For ||, if value0 is true, then we skip evaluating value1
01701             // entirely.
01702             ctx->BranchInst(bbSkipEvalValue1, bbEvalValue1, value0True);
01703 
01704             // If value0 is true, the complete result is true (either
01705             // uniform or varying)
01706             ctx->SetCurrentBasicBlock(bbSkipEvalValue1);
01707             llvm::Value *trueValue = retType->IsUniformType() ? LLVMTrue :
01708                 LLVMMaskAllOn;
01709             ctx->StoreInst(trueValue, retPtr);
01710             ctx->BranchInst(bbLogicalDone);
01711         }
01712         else {
01713             AssertPos(pos, op == BinaryExpr::LogicalAnd);
01714 
01715             // Conversely, for &&, if value0 is false, we skip evaluating
01716             // value1.
01717             ctx->BranchInst(bbEvalValue1, bbSkipEvalValue1, value0True);
01718 
01719             // In this case, the complete result is false (again, either a
01720             // uniform or varying false).
01721             ctx->SetCurrentBasicBlock(bbSkipEvalValue1);
01722             llvm::Value *falseValue = retType->IsUniformType() ? LLVMFalse :
01723                 LLVMMaskAllOff;
01724             ctx->StoreInst(falseValue, retPtr);
01725             ctx->BranchInst(bbLogicalDone);
01726         }
01727 
01728         // Both || and && are in the same situation if the first operand's
01729         // value didn't resolve the final result: they need to evaluate the
01730         // value of the second operand, which in turn gives the value for
01731         // the full expression.
01732         ctx->SetCurrentBasicBlock(bbEvalValue1);
01733         if (type1->IsUniformType() && retType->IsVaryingType()) {
01734             arg1 = TypeConvertExpr(arg1, AtomicType::VaryingBool, "logical op");
01735             AssertPos(pos, arg1 != NULL);
01736         }
01737 
01738         llvm::Value *value1 = arg1->GetValue(ctx);
01739         if (value1 == NULL) {
01740             AssertPos(pos, m->errorCount > 0);
01741             return NULL;
01742         }
01743         ctx->StoreInst(value1, retPtr);
01744         ctx->BranchInst(bbLogicalDone);
01745 
01746         // In all cases, we end up at the bbLogicalDone basic block;
01747         // loading the value stored in retPtr in turn gives the overall
01748         // result.
01749         ctx->SetCurrentBasicBlock(bbLogicalDone);
01750         return ctx->LoadInst(retPtr);
01751     }
01752     else {
01753         // Otherwise, the first operand is varying...  Save the current
01754         // value of the mask so that we can restore it at the end.
01755         llvm::Value *oldMask = ctx->GetInternalMask();
01756         llvm::Value *oldFullMask = ctx->GetFullMask();
01757 
01758         // Convert the second operand to be varying as well, so that we can
01759         // perform logical vector ops with its value.
01760         if (type1->IsUniformType()) {
01761             arg1 = TypeConvertExpr(arg1, AtomicType::VaryingBool, "logical op");
01762             AssertPos(pos, arg1 != NULL);
01763             type1 = arg1->GetType();
01764         }
01765 
01766         if (op == BinaryExpr::LogicalOr) {
01767             // See if value0 is true for all currently executing
01768             // lanes--i.e. if (value0 & mask) == mask.  If so, we don't
01769             // need to evaluate the second operand of the expression.
01770             llvm::Value *value0AndMask = 
01771                 ctx->BinaryOperator(llvm::Instruction::And, value0, 
01772                                     oldFullMask, "op&mask");
01773             llvm::Value *equalsMask =
01774                 ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ,
01775                              value0AndMask, oldFullMask, "value0&mask==mask");
01776             equalsMask = ctx->I1VecToBoolVec(equalsMask);
01777             llvm::Value *allMatch = ctx->All(equalsMask);
01778             ctx->BranchInst(bbSkipEvalValue1, bbEvalValue1, allMatch);
01779 
01780             // value0 is true for all running lanes, so it can be used for
01781             // the final result
01782             ctx->SetCurrentBasicBlock(bbSkipEvalValue1);
01783             ctx->StoreInst(value0, retPtr);
01784             ctx->BranchInst(bbLogicalDone);
01785 
01786             // Otherwise, we need to valuate arg1. However, first we need
01787             // to set the execution mask to be (oldMask & ~a); in other
01788             // words, only execute the instances where value0 is false.
01789             // For the instances where value0 was true, we need to inhibit
01790             // execution.
01791             ctx->SetCurrentBasicBlock(bbEvalValue1);
01792             llvm::Value *not0 = ctx->NotOperator(value0);
01793             ctx->SetInternalMaskAnd(oldMask, not0);
01794 
01795             llvm::Value *value1 = arg1->GetValue(ctx);
01796             if (value1 == NULL) {
01797                 AssertPos(pos, m->errorCount > 0);
01798                 return NULL;
01799             }
01800 
01801             // We need to compute the result carefully, since vector
01802             // elements that were computed when the corresponding lane was
01803             // disabled have undefined values:
01804             // result = (value0 & old_mask) | (value1 & current_mask)
01805             llvm::Value *value1AndMask =
01806                 ctx->BinaryOperator(llvm::Instruction::And, value1, 
01807                                     ctx->GetInternalMask(), "op&mask");
01808             llvm::Value *result =
01809                 ctx->BinaryOperator(llvm::Instruction::Or, value0AndMask, 
01810                                     value1AndMask, "or_result");
01811             ctx->StoreInst(result, retPtr);
01812             ctx->BranchInst(bbLogicalDone);
01813         }
01814         else {
01815             AssertPos(pos, op == BinaryExpr::LogicalAnd);
01816 
01817             // If value0 is false for all currently running lanes, the
01818             // overall result must be false: this corresponds to checking
01819             // if (mask & ~value0) == mask.
01820             llvm::Value *notValue0 = ctx->NotOperator(value0, "not_value0");
01821             llvm::Value *notValue0AndMask = 
01822                 ctx->BinaryOperator(llvm::Instruction::And, notValue0, 
01823                                     oldFullMask, "not_value0&mask");
01824             llvm::Value *equalsMask =
01825                 ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ,
01826                              notValue0AndMask, oldFullMask, "not_value0&mask==mask");
01827             equalsMask = ctx->I1VecToBoolVec(equalsMask);
01828             llvm::Value *allMatch = ctx->All(equalsMask);
01829             ctx->BranchInst(bbSkipEvalValue1, bbEvalValue1, allMatch);
01830 
01831             // value0 was false for all running lanes, so use its value as
01832             // the overall result.
01833             ctx->SetCurrentBasicBlock(bbSkipEvalValue1);
01834             ctx->StoreInst(value0, retPtr);
01835             ctx->BranchInst(bbLogicalDone);
01836 
01837             // Otherwise we need to evaluate value1, but again with the
01838             // mask set to only be on for the lanes where value0 was true.
01839             // For the lanes where value0 was false, execution needs to be
01840             // disabled: mask = (mask & value0).
01841             ctx->SetCurrentBasicBlock(bbEvalValue1);
01842             ctx->SetInternalMaskAnd(oldMask, value0);
01843 
01844             llvm::Value *value1 = arg1->GetValue(ctx);
01845             if (value1 == NULL) {
01846                 AssertPos(pos, m->errorCount > 0);
01847                 return NULL;
01848             }
01849 
01850             // And as in the || case, we compute the overall result by
01851             // masking off the valid lanes before we AND them together:
01852             // result = (value0 & old_mask) & (value1 & current_mask)
01853             llvm::Value *value0AndMask = 
01854                 ctx->BinaryOperator(llvm::Instruction::And, value0, 
01855                                     oldFullMask, "op&mask");
01856             llvm::Value *value1AndMask =
01857                 ctx->BinaryOperator(llvm::Instruction::And, value1,
01858                                     ctx->GetInternalMask(), "value1&mask");
01859             llvm::Value *result =
01860                 ctx->BinaryOperator(llvm::Instruction::And, value0AndMask, 
01861                                     value1AndMask, "or_result");
01862             ctx->StoreInst(result, retPtr);
01863             ctx->BranchInst(bbLogicalDone);
01864         }
01865 
01866         // And finally we always end up in bbLogicalDone, where we restore
01867         // the old mask and return the computed result
01868         ctx->SetCurrentBasicBlock(bbLogicalDone);
01869         ctx->SetInternalMask(oldMask);
01870         return ctx->LoadInst(retPtr);
01871     }
01872 }
01873 
01874 
01875 llvm::Value *
01876 BinaryExpr::GetValue(FunctionEmitContext *ctx) const {
01877     if (!arg0 || !arg1) {
01878         AssertPos(pos, m->errorCount > 0);
01879         return NULL;
01880     }
01881 
01882     // Handle these specially, since we want to short-circuit their evaluation...
01883     if (op == LogicalAnd || op == LogicalOr)
01884         return lEmitLogicalOp(op, arg0, arg1, ctx, pos);
01885 
01886     llvm::Value *value0 = arg0->GetValue(ctx);
01887     llvm::Value *value1 = arg1->GetValue(ctx);
01888     if (value0 == NULL || value1 == NULL) {
01889         AssertPos(pos, m->errorCount > 0);
01890         return NULL;
01891     }
01892 
01893     ctx->SetDebugPos(pos);
01894 
01895     switch (op) {
01896     case Add:
01897     case Sub:
01898     case Mul:
01899     case Div:
01900     case Mod:
01901         return lEmitBinaryArith(op, value0, value1, arg0->GetType(), arg1->GetType(),
01902                                 ctx, pos);
01903     case Lt:
01904     case Gt:
01905     case Le:
01906     case Ge:
01907     case Equal:
01908     case NotEqual:
01909         return lEmitBinaryCmp(op, value0, value1, arg0->GetType(), ctx, pos);
01910     case Shl:
01911     case Shr:
01912     case BitAnd:
01913     case BitXor:
01914     case BitOr: {
01915         if (op == Shr && arg1->GetType()->IsVaryingType() && 
01916             dynamic_cast<ConstExpr *>(arg1) == NULL)
01917             PerformanceWarning(pos, "Shift right is extremely inefficient for "
01918                                "varying shift amounts.");
01919         return lEmitBinaryBitOp(op, value0, value1, 
01920                                 arg0->GetType()->IsUnsignedType(), ctx);
01921     }
01922     case Comma:
01923         return value1;
01924     default:
01925         FATAL("logic error");
01926         return NULL;
01927     }
01928 }
01929 
01930 
01931 const Type *
01932 BinaryExpr::GetType() const {
01933     if (arg0 == NULL || arg1 == NULL)
01934         return NULL;
01935 
01936     const Type *type0 = arg0->GetType(), *type1 = arg1->GetType();
01937     if (type0 == NULL || type1 == NULL)
01938         return NULL;
01939 
01940     // If this hits, it means that our TypeCheck() method hasn't been
01941     // called before GetType() was called; adding two pointers is illegal
01942     // and will fail type checking and (int + ptr) should be canonicalized
01943     // into (ptr + int) by type checking.
01944     if (op == Add)
01945         AssertPos(pos, CastType<PointerType>(type1) == NULL);
01946 
01947     if (op == Comma)
01948         return arg1->GetType();
01949 
01950     if (CastType<PointerType>(type0) != NULL) {
01951         if (op == Add)
01952             // ptr + int -> ptr
01953             return type0;
01954         else if (op == Sub) {
01955             if (CastType<PointerType>(type1) != NULL) {
01956                 // ptr - ptr -> ~ptrdiff_t
01957                 const Type *diffType = (g->target.is32Bit || 
01958                                         g->opt.force32BitAddressing) ? 
01959                     AtomicType::UniformInt32 : AtomicType::UniformInt64;
01960                 if (type0->IsVaryingType() || type1->IsVaryingType())
01961                     diffType = diffType->GetAsVaryingType();
01962                 return diffType;
01963             }
01964             else
01965                 // ptr - int -> ptr
01966                 return type0;
01967         }
01968 
01969         // otherwise fall through for these...
01970         AssertPos(pos, op == Lt || op == Gt || op == Le || op == Ge ||
01971                op == Equal || op == NotEqual);
01972     }
01973 
01974     const Type *exprType = Type::MoreGeneralType(type0, type1, pos, lOpString(op));
01975     // I don't think that MoreGeneralType should be able to fail after the
01976     // checks done in BinaryExpr::TypeCheck().
01977     AssertPos(pos, exprType != NULL);
01978 
01979     switch (op) {
01980     case Add:
01981     case Sub:
01982     case Mul:
01983     case Div:
01984     case Mod:
01985         return exprType;
01986     case Lt:
01987     case Gt:
01988     case Le:
01989     case Ge:
01990     case Equal:
01991     case NotEqual:
01992     case LogicalAnd:
01993     case LogicalOr:
01994         return lMatchingBoolType(exprType);
01995     case Shl:
01996     case Shr:
01997         return type1->IsVaryingType() ? type0->GetAsVaryingType() : type0;
01998     case BitAnd:
01999     case BitXor:
02000     case BitOr:
02001         return exprType;
02002     case Comma:
02003         // handled above, so fall through here just in case
02004     default:
02005         FATAL("logic error in BinaryExpr::GetType()");
02006         return NULL;
02007     }
02008 }
02009 
02010 
02011 #define FOLD_OP(O, E)                           \
02012     case O:                                     \
02013         for (int i = 0; i < count; ++i)         \
02014             result[i] = (v0[i] E v1[i]);        \
02015         break
02016 
02017 /** Constant fold the binary integer operations that aren't also applicable
02018     to floating-point types. 
02019 */
02020 template <typename T> static ConstExpr *
02021 lConstFoldBinIntOp(BinaryExpr::Op op, const T *v0, const T *v1, ConstExpr *carg0) {
02022     T result[ISPC_MAX_NVEC];
02023     int count = carg0->Count();
02024         
02025     switch (op) {
02026         FOLD_OP(BinaryExpr::Mod, %);
02027         FOLD_OP(BinaryExpr::Shl, <<);
02028         FOLD_OP(BinaryExpr::Shr, >>);
02029         FOLD_OP(BinaryExpr::BitAnd, &);
02030         FOLD_OP(BinaryExpr::BitXor, ^);
02031         FOLD_OP(BinaryExpr::BitOr, |);
02032     default:
02033         return NULL;
02034     }
02035 
02036     return new ConstExpr(carg0->GetType(), result, carg0->pos);
02037 }
02038 
02039 
02040 /** Constant fold the binary logical ops.
02041  */ 
02042 template <typename T> static ConstExpr *
02043 lConstFoldBinLogicalOp(BinaryExpr::Op op, const T *v0, const T *v1, ConstExpr *carg0) {
02044     bool result[ISPC_MAX_NVEC];
02045     int count = carg0->Count();
02046 
02047     switch (op) {
02048         FOLD_OP(BinaryExpr::Lt, <);
02049         FOLD_OP(BinaryExpr::Gt, >);
02050         FOLD_OP(BinaryExpr::Le, <=);
02051         FOLD_OP(BinaryExpr::Ge, >=);
02052         FOLD_OP(BinaryExpr::Equal, ==);
02053         FOLD_OP(BinaryExpr::NotEqual, !=);
02054         FOLD_OP(BinaryExpr::LogicalAnd, &&);
02055         FOLD_OP(BinaryExpr::LogicalOr, ||);
02056     default:
02057         return NULL;
02058     }
02059 
02060     const Type *rType = carg0->GetType()->IsUniformType() ? 
02061         AtomicType::UniformBool : AtomicType::VaryingBool;
02062     return new ConstExpr(rType, result, carg0->pos);
02063 }
02064 
02065 
02066 /** Constant fold binary arithmetic ops.
02067  */
02068 template <typename T> static ConstExpr *
02069 lConstFoldBinArithOp(BinaryExpr::Op op, const T *v0, const T *v1, ConstExpr *carg0,
02070                      SourcePos pos) {
02071     T result[ISPC_MAX_NVEC];
02072     int count = carg0->Count();
02073 
02074     switch (op) {
02075         FOLD_OP(BinaryExpr::Add, +);
02076         FOLD_OP(BinaryExpr::Sub, -);
02077         FOLD_OP(BinaryExpr::Mul, *);
02078     case BinaryExpr::Div:
02079         for (int i = 0; i < count; ++i) {
02080             if (v1[i] == 0) {
02081                 Error(pos, "Division by zero encountered in expression.");
02082                 result[i] = 0;
02083             }
02084             else
02085                 result[i] = (v0[i] / v1[i]);
02086         }
02087         break;
02088     default:
02089         return NULL;
02090     }
02091     
02092     return new ConstExpr(carg0->GetType(), result, carg0->pos);
02093 }
02094 
02095 
02096 /** Constant fold the various boolean binary ops.
02097  */
02098 static ConstExpr *
02099 lConstFoldBoolBinOp(BinaryExpr::Op op, const bool *v0, const bool *v1, 
02100                     ConstExpr *carg0) {
02101     bool result[ISPC_MAX_NVEC];
02102     int count = carg0->Count();
02103 
02104     switch (op) {
02105         FOLD_OP(BinaryExpr::BitAnd, &);
02106         FOLD_OP(BinaryExpr::BitXor, ^);
02107         FOLD_OP(BinaryExpr::BitOr, |);
02108         FOLD_OP(BinaryExpr::Lt, <);
02109         FOLD_OP(BinaryExpr::Gt, >);
02110         FOLD_OP(BinaryExpr::Le, <=);
02111         FOLD_OP(BinaryExpr::Ge, >=);
02112         FOLD_OP(BinaryExpr::Equal, ==);
02113         FOLD_OP(BinaryExpr::NotEqual, !=);
02114         FOLD_OP(BinaryExpr::LogicalAnd, &&);
02115         FOLD_OP(BinaryExpr::LogicalOr, ||);
02116     default:
02117         return NULL;
02118     }
02119 
02120     return new ConstExpr(carg0->GetType(), result, carg0->pos);
02121 }
02122 
02123 
02124 Expr *
02125 BinaryExpr::Optimize() {
02126     if (arg0 == NULL || arg1 == NULL)
02127         return NULL;
02128 
02129     ConstExpr *constArg0 = dynamic_cast<ConstExpr *>(arg0);
02130     ConstExpr *constArg1 = dynamic_cast<ConstExpr *>(arg1);
02131 
02132     if (g->opt.fastMath) {
02133         // optimizations related to division by floats..
02134 
02135         // transform x / const -> x * (1/const)
02136         if (op == Div && constArg1 != NULL) {
02137             const Type *type1 = constArg1->GetType();
02138             if (Type::EqualIgnoringConst(type1, AtomicType::UniformFloat) ||
02139                 Type::EqualIgnoringConst(type1, AtomicType::VaryingFloat)) {
02140                 float inv[ISPC_MAX_NVEC];
02141                 int count = constArg1->AsFloat(inv);
02142                 for (int i = 0; i < count; ++i)
02143                     inv[i] = 1.f / inv[i];
02144                 Expr *einv = new ConstExpr(type1, inv, constArg1->pos);
02145                 Expr *e = new BinaryExpr(Mul, arg0, einv, pos);
02146                 e = ::TypeCheck(e);
02147                 if (e == NULL)
02148                     return NULL;
02149                 return ::Optimize(e);
02150             }
02151         }
02152 
02153         // transform x / y -> x * rcp(y)
02154         if (op == Div) {
02155             const Type *type1 = arg1->GetType();
02156             if (Type::EqualIgnoringConst(type1, AtomicType::UniformFloat) ||
02157                 Type::EqualIgnoringConst(type1, AtomicType::VaryingFloat)) {
02158                 // Get the symbol for the appropriate builtin
02159                 std::vector<Symbol *> rcpFuns;
02160                 m->symbolTable->LookupFunction("rcp", &rcpFuns);
02161                 if (rcpFuns.size() > 0) {
02162                     AssertPos(pos, rcpFuns.size() == 2);
02163                     Expr *rcpSymExpr = new FunctionSymbolExpr("rcp", rcpFuns, pos);
02164                     ExprList *args = new ExprList(arg1, arg1->pos);
02165                     Expr *rcpCall = new FunctionCallExpr(rcpSymExpr, args, 
02166                                                          arg1->pos);
02167                     rcpCall = ::TypeCheck(rcpCall);
02168                     if (rcpCall == NULL)
02169                         return NULL;
02170                     rcpCall = ::Optimize(rcpCall);
02171                     if (rcpCall == NULL)
02172                         return NULL;
02173 
02174                     Expr *ret = new BinaryExpr(Mul, arg0, rcpCall, pos);
02175                     ret = ::TypeCheck(ret);
02176                     if (ret == NULL)
02177                         return NULL;
02178                     return ::Optimize(ret);
02179                 }
02180                 else
02181                     Warning(pos, "rcp() not found from stdlib.  Can't apply "
02182                             "fast-math rcp optimization.");
02183             }
02184         }
02185     }
02186 
02187     // From here on out, we're just doing constant folding, so if both args
02188     // aren't constants then we're done...
02189     if (constArg0 == NULL || constArg1 == NULL)
02190         return this;
02191 
02192     AssertPos(pos, Type::EqualIgnoringConst(arg0->GetType(), arg1->GetType()));
02193     const Type *type = arg0->GetType()->GetAsNonConstType();
02194     if (Type::Equal(type, AtomicType::UniformFloat) || 
02195         Type::Equal(type, AtomicType::VaryingFloat)) {
02196         float v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
02197         constArg0->AsFloat(v0);
02198         constArg1->AsFloat(v1);
02199         ConstExpr *ret;
02200         if ((ret = lConstFoldBinArithOp(op, v0, v1, constArg0, pos)) != NULL)
02201             return ret;
02202         else if ((ret = lConstFoldBinLogicalOp(op, v0, v1, constArg0)) != NULL)
02203             return ret;
02204         else 
02205             return this;
02206     }
02207     if (Type::Equal(type, AtomicType::UniformDouble) || 
02208         Type::Equal(type, AtomicType::VaryingDouble)) {
02209         double v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
02210         constArg0->AsDouble(v0);
02211         constArg1->AsDouble(v1);
02212         ConstExpr *ret;
02213         if ((ret = lConstFoldBinArithOp(op, v0, v1, constArg0, pos)) != NULL)
02214             return ret;
02215         else if ((ret = lConstFoldBinLogicalOp(op, v0, v1, constArg0)) != NULL)
02216             return ret;
02217         else 
02218             return this;
02219     }
02220     if (Type::Equal(type, AtomicType::UniformInt32) || 
02221         Type::Equal(type, AtomicType::VaryingInt32)) {
02222         int32_t v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
02223         constArg0->AsInt32(v0);
02224         constArg1->AsInt32(v1);
02225         ConstExpr *ret;
02226         if ((ret = lConstFoldBinArithOp(op, v0, v1, constArg0, pos)) != NULL)
02227             return ret;
02228         else if ((ret = lConstFoldBinIntOp(op, v0, v1, constArg0)) != NULL)
02229             return ret;
02230         else if ((ret = lConstFoldBinLogicalOp(op, v0, v1, constArg0)) != NULL)
02231             return ret;
02232         else
02233             return this;
02234     }
02235     else if (Type::Equal(type, AtomicType::UniformUInt32) || 
02236              Type::Equal(type, AtomicType::VaryingUInt32) ||
02237              CastType<EnumType>(type) != NULL) {
02238         uint32_t v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
02239         constArg0->AsUInt32(v0);
02240         constArg1->AsUInt32(v1);
02241         ConstExpr *ret;
02242         if ((ret = lConstFoldBinArithOp(op, v0, v1, constArg0, pos)) != NULL)
02243             return ret;
02244         else if ((ret = lConstFoldBinIntOp(op, v0, v1, constArg0)) != NULL)
02245             return ret;
02246         else if ((ret = lConstFoldBinLogicalOp(op, v0, v1, constArg0)) != NULL)
02247             return ret;
02248         else
02249             return this;
02250     }
02251     else if (Type::Equal(type, AtomicType::UniformBool) || 
02252              Type::Equal(type, AtomicType::VaryingBool)) {
02253         bool v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
02254         constArg0->AsBool(v0);
02255         constArg1->AsBool(v1);
02256         ConstExpr *ret;
02257         if ((ret = lConstFoldBoolBinOp(op, v0, v1, constArg0)) != NULL)
02258             return ret;
02259         else if ((ret = lConstFoldBinLogicalOp(op, v0, v1, constArg0)) != NULL)
02260             return ret;
02261         else 
02262             return this;
02263     }
02264     else
02265         return this;
02266 }
02267 
02268 
02269 Expr *
02270 BinaryExpr::TypeCheck() {
02271     if (arg0 == NULL || arg1 == NULL)
02272         return NULL;
02273 
02274     const Type *type0 = arg0->GetType(), *type1 = arg1->GetType();
02275     if (type0 == NULL || type1 == NULL)
02276         return NULL;
02277 
02278     // If either operand is a reference, dereference it before we move
02279     // forward
02280     if (CastType<ReferenceType>(type0) != NULL) {
02281         arg0 = new RefDerefExpr(arg0, arg0->pos);
02282         type0 = arg0->GetType();
02283         AssertPos(pos, type0 != NULL);
02284     }
02285     if (CastType<ReferenceType>(type1) != NULL) {
02286         arg1 = new RefDerefExpr(arg1, arg1->pos);
02287         type1 = arg1->GetType();
02288         AssertPos(pos, type1 != NULL);
02289     }
02290 
02291     // Convert arrays to pointers to their first elements
02292     if (CastType<ArrayType>(type0) != NULL) {
02293         arg0 = lArrayToPointer(arg0);
02294         type0 = arg0->GetType();
02295     }
02296     if (CastType<ArrayType>(type1) != NULL) {
02297         arg1 = lArrayToPointer(arg1);
02298         type1 = arg1->GetType();
02299     }
02300 
02301     // Prohibit binary operators with SOA types
02302     if (type0->GetSOAWidth() > 0) {
02303         Error(arg0->pos, "Illegal to use binary operator %s with SOA type "
02304               "\"%s\".", lOpString(op), type0->GetString().c_str());
02305         return NULL;
02306     }
02307     if (type1->GetSOAWidth() > 0) {
02308         Error(arg1->pos, "Illegal to use binary operator %s with SOA type "
02309               "\"%s\".", lOpString(op), type1->GetString().c_str());
02310         return NULL;
02311     }
02312 
02313     const PointerType *pt0 = CastType<PointerType>(type0);
02314     const PointerType *pt1 = CastType<PointerType>(type1);
02315     if (pt0 != NULL && pt1 != NULL && op == Sub) {
02316         // Pointer subtraction
02317         if (PointerType::IsVoidPointer(type0)) {
02318             Error(pos, "Illegal to perform pointer arithmetic "
02319                   "on \"%s\" type.", type0->GetString().c_str());
02320             return NULL;
02321         }
02322         if (PointerType::IsVoidPointer(type1)) {
02323             Error(pos, "Illegal to perform pointer arithmetic "
02324                   "on \"%s\" type.", type1->GetString().c_str());
02325             return NULL;
02326         }
02327         if (CastType<UndefinedStructType>(pt0->GetBaseType())) {
02328             Error(pos, "Illegal to perform pointer arithmetic "
02329                   "on undefined struct type \"%s\".", pt0->GetString().c_str());
02330             return NULL;
02331         }
02332         if (CastType<UndefinedStructType>(pt1->GetBaseType())) {
02333             Error(pos, "Illegal to perform pointer arithmetic "
02334                   "on undefined struct type \"%s\".", pt1->GetString().c_str());
02335             return NULL;
02336         }
02337 
02338         const Type *t = Type::MoreGeneralType(type0, type1, pos, "-");
02339         if (t == NULL)
02340             return NULL;
02341 
02342         arg0 = TypeConvertExpr(arg0, t, "pointer subtraction");
02343         arg1 = TypeConvertExpr(arg1, t, "pointer subtraction");
02344         if (arg0 == NULL || arg1 == NULL)
02345             return NULL;
02346 
02347         return this;
02348     }
02349     else if (((pt0 != NULL || pt1 != NULL) && op == Add) ||
02350              (pt0 != NULL && op == Sub)) {
02351         // Handle ptr + int, int + ptr, ptr - int
02352         if (pt0 != NULL && pt1 != NULL) {
02353             Error(pos, "Illegal to add two pointer types \"%s\" and \"%s\".",
02354                   pt0->GetString().c_str(), pt1->GetString().c_str());
02355             return NULL;
02356         }
02357         else if (pt1 != NULL) {
02358             // put in canonical order with the pointer as the first operand
02359             // for GetValue()
02360             std::swap(arg0, arg1);
02361             std::swap(type0, type1);
02362             std::swap(pt0, pt1);
02363         }
02364 
02365         AssertPos(pos, pt0 != NULL);
02366 
02367         if (PointerType::IsVoidPointer(pt0)) {
02368             Error(pos, "Illegal to perform pointer arithmetic "
02369                   "on \"%s\" type.", pt0->GetString().c_str());
02370             return NULL;
02371         }
02372         if (CastType<UndefinedStructType>(pt0->GetBaseType())) {
02373             Error(pos, "Illegal to perform pointer arithmetic "
02374                   "on undefined struct type \"%s\".", pt0->GetString().c_str());
02375             return NULL;
02376         }
02377 
02378         const Type *offsetType = g->target.is32Bit ? 
02379             AtomicType::UniformInt32 : AtomicType::UniformInt64;
02380         if (pt0->IsVaryingType())
02381             offsetType = offsetType->GetAsVaryingType();
02382         if (type1->IsVaryingType()) {
02383             arg0 = TypeConvertExpr(arg0, type0->GetAsVaryingType(), 
02384                                    "pointer addition");
02385             offsetType = offsetType->GetAsVaryingType();
02386             AssertPos(pos, arg0 != NULL);
02387         }
02388 
02389         arg1 = TypeConvertExpr(arg1, offsetType, lOpString(op));
02390         if (arg1 == NULL)
02391             return NULL;
02392 
02393         return this;
02394     }
02395 
02396     switch (op) {
02397     case Shl:
02398     case Shr:
02399     case BitAnd:
02400     case BitXor:
02401     case BitOr: {
02402         // Must have integer or bool-typed operands for these bit-related
02403         // ops; don't do any implicit conversions from floats here...
02404         if (!type0->IsIntType() && !type0->IsBoolType()) {
02405             Error(arg0->pos, "First operand to binary operator \"%s\" must be "
02406                   "an integer or bool.", lOpString(op));
02407             return NULL;
02408         }
02409         if (!type1->IsIntType() && !type1->IsBoolType()) {
02410             Error(arg1->pos, "Second operand to binary operator \"%s\" must be "
02411                   "an integer or bool.", lOpString(op));
02412             return NULL;
02413         }
02414 
02415         if (op == Shl || op == Shr) {
02416             bool isVarying = (type0->IsVaryingType() ||
02417                               type1->IsVaryingType());
02418             if (isVarying) {
02419                 arg0 = TypeConvertExpr(arg0, type0->GetAsVaryingType(), 
02420                                        "shift operator");
02421                 if (arg0 == NULL)
02422                     return NULL;
02423                 type0 = arg0->GetType();
02424             }
02425             arg1 = TypeConvertExpr(arg1, type0, "shift operator");
02426             if (arg1 == NULL)
02427                 return NULL;
02428         }
02429         else {
02430             const Type *promotedType = Type::MoreGeneralType(type0, type1, arg0->pos,
02431                                                              "binary bit op");
02432             if (promotedType == NULL)
02433                 return NULL;
02434 
02435             arg0 = TypeConvertExpr(arg0, promotedType, "binary bit op");
02436             arg1 = TypeConvertExpr(arg1, promotedType, "binary bit op");
02437             if (arg0 == NULL || arg1 == NULL)
02438                 return NULL;
02439         }
02440         return this;
02441     }
02442     case Add:
02443     case Sub:
02444     case Mul:
02445     case Div:
02446     case Mod: {
02447         // Must be numeric type for these.  (And mod is special--can't be float)
02448         if (!type0->IsNumericType() || (op == Mod && type0->IsFloatType())) {
02449             Error(arg0->pos, "First operand to binary operator \"%s\" is of "
02450                   "invalid type \"%s\".", lOpString(op), 
02451                   type0->GetString().c_str());
02452             return NULL;
02453         }
02454         if (!type1->IsNumericType() || (op == Mod && type1->IsFloatType())) {
02455             Error(arg1->pos, "First operand to binary operator \"%s\" is of "
02456                   "invalid type \"%s\".", lOpString(op), 
02457                   type1->GetString().c_str());
02458             return NULL;
02459         }
02460 
02461         const Type *promotedType = Type::MoreGeneralType(type0, type1, 
02462                                                          Union(arg0->pos, arg1->pos),
02463                                                          lOpString(op));
02464         if (promotedType == NULL)
02465             return NULL;
02466 
02467         arg0 = TypeConvertExpr(arg0, promotedType, lOpString(op));
02468         arg1 = TypeConvertExpr(arg1, promotedType, lOpString(op));
02469         if (arg0 == NULL || arg1 == NULL)
02470             return NULL;
02471         return this;
02472     }
02473     case Lt:
02474     case Gt:
02475     case Le:
02476     case Ge:
02477     case Equal:
02478     case NotEqual: {
02479         const PointerType *pt0 = CastType<PointerType>(type0);
02480         const PointerType *pt1 = CastType<PointerType>(type1);
02481 
02482         // Convert '0' in expressions where the other expression is a
02483         // pointer type to a NULL pointer.
02484         if (pt0 != NULL && lIsAllIntZeros(arg1)) {
02485             arg1 = new NullPointerExpr(pos);
02486             type1 = arg1->GetType();
02487             pt1 = CastType<PointerType>(type1);
02488         }
02489         else if (pt1 != NULL && lIsAllIntZeros(arg0)) {
02490             arg0 = new NullPointerExpr(pos);
02491             type0 = arg1->GetType();
02492             pt0 = CastType<PointerType>(type0);
02493         }
02494 
02495         if (pt0 == NULL && pt1 == NULL) {
02496             if (!type0->IsBoolType() && !type0->IsNumericType()) {
02497                 Error(arg0->pos,
02498                       "First operand to operator \"%s\" is of "
02499                       "non-comparable type \"%s\".", lOpString(op), 
02500                       type0->GetString().c_str());
02501                 return NULL;
02502             }
02503             if (!type1->IsBoolType() && !type1->IsNumericType()) {
02504                 Error(arg1->pos,
02505                       "Second operand to operator \"%s\" is of "
02506                       "non-comparable type \"%s\".", lOpString(op), 
02507                       type1->GetString().c_str());
02508                 return NULL;
02509             }
02510         }
02511 
02512         const Type *promotedType = 
02513             Type::MoreGeneralType(type0, type1, arg0->pos, lOpString(op));
02514         if (promotedType == NULL)
02515             return NULL;
02516 
02517         arg0 = TypeConvertExpr(arg0, promotedType, lOpString(op));
02518         arg1 = TypeConvertExpr(arg1, promotedType, lOpString(op));
02519         if (arg0 == NULL || arg1 == NULL)
02520             return NULL;
02521         return this;
02522     }
02523     case LogicalAnd:
02524     case LogicalOr: {
02525         // For now, we just type convert to boolean types, of the same
02526         // variability as the original types.  (When generating code, it's
02527         // useful to have preserved the uniform/varying distinction.)
02528         const AtomicType *boolType0 = type0->IsUniformType() ? 
02529             AtomicType::UniformBool : AtomicType::VaryingBool;
02530         const AtomicType *boolType1 = type1->IsUniformType() ? 
02531             AtomicType::UniformBool : AtomicType::VaryingBool;
02532 
02533         const Type *destType0 = NULL, *destType1 = NULL;
02534         const VectorType *vtype0 = CastType<VectorType>(type0);
02535         const VectorType *vtype1 = CastType<VectorType>(type1);
02536         if (vtype0 && vtype1) {
02537             int sz0 = vtype0->GetElementCount(), sz1 = vtype1->GetElementCount();
02538             if (sz0 != sz1) {
02539                 Error(pos, "Can't do logical operation \"%s\" between vector types of "
02540                       "different sizes (%d vs. %d).", lOpString(op), sz0, sz1);
02541                 return NULL;
02542             }
02543             destType0 = new VectorType(boolType0, sz0);
02544             destType1 = new VectorType(boolType1, sz1);
02545         }
02546         else if (vtype0 != NULL) {
02547             destType0 = new VectorType(boolType0, vtype0->GetElementCount());
02548             destType1 = new VectorType(boolType1, vtype0->GetElementCount());
02549         }
02550         else if (vtype1 != NULL) {
02551             destType0 = new VectorType(boolType0, vtype1->GetElementCount());
02552             destType1 = new VectorType(boolType1, vtype1->GetElementCount());
02553         }
02554         else {
02555             destType0 = boolType0;
02556             destType1 = boolType1;
02557         }
02558 
02559         arg0 = TypeConvertExpr(arg0, destType0, lOpString(op));
02560         arg1 = TypeConvertExpr(arg1, destType1, lOpString(op));
02561         if (arg0 == NULL || arg1 == NULL)
02562             return NULL;
02563         return this;
02564     }
02565     case Comma:
02566         return this;
02567     default:
02568         FATAL("logic error");
02569         return NULL;
02570     }
02571 }
02572 
02573 
02574 int
02575 BinaryExpr::EstimateCost() const {
02576     if (dynamic_cast<ConstExpr *>(arg0) != NULL &&
02577         dynamic_cast<ConstExpr *>(arg1) != NULL)
02578         return 0;
02579 
02580     return (op == Div || op == Mod) ? COST_COMPLEX_ARITH_OP : 
02581                                       COST_SIMPLE_ARITH_LOGIC_OP;
02582 }
02583 
02584 
02585 void
02586 BinaryExpr::Print() const {
02587     if (!arg0 || !arg1 || !GetType())
02588         return;
02589 
02590     printf("[ %s ] (", GetType()->GetString().c_str());
02591     arg0->Print();
02592     printf(" %s ", lOpString(op));
02593     arg1->Print();
02594     printf(")");
02595     pos.Print();
02596 }
02597 
02598 
02599 ///////////////////////////////////////////////////////////////////////////
02600 // AssignExpr
02601 
02602 static const char *
02603 lOpString(AssignExpr::Op op) {
02604     switch (op) {
02605     case AssignExpr::Assign:    return "assignment operator";
02606     case AssignExpr::MulAssign: return "*=";
02607     case AssignExpr::DivAssign: return "/=";
02608     case AssignExpr::ModAssign: return "%%=";
02609     case AssignExpr::AddAssign: return "+=";
02610     case AssignExpr::SubAssign: return "-=";
02611     case AssignExpr::ShlAssign: return "<<=";
02612     case AssignExpr::ShrAssign: return ">>=";
02613     case AssignExpr::AndAssign: return "&=";
02614     case AssignExpr::XorAssign: return "^=";
02615     case AssignExpr::OrAssign:  return "|=";
02616     default:
02617         FATAL("Missing op in lOpstring");
02618         return "";
02619     }
02620 }
02621 
02622 /** Emit code to do an "assignment + operation" operator, e.g. "+=".
02623  */
02624 static llvm::Value *
02625 lEmitOpAssign(AssignExpr::Op op, Expr *arg0, Expr *arg1, const Type *type, 
02626               Symbol *baseSym, SourcePos pos, FunctionEmitContext *ctx) {
02627     llvm::Value *lv = arg0->GetLValue(ctx);
02628     if (!lv) {
02629         // FIXME: I think this test is unnecessary and that this case
02630         // should be caught during typechecking
02631         Error(pos, "Can't assign to left-hand side of expression.");
02632         return NULL;
02633     }
02634     const Type *lvalueType = arg0->GetLValueType();
02635     const Type *resultType = arg0->GetType();
02636     if (lvalueType == NULL || resultType == NULL)
02637         return NULL;
02638 
02639     // Get the value on the right-hand side of the assignment+operation
02640     // operator and load the current value on the left-hand side.
02641     llvm::Value *rvalue = arg1->GetValue(ctx);
02642     llvm::Value *mask = lMaskForSymbol(baseSym, ctx);
02643     ctx->SetDebugPos(arg0->pos);
02644     llvm::Value *oldLHS = ctx->LoadInst(lv, mask, lvalueType);
02645     ctx->SetDebugPos(pos);
02646 
02647     // Map the operator to the corresponding BinaryExpr::Op operator
02648     BinaryExpr::Op basicop;
02649     switch (op) {
02650     case AssignExpr::MulAssign: basicop = BinaryExpr::Mul;    break;
02651     case AssignExpr::DivAssign: basicop = BinaryExpr::Div;    break;
02652     case AssignExpr::ModAssign: basicop = BinaryExpr::Mod;    break;
02653     case AssignExpr::AddAssign: basicop = BinaryExpr::Add;    break;
02654     case AssignExpr::SubAssign: basicop = BinaryExpr::Sub;    break;
02655     case AssignExpr::ShlAssign: basicop = BinaryExpr::Shl;    break;
02656     case AssignExpr::ShrAssign: basicop = BinaryExpr::Shr;    break;
02657     case AssignExpr::AndAssign: basicop = BinaryExpr::BitAnd; break;
02658     case AssignExpr::XorAssign: basicop = BinaryExpr::BitXor; break;
02659     case AssignExpr::OrAssign:  basicop = BinaryExpr::BitOr;  break;
02660     default:
02661         FATAL("logic error in lEmitOpAssign()");
02662         return NULL;
02663     }
02664 
02665     // Emit the code to compute the new value
02666     llvm::Value *newValue = NULL;
02667     switch (op) {
02668     case AssignExpr::MulAssign:
02669     case AssignExpr::DivAssign:
02670     case AssignExpr::ModAssign:
02671     case AssignExpr::AddAssign:
02672     case AssignExpr::SubAssign:
02673         newValue = lEmitBinaryArith(basicop, oldLHS, rvalue, type,
02674                                     arg1->GetType(), ctx, pos);
02675         break;
02676     case AssignExpr::ShlAssign:
02677     case AssignExpr::ShrAssign:
02678     case AssignExpr::AndAssign:
02679     case AssignExpr::XorAssign:
02680     case AssignExpr::OrAssign:
02681         newValue = lEmitBinaryBitOp(basicop, oldLHS, rvalue, 
02682                                     arg0->GetType()->IsUnsignedType(), ctx);
02683         break;
02684     default:
02685         FATAL("logic error in lEmitOpAssign");
02686         return NULL;
02687     }
02688 
02689     // And store the result back to the lvalue.
02690     ctx->SetDebugPos(arg0->pos);
02691     lStoreAssignResult(newValue, lv, resultType, lvalueType, ctx, baseSym);
02692 
02693     return newValue;
02694 }
02695 
02696 
02697 AssignExpr::AssignExpr(AssignExpr::Op o, Expr *a, Expr *b, SourcePos p) 
02698     : Expr(p), op(o) {
02699     lvalue = a;
02700     rvalue = b;
02701 }
02702 
02703 
02704 llvm::Value *
02705 AssignExpr::GetValue(FunctionEmitContext *ctx) const {
02706     const Type *type = NULL;
02707     if (lvalue == NULL || rvalue == NULL || (type = GetType()) == NULL)
02708         return NULL;
02709 
02710     ctx->SetDebugPos(pos);
02711 
02712     Symbol *baseSym = lvalue->GetBaseSymbol();
02713 
02714     switch (op) {
02715     case Assign: {
02716         llvm::Value *ptr = lvalue->GetLValue(ctx);
02717         if (ptr == NULL) {
02718             Error(lvalue->pos, "Left hand side of assignment expression can't "
02719                   "be assigned to.");
02720             return NULL;
02721         }
02722         const Type *ptrType = lvalue->GetLValueType();
02723         const Type *valueType = rvalue->GetType();
02724         if (ptrType == NULL || valueType == NULL) {
02725             AssertPos(pos, m->errorCount > 0);
02726             return NULL;
02727         }
02728 
02729         llvm::Value *value = rvalue->GetValue(ctx);
02730         if (value == NULL) {
02731             AssertPos(pos, m->errorCount > 0);
02732             return NULL;
02733         }
02734 
02735         ctx->SetDebugPos(lvalue->pos);
02736 
02737         lStoreAssignResult(value, ptr, valueType, ptrType, ctx, baseSym);
02738 
02739         return value;
02740     }
02741     case MulAssign:
02742     case DivAssign:
02743     case ModAssign:
02744     case AddAssign:
02745     case SubAssign:
02746     case ShlAssign:
02747     case ShrAssign:
02748     case AndAssign:
02749     case XorAssign:
02750     case OrAssign: {
02751         // This should be caught during type checking
02752         AssertPos(pos, !CastType<ArrayType>(type) &&
02753                !CastType<StructType>(type));
02754         return lEmitOpAssign(op, lvalue, rvalue, type, baseSym, pos, ctx);
02755     }
02756     default:
02757         FATAL("logic error in AssignExpr::GetValue()");
02758         return NULL;
02759     }
02760 }
02761 
02762 
02763 Expr *
02764 AssignExpr::Optimize() {
02765     if (lvalue == NULL || rvalue == NULL)
02766         return NULL;
02767     return this;
02768 }
02769 
02770 
02771 const Type *
02772 AssignExpr::GetType() const {
02773     return lvalue ? lvalue->GetType() : NULL;
02774 }
02775 
02776 
02777 /** Recursively checks a structure type to see if it (or any struct type
02778     that it holds) has a const-qualified member. */
02779 static bool
02780 lCheckForConstStructMember(SourcePos pos, const StructType *structType,
02781                            const StructType *initialType) {
02782     for (int i = 0; i < structType->GetElementCount(); ++i) {
02783         const Type *t = structType->GetElementType(i);
02784         if (t->IsConstType()) {
02785             if (structType == initialType)
02786                 Error(pos, "Illegal to assign to type \"%s\" due to element "
02787                       "\"%s\" with type \"%s\".", structType->GetString().c_str(),
02788                       structType->GetElementName(i).c_str(),
02789                       t->GetString().c_str());
02790             else
02791                 Error(pos, "Illegal to assign to type \"%s\" in type \"%s\" "
02792                       "due to element \"%s\" with type \"%s\".", 
02793                       structType->GetString().c_str(),
02794                       initialType->GetString().c_str(), 
02795                       structType->GetElementName(i).c_str(),
02796                       t->GetString().c_str());
02797             return true;
02798         }
02799 
02800         const StructType *st = CastType<StructType>(t);
02801         if (st != NULL && lCheckForConstStructMember(pos, st, initialType))
02802             return true;
02803     }
02804     return false;
02805 }
02806 
02807 
02808 Expr *
02809 AssignExpr::TypeCheck() {
02810     if (lvalue == NULL || rvalue == NULL) 
02811         return NULL;
02812 
02813     bool lvalueIsReference = 
02814         CastType<ReferenceType>(lvalue->GetType()) != NULL;
02815     if (lvalueIsReference)
02816         lvalue = new RefDerefExpr(lvalue, lvalue->pos);
02817 
02818     FunctionSymbolExpr *fse;
02819     if ((fse = dynamic_cast<FunctionSymbolExpr *>(rvalue)) != NULL) {
02820         // Special case to use the type of the LHS to resolve function
02821         // overloads when we're assigning a function pointer where the
02822         // function is overloaded.
02823         const Type *lvalueType = lvalue->GetType();
02824         const FunctionType *ftype;
02825         if (CastType<PointerType>(lvalueType) == NULL ||
02826             (ftype = CastType<FunctionType>(lvalueType->GetBaseType())) == NULL) {
02827             Error(lvalue->pos, "Can't assign function pointer to type \"%s\".",
02828                   lvalue->GetType()->GetString().c_str());
02829             return NULL;
02830         }
02831 
02832         std::vector<const Type *> paramTypes;
02833         for (int i = 0; i < ftype->GetNumParameters(); ++i)
02834             paramTypes.push_back(ftype->GetParameterType(i));
02835 
02836         if (!fse->ResolveOverloads(rvalue->pos, paramTypes)) {
02837             Error(pos, "Unable to find overloaded function for function "
02838                   "pointer assignment.");
02839             return NULL;
02840         }
02841     }
02842 
02843     const Type *lhsType = lvalue->GetType();
02844     if (lhsType == NULL) {
02845         AssertPos(pos, m->errorCount > 0);
02846         return NULL;
02847     }
02848 
02849     if (lhsType->IsConstType()) {
02850         Error(lvalue->pos, "Can't assign to type \"%s\" on left-hand side of "
02851               "expression.", lhsType->GetString().c_str());
02852         return NULL;
02853     }
02854 
02855     if (CastType<PointerType>(lhsType) != NULL) {
02856         if (op == AddAssign || op == SubAssign) {
02857             if (PointerType::IsVoidPointer(lhsType)) {
02858                 Error(pos, "Illegal to perform pointer arithmetic on \"%s\" "
02859                       "type.", lhsType->GetString().c_str());
02860                 return NULL;
02861             }
02862 
02863             const Type *deltaType = g->target.is32Bit ? AtomicType::UniformInt32 :
02864                 AtomicType::UniformInt64;
02865             if (lhsType->IsVaryingType())
02866                 deltaType = deltaType->GetAsVaryingType();
02867             rvalue = TypeConvertExpr(rvalue, deltaType, lOpString(op));
02868         }
02869         else if (op == Assign)
02870             rvalue = TypeConvertExpr(rvalue, lhsType, "assignment");
02871         else {
02872             Error(lvalue->pos, "Assignment operator \"%s\" is illegal with pointer types.",
02873                   lOpString(op));
02874             return NULL;
02875         }
02876     }
02877     else if (CastType<ArrayType>(lhsType) != NULL) {
02878         Error(lvalue->pos, "Illegal to assign to array type \"%s\".",
02879               lhsType->GetString().c_str());
02880         return NULL;
02881     }
02882     else
02883         rvalue = TypeConvertExpr(rvalue, lhsType, lOpString(op));
02884 
02885     if (rvalue == NULL)
02886         return NULL;
02887 
02888     if (lhsType->IsFloatType() == true &&
02889         (op == ShlAssign || op == ShrAssign || op == AndAssign || 
02890          op == XorAssign || op == OrAssign)) {
02891             Error(pos, "Illegal to use %s operator with floating-point "
02892                   "operands.", lOpString(op));
02893             return NULL;
02894     }
02895 
02896     const StructType *st = CastType<StructType>(lhsType);
02897     if (st != NULL) {
02898         // Make sure we're not assigning to a struct that has a constant member
02899         if (lCheckForConstStructMember(pos, st, st))
02900             return NULL;
02901         
02902         if (op != Assign) {
02903             Error(lvalue->pos,  "Assignment operator \"%s\" is illegal with struct "
02904                   "type \"%s\".", lOpString(op), st->GetString().c_str());
02905             return NULL;
02906         }
02907     }
02908 
02909     return this;
02910 }
02911 
02912 
02913 int
02914 AssignExpr::EstimateCost() const {
02915     if (op == Assign)
02916         return COST_ASSIGN;
02917     if (op == DivAssign || op == ModAssign)
02918         return COST_ASSIGN + COST_COMPLEX_ARITH_OP;
02919     else
02920         return COST_ASSIGN + COST_SIMPLE_ARITH_LOGIC_OP;
02921 }
02922 
02923 
02924 void
02925 AssignExpr::Print() const {
02926     if (!lvalue || !rvalue || !GetType())
02927         return;
02928 
02929     printf("[%s] assign (", GetType()->GetString().c_str());
02930     lvalue->Print();
02931     printf(" %s ", lOpString(op));
02932     rvalue->Print();
02933     printf(")");
02934     pos.Print();
02935 }
02936 
02937 
02938 ///////////////////////////////////////////////////////////////////////////
02939 // SelectExpr
02940 
02941 SelectExpr::SelectExpr(Expr *t, Expr *e1, Expr *e2, SourcePos p) 
02942     : Expr(p) {
02943     test = t;
02944     expr1 = e1;
02945     expr2 = e2;
02946 }
02947 
02948 
02949 /** Emit code to select between two varying values based on a varying test
02950     value.
02951  */
02952 static llvm::Value *
02953 lEmitVaryingSelect(FunctionEmitContext *ctx, llvm::Value *test, 
02954                    llvm::Value *expr1, llvm::Value *expr2, 
02955                    const Type *type) {
02956     llvm::Value *resultPtr = ctx->AllocaInst(expr1->getType(), "selectexpr_tmp");
02957     // Don't need to worry about masking here
02958     ctx->StoreInst(expr2, resultPtr);
02959     // Use masking to conditionally store the expr1 values
02960     Assert(resultPtr->getType() ==
02961            PointerType::GetUniform(type)->LLVMType(g->ctx));
02962     ctx->StoreInst(expr1, resultPtr, test, type, PointerType::GetUniform(type));
02963     return ctx->LoadInst(resultPtr, "selectexpr_final");
02964 }
02965 
02966 
02967 static void
02968 lEmitSelectExprCode(FunctionEmitContext *ctx, llvm::Value *testVal, 
02969                     llvm::Value *oldMask, llvm::Value *fullMask,
02970                     Expr *expr, llvm::Value *exprPtr) {
02971     llvm::BasicBlock *bbEval = ctx->CreateBasicBlock("select_eval_expr");
02972     llvm::BasicBlock *bbDone = ctx->CreateBasicBlock("select_done");
02973 
02974     // Check to see if the test was true for any of the currently executing
02975     // program instances.
02976     llvm::Value *testAndFullMask = 
02977         ctx->BinaryOperator(llvm::Instruction::And, testVal, fullMask, 
02978                             "test&mask");
02979     llvm::Value *anyOn = ctx->Any(testAndFullMask);
02980     ctx->BranchInst(bbEval, bbDone, anyOn);
02981 
02982     ctx->SetCurrentBasicBlock(bbEval);
02983     llvm::Value *testAndMask = 
02984         ctx->BinaryOperator(llvm::Instruction::And, testVal, oldMask, 
02985                             "test&mask");
02986     ctx->SetInternalMask(testAndMask);
02987     llvm::Value *exprVal = expr->GetValue(ctx);
02988     ctx->StoreInst(exprVal, exprPtr);
02989     ctx->BranchInst(bbDone);
02990 
02991     ctx->SetCurrentBasicBlock(bbDone);
02992 }
02993 
02994 
02995 llvm::Value *
02996 SelectExpr::GetValue(FunctionEmitContext *ctx) const {
02997     if (!expr1 || !expr2 || !test)
02998         return NULL;
02999 
03000     ctx->SetDebugPos(pos);
03001 
03002     const Type *testType = test->GetType()->GetAsNonConstType();
03003     // This should be taken care of during typechecking
03004     AssertPos(pos, Type::Equal(testType->GetBaseType(), AtomicType::UniformBool) ||
03005            Type::Equal(testType->GetBaseType(), AtomicType::VaryingBool));
03006 
03007     const Type *type = expr1->GetType();
03008 
03009     if (Type::Equal(testType, AtomicType::UniformBool)) {
03010         // Simple case of a single uniform bool test expression; we just
03011         // want one of the two expressions.  In this case, we can be
03012         // careful to evaluate just the one of the expressions that we need
03013         // the value of so that if the other one has side-effects or
03014         // accesses invalid memory, it doesn't execute.
03015         llvm::Value *testVal = test->GetValue(ctx);
03016         llvm::BasicBlock *testTrue = ctx->CreateBasicBlock("select_true");
03017         llvm::BasicBlock *testFalse = ctx->CreateBasicBlock("select_false");
03018         llvm::BasicBlock *testDone = ctx->CreateBasicBlock("select_done");
03019         ctx->BranchInst(testTrue, testFalse, testVal);
03020 
03021         ctx->SetCurrentBasicBlock(testTrue);
03022         llvm::Value *expr1Val = expr1->GetValue(ctx);
03023         // Note that truePred won't be necessarily equal to testTrue, in
03024         // case the expr1->GetValue() call changes the current basic block.
03025         llvm::BasicBlock *truePred = ctx->GetCurrentBasicBlock();
03026         ctx->BranchInst(testDone);
03027 
03028         ctx->SetCurrentBasicBlock(testFalse);
03029         llvm::Value *expr2Val = expr2->GetValue(ctx);
03030         // See comment above truePred for why we can't just assume we're in
03031         // the testFalse basic block here.
03032         llvm::BasicBlock *falsePred = ctx->GetCurrentBasicBlock();
03033         ctx->BranchInst(testDone);
03034 
03035         ctx->SetCurrentBasicBlock(testDone);
03036         llvm::PHINode *ret = ctx->PhiNode(expr1Val->getType(), 2, "select");
03037         ret->addIncoming(expr1Val, truePred);
03038         ret->addIncoming(expr2Val, falsePred);
03039         return ret;
03040     }
03041     else if (CastType<VectorType>(testType) == NULL) {
03042         // the test is a varying bool type
03043         llvm::Value *testVal = test->GetValue(ctx);
03044         AssertPos(pos, testVal->getType() == LLVMTypes::MaskType);
03045         llvm::Value *oldMask = ctx->GetInternalMask();
03046         llvm::Value *fullMask = ctx->GetFullMask();
03047 
03048         // We don't want to incur the overhead for short-circuit evaluation
03049         // for expressions that are both computationally simple and safe to
03050         // run with an "all off" mask.
03051         bool shortCircuit1 =
03052             (::EstimateCost(expr1) > PREDICATE_SAFE_IF_STATEMENT_COST ||
03053              SafeToRunWithMaskAllOff(expr1) == false);
03054         bool shortCircuit2 =
03055             (::EstimateCost(expr2) > PREDICATE_SAFE_IF_STATEMENT_COST ||
03056              SafeToRunWithMaskAllOff(expr2) == false);
03057 
03058         Debug(expr1->pos, "%sshort circuiting evaluation for select expr",
03059               shortCircuit1 ? "" : "Not ");
03060         Debug(expr2->pos, "%sshort circuiting evaluation for select expr",
03061               shortCircuit2 ? "" : "Not ");
03062 
03063         // Temporary storage to store the values computed for each
03064         // expression, if any.  (These stay as uninitialized memory if we
03065         // short circuit around the corresponding expression.)
03066         llvm::Type *exprType = 
03067             expr1->GetType()->LLVMType(g->ctx);
03068         llvm::Value *expr1Ptr = ctx->AllocaInst(exprType);
03069         llvm::Value *expr2Ptr = ctx->AllocaInst(exprType);
03070 
03071         if (shortCircuit1)
03072             lEmitSelectExprCode(ctx, testVal, oldMask, fullMask, expr1, 
03073                                 expr1Ptr);
03074         else {
03075             ctx->SetInternalMaskAnd(oldMask, testVal);
03076             llvm::Value *expr1Val = expr1->GetValue(ctx);
03077             ctx->StoreInst(expr1Val, expr1Ptr);
03078         }
03079 
03080         if (shortCircuit2) {
03081             llvm::Value *notTest = ctx->NotOperator(testVal);
03082             lEmitSelectExprCode(ctx, notTest, oldMask, fullMask, expr2, 
03083                                 expr2Ptr);
03084         }
03085         else {
03086             ctx->SetInternalMaskAndNot(oldMask, testVal);
03087             llvm::Value *expr2Val = expr2->GetValue(ctx);
03088             ctx->StoreInst(expr2Val, expr2Ptr);
03089         }
03090 
03091         ctx->SetInternalMask(oldMask);
03092         llvm::Value *expr1Val = ctx->LoadInst(expr1Ptr);
03093         llvm::Value *expr2Val = ctx->LoadInst(expr2Ptr);
03094         return lEmitVaryingSelect(ctx, testVal, expr1Val, expr2Val, type);
03095     }
03096     else {
03097         // FIXME? Short-circuiting doesn't work in the case of
03098         // vector-valued test expressions.  (We could also just prohibit
03099         // these and place the issue in the user's hands...)
03100         llvm::Value *testVal = test->GetValue(ctx);
03101         llvm::Value *expr1Val = expr1->GetValue(ctx);
03102         llvm::Value *expr2Val = expr2->GetValue(ctx);
03103 
03104         ctx->SetDebugPos(pos);
03105         const VectorType *vt = CastType<VectorType>(type);
03106         // Things that typechecking should have caught
03107         AssertPos(pos, vt != NULL);
03108         AssertPos(pos, CastType<VectorType>(testType) != NULL &&
03109                (CastType<VectorType>(testType)->GetElementCount() == 
03110                 vt->GetElementCount()));
03111 
03112         // Do an element-wise select  
03113         llvm::Value *result = llvm::UndefValue::get(type->LLVMType(g->ctx));
03114         for (int i = 0; i < vt->GetElementCount(); ++i) {
03115             llvm::Value *ti = ctx->ExtractInst(testVal, i);
03116             llvm::Value *e1i = ctx->ExtractInst(expr1Val, i);
03117             llvm::Value *e2i = ctx->ExtractInst(expr2Val, i);
03118             llvm::Value *sel = NULL;
03119             if (testType->IsUniformType())
03120                 sel = ctx->SelectInst(ti, e1i, e2i);
03121             else
03122                 sel = lEmitVaryingSelect(ctx, ti, e1i, e2i, vt->GetElementType());
03123             result = ctx->InsertInst(result, sel, i);
03124         }
03125         return result;
03126     }
03127 }
03128 
03129 
03130 const Type *
03131 SelectExpr::GetType() const {
03132     if (!test || !expr1 || !expr2)
03133         return NULL;
03134 
03135     const Type *testType = test->GetType();
03136     const Type *expr1Type = expr1->GetType();
03137     const Type *expr2Type = expr2->GetType();
03138 
03139     if (!testType || !expr1Type || !expr2Type)
03140         return NULL;
03141 
03142     bool becomesVarying = (testType->IsVaryingType() || expr1Type->IsVaryingType() ||
03143                            expr2Type->IsVaryingType());
03144     // if expr1 and expr2 have different vector sizes, typechecking should fail...
03145     int testVecSize = CastType<VectorType>(testType) != NULL ?
03146         CastType<VectorType>(testType)->GetElementCount() : 0;
03147     int expr1VecSize = CastType<VectorType>(expr1Type) != NULL ?
03148         CastType<VectorType>(expr1Type)->GetElementCount() : 0;
03149     AssertPos(pos, !(testVecSize != 0 && expr1VecSize != 0 && testVecSize != expr1VecSize));
03150     
03151     int vectorSize = std::max(testVecSize, expr1VecSize);
03152     return Type::MoreGeneralType(expr1Type, expr2Type, Union(expr1->pos, expr2->pos),
03153                                  "select expression", becomesVarying, vectorSize);
03154 }
03155 
03156 
03157 Expr *
03158 SelectExpr::Optimize() {
03159     if (test == NULL || expr1 == NULL || expr2 == NULL)
03160         return NULL;
03161 
03162     ConstExpr *constTest = dynamic_cast<ConstExpr *>(test);
03163     if (constTest == NULL)
03164         return this;
03165 
03166     // The test is a constant; see if we can resolve to one of the
03167     // expressions..
03168     bool bv[ISPC_MAX_NVEC];
03169     int count = constTest->AsBool(bv);
03170     if (count == 1)
03171         // Uniform test value; return the corresponding expression
03172         return (bv[0] == true) ? expr1 : expr2;
03173     else {
03174         // Varying test: see if all of the values are the same; if so, then
03175         // return the corresponding expression
03176         bool first = bv[0];
03177         bool mismatch = false;
03178         for (int i = 0; i < count; ++i)
03179             if (bv[i] != first) {
03180                 mismatch = true;
03181                 break;
03182             }
03183         if (mismatch == false)
03184             return (bv[0] == true) ? expr1 : expr2;
03185 
03186         // Last chance: see if the two expressions are constants; if so,
03187         // then we can do an element-wise selection based on the constant
03188         // condition..
03189         ConstExpr *constExpr1 = dynamic_cast<ConstExpr *>(expr1);
03190         ConstExpr *constExpr2 = dynamic_cast<ConstExpr *>(expr2);
03191         if (constExpr1 == NULL || constExpr2 == NULL)
03192             return this;
03193 
03194         AssertPos(pos, Type::Equal(constExpr1->GetType(), constExpr2->GetType()));
03195         const Type *exprType = constExpr1->GetType()->GetAsNonConstType();
03196         AssertPos(pos, exprType->IsVaryingType());
03197 
03198         // FIXME: it's annoying to have to have all of this replicated code.
03199         if (Type::Equal(exprType, AtomicType::VaryingInt32) ||
03200             Type::Equal(exprType, AtomicType::VaryingUInt32)) {
03201             int32_t v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
03202             int32_t result[ISPC_MAX_NVEC];
03203             constExpr1->AsInt32(v1);
03204             constExpr2->AsInt32(v2);
03205             for (int i = 0; i < count; ++i)
03206                 result[i] = bv[i] ? v1[i] : v2[i];
03207             return new ConstExpr(exprType, result, pos);
03208         }
03209         else if (Type::Equal(exprType, AtomicType::VaryingInt64) ||
03210                  Type::Equal(exprType, AtomicType::VaryingUInt64)) {
03211             int64_t v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
03212             int64_t result[ISPC_MAX_NVEC];
03213             constExpr1->AsInt64(v1);
03214             constExpr2->AsInt64(v2);
03215             for (int i = 0; i < count; ++i)
03216                 result[i] = bv[i] ? v1[i] : v2[i];
03217             return new ConstExpr(exprType, result, pos);
03218         }
03219         else if (Type::Equal(exprType, AtomicType::VaryingFloat)) {
03220             float v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
03221             float result[ISPC_MAX_NVEC];
03222             constExpr1->AsFloat(v1);
03223             constExpr2->AsFloat(v2);
03224             for (int i = 0; i < count; ++i)
03225                 result[i] = bv[i] ? v1[i] : v2[i];
03226             return new ConstExpr(exprType, result, pos);
03227         }
03228         else if (Type::Equal(exprType, AtomicType::VaryingDouble)) {
03229             double v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
03230             double result[ISPC_MAX_NVEC];
03231             constExpr1->AsDouble(v1);
03232             constExpr2->AsDouble(v2);
03233             for (int i = 0; i < count; ++i)
03234                 result[i] = bv[i] ? v1[i] : v2[i];
03235             return new ConstExpr(exprType, result, pos);
03236         }
03237         else if (Type::Equal(exprType, AtomicType::VaryingBool)) {
03238             bool v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
03239             bool result[ISPC_MAX_NVEC];
03240             constExpr1->AsBool(v1);
03241             constExpr2->AsBool(v2);
03242             for (int i = 0; i < count; ++i)
03243                 result[i] = bv[i] ? v1[i] : v2[i];
03244             return new ConstExpr(exprType, result, pos);
03245         }
03246 
03247         return this;
03248     }
03249 }
03250 
03251 
03252 Expr *
03253 SelectExpr::TypeCheck() {
03254     if (test == NULL || expr1 == NULL || expr2 == NULL)
03255         return NULL;
03256 
03257     const Type *type1 = expr1->GetType(), *type2 = expr2->GetType();
03258     if (!type1 || !type2)
03259         return NULL;
03260 
03261     if (CastType<ArrayType>(type1)) {
03262         Error(pos, "Array type \"%s\" can't be used in select expression", 
03263               type1->GetString().c_str());
03264         return NULL;
03265     }
03266     if (CastType<ArrayType>(type2)) {
03267         Error(pos, "Array type \"%s\" can't be used in select expression", 
03268               type2->GetString().c_str());
03269         return NULL;
03270     }
03271 
03272     const Type *testType = test->GetType();
03273     if (testType == NULL)
03274         return NULL;
03275     test = TypeConvertExpr(test, lMatchingBoolType(testType), "select");
03276     if (test == NULL)
03277         return NULL;
03278     testType = test->GetType();
03279 
03280     int testVecSize = CastType<VectorType>(testType) ?
03281         CastType<VectorType>(testType)->GetElementCount() : 0;
03282     const Type *promotedType = 
03283         Type::MoreGeneralType(type1, type2, Union(expr1->pos, expr2->pos),
03284                               "select expression", testType->IsVaryingType(), testVecSize);
03285     if (promotedType == NULL)
03286         return NULL;
03287 
03288     expr1 = TypeConvertExpr(expr1, promotedType, "select");
03289     expr2 = TypeConvertExpr(expr2, promotedType, "select");
03290     if (expr1 == NULL || expr2 == NULL)
03291         return NULL;
03292 
03293     return this;
03294 }
03295 
03296 
03297 int
03298 SelectExpr::EstimateCost() const {
03299     return COST_SELECT;
03300 }
03301 
03302 
03303 void
03304 SelectExpr::Print() const {
03305     if (!test || !expr1 || !expr2 || !GetType())
03306         return;
03307 
03308     printf("[%s] (", GetType()->GetString().c_str());
03309     test->Print();
03310     printf(" ? ");
03311     expr1->Print();
03312     printf(" : ");
03313     expr2->Print();
03314     printf(")");
03315     pos.Print();
03316 }
03317 
03318 
03319 ///////////////////////////////////////////////////////////////////////////
03320 // FunctionCallExpr
03321 
03322 FunctionCallExpr::FunctionCallExpr(Expr *f, ExprList *a, SourcePos p, 
03323                                    bool il, Expr *lce) 
03324     : Expr(p), isLaunch(il) {
03325     func = f;
03326     args = a;
03327     launchCountExpr = lce;
03328 }
03329 
03330 
03331 static const FunctionType *
03332 lGetFunctionType(Expr *func) {
03333     if (func == NULL)
03334         return NULL;
03335 
03336     const Type *type = func->GetType();
03337     if (type == NULL)
03338         return NULL;
03339 
03340     const FunctionType *ftype = CastType<FunctionType>(type);
03341     if (ftype == NULL) {
03342         // Not a regular function symbol--is it a function pointer?
03343         if (CastType<PointerType>(type) != NULL)
03344             ftype = CastType<FunctionType>(type->GetBaseType());
03345     }
03346     return ftype;
03347 }
03348 
03349 
03350 llvm::Value *
03351 FunctionCallExpr::GetValue(FunctionEmitContext *ctx) const {
03352     if (func == NULL || args == NULL)
03353         return NULL;
03354 
03355     ctx->SetDebugPos(pos);
03356 
03357     llvm::Value *callee = func->GetValue(ctx);
03358 
03359     if (callee == NULL) {
03360         AssertPos(pos, m->errorCount > 0);
03361         return NULL;
03362     }
03363 
03364     const FunctionType *ft = lGetFunctionType(func);
03365     AssertPos(pos, ft != NULL);
03366     bool isVoidFunc = Type::Equal(ft->GetReturnType(), AtomicType::Void);
03367 
03368     // Automatically convert function call args to references if needed.
03369     // FIXME: this should move to the TypeCheck() method... (but the
03370     // GetLValue call below needs a FunctionEmitContext, which is
03371     // problematic...)  
03372     std::vector<Expr *> callargs = args->exprs;
03373     bool err = false;
03374 
03375     // Specifically, this can happen if there's an error earlier during
03376     // overload resolution.
03377     if ((int)callargs.size() > ft->GetNumParameters()) {
03378         AssertPos(pos, m->errorCount > 0);
03379         return NULL;
03380     }
03381 
03382     for (unsigned int i = 0; i < callargs.size(); ++i) {
03383         Expr *argExpr = callargs[i];
03384         if (argExpr == NULL)
03385             continue;
03386 
03387         const Type *paramType = ft->GetParameterType(i); 
03388 
03389         const Type *argLValueType = argExpr->GetLValueType();
03390         if (argLValueType != NULL &&
03391             CastType<PointerType>(argLValueType) != NULL &&
03392             argLValueType->IsVaryingType() &&
03393             CastType<ReferenceType>(paramType) != NULL) {
03394             Error(argExpr->pos, "Illegal to pass a \"varying\" lvalue to a "
03395                   "reference parameter of type \"%s\".",
03396                   paramType->GetString().c_str());
03397             return NULL;
03398         }
03399 
03400         // Do whatever type conversion is needed
03401         argExpr = TypeConvertExpr(argExpr, paramType,
03402                                   "function call argument");
03403         if (argExpr == NULL)
03404             return NULL;
03405         callargs[i] = argExpr;
03406     }
03407     if (err)
03408         return NULL;
03409 
03410     // Fill in any default argument values needed.
03411     // FIXME: should we do this during type checking?
03412     for (int i = callargs.size(); i < ft->GetNumParameters(); ++i) {
03413         Expr *paramDefault = ft->GetParameterDefault(i);
03414         const Type *paramType = ft->GetParameterType(i);
03415         // FIXME: this type conv should happen when we create the function
03416         // type!
03417         Expr *d = TypeConvertExpr(paramDefault, paramType,
03418                                   "function call default argument");
03419         if (d == NULL)
03420             return NULL;
03421         callargs.push_back(d);
03422     }
03423 
03424     // Now evaluate the values of all of the parameters being passed.
03425     std::vector<llvm::Value *> argVals;
03426     for (unsigned int i = 0; i < callargs.size(); ++i) {
03427         Expr *argExpr = callargs[i];
03428         if (argExpr == NULL)
03429             // give up; we hit an error earlier
03430             return NULL;
03431 
03432         llvm::Value *argValue = argExpr->GetValue(ctx);
03433         if (argValue == NULL)
03434             // something went wrong in evaluating the argument's
03435             // expression, so give up on this
03436             return NULL;
03437 
03438         argVals.push_back(argValue);
03439     }
03440 
03441 
03442     llvm::Value *retVal = NULL;
03443     ctx->SetDebugPos(pos);
03444     if (ft->isTask) {
03445         AssertPos(pos, launchCountExpr != NULL);
03446         llvm::Value *launchCount = launchCountExpr->GetValue(ctx);
03447         if (launchCount != NULL)
03448             ctx->LaunchInst(callee, argVals, launchCount);
03449     }
03450     else
03451         retVal = ctx->CallInst(callee, ft, argVals, 
03452                                isVoidFunc ? "" : "calltmp");
03453 
03454     if (isVoidFunc)
03455         return NULL;
03456     else
03457         return retVal;
03458 }
03459 
03460 
03461 const Type *
03462 FunctionCallExpr::GetType() const {
03463     const FunctionType *ftype = lGetFunctionType(func);
03464     return ftype ? ftype->GetReturnType() : NULL;
03465 }
03466 
03467 
03468 Expr *
03469 FunctionCallExpr::Optimize() {
03470     if (func == NULL || args == NULL)
03471         return NULL;
03472     return this;
03473 }
03474 
03475 
03476 Expr *
03477 FunctionCallExpr::TypeCheck() {
03478     if (func == NULL || args == NULL)
03479         return NULL;
03480 
03481     std::vector<const Type *> argTypes;
03482     std::vector<bool> argCouldBeNULL, argIsConstant;
03483     for (unsigned int i = 0; i < args->exprs.size(); ++i) {
03484         Expr *expr = args->exprs[i];
03485 
03486         if (expr == NULL)
03487             return NULL;
03488         const Type *t = expr->GetType();
03489         if (t == NULL)
03490             return NULL;
03491 
03492         argTypes.push_back(t);
03493         argCouldBeNULL.push_back(lIsAllIntZeros(expr) ||
03494                                  dynamic_cast<NullPointerExpr *>(expr));
03495         argIsConstant.push_back(dynamic_cast<ConstExpr *>(expr) ||
03496                                 dynamic_cast<NullPointerExpr *>(expr));
03497     }
03498 
03499     FunctionSymbolExpr *fse = dynamic_cast<FunctionSymbolExpr *>(func);
03500     if (fse != NULL) {
03501         // Regular function call
03502         if (fse->ResolveOverloads(args->pos, argTypes, &argCouldBeNULL,
03503                                   &argIsConstant) == false)
03504             return NULL;
03505 
03506         func = ::TypeCheck(fse);
03507         if (func == NULL)
03508             return NULL;
03509 
03510         const FunctionType *ft = CastType<FunctionType>(func->GetType());
03511         if (ft == NULL) {
03512             const PointerType *pt = CastType<PointerType>(func->GetType());
03513             ft = (pt == NULL) ? NULL : 
03514                 CastType<FunctionType>(pt->GetBaseType());
03515         }
03516 
03517         if (ft == NULL) {
03518             Error(pos, "Valid function name must be used for function call.");
03519             return NULL;
03520         }
03521 
03522         if (ft->isTask) {
03523             if (!isLaunch)
03524                 Error(pos, "\"launch\" expression needed to call function "
03525                       "with \"task\" qualifier.");
03526             if (!launchCountExpr)
03527                 return NULL;
03528 
03529             launchCountExpr = 
03530                 TypeConvertExpr(launchCountExpr, AtomicType::UniformInt32,
03531                                 "task launch count");
03532             if (launchCountExpr == NULL)
03533                 return NULL;
03534         }
03535         else {
03536             if (isLaunch)
03537                 Error(pos, "\"launch\" expression illegal with non-\"task\"-"
03538                       "qualified function.");
03539             AssertPos(pos, launchCountExpr == NULL);
03540         }
03541     }
03542     else {
03543         // Call through a function pointer
03544         const Type *fptrType = func->GetType();
03545         if (fptrType == NULL)
03546             return NULL;
03547 
03548         // Make sure we do in fact have a function to call
03549         const FunctionType *funcType;
03550         if (CastType<PointerType>(fptrType) == NULL ||
03551             (funcType = CastType<FunctionType>(fptrType->GetBaseType())) == NULL) {
03552             Error(func->pos, "Must provide function name or function pointer for "
03553                   "function call expression.");
03554             return NULL;
03555         }
03556             
03557         // Make sure we don't have too many arguments for the function
03558         if ((int)argTypes.size() > funcType->GetNumParameters()) {
03559             Error(args->pos, "Too many parameter values provided in "
03560                   "function call (%d provided, %d expected).",
03561                   (int)argTypes.size(), funcType->GetNumParameters());
03562             return NULL;
03563         }
03564         // It's ok to have too few arguments, as long as the function's
03565         // default parameter values have started by the time we run out
03566         // of arguments
03567         if ((int)argTypes.size() < funcType->GetNumParameters() &&
03568             funcType->GetParameterDefault(argTypes.size()) == NULL) {
03569             Error(args->pos, "Too few parameter values provided in "
03570                   "function call (%d provided, %d expected).",
03571                   (int)argTypes.size(), funcType->GetNumParameters());
03572             return NULL;
03573         }
03574 
03575         // Now make sure they can all type convert to the corresponding
03576         // parameter types..
03577         for (int i = 0; i < (int)argTypes.size(); ++i) {
03578             if (i < funcType->GetNumParameters()) {
03579                 // make sure it can type convert
03580                 const Type *paramType = funcType->GetParameterType(i);
03581                 if (CanConvertTypes(argTypes[i], paramType) == false &&
03582                     !(argCouldBeNULL[i] == true &&
03583                       CastType<PointerType>(paramType) != NULL)) {
03584                     Error(args->exprs[i]->pos, "Can't convert argument of "
03585                           "type \"%s\" to type \"%s\" for function call "
03586                           "argument.", argTypes[i]->GetString().c_str(),
03587                           paramType->GetString().c_str());
03588                     return NULL;
03589                 }
03590             }
03591             else
03592                 // Otherwise the parameter default saves us.  It should
03593                 // be there for sure, given the check right above the
03594                 // for loop.
03595                 AssertPos(pos, funcType->GetParameterDefault(i) != NULL);
03596         }
03597 
03598         if (fptrType->IsVaryingType()) {
03599             const Type *retType = funcType->GetReturnType();
03600             if (Type::Equal(retType, AtomicType::Void) == false &&
03601                 retType->IsUniformType()) {
03602                 Error(pos, "Illegal to call a varying function pointer that "
03603                       "points to a function with a uniform return type \"%s\".",
03604                       funcType->GetReturnType()->GetString().c_str());
03605                 return NULL;
03606             }
03607         }
03608     }
03609 
03610     if (func == NULL || args == NULL)
03611         return NULL;
03612     return this;
03613 }
03614 
03615 
03616 int
03617 FunctionCallExpr::EstimateCost() const {
03618     if (isLaunch)
03619         return COST_TASK_LAUNCH;
03620 
03621     const Type *type = func->GetType();
03622     if (type == NULL)
03623         return 0;
03624 
03625     const PointerType *pt = CastType<PointerType>(type);
03626     if (pt != NULL)
03627         type = type->GetBaseType();
03628     const FunctionType *ftype = CastType<FunctionType>(type);
03629 
03630     if (ftype->costOverride > -1)
03631         return ftype->costOverride;
03632 
03633     if (pt != NULL)
03634         return pt->IsUniformType() ? COST_FUNPTR_UNIFORM : COST_FUNPTR_VARYING;
03635     else
03636         return COST_FUNCALL;
03637 }
03638 
03639 
03640 void
03641 FunctionCallExpr::Print() const {
03642     if (!func || !args || !GetType())
03643         return;
03644 
03645     printf("[%s] funcall %s ", GetType()->GetString().c_str(),
03646            isLaunch ? "launch" : "");
03647     func->Print();
03648     printf(" args (");
03649     args->Print();
03650     printf(")");
03651     pos.Print();
03652 }
03653 
03654 
03655 ///////////////////////////////////////////////////////////////////////////
03656 // ExprList
03657 
03658 llvm::Value *
03659 ExprList::GetValue(FunctionEmitContext *ctx) const {
03660     FATAL("ExprList::GetValue() should never be called");
03661     return NULL;
03662 }
03663 
03664 
03665 const Type *
03666 ExprList::GetType() const {
03667     FATAL("ExprList::GetType() should never be called");
03668     return NULL;
03669 }
03670 
03671 
03672 ExprList *
03673 ExprList::Optimize() {
03674     return this;
03675 }
03676 
03677 
03678 ExprList *
03679 ExprList::TypeCheck() {
03680     return this;
03681 }
03682 
03683 
03684 llvm::Constant *
03685 ExprList::GetConstant(const Type *type) const {
03686     if (exprs.size() == 1 &&
03687         (CastType<AtomicType>(type) != NULL ||
03688          CastType<EnumType>(type) != NULL ||
03689          CastType<PointerType>(type) != NULL))
03690         return exprs[0]->GetConstant(type);
03691 
03692     const CollectionType *collectionType = CastType<CollectionType>(type);
03693     if (collectionType == NULL)
03694         return NULL;
03695 
03696     std::string name;
03697     if (CastType<StructType>(type) != NULL)
03698         name = "struct";
03699     else if (CastType<ArrayType>(type) != NULL) 
03700         name = "array";
03701     else if (CastType<VectorType>(type) != NULL) 
03702         name = "vector";
03703     else 
03704         FATAL("Unexpected CollectionType in ExprList::GetConstant()");
03705 
03706     if ((int)exprs.size() > collectionType->GetElementCount()) {
03707         Error(pos, "Initializer list for %s \"%s\" must have no more than %d "
03708               "elements (has %d).", name.c_str(), 
03709               collectionType->GetString().c_str(),
03710               collectionType->GetElementCount(), (int)exprs.size());
03711         return NULL;
03712     }
03713 
03714     std::vector<llvm::Constant *> cv;
03715     for (unsigned int i = 0; i < exprs.size(); ++i) {
03716         if (exprs[i] == NULL)
03717             return NULL;
03718         const Type *elementType = collectionType->GetElementType(i);
03719 
03720         Expr *expr = exprs[i];
03721         if (dynamic_cast<ExprList *>(expr) == NULL) {
03722             // If there's a simple type conversion from the type of this
03723             // expression to the type we need, then let the regular type
03724             // conversion machinery handle it.
03725             expr = TypeConvertExpr(exprs[i], elementType, "initializer list");
03726             if (expr == NULL) {
03727                 AssertPos(pos, m->errorCount > 0);
03728                 return NULL;
03729             }
03730             // Re-establish const-ness if possible
03731             expr = ::Optimize(expr);
03732         }
03733 
03734         llvm::Constant *c = expr->GetConstant(elementType);
03735         if (c == NULL)
03736             // If this list element couldn't convert to the right constant
03737             // type for the corresponding collection member, then give up.
03738             return NULL;
03739         cv.push_back(c);
03740     }
03741 
03742     // If there are too few, then treat missing ones as if they were zero
03743     for (int i = (int)exprs.size(); i < collectionType->GetElementCount(); ++i) {
03744         const Type *elementType = collectionType->GetElementType(i);
03745         if (elementType == NULL) {
03746             AssertPos(pos, m->errorCount > 0);
03747             return NULL;
03748         }
03749 
03750         llvm::Type *llvmType = elementType->LLVMType(g->ctx);
03751         if (llvmType == NULL) {
03752             AssertPos(pos, m->errorCount > 0);
03753             return NULL;
03754         }
03755 
03756         llvm::Constant *c = llvm::Constant::getNullValue(llvmType);
03757         cv.push_back(c);
03758     }
03759 
03760     if (CastType<StructType>(type) != NULL) {
03761         llvm::StructType *llvmStructType =
03762             llvm::dyn_cast<llvm::StructType>(collectionType->LLVMType(g->ctx));
03763         AssertPos(pos, llvmStructType != NULL);
03764         return llvm::ConstantStruct::get(llvmStructType, cv);
03765     }
03766     else {
03767         llvm::Type *lt = type->LLVMType(g->ctx);
03768         llvm::ArrayType *lat = 
03769             llvm::dyn_cast<llvm::ArrayType>(lt);
03770         if (lat != NULL)
03771             return llvm::ConstantArray::get(lat, cv);
03772         else {
03773             // uniform short vector type
03774             AssertPos(pos, type->IsUniformType() &&
03775                    CastType<VectorType>(type) != NULL);
03776             llvm::VectorType *lvt = 
03777                 llvm::dyn_cast<llvm::VectorType>(lt);
03778             AssertPos(pos, lvt != NULL);
03779 
03780             // Uniform short vectors are stored as vectors of length
03781             // rounded up to the native vector width.  So we add additional
03782             // undef values here until we get the right size.
03783             while ((cv.size() % g->target.nativeVectorWidth) != 0)
03784                 cv.push_back(llvm::UndefValue::get(lvt->getElementType()));
03785 
03786             return llvm::ConstantVector::get(cv);
03787         }
03788     }
03789     return NULL;
03790 }
03791 
03792 
03793 int
03794 ExprList::EstimateCost() const {
03795     return 0;
03796 }
03797 
03798 
03799 void
03800 ExprList::Print() const {
03801     printf("expr list (");
03802     for (unsigned int i = 0; i < exprs.size(); ++i) {
03803         if (exprs[i] != NULL)
03804             exprs[i]->Print();
03805         printf("%s", (i == exprs.size() - 1) ? ")" : ", ");
03806     }
03807     pos.Print();
03808 }
03809 
03810 
03811 ///////////////////////////////////////////////////////////////////////////
03812 // IndexExpr
03813 
03814 IndexExpr::IndexExpr(Expr *a, Expr *i, SourcePos p) 
03815     : Expr(p) {
03816     baseExpr = a;
03817     index = i;
03818     type = lvalueType = NULL;
03819 }
03820 
03821 
03822 /** When computing pointer values, we need to apply a per-lane offset when
03823     we have a varying pointer that is itself indexing into varying data.
03824     Consdier the following ispc code:
03825 
03826     uniform float u[] = ...;
03827     float v[] = ...;
03828     int index = ...;
03829     float a = u[index];
03830     float b = v[index];
03831 
03832     To compute the varying pointer that holds the addresses to load from
03833     for u[index], we basically just need to multiply index element-wise by
03834     sizeof(float) before doing the memory load.  For v[index], we need to
03835     do the same scaling but also need to add per-lane offsets <0,
03836     sizeof(float), 2*sizeof(float), ...> so that the i'th lane loads the
03837     i'th of the varying values at its index value.  
03838 
03839     This function handles figuring out when this additional offset is
03840     needed and then incorporates it in the varying pointer value.
03841  */ 
03842 static llvm::Value *
03843 lAddVaryingOffsetsIfNeeded(FunctionEmitContext *ctx, llvm::Value *ptr, 
03844                            const Type *ptrRefType) {
03845     if (CastType<ReferenceType>(ptrRefType) != NULL)
03846         // References are uniform pointers, so no offsetting is needed
03847         return ptr;
03848 
03849     const PointerType *ptrType = CastType<PointerType>(ptrRefType);
03850     Assert(ptrType != NULL);
03851     if (ptrType->IsUniformType() || ptrType->IsSlice())
03852         return ptr;
03853 
03854     const Type *baseType = ptrType->GetBaseType();
03855     if (baseType->IsVaryingType() == false)
03856         return ptr;
03857 
03858     // must be indexing into varying atomic, enum, or pointer types
03859     if (Type::IsBasicType(baseType) == false)
03860         return ptr;
03861 
03862     // Onward: compute the per lane offsets.
03863     llvm::Value *varyingOffsets = 
03864         llvm::UndefValue::get(LLVMTypes::Int32VectorType);
03865     for (int i = 0; i < g->target.vectorWidth; ++i)
03866         varyingOffsets = ctx->InsertInst(varyingOffsets, LLVMInt32(i), i,
03867                                          "varying_delta");
03868 
03869     // And finally add the per-lane offsets.  Note that we lie to the GEP
03870     // call and tell it that the pointers are to uniform elements and not
03871     // varying elements, so that the offsets in terms of (0,1,2,...) will
03872     // end up turning into the correct step in bytes...
03873     const Type *uniformElementType = baseType->GetAsUniformType();
03874     const Type *ptrUnifType = PointerType::GetVarying(uniformElementType);
03875     return ctx->GetElementPtrInst(ptr, varyingOffsets, ptrUnifType);
03876 }
03877 
03878 
03879 /** Check to see if the given type is an array of or pointer to a varying
03880     struct type that in turn has a member with bound 'uniform' variability.
03881     Issue an error and return true if such a member is found.
03882  */
03883 static bool
03884 lVaryingStructHasUniformMember(const Type *type, SourcePos pos) {
03885     if (CastType<VectorType>(type) != NULL ||
03886         CastType<ReferenceType>(type) != NULL)
03887         return false;
03888 
03889     const StructType *st = CastType<StructType>(type);
03890     if (st == NULL) {
03891         const ArrayType *at = CastType<ArrayType>(type);
03892         if (at != NULL)
03893             st = CastType<StructType>(at->GetElementType());
03894         else {
03895             const PointerType *pt = CastType<PointerType>(type);
03896             if (pt == NULL)
03897                 return false;
03898 
03899             st = CastType<StructType>(pt->GetBaseType());
03900         }
03901 
03902         if (st == NULL)
03903             return false;
03904     }
03905 
03906     if (st->IsVaryingType() == false)
03907         return false;
03908 
03909     for (int i = 0; i < st->GetElementCount(); ++i) {
03910         const Type *eltType = st->GetElementType(i);
03911         if (eltType == NULL) {
03912             AssertPos(pos, m->errorCount > 0);
03913             continue;
03914         }
03915 
03916         if (CastType<StructType>(eltType) != NULL) {
03917             // We know that the enclosing struct is varying at this point,
03918             // so push that down to the enclosed struct before makign the
03919             // recursive call.
03920             eltType = eltType->GetAsVaryingType();
03921             if (lVaryingStructHasUniformMember(eltType, pos))
03922                 return true;
03923         }
03924         else if (eltType->IsUniformType()) {
03925             Error(pos, "Gather operation is impossible due to the presence of "
03926                   "struct member \"%s\" with uniform type \"%s\" in the "
03927                   "varying struct type \"%s\".",
03928                   st->GetElementName(i).c_str(), eltType->GetString().c_str(),
03929                   st->GetString().c_str());
03930             return true;
03931         }
03932     }
03933 
03934     return false;
03935 }
03936 
03937 
03938 llvm::Value *
03939 IndexExpr::GetValue(FunctionEmitContext *ctx) const {
03940     const Type *indexType, *returnType;
03941     if (baseExpr == NULL || index == NULL || 
03942         ((indexType = index->GetType()) == NULL) ||
03943         ((returnType = GetType()) == NULL)) {
03944         AssertPos(pos, m->errorCount > 0);
03945         return NULL;
03946     }
03947 
03948     // If this is going to be a gather, make sure that the varying return
03949     // type can represent the result (i.e. that we don't have a bound
03950     // 'uniform' member in a varying struct...)
03951     if (indexType->IsVaryingType() && 
03952         lVaryingStructHasUniformMember(returnType, pos))
03953         return NULL;
03954 
03955     ctx->SetDebugPos(pos);
03956 
03957     llvm::Value *ptr = GetLValue(ctx);
03958     llvm::Value *mask = NULL;
03959     const Type *lvType = GetLValueType();
03960     if (ptr == NULL) {
03961         // We may be indexing into a temporary that hasn't hit memory, so
03962         // get the full value and stuff it into temporary alloca'd space so
03963         // that we can index from there...
03964         const Type *baseExprType = baseExpr->GetType();
03965         llvm::Value *val = baseExpr->GetValue(ctx);
03966         if (baseExprType == NULL || val == NULL) {
03967             AssertPos(pos, m->errorCount > 0);
03968             return NULL;
03969         }
03970         ctx->SetDebugPos(pos);
03971         llvm::Value *tmpPtr = ctx->AllocaInst(baseExprType->LLVMType(g->ctx), 
03972                                               "array_tmp");
03973         ctx->StoreInst(val, tmpPtr);
03974 
03975         // Get a pointer type to the underlying elements
03976         const SequentialType *st = CastType<SequentialType>(baseExprType);
03977         AssertPos(pos, st != NULL);
03978         lvType = PointerType::GetUniform(st->GetElementType());
03979 
03980         // And do the indexing calculation into the temporary array in memory
03981         ptr = ctx->GetElementPtrInst(tmpPtr, LLVMInt32(0), index->GetValue(ctx), 
03982                                      PointerType::GetUniform(baseExprType));
03983         ptr = lAddVaryingOffsetsIfNeeded(ctx, ptr, lvType);
03984 
03985         mask = LLVMMaskAllOn;
03986     }
03987     else {
03988         Symbol *baseSym = GetBaseSymbol();
03989         AssertPos(pos, baseSym != NULL);
03990         mask = lMaskForSymbol(baseSym, ctx);
03991     }
03992 
03993     ctx->SetDebugPos(pos);
03994     return ctx->LoadInst(ptr, mask, lvType);
03995 }
03996 
03997 
03998 const Type *
03999 IndexExpr::GetType() const {
04000     if (type != NULL)
04001         return type;
04002 
04003     const Type *baseExprType, *indexType;
04004     if (!baseExpr || !index || 
04005         ((baseExprType = baseExpr->GetType()) == NULL) ||
04006         ((indexType = index->GetType()) == NULL))
04007         return NULL;
04008 
04009     const Type *elementType = NULL;
04010     const PointerType *pointerType = CastType<PointerType>(baseExprType);
04011     if (pointerType != NULL)
04012         // ptr[index] -> type that the pointer points to
04013         elementType = pointerType->GetBaseType();
04014     else {
04015         // sequential type[index] -> element type of the sequential type
04016         const SequentialType *sequentialType = 
04017             CastType<SequentialType>(baseExprType->GetReferenceTarget());
04018         // Typechecking should have caught this...
04019         AssertPos(pos, sequentialType != NULL);
04020         elementType = sequentialType->GetElementType();
04021     }
04022 
04023     // If we're indexing into a sequence of SOA types, the result type is
04024     // actually the underlying type, as a uniform or varying.  Get the
04025     // uniform variant of it for starters, then below we'll make it varying
04026     // if the index is varying.
04027     // (If we ever provide a way to index into SOA types and get an entire
04028     // SOA'd struct out of the array, then we won't want to do this in that
04029     // case..)
04030     if (elementType->IsSOAType())
04031         elementType = elementType->GetAsUniformType();
04032 
04033     // If either the index is varying or we're indexing into a varying
04034     // pointer, then the result type is the varying variant of the indexed
04035     // type.
04036     if (indexType->IsUniformType() &&
04037         (pointerType == NULL || pointerType->IsUniformType()))
04038         type = elementType;
04039     else
04040         type = elementType->GetAsVaryingType();
04041 
04042     return type;
04043 }
04044 
04045 
04046 Symbol *
04047 IndexExpr::GetBaseSymbol() const {
04048     return baseExpr ? baseExpr->GetBaseSymbol() : NULL;
04049 }
04050 
04051 
04052 /** Utility routine that takes a regualr pointer (either uniform or
04053     varying) and returns a slice pointer with zero offsets.
04054  */
04055 static llvm::Value *
04056 lConvertToSlicePointer(FunctionEmitContext *ctx, llvm::Value *ptr,
04057                        const PointerType *slicePtrType) {
04058     llvm::Type *llvmSlicePtrType = 
04059         slicePtrType->LLVMType(g->ctx);
04060     llvm::StructType *sliceStructType =
04061         llvm::dyn_cast<llvm::StructType>(llvmSlicePtrType);
04062     Assert(sliceStructType != NULL &&
04063            sliceStructType->getElementType(0) == ptr->getType());
04064 
04065     // Get a null-initialized struct to take care of having zeros for the
04066     // offsets
04067     llvm::Value *result = llvm::Constant::getNullValue(sliceStructType);
04068     // And replace the pointer in the struct with the given pointer
04069     return ctx->InsertInst(result, ptr, 0, LLVMGetName(ptr, "_slice"));
04070 }
04071 
04072 
04073 /** If the given array index is a compile time constant, check to see if it
04074     value/values don't go past the end of the array; issue a warning if
04075     so.
04076 */
04077 static void
04078 lCheckIndicesVersusBounds(const Type *baseExprType, Expr *index) {
04079     const SequentialType *seqType = CastType<SequentialType>(baseExprType);
04080     if (seqType == NULL)
04081         return;
04082 
04083     int nElements = seqType->GetElementCount();
04084     if (nElements == 0)
04085         // Unsized array...
04086         return;
04087 
04088     // If it's an array of soa<> items, then the number of elements to
04089     // worry about w.r.t. index values is the product of the array size and
04090     // the soa width.
04091     int soaWidth = seqType->GetElementType()->GetSOAWidth();
04092     if (soaWidth > 0)
04093         nElements *= soaWidth;
04094 
04095     ConstExpr *ce = dynamic_cast<ConstExpr *>(index);
04096     if (ce == NULL)
04097         return;
04098 
04099     int32_t indices[ISPC_MAX_NVEC];
04100     int count = ce->AsInt32(indices);
04101     for (int i = 0; i < count; ++i) {
04102         if (indices[i] < 0 || indices[i] >= nElements)
04103             Warning(index->pos, "Array index \"%d\" may be out of bounds for %d "
04104                     "element array.", indices[i], nElements);
04105     }
04106 }
04107 
04108 
04109 /** Converts the given pointer value to a slice pointer if the pointer
04110     points to SOA'ed data. 
04111 */
04112 static llvm::Value *
04113 lConvertPtrToSliceIfNeeded(FunctionEmitContext *ctx, 
04114                            llvm::Value *ptr, const Type **type) {
04115     Assert(*type != NULL);
04116     const PointerType *ptrType = CastType<PointerType>(*type);
04117     bool convertToSlice = (ptrType->GetBaseType()->IsSOAType() &&
04118                            ptrType->IsSlice() == false);
04119     if (convertToSlice == false)
04120         return ptr;
04121 
04122     *type = ptrType->GetAsSlice();
04123     return lConvertToSlicePointer(ctx, ptr, ptrType->GetAsSlice());
04124 }
04125 
04126 
04127 llvm::Value *
04128 IndexExpr::GetLValue(FunctionEmitContext *ctx) const {
04129     const Type *baseExprType;
04130     if (baseExpr == NULL || index == NULL || 
04131         ((baseExprType = baseExpr->GetType()) == NULL)) {
04132         AssertPos(pos, m->errorCount > 0);
04133         return NULL;
04134     }
04135 
04136     ctx->SetDebugPos(pos);
04137     llvm::Value *indexValue = index->GetValue(ctx);
04138     if (indexValue == NULL) {
04139         AssertPos(pos, m->errorCount > 0);
04140         return NULL;
04141     }
04142 
04143     ctx->SetDebugPos(pos);
04144     if (CastType<PointerType>(baseExprType) != NULL) {
04145         // We're indexing off of a pointer 
04146         llvm::Value *basePtrValue = baseExpr->GetValue(ctx);
04147         if (basePtrValue == NULL) {
04148             AssertPos(pos, m->errorCount > 0);
04149             return NULL;
04150         }
04151         ctx->SetDebugPos(pos);
04152 
04153         // Convert to a slice pointer if we're indexing into SOA data
04154         basePtrValue = lConvertPtrToSliceIfNeeded(ctx, basePtrValue,
04155                                                   &baseExprType);
04156 
04157         llvm::Value *ptr = ctx->GetElementPtrInst(basePtrValue, indexValue,
04158                                                   baseExprType, 
04159                                                   LLVMGetName(basePtrValue, "_offset"));
04160         return lAddVaryingOffsetsIfNeeded(ctx, ptr, GetLValueType());
04161     }
04162 
04163     // Not a pointer: we must be indexing an array or vector (and possibly
04164     // a reference thereuponfore.)
04165     llvm::Value *basePtr = NULL;
04166     const PointerType *basePtrType = NULL;
04167     if (CastType<ArrayType>(baseExprType) ||
04168         CastType<VectorType>(baseExprType)) {
04169         basePtr = baseExpr->GetLValue(ctx);
04170         basePtrType = CastType<PointerType>(baseExpr->GetLValueType());
04171         if (baseExpr->GetLValueType()) AssertPos(pos, basePtrType != NULL);
04172     }
04173     else {
04174         baseExprType = baseExprType->GetReferenceTarget();
04175         AssertPos(pos, CastType<ArrayType>(baseExprType) ||
04176                CastType<VectorType>(baseExprType));
04177         basePtr = baseExpr->GetValue(ctx);
04178         basePtrType = PointerType::GetUniform(baseExprType);
04179     }
04180     if (!basePtr)
04181         return NULL;
04182 
04183     // If possible, check the index value(s) against the size of the array
04184     lCheckIndicesVersusBounds(baseExprType, index);
04185 
04186     // Convert to a slice pointer if indexing into SOA data
04187     basePtr = lConvertPtrToSliceIfNeeded(ctx, basePtr, 
04188                                          (const Type **)&basePtrType);
04189 
04190     ctx->SetDebugPos(pos);
04191 
04192     // And do the actual indexing calculation..
04193     llvm::Value *ptr = 
04194         ctx->GetElementPtrInst(basePtr, LLVMInt32(0), indexValue, 
04195                                basePtrType, LLVMGetName(basePtr, "_offset"));
04196     return lAddVaryingOffsetsIfNeeded(ctx, ptr, GetLValueType());
04197 }
04198 
04199 
04200 const Type *
04201 IndexExpr::GetLValueType() const {
04202     if (lvalueType != NULL)
04203         return lvalueType;
04204 
04205     const Type *baseExprType, *baseExprLValueType, *indexType;
04206     if (baseExpr == NULL || index == NULL ||
04207         ((baseExprType = baseExpr->GetType()) == NULL) ||
04208         ((baseExprLValueType = baseExpr->GetLValueType()) == NULL) ||
04209         ((indexType = index->GetType()) == NULL))
04210         return NULL;
04211 
04212     // regularize to a PointerType 
04213     if (CastType<ReferenceType>(baseExprLValueType) != NULL) {
04214         const Type *refTarget = baseExprLValueType->GetReferenceTarget();
04215         baseExprLValueType = PointerType::GetUniform(refTarget);
04216     }
04217     AssertPos(pos, CastType<PointerType>(baseExprLValueType) != NULL);
04218 
04219     // Find the type of thing that we're indexing into
04220     const Type *elementType;
04221     const SequentialType *st = 
04222         CastType<SequentialType>(baseExprLValueType->GetBaseType());
04223     if (st != NULL)
04224         elementType = st->GetElementType();
04225     else {
04226         const PointerType *pt = 
04227             CastType<PointerType>(baseExprLValueType->GetBaseType());
04228         AssertPos(pos, pt != NULL);
04229         elementType = pt->GetBaseType();
04230     }
04231 
04232     // Are we indexing into a varying type, or are we indexing with a
04233     // varying pointer?
04234     bool baseVarying;
04235     if (CastType<PointerType>(baseExprType) != NULL)
04236         baseVarying = baseExprType->IsVaryingType();
04237     else
04238         baseVarying = baseExprLValueType->IsVaryingType();
04239 
04240     // The return type is uniform iff. the base is a uniform pointer / a
04241     // collection of uniform typed elements and the index is uniform.
04242     if (baseVarying == false && indexType->IsUniformType())
04243         lvalueType = PointerType::GetUniform(elementType);
04244     else
04245         lvalueType = PointerType::GetVarying(elementType);
04246 
04247     // Finally, if we're indexing into an SOA type, then the resulting
04248     // pointer must (currently) be a slice pointer; we don't allow indexing
04249     // the soa-width-wide structs directly.
04250     if (elementType->IsSOAType())
04251         lvalueType = lvalueType->GetAsSlice();
04252 
04253     return lvalueType;
04254 }
04255 
04256 
04257 Expr *
04258 IndexExpr::Optimize() {
04259     if (baseExpr == NULL || index == NULL)
04260         return NULL;
04261     return this;
04262 }
04263 
04264 
04265 Expr *
04266 IndexExpr::TypeCheck() {
04267     const Type *indexType;
04268     if (baseExpr == NULL || index == NULL || 
04269         ((indexType = index->GetType()) == NULL)) {
04270         AssertPos(pos, m->errorCount > 0);
04271         return NULL;
04272     }
04273 
04274     const Type *baseExprType = baseExpr->GetType();
04275     if (baseExprType == NULL) {
04276         AssertPos(pos, m->errorCount > 0);
04277         return NULL;
04278     }
04279 
04280     if (!CastType<SequentialType>(baseExprType->GetReferenceTarget())) {
04281         if (const PointerType *pt = CastType<PointerType>(baseExprType)) {
04282             if (Type::Equal(AtomicType::Void, pt->GetBaseType())) {
04283                 Error(pos, "Illegal to dereference void pointer type \"%s\".",
04284                       baseExprType->GetString().c_str());
04285                 return NULL;
04286             }
04287         }
04288         else {
04289             Error(pos, "Trying to index into non-array, vector, or pointer "
04290               "type \"%s\".", baseExprType->GetString().c_str());
04291             return NULL;
04292         }
04293     }
04294 
04295     bool isUniform = (index->GetType()->IsUniformType() && 
04296                       !g->opt.disableUniformMemoryOptimizations);
04297 
04298     // Unless we have an explicit 64-bit index and are compiling to a
04299     // 64-bit target with 64-bit addressing, convert the index to an int32
04300     // type.
04301     if (Type::EqualIgnoringConst(indexType->GetAsUniformType(),
04302                                  AtomicType::UniformInt64) == false ||
04303         g->target.is32Bit ||
04304         g->opt.force32BitAddressing) {
04305         const Type *indexType = isUniform ? AtomicType::UniformInt32 : 
04306             AtomicType::VaryingInt32;
04307         index = TypeConvertExpr(index, indexType, "array index");
04308         if (index == NULL)
04309             return NULL;
04310     }
04311 
04312     return this;
04313 }
04314 
04315 
04316 int
04317 IndexExpr::EstimateCost() const {
04318     if (index == NULL || baseExpr == NULL)
04319         return 0;
04320 
04321     const Type *indexType = index->GetType();
04322     const Type *baseExprType = baseExpr->GetType();
04323     
04324     if ((indexType != NULL && indexType->IsVaryingType()) ||
04325         (CastType<PointerType>(baseExprType) != NULL &&
04326          baseExprType->IsVaryingType()))
04327         // be pessimistic; some of these will later turn out to be vector
04328         // loads/stores, but it's too early for us to know that here.
04329         return COST_GATHER;
04330     else
04331         return COST_LOAD;
04332 }
04333 
04334 
04335 void
04336 IndexExpr::Print() const {
04337     if (!baseExpr || !index || !GetType())
04338         return;
04339 
04340     printf("[%s] index ", GetType()->GetString().c_str());
04341     baseExpr->Print();
04342     printf("[");
04343     index->Print();
04344     printf("]");
04345     pos.Print();
04346 }
04347 
04348 
04349 ///////////////////////////////////////////////////////////////////////////
04350 // MemberExpr
04351 
04352 /** Map one character ids to vector element numbers.  Allow a few different
04353     conventions--xyzw, rgba, uv.
04354 */
04355 static int
04356 lIdentifierToVectorElement(char id) {
04357     switch (id) {
04358     case 'x':
04359     case 'r':
04360     case 'u':
04361         return 0;
04362     case 'y':
04363     case 'g':
04364     case 'v':
04365         return 1;
04366     case 'z':
04367     case 'b':
04368         return 2;
04369     case 'w':
04370     case 'a':
04371         return 3;
04372     default:
04373         return -1;
04374     }
04375 }
04376 
04377 //////////////////////////////////////////////////
04378 // StructMemberExpr
04379 
04380 class StructMemberExpr : public MemberExpr
04381 {
04382 public:
04383     StructMemberExpr(Expr *e, const char *id, SourcePos p,
04384                      SourcePos idpos, bool derefLValue);
04385 
04386     const Type *GetType() const;
04387     const Type *GetLValueType() const;
04388     int getElementNumber() const;
04389     const Type *getElementType() const;
04390 
04391 private:
04392     const StructType *getStructType() const;
04393 };
04394 
04395 
04396 StructMemberExpr::StructMemberExpr(Expr *e, const char *id, SourcePos p,
04397                                    SourcePos idpos, bool derefLValue)
04398     : MemberExpr(e, id, p, idpos, derefLValue) {
04399 }
04400 
04401 
04402 const Type *
04403 StructMemberExpr::GetType() const {
04404     if (type != NULL)
04405         return type;
04406 
04407     // It's a struct, and the result type is the element type, possibly
04408     // promoted to varying if the struct type / lvalue is varying.
04409     const Type *exprType, *lvalueType;
04410     const StructType *structType;
04411     if (expr == NULL ||
04412         ((exprType = expr->GetType()) == NULL) ||
04413         ((structType = getStructType()) == NULL) ||
04414         ((lvalueType = GetLValueType()) == NULL)) {
04415         AssertPos(pos, m->errorCount > 0);
04416         return NULL;
04417     }
04418 
04419     const Type *elementType = structType->GetElementType(identifier);
04420     if (elementType == NULL) {
04421         Error(identifierPos,
04422               "Element name \"%s\" not present in struct type \"%s\".%s",
04423               identifier.c_str(), structType->GetString().c_str(),
04424               getCandidateNearMatches().c_str());
04425         return NULL;
04426     }
04427     AssertPos(pos, Type::Equal(lvalueType->GetBaseType(), elementType));
04428 
04429     bool isSlice = (CastType<PointerType>(lvalueType) &&
04430                     CastType<PointerType>(lvalueType)->IsSlice());
04431     if (isSlice) {
04432         // FIXME: not true if we allow bound unif/varying for soa<>
04433         // structs?...
04434         AssertPos(pos, elementType->IsSOAType());
04435 
04436         // If we're accessing a member of an soa structure via a uniform
04437         // slice pointer, then the result type is the uniform variant of
04438         // the element type.
04439         if (lvalueType->IsUniformType())
04440             elementType = elementType->GetAsUniformType();
04441     }
04442 
04443     if (lvalueType->IsVaryingType())
04444         // If the expression we're getting the member of has an lvalue that
04445         // is a varying pointer type (be it slice or non-slice), then the
04446         // result type must be the varying version of the element type.
04447         elementType = elementType->GetAsVaryingType();
04448 
04449     type = elementType;
04450     return type;
04451 }
04452 
04453 
04454 const Type *
04455 StructMemberExpr::GetLValueType() const {
04456     if (lvalueType != NULL)
04457         return lvalueType;
04458 
04459     if (expr == NULL) {
04460         AssertPos(pos, m->errorCount > 0);
04461         return NULL;
04462     }
04463 
04464     const Type *exprLValueType = dereferenceExpr ? expr->GetType() :
04465         expr->GetLValueType();
04466     if (exprLValueType == NULL) {
04467         AssertPos(pos, m->errorCount > 0);
04468         return NULL;
04469     }
04470 
04471     // The pointer type is varying if the lvalue type of the expression is
04472     // varying (and otherwise uniform)
04473     const PointerType *ptrType =
04474         (exprLValueType->IsUniformType() ||
04475          CastType<ReferenceType>(exprLValueType) != NULL) ?
04476         PointerType::GetUniform(getElementType()) : 
04477         PointerType::GetVarying(getElementType());
04478 
04479     // If struct pointer is a slice pointer, the resulting member pointer
04480     // needs to be a frozen slice pointer--i.e. any further indexing with
04481     // the result shouldn't modify the minor slice offset, but it should be
04482     // left unchanged until we get to a leaf SOA value.
04483     if (CastType<PointerType>(exprLValueType) &&
04484         CastType<PointerType>(exprLValueType)->IsSlice())
04485         ptrType = ptrType->GetAsFrozenSlice();
04486 
04487     lvalueType = ptrType;
04488     return lvalueType;
04489 }
04490 
04491 
04492 int
04493 StructMemberExpr::getElementNumber() const {
04494     const StructType *structType = getStructType();
04495     if (structType == NULL)
04496         return -1;
04497 
04498     int elementNumber = structType->GetElementNumber(identifier);
04499     if (elementNumber == -1)
04500         Error(identifierPos,
04501               "Element name \"%s\" not present in struct type \"%s\".%s",
04502               identifier.c_str(), structType->GetString().c_str(),
04503               getCandidateNearMatches().c_str());
04504 
04505     return elementNumber;
04506 }
04507 
04508 
04509 const Type *
04510 StructMemberExpr::getElementType() const {
04511     const StructType *structType = getStructType();
04512     if (structType == NULL)
04513         return NULL;
04514 
04515     return structType->GetElementType(identifier);
04516 }
04517 
04518 
04519 /** Returns the type of the underlying struct that we're returning a member
04520     of. */
04521 const StructType *
04522 StructMemberExpr::getStructType() const {
04523     const Type *type = dereferenceExpr ? expr->GetType() :
04524         expr->GetLValueType();
04525     if (type == NULL)
04526         return NULL;
04527 
04528     const Type *structType;
04529     const ReferenceType *rt = CastType<ReferenceType>(type);
04530     if (rt != NULL)
04531         structType = rt->GetReferenceTarget();
04532     else {
04533         const PointerType *pt = CastType<PointerType>(type);
04534         AssertPos(pos, pt != NULL);
04535         structType = pt->GetBaseType();
04536     }
04537 
04538     const StructType *ret = CastType<StructType>(structType);
04539     AssertPos(pos, ret != NULL);
04540     return ret;
04541 }
04542 
04543 
04544 //////////////////////////////////////////////////
04545 // VectorMemberExpr
04546 
04547 class VectorMemberExpr : public MemberExpr
04548 {
04549 public:
04550     VectorMemberExpr(Expr *e, const char *id, SourcePos p,
04551                      SourcePos idpos, bool derefLValue);
04552 
04553     llvm::Value *GetValue(FunctionEmitContext* ctx) const;
04554     llvm::Value *GetLValue(FunctionEmitContext* ctx) const;
04555     const Type *GetType() const;
04556     const Type *GetLValueType() const;
04557 
04558     int getElementNumber() const;
04559     const Type *getElementType() const;
04560 
04561 private:
04562     const VectorType *exprVectorType;
04563     const VectorType *memberType;
04564 };
04565 
04566 
04567 VectorMemberExpr::VectorMemberExpr(Expr *e, const char *id, SourcePos p,
04568                                    SourcePos idpos, bool derefLValue)
04569     : MemberExpr(e, id, p, idpos, derefLValue) {
04570     const Type *exprType = e->GetType();
04571     exprVectorType = CastType<VectorType>(exprType);
04572     if (exprVectorType == NULL) {
04573         const PointerType *pt = CastType<PointerType>(exprType);
04574         if (pt != NULL)
04575             exprVectorType = CastType<VectorType>(pt->GetBaseType());
04576         else {
04577             AssertPos(pos, CastType<ReferenceType>(exprType) != NULL);
04578             exprVectorType = 
04579                 CastType<VectorType>(exprType->GetReferenceTarget());
04580         }
04581         AssertPos(pos, exprVectorType != NULL);
04582     }
04583     memberType = new VectorType(exprVectorType->GetElementType(),
04584                                 identifier.length());
04585 }
04586 
04587 
04588 const Type *
04589 VectorMemberExpr::GetType() const {
04590     if (type != NULL)
04591         return type;
04592 
04593     // For 1-element expressions, we have the base vector element
04594     // type.  For n-element expressions, we have a shortvec type
04595     // with n > 1 elements.  This can be changed when we get
04596     // type<1> -> type conversions.
04597     type = (identifier.length() == 1) ? 
04598         (const Type *)exprVectorType->GetElementType() : 
04599         (const Type *)memberType;
04600 
04601     const Type *lvType = GetLValueType();
04602     if (lvType != NULL) {
04603         bool isSlice = (CastType<PointerType>(lvType) &&
04604                         CastType<PointerType>(lvType)->IsSlice());
04605         if (isSlice) {
04606 //CO            AssertPos(pos, type->IsSOAType());
04607             if (lvType->IsUniformType())
04608                 type = type->GetAsUniformType();
04609         }
04610 
04611         if (lvType->IsVaryingType())
04612             type = type->GetAsVaryingType();
04613     }
04614 
04615     return type;
04616 }
04617 
04618 
04619 llvm::Value *
04620 VectorMemberExpr::GetLValue(FunctionEmitContext* ctx) const {
04621     if (identifier.length() == 1) {
04622         return MemberExpr::GetLValue(ctx);
04623     } else {
04624         return NULL;
04625     }
04626 }
04627 
04628 
04629 const Type *
04630 VectorMemberExpr::GetLValueType() const {
04631     if (lvalueType != NULL)
04632         return lvalueType;
04633 
04634     if (identifier.length() == 1) {
04635         if (expr == NULL) {
04636             AssertPos(pos, m->errorCount > 0);
04637             return NULL;
04638         }
04639 
04640         const Type *exprLValueType = dereferenceExpr ? expr->GetType() :
04641             expr->GetLValueType();
04642         if (exprLValueType == NULL)
04643             return NULL;
04644 
04645         const VectorType *vt = NULL;
04646         if (CastType<ReferenceType>(exprLValueType) != NULL)
04647             vt = CastType<VectorType>(exprLValueType->GetReferenceTarget());
04648         else
04649             vt = CastType<VectorType>(exprLValueType->GetBaseType());
04650         AssertPos(pos, vt != NULL);
04651 
04652         // we don't want to report that it's e.g. a pointer to a float<1>,
04653         // but a pointer to a float, etc.
04654         const Type *elementType = vt->GetElementType();
04655         if (CastType<ReferenceType>(exprLValueType) != NULL)
04656             lvalueType = new ReferenceType(elementType);
04657         else {
04658             const PointerType *ptrType = exprLValueType->IsUniformType() ?
04659                 PointerType::GetUniform(elementType) : 
04660                 PointerType::GetVarying(elementType);
04661             // FIXME: replicated logic with structmemberexpr.... 
04662             if (CastType<PointerType>(exprLValueType) &&
04663                 CastType<PointerType>(exprLValueType)->IsSlice())
04664                 ptrType = ptrType->GetAsFrozenSlice();
04665             lvalueType = ptrType;
04666         }
04667     }
04668 
04669     return lvalueType;
04670 }
04671 
04672 
04673 llvm::Value *
04674 VectorMemberExpr::GetValue(FunctionEmitContext *ctx) const {
04675     if (identifier.length() == 1) {
04676         return MemberExpr::GetValue(ctx);
04677     } 
04678     else {
04679         std::vector<int> indices;
04680 
04681         for (size_t i = 0; i < identifier.size(); ++i) {
04682             int idx = lIdentifierToVectorElement(identifier[i]);
04683             if (idx == -1)
04684                 Error(pos,
04685                       "Invalid swizzle charcter '%c' in swizzle \"%s\".",
04686                       identifier[i], identifier.c_str());
04687 
04688             indices.push_back(idx);
04689         }
04690 
04691         llvm::Value *basePtr = NULL;
04692         const Type *basePtrType = NULL;
04693         if (dereferenceExpr) {
04694             basePtr = expr->GetValue(ctx);
04695             basePtrType = expr->GetType();
04696         }
04697         else {
04698             basePtr = expr->GetLValue(ctx);
04699             basePtrType = expr->GetLValueType();
04700         }
04701 
04702         if (basePtr == NULL || basePtrType == NULL) {
04703             AssertPos(pos, m->errorCount > 0);
04704             return NULL;
04705         }
04706 
04707         // Allocate temporary memory to tore the result
04708         llvm::Value *resultPtr = ctx->AllocaInst(memberType->LLVMType(g->ctx), 
04709                                                  "vector_tmp");
04710         
04711         // FIXME: we should be able to use the internal mask here according
04712         // to the same logic where it's used elsewhere
04713         llvm::Value *elementMask = ctx->GetFullMask();
04714 
04715         const Type *elementPtrType = basePtrType->IsUniformType() ? 
04716             PointerType::GetUniform(exprVectorType->GetElementType()) :
04717             PointerType::GetVarying(exprVectorType->GetElementType());
04718 
04719         ctx->SetDebugPos(pos);
04720         for (size_t i = 0; i < identifier.size(); ++i) {
04721             char idStr[2] = { identifier[i], '\0' };
04722             llvm::Value *elementPtr = ctx->AddElementOffset(basePtr, indices[i],
04723                                                             basePtrType,
04724                                                             LLVMGetName(basePtr, idStr));
04725             llvm::Value *elementValue = 
04726                 ctx->LoadInst(elementPtr, elementMask, elementPtrType);
04727 
04728             const char *resultName = LLVMGetName(resultPtr, idStr);
04729             llvm::Value *ptmp = ctx->AddElementOffset(resultPtr, i, NULL, resultName);
04730             ctx->StoreInst(elementValue, ptmp);
04731         }
04732 
04733         return ctx->LoadInst(resultPtr, LLVMGetName(basePtr, "_swizzle"));
04734     }
04735 }
04736 
04737 
04738 int
04739 VectorMemberExpr::getElementNumber() const {
04740     int elementNumber = lIdentifierToVectorElement(identifier[0]);
04741     if (elementNumber == -1)
04742         Error(pos, "Vector element identifier \"%s\" unknown.", 
04743               identifier.c_str());
04744     return elementNumber;
04745 }
04746 
04747 
04748 const Type *
04749 VectorMemberExpr::getElementType() const {
04750     return memberType;
04751 }
04752 
04753 
04754 
04755 MemberExpr *
04756 MemberExpr::create(Expr *e, const char *id, SourcePos p, SourcePos idpos,
04757                    bool derefLValue) {
04758     // FIXME: we need to call TypeCheck() here so that we can call
04759     // e->GetType() in the following.  But really we just shouldn't try to
04760     // resolve this now but just have a generic MemberExpr type that
04761     // handles all cases so that this is unnecessary.
04762     e = ::TypeCheck(e);
04763 
04764     const Type *exprType;
04765     if (e == NULL || (exprType = e->GetType()) == NULL)
04766         return NULL;
04767 
04768     const ReferenceType *referenceType = CastType<ReferenceType>(exprType);
04769     if (referenceType != NULL) {
04770         e = new RefDerefExpr(e, e->pos);
04771         exprType = e->GetType();
04772         Assert(exprType != NULL);
04773     }
04774 
04775     const PointerType *pointerType = CastType<PointerType>(exprType);
04776     if (pointerType != NULL)
04777         exprType = pointerType->GetBaseType();
04778 
04779     if (derefLValue == true && pointerType == NULL) {
04780         const Type *targetType = exprType->GetReferenceTarget();
04781         if (CastType<StructType>(targetType) != NULL)
04782             Error(p, "Member operator \"->\" can't be applied to non-pointer "
04783                   "type \"%s\".  Did you mean to use \".\"?", 
04784                   exprType->GetString().c_str());
04785         else
04786             Error(p, "Member operator \"->\" can't be applied to non-struct "
04787                   "pointer type \"%s\".", exprType->GetString().c_str());
04788         return NULL;
04789     }
04790     if (derefLValue == false && pointerType != NULL &&
04791         CastType<StructType>(pointerType->GetBaseType()) != NULL) {
04792             Error(p, "Member operator \".\" can't be applied to pointer "
04793                   "type \"%s\".  Did you mean to use \"->\"?", 
04794                   exprType->GetString().c_str());
04795         return NULL;
04796     }
04797 
04798     if (CastType<StructType>(exprType) != NULL)
04799         return new StructMemberExpr(e, id, p, idpos, derefLValue);
04800     else if (CastType<VectorType>(exprType) != NULL)
04801         return new VectorMemberExpr(e, id, p, idpos, derefLValue);
04802     else if (CastType<UndefinedStructType>(exprType)) {
04803         Error(p, "Member operator \"%s\" can't be applied to declared "
04804               "but not defined struct type \"%s\".", derefLValue ? "->" : ".",
04805               exprType->GetString().c_str());
04806         return NULL;
04807     }
04808     else {
04809         Error(p, "Member operator \"%s\" can't be used with expression of "
04810               "\"%s\" type.", derefLValue ? "->" : ".", 
04811               exprType->GetString().c_str());
04812         return NULL;
04813     }
04814 }
04815 
04816 
04817 MemberExpr::MemberExpr(Expr *e, const char *id, SourcePos p, SourcePos idpos,
04818                        bool derefLValue) 
04819     : Expr(p), identifierPos(idpos) {
04820     expr = e;
04821     identifier = id;
04822     dereferenceExpr = derefLValue;
04823     type = lvalueType = NULL;
04824 }
04825 
04826 
04827 llvm::Value *
04828 MemberExpr::GetValue(FunctionEmitContext *ctx) const {
04829     if (!expr) 
04830         return NULL;
04831 
04832     llvm::Value *lvalue = GetLValue(ctx);
04833     const Type *lvalueType = GetLValueType();
04834 
04835     llvm::Value *mask = NULL;
04836     if (lvalue == NULL) {
04837         if (m->errorCount > 0)
04838             return NULL;
04839 
04840         // As in the array case, this may be a temporary that hasn't hit
04841         // memory; get the full value and stuff it into a temporary array
04842         // so that we can index from there...
04843         llvm::Value *val = expr->GetValue(ctx);
04844         if (!val) {
04845             AssertPos(pos, m->errorCount > 0);
04846             return NULL;
04847         }
04848         ctx->SetDebugPos(pos);
04849         const Type *exprType = expr->GetType();
04850         llvm::Value *ptr = ctx->AllocaInst(exprType->LLVMType(g->ctx), 
04851                                            "struct_tmp");
04852         ctx->StoreInst(val, ptr);
04853 
04854         int elementNumber = getElementNumber();
04855         if (elementNumber == -1)
04856             return NULL;
04857 
04858         lvalue = ctx->AddElementOffset(ptr, elementNumber, 
04859                                        PointerType::GetUniform(exprType));
04860         lvalueType = PointerType::GetUniform(GetType());
04861         mask = LLVMMaskAllOn;
04862     }
04863     else {
04864         Symbol *baseSym = GetBaseSymbol();
04865         AssertPos(pos, baseSym != NULL);
04866         mask = lMaskForSymbol(baseSym, ctx);
04867     }
04868 
04869     ctx->SetDebugPos(pos);
04870     std::string suffix = std::string("_") + identifier;
04871     return ctx->LoadInst(lvalue, mask, lvalueType, 
04872                          LLVMGetName(lvalue, suffix.c_str()));
04873 }
04874 
04875 
04876 const Type *
04877 MemberExpr::GetType() const {
04878     return NULL;
04879 }
04880 
04881 
04882 Symbol *
04883 MemberExpr::GetBaseSymbol() const {
04884     return expr ? expr->GetBaseSymbol() : NULL;
04885 }
04886 
04887 
04888 int
04889 MemberExpr::getElementNumber() const {
04890     return -1;
04891 }
04892 
04893 
04894 llvm::Value *
04895 MemberExpr::GetLValue(FunctionEmitContext *ctx) const {
04896     const Type *exprType;
04897     if (!expr || ((exprType = expr->GetType()) == NULL))
04898         return NULL;
04899 
04900     ctx->SetDebugPos(pos);
04901     llvm::Value *basePtr = dereferenceExpr ? expr->GetValue(ctx) :
04902         expr->GetLValue(ctx);
04903     if (!basePtr)
04904         return NULL;
04905 
04906     int elementNumber = getElementNumber();
04907     if (elementNumber == -1)
04908         return NULL;
04909 
04910     const Type *exprLValueType = dereferenceExpr ? expr->GetType() :
04911         expr->GetLValueType();
04912     ctx->SetDebugPos(pos);
04913     llvm::Value *ptr = ctx->AddElementOffset(basePtr, elementNumber,
04914                                              exprLValueType, 
04915                                              basePtr->getName().str().c_str());
04916     if (ptr == NULL) {
04917         AssertPos(pos, m->errorCount > 0);
04918         return NULL;
04919     }
04920 
04921     ptr = lAddVaryingOffsetsIfNeeded(ctx, ptr, GetLValueType());
04922 
04923     return ptr;
04924 }
04925 
04926 
04927 Expr *
04928 MemberExpr::TypeCheck() {
04929     return expr ? this : NULL;
04930 }
04931 
04932 
04933 Expr *
04934 MemberExpr::Optimize() {
04935     return expr ? this : NULL;
04936 }
04937 
04938 
04939 int
04940 MemberExpr::EstimateCost() const {
04941     const Type *lvalueType = GetLValueType();
04942     if (lvalueType != NULL && lvalueType->IsVaryingType())
04943         return COST_GATHER + COST_SIMPLE_ARITH_LOGIC_OP;
04944     else
04945         return COST_SIMPLE_ARITH_LOGIC_OP;
04946 }
04947 
04948 
04949 void
04950 MemberExpr::Print() const {
04951     if (!expr || !GetType())
04952         return;
04953 
04954     printf("[%s] member (", GetType()->GetString().c_str());
04955     expr->Print();
04956     printf(" . %s)", identifier.c_str());
04957     pos.Print();
04958 }
04959 
04960 
04961 /** There is no structure member with the name we've got in "identifier".
04962     Use the approximate string matching routine to see if the identifier is
04963     a minor misspelling of one of the ones that is there.
04964  */
04965 std::string
04966 MemberExpr::getCandidateNearMatches() const {
04967     const StructType *structType = CastType<StructType>(expr->GetType());
04968     if (!structType)
04969         return "";
04970 
04971     std::vector<std::string> elementNames;
04972     for (int i = 0; i < structType->GetElementCount(); ++i)
04973         elementNames.push_back(structType->GetElementName(i));
04974     std::vector<std::string> alternates = MatchStrings(identifier, elementNames);
04975     if (!alternates.size())
04976         return "";
04977 
04978     std::string ret = " Did you mean ";
04979     for (unsigned int i = 0; i < alternates.size(); ++i) {
04980         ret += std::string("\"") + alternates[i] + std::string("\"");
04981         if (i < alternates.size() - 1) ret += ", or ";
04982     }
04983     ret += "?";
04984     return ret;
04985 }
04986 
04987 
04988 ///////////////////////////////////////////////////////////////////////////
04989 // ConstExpr
04990 
04991 ConstExpr::ConstExpr(const Type *t, int8_t i, SourcePos p) 
04992   : Expr(p) {
04993     type = t;
04994     type = type->GetAsConstType();
04995     AssertPos(pos, Type::Equal(type, AtomicType::UniformInt8->GetAsConstType()));
04996     int8Val[0] = i;
04997 }
04998 
04999 
05000 ConstExpr::ConstExpr(const Type *t, int8_t *i, SourcePos p) 
05001   : Expr(p) {
05002     type = t;
05003     type = type->GetAsConstType();
05004     AssertPos(pos, Type::Equal(type, AtomicType::UniformInt8->GetAsConstType()) || 
05005            Type::Equal(type, AtomicType::VaryingInt8->GetAsConstType()));
05006     for (int j = 0; j < Count(); ++j)
05007         int8Val[j] = i[j];
05008 }
05009 
05010 
05011 ConstExpr::ConstExpr(const Type *t, uint8_t u, SourcePos p) 
05012   : Expr(p) {
05013     type = t;
05014     type = type->GetAsConstType();
05015     AssertPos(pos, Type::Equal(type, AtomicType::UniformUInt8->GetAsConstType()));
05016     uint8Val[0] = u;
05017 }
05018 
05019 
05020 ConstExpr::ConstExpr(const Type *t, uint8_t *u, SourcePos p) 
05021   : Expr(p) {
05022     type = t;
05023     type = type->GetAsConstType();
05024     AssertPos(pos, Type::Equal(type, AtomicType::UniformUInt8->GetAsConstType()) || 
05025            Type::Equal(type, AtomicType::VaryingUInt8->GetAsConstType()));
05026     for (int j = 0; j < Count(); ++j)
05027         uint8Val[j] = u[j];
05028 }
05029 
05030 
05031 ConstExpr::ConstExpr(const Type *t, int16_t i, SourcePos p) 
05032   : Expr(p) {
05033     type = t;
05034     type = type->GetAsConstType();
05035     AssertPos(pos, Type::Equal(type, AtomicType::UniformInt16->GetAsConstType()));
05036     int16Val[0] = i;
05037 }
05038 
05039 
05040 ConstExpr::ConstExpr(const Type *t, int16_t *i, SourcePos p) 
05041   : Expr(p) {
05042     type = t;
05043     type = type->GetAsConstType();
05044     AssertPos(pos, Type::Equal(type, AtomicType::UniformInt16->GetAsConstType()) || 
05045            Type::Equal(type, AtomicType::VaryingInt16->GetAsConstType()));
05046     for (int j = 0; j < Count(); ++j)
05047         int16Val[j] = i[j];
05048 }
05049 
05050 
05051 ConstExpr::ConstExpr(const Type *t, uint16_t u, SourcePos p) 
05052   : Expr(p) {
05053     type = t;
05054     type = type->GetAsConstType();
05055     AssertPos(pos, Type::Equal(type, AtomicType::UniformUInt16->GetAsConstType()));
05056     uint16Val[0] = u;
05057 }
05058 
05059 
05060 ConstExpr::ConstExpr(const Type *t, uint16_t *u, SourcePos p) 
05061   : Expr(p) {
05062     type = t;
05063     type = type->GetAsConstType();
05064     AssertPos(pos, Type::Equal(type, AtomicType::UniformUInt16->GetAsConstType()) || 
05065            Type::Equal(type, AtomicType::VaryingUInt16->GetAsConstType()));
05066     for (int j = 0; j < Count(); ++j)
05067         uint16Val[j] = u[j];
05068 }
05069 
05070 
05071 ConstExpr::ConstExpr(const Type *t, int32_t i, SourcePos p) 
05072   : Expr(p) {
05073     type = t;
05074     type = type->GetAsConstType();
05075     AssertPos(pos, Type::Equal(type, AtomicType::UniformInt32->GetAsConstType()));
05076     int32Val[0] = i;
05077 }
05078 
05079 
05080 ConstExpr::ConstExpr(const Type *t, int32_t *i, SourcePos p) 
05081   : Expr(p) {
05082     type = t;
05083     type = type->GetAsConstType();
05084     AssertPos(pos, Type::Equal(type, AtomicType::UniformInt32->GetAsConstType()) || 
05085            Type::Equal(type, AtomicType::VaryingInt32->GetAsConstType()));
05086     for (int j = 0; j < Count(); ++j)
05087         int32Val[j] = i[j];
05088 }
05089 
05090 
05091 ConstExpr::ConstExpr(const Type *t, uint32_t u, SourcePos p) 
05092   : Expr(p) {
05093     type = t;
05094     type = type->GetAsConstType();
05095     AssertPos(pos, Type::Equal(type, AtomicType::UniformUInt32->GetAsConstType()) ||
05096            (CastType<EnumType>(type) != NULL &&
05097             type->IsUniformType()));
05098     uint32Val[0] = u;
05099 }
05100 
05101 
05102 ConstExpr::ConstExpr(const Type *t, uint32_t *u, SourcePos p) 
05103   : Expr(p) {
05104     type = t;
05105     type = type->GetAsConstType();
05106     AssertPos(pos, Type::Equal(type, AtomicType::UniformUInt32->GetAsConstType()) || 
05107            Type::Equal(type, AtomicType::VaryingUInt32->GetAsConstType()) ||
05108            (CastType<EnumType>(type) != NULL));
05109     for (int j = 0; j < Count(); ++j)
05110         uint32Val[j] = u[j];
05111 }
05112 
05113 
05114 ConstExpr::ConstExpr(const Type *t, float f, SourcePos p)
05115     : Expr(p) {
05116     type = t;
05117     type = type->GetAsConstType();
05118     AssertPos(pos, Type::Equal(type, AtomicType::UniformFloat->GetAsConstType()));
05119     floatVal[0] = f;
05120 }
05121 
05122 
05123 ConstExpr::ConstExpr(const Type *t, float *f, SourcePos p) 
05124   : Expr(p) {
05125     type = t;
05126     type = type->GetAsConstType();
05127     AssertPos(pos, Type::Equal(type, AtomicType::UniformFloat->GetAsConstType()) || 
05128            Type::Equal(type, AtomicType::VaryingFloat->GetAsConstType()));
05129     for (int j = 0; j < Count(); ++j)
05130         floatVal[j] = f[j];
05131 }
05132 
05133 
05134 ConstExpr::ConstExpr(const Type *t, int64_t i, SourcePos p) 
05135   : Expr(p) {
05136     type = t;
05137     type = type->GetAsConstType();
05138     AssertPos(pos, Type::Equal(type, AtomicType::UniformInt64->GetAsConstType()));
05139     int64Val[0] = i;
05140 }
05141 
05142 
05143 ConstExpr::ConstExpr(const Type *t, int64_t *i, SourcePos p) 
05144   : Expr(p) {
05145     type = t;
05146     type = type->GetAsConstType();
05147     AssertPos(pos, Type::Equal(type, AtomicType::UniformInt64->GetAsConstType()) || 
05148            Type::Equal(type, AtomicType::VaryingInt64->GetAsConstType()));
05149     for (int j = 0; j < Count(); ++j)
05150         int64Val[j] = i[j];
05151 }
05152 
05153 
05154 ConstExpr::ConstExpr(const Type *t, uint64_t u, SourcePos p) 
05155   : Expr(p) {
05156     type = t;
05157     type = type->GetAsConstType();
05158     AssertPos(pos, Type::Equal(type, AtomicType::UniformUInt64->GetAsConstType()));
05159     uint64Val[0] = u;
05160 }
05161 
05162 
05163 ConstExpr::ConstExpr(const Type *t, uint64_t *u, SourcePos p) 
05164   : Expr(p) {
05165     type = t;
05166     type = type->GetAsConstType();
05167     AssertPos(pos, Type::Equal(type, AtomicType::UniformUInt64->GetAsConstType()) || 
05168            Type::Equal(type, AtomicType::VaryingUInt64->GetAsConstType()));
05169     for (int j = 0; j < Count(); ++j)
05170         uint64Val[j] = u[j];
05171 }
05172 
05173 
05174 ConstExpr::ConstExpr(const Type *t, double f, SourcePos p)
05175     : Expr(p) {
05176     type = t;
05177     type = type->GetAsConstType();
05178     AssertPos(pos, Type::Equal(type, AtomicType::UniformDouble->GetAsConstType()));
05179     doubleVal[0] = f;
05180 }
05181 
05182 
05183 ConstExpr::ConstExpr(const Type *t, double *f, SourcePos p) 
05184   : Expr(p) {
05185     type = t;
05186     type = type->GetAsConstType();
05187     AssertPos(pos, Type::Equal(type, AtomicType::UniformDouble->GetAsConstType()) || 
05188            Type::Equal(type, AtomicType::VaryingDouble->GetAsConstType()));
05189     for (int j = 0; j < Count(); ++j)
05190         doubleVal[j] = f[j];
05191 }
05192 
05193 
05194 ConstExpr::ConstExpr(const Type *t, bool b, SourcePos p) 
05195   : Expr(p) {
05196     type = t;
05197     type = type->GetAsConstType();
05198     AssertPos(pos, Type::Equal(type, AtomicType::UniformBool->GetAsConstType()));
05199     boolVal[0] = b;
05200 }
05201 
05202 
05203 ConstExpr::ConstExpr(const Type *t, bool *b, SourcePos p) 
05204   : Expr(p) {
05205     type = t;
05206     type = type->GetAsConstType();
05207     AssertPos(pos, Type::Equal(type, AtomicType::UniformBool->GetAsConstType()) || 
05208            Type::Equal(type, AtomicType::VaryingBool->GetAsConstType()));
05209     for (int j = 0; j < Count(); ++j)
05210         boolVal[j] = b[j];
05211 }
05212 
05213 
05214 ConstExpr::ConstExpr(ConstExpr *old, double *v) 
05215     : Expr(old->pos) {
05216     type = old->type;
05217 
05218     AtomicType::BasicType basicType = getBasicType();
05219 
05220     switch (basicType) {
05221     case AtomicType::TYPE_BOOL:
05222         for (int i = 0; i < Count(); ++i)
05223             boolVal[i] = (v[i] != 0.);
05224         break;
05225     case AtomicType::TYPE_INT8:
05226         for (int i = 0; i < Count(); ++i)
05227             int8Val[i] = (int)v[i];
05228         break;
05229     case AtomicType::TYPE_UINT8:
05230         for (int i = 0; i < Count(); ++i)
05231             uint8Val[i] = (unsigned int)v[i];
05232         break;
05233     case AtomicType::TYPE_INT16:
05234         for (int i = 0; i < Count(); ++i)
05235             int16Val[i] = (int)v[i];
05236         break;
05237     case AtomicType::TYPE_UINT16:
05238         for (int i = 0; i < Count(); ++i)
05239             uint16Val[i] = (unsigned int)v[i];
05240         break;
05241     case AtomicType::TYPE_INT32:
05242         for (int i = 0; i < Count(); ++i)
05243             int32Val[i] = (int)v[i];
05244         break;
05245     case AtomicType::TYPE_UINT32:
05246         for (int i = 0; i < Count(); ++i)
05247             uint32Val[i] = (unsigned int)v[i];
05248         break;
05249     case AtomicType::TYPE_FLOAT:
05250         for (int i = 0; i < Count(); ++i)
05251             floatVal[i] = (float)v[i];
05252         break;
05253     case AtomicType::TYPE_DOUBLE:
05254         for (int i = 0; i < Count(); ++i)
05255             doubleVal[i] = v[i];
05256         break;
05257     case AtomicType::TYPE_INT64:
05258     case AtomicType::TYPE_UINT64:
05259         // For now, this should never be reached 
05260         FATAL("fixme; we need another constructor so that we're not trying to pass "
05261                "double values to init an int64 type...");
05262     default:
05263         FATAL("unimplemented const type");
05264     }
05265 }
05266 
05267 
05268 ConstExpr::ConstExpr(ConstExpr *old, SourcePos p)
05269     : Expr(p) {
05270     type = old->type;
05271 
05272     AtomicType::BasicType basicType = getBasicType();
05273 
05274     switch (basicType) {
05275     case AtomicType::TYPE_BOOL:
05276         memcpy(boolVal, old->boolVal, Count() * sizeof(bool));
05277         break;
05278     case AtomicType::TYPE_INT8:
05279         memcpy(int8Val, old->int8Val, Count() * sizeof(int8_t));
05280         break;
05281     case AtomicType::TYPE_UINT8:
05282         memcpy(uint8Val, old->uint8Val, Count() * sizeof(uint8_t));
05283         break;
05284     case AtomicType::TYPE_INT16:
05285         memcpy(int16Val, old->int16Val, Count() * sizeof(int16_t));
05286         break;
05287     case AtomicType::TYPE_UINT16:
05288         memcpy(uint16Val, old->uint16Val, Count() * sizeof(uint16_t));
05289         break;
05290     case AtomicType::TYPE_INT32:
05291         memcpy(int32Val, old->int32Val, Count() * sizeof(int32_t));
05292         break;
05293     case AtomicType::TYPE_UINT32:
05294         memcpy(uint32Val, old->uint32Val, Count() * sizeof(uint32_t));
05295         break;
05296     case AtomicType::TYPE_FLOAT:
05297         memcpy(floatVal, old->floatVal, Count() * sizeof(float));
05298         break;
05299     case AtomicType::TYPE_DOUBLE:
05300         memcpy(doubleVal, old->doubleVal, Count() * sizeof(double));
05301         break;
05302     case AtomicType::TYPE_INT64:
05303         memcpy(int64Val, old->int64Val, Count() * sizeof(int64_t));
05304         break;
05305     case AtomicType::TYPE_UINT64:
05306         memcpy(uint64Val, old->uint64Val, Count() * sizeof(uint64_t));
05307         break;
05308     default:
05309         FATAL("unimplemented const type");
05310     }
05311     
05312 }
05313 
05314 
05315 AtomicType::BasicType
05316 ConstExpr::getBasicType() const {
05317     const AtomicType *at = CastType<AtomicType>(type);
05318     if (at != NULL)
05319         return at->basicType;
05320     else {
05321         AssertPos(pos, CastType<EnumType>(type) != NULL);
05322         return AtomicType::TYPE_UINT32;
05323     }
05324 }
05325 
05326 
05327 const Type *
05328 ConstExpr::GetType() const { 
05329     return type; 
05330 }
05331 
05332 
05333 llvm::Value *
05334 ConstExpr::GetValue(FunctionEmitContext *ctx) const {
05335     ctx->SetDebugPos(pos);
05336     bool isVarying = type->IsVaryingType();
05337 
05338     AtomicType::BasicType basicType = getBasicType();
05339 
05340     switch (basicType) {
05341     case AtomicType::TYPE_BOOL:
05342         if (isVarying)
05343             return LLVMBoolVector(boolVal);
05344         else
05345             return boolVal[0] ? LLVMTrue : LLVMFalse;
05346     case AtomicType::TYPE_INT8:
05347         return isVarying ? LLVMInt8Vector(int8Val) : 
05348                            LLVMInt8(int8Val[0]);
05349     case AtomicType::TYPE_UINT8:
05350         return isVarying ? LLVMUInt8Vector(uint8Val) : 
05351                            LLVMUInt8(uint8Val[0]);
05352     case AtomicType::TYPE_INT16:
05353         return isVarying ? LLVMInt16Vector(int16Val) : 
05354                            LLVMInt16(int16Val[0]);
05355     case AtomicType::TYPE_UINT16:
05356         return isVarying ? LLVMUInt16Vector(uint16Val) : 
05357                            LLVMUInt16(uint16Val[0]);
05358     case AtomicType::TYPE_INT32:
05359         return isVarying ? LLVMInt32Vector(int32Val) : 
05360                            LLVMInt32(int32Val[0]);
05361     case AtomicType::TYPE_UINT32:
05362         return isVarying ? LLVMUInt32Vector(uint32Val) : 
05363                            LLVMUInt32(uint32Val[0]);
05364     case AtomicType::TYPE_FLOAT:
05365         return isVarying ? LLVMFloatVector(floatVal) : 
05366                            LLVMFloat(floatVal[0]);
05367     case AtomicType::TYPE_INT64:
05368         return isVarying ? LLVMInt64Vector(int64Val) : 
05369                            LLVMInt64(int64Val[0]);
05370     case AtomicType::TYPE_UINT64:
05371         return isVarying ? LLVMUInt64Vector(uint64Val) : 
05372                            LLVMUInt64(uint64Val[0]);
05373     case AtomicType::TYPE_DOUBLE:
05374         return isVarying ? LLVMDoubleVector(doubleVal) : 
05375                            LLVMDouble(doubleVal[0]);
05376     default:
05377         FATAL("unimplemented const type");
05378         return NULL;
05379     }
05380 }
05381 
05382 
05383 /* Type conversion templates: take advantage of C++ function overloading
05384    rules to get the one we want to match. */
05385 
05386 /* First the most general case, just use C++ type conversion if nothing
05387    else matches */
05388 template <typename From, typename To> static inline void
05389 lConvertElement(From from, To *to) {
05390     *to = (To)from;
05391 }
05392 
05393 
05394 /** When converting from bool types to numeric types, make sure the result
05395     is one or zero.
05396  */ 
05397 template <typename To> static inline void
05398 lConvertElement(bool from, To *to) {
05399     *to = from ? (To)1 : (To)0;
05400 }
05401 
05402 
05403 /** When converting numeric types to bool, compare to zero.  (Do we
05404     actually need this one??) */
05405 template <typename From> static inline void
05406 lConvertElement(From from, bool *to) {
05407     *to = (from != 0);
05408 }
05409 
05410 
05411 /** And bool -> bool is just assignment */
05412 static inline void
05413 lConvertElement(bool from, bool *to) {
05414     *to = from;
05415 }
05416 
05417 
05418 /** Type conversion utility function
05419  */
05420 template <typename From, typename To> static void
05421 lConvert(const From *from, To *to, int count, bool forceVarying) {
05422     for (int i = 0; i < count; ++i)
05423         lConvertElement(from[i], &to[i]);
05424 
05425     if (forceVarying && count == 1)
05426         for (int i = 1; i < g->target.vectorWidth; ++i)
05427             to[i] = to[0];
05428 }
05429 
05430 
05431 int
05432 ConstExpr::AsInt64(int64_t *ip, bool forceVarying) const {
05433     switch (getBasicType()) {
05434     case AtomicType::TYPE_BOOL:   lConvert(boolVal,   ip, Count(), forceVarying); break;
05435     case AtomicType::TYPE_INT8:   lConvert(int8Val,   ip, Count(), forceVarying); break;
05436     case AtomicType::TYPE_UINT8:  lConvert(uint8Val,  ip, Count(), forceVarying); break;
05437     case AtomicType::TYPE_INT16:  lConvert(int16Val,  ip, Count(), forceVarying); break;
05438     case AtomicType::TYPE_UINT16: lConvert(uint16Val, ip, Count(), forceVarying); break;
05439     case AtomicType::TYPE_INT32:  lConvert(int32Val,  ip, Count(), forceVarying); break;
05440     case AtomicType::TYPE_UINT32: lConvert(uint32Val, ip, Count(), forceVarying); break;
05441     case AtomicType::TYPE_FLOAT:  lConvert(floatVal,  ip, Count(), forceVarying); break;
05442     case AtomicType::TYPE_DOUBLE: lConvert(doubleVal, ip, Count(), forceVarying); break;
05443     case AtomicType::TYPE_INT64:  lConvert(int64Val,  ip, Count(), forceVarying); break;
05444     case AtomicType::TYPE_UINT64: lConvert(uint64Val, ip, Count(), forceVarying); break;
05445     default:
05446         FATAL("unimplemented const type");
05447     }
05448     return Count();
05449 }
05450 
05451 
05452 int
05453 ConstExpr::AsUInt64(uint64_t *up, bool forceVarying) const {
05454     switch (getBasicType()) {
05455     case AtomicType::TYPE_BOOL:   lConvert(boolVal,   up, Count(), forceVarying); break;
05456     case AtomicType::TYPE_INT8:   lConvert(int8Val,   up, Count(), forceVarying); break;
05457     case AtomicType::TYPE_UINT8:  lConvert(uint8Val,  up, Count(), forceVarying); break;
05458     case AtomicType::TYPE_INT16:  lConvert(int16Val,  up, Count(), forceVarying); break;
05459     case AtomicType::TYPE_UINT16: lConvert(uint16Val, up, Count(), forceVarying); break;
05460     case AtomicType::TYPE_INT32:  lConvert(int32Val,  up, Count(), forceVarying); break;
05461     case AtomicType::TYPE_UINT32: lConvert(uint32Val, up, Count(), forceVarying); break;
05462     case AtomicType::TYPE_FLOAT:  lConvert(floatVal,  up, Count(), forceVarying); break;
05463     case AtomicType::TYPE_DOUBLE: lConvert(doubleVal, up, Count(), forceVarying); break;
05464     case AtomicType::TYPE_INT64:  lConvert(int64Val,  up, Count(), forceVarying); break;
05465     case AtomicType::TYPE_UINT64: lConvert(uint64Val, up, Count(), forceVarying); break;
05466     default:
05467         FATAL("unimplemented const type");
05468     }
05469     return Count();
05470 }
05471 
05472 
05473 int
05474 ConstExpr::AsDouble(double *d, bool forceVarying) const {
05475     switch (getBasicType()) {
05476     case AtomicType::TYPE_BOOL:   lConvert(boolVal,   d, Count(), forceVarying); break;
05477     case AtomicType::TYPE_INT8:   lConvert(int8Val,   d, Count(), forceVarying); break;
05478     case AtomicType::TYPE_UINT8:  lConvert(uint8Val,  d, Count(), forceVarying); break;
05479     case AtomicType::TYPE_INT16:  lConvert(int16Val,  d, Count(), forceVarying); break;
05480     case AtomicType::TYPE_UINT16: lConvert(uint16Val, d, Count(), forceVarying); break;
05481     case AtomicType::TYPE_INT32:  lConvert(int32Val,  d, Count(), forceVarying); break;
05482     case AtomicType::TYPE_UINT32: lConvert(uint32Val, d, Count(), forceVarying); break;
05483     case AtomicType::TYPE_FLOAT:  lConvert(floatVal,  d, Count(), forceVarying); break;
05484     case AtomicType::TYPE_DOUBLE: lConvert(doubleVal, d, Count(), forceVarying); break;
05485     case AtomicType::TYPE_INT64:  lConvert(int64Val,  d, Count(), forceVarying); break;
05486     case AtomicType::TYPE_UINT64: lConvert(uint64Val, d, Count(), forceVarying); break;
05487     default:
05488         FATAL("unimplemented const type");
05489     }
05490     return Count();
05491 }
05492 
05493 
05494 int
05495 ConstExpr::AsFloat(float *fp, bool forceVarying) const {
05496     switch (getBasicType()) {
05497     case AtomicType::TYPE_BOOL:   lConvert(boolVal,   fp, Count(), forceVarying); break;
05498     case AtomicType::TYPE_INT8:   lConvert(int8Val,   fp, Count(), forceVarying); break;
05499     case AtomicType::TYPE_UINT8:  lConvert(uint8Val,  fp, Count(), forceVarying); break;
05500     case AtomicType::TYPE_INT16:  lConvert(int16Val,  fp, Count(), forceVarying); break;
05501     case AtomicType::TYPE_UINT16: lConvert(uint16Val, fp, Count(), forceVarying); break;
05502     case AtomicType::TYPE_INT32:  lConvert(int32Val,  fp, Count(), forceVarying); break;
05503     case AtomicType::TYPE_UINT32: lConvert(uint32Val, fp, Count(), forceVarying); break;
05504     case AtomicType::TYPE_FLOAT:  lConvert(floatVal,  fp, Count(), forceVarying); break;
05505     case AtomicType::TYPE_DOUBLE: lConvert(doubleVal, fp, Count(), forceVarying); break;
05506     case AtomicType::TYPE_INT64:  lConvert(int64Val,  fp, Count(), forceVarying); break;
05507     case AtomicType::TYPE_UINT64: lConvert(uint64Val, fp, Count(), forceVarying); break;
05508     default:
05509         FATAL("unimplemented const type");
05510     }
05511     return Count();
05512 }
05513 
05514 
05515 int
05516 ConstExpr::AsBool(bool *b, bool forceVarying) const {
05517     switch (getBasicType()) {
05518     case AtomicType::TYPE_BOOL:   lConvert(boolVal,   b, Count(), forceVarying); break;
05519     case AtomicType::TYPE_INT8:   lConvert(int8Val,   b, Count(), forceVarying); break;
05520     case AtomicType::TYPE_UINT8:  lConvert(uint8Val,  b, Count(), forceVarying); break;
05521     case AtomicType::TYPE_INT16:  lConvert(int16Val,  b, Count(), forceVarying); break;
05522     case AtomicType::TYPE_UINT16: lConvert(uint16Val, b, Count(), forceVarying); break;
05523     case AtomicType::TYPE_INT32:  lConvert(int32Val,  b, Count(), forceVarying); break;
05524     case AtomicType::TYPE_UINT32: lConvert(uint32Val, b, Count(), forceVarying); break;
05525     case AtomicType::TYPE_FLOAT:  lConvert(floatVal,  b, Count(), forceVarying); break;
05526     case AtomicType::TYPE_DOUBLE: lConvert(doubleVal, b, Count(), forceVarying); break;
05527     case AtomicType::TYPE_INT64:  lConvert(int64Val,  b, Count(), forceVarying); break;
05528     case AtomicType::TYPE_UINT64: lConvert(uint64Val, b, Count(), forceVarying); break;
05529     default:
05530         FATAL("unimplemented const type");
05531     }
05532     return Count();
05533 }
05534 
05535 
05536 int
05537 ConstExpr::AsInt8(int8_t *ip, bool forceVarying) const {
05538     switch (getBasicType()) {
05539     case AtomicType::TYPE_BOOL:   lConvert(boolVal,   ip, Count(), forceVarying); break;
05540     case AtomicType::TYPE_INT8:   lConvert(int8Val,   ip, Count(), forceVarying); break;
05541     case AtomicType::TYPE_UINT8:  lConvert(uint8Val,  ip, Count(), forceVarying); break;
05542     case AtomicType::TYPE_INT16:  lConvert(int16Val,  ip, Count(), forceVarying); break;
05543     case AtomicType::TYPE_UINT16: lConvert(uint16Val, ip, Count(), forceVarying); break;
05544     case AtomicType::TYPE_INT32:  lConvert(int32Val,  ip, Count(), forceVarying); break;
05545     case AtomicType::TYPE_UINT32: lConvert(uint32Val, ip, Count(), forceVarying); break;
05546     case AtomicType::TYPE_FLOAT:  lConvert(floatVal,  ip, Count(), forceVarying); break;
05547     case AtomicType::TYPE_DOUBLE: lConvert(doubleVal, ip, Count(), forceVarying); break;
05548     case AtomicType::TYPE_INT64:  lConvert(int64Val,  ip, Count(), forceVarying); break;
05549     case AtomicType::TYPE_UINT64: lConvert(uint64Val, ip, Count(), forceVarying); break;
05550     default:
05551         FATAL("unimplemented const type");
05552     }
05553     return Count();
05554 }
05555 
05556 
05557 int
05558 ConstExpr::AsUInt8(uint8_t *up, bool forceVarying) const {
05559     switch (getBasicType()) {
05560     case AtomicType::TYPE_BOOL:   lConvert(boolVal,   up, Count(), forceVarying); break;
05561     case AtomicType::TYPE_INT8:   lConvert(int8Val,   up, Count(), forceVarying); break;
05562     case AtomicType::TYPE_UINT8:  lConvert(uint8Val,  up, Count(), forceVarying); break;
05563     case AtomicType::TYPE_INT16:  lConvert(int16Val,  up, Count(), forceVarying); break;
05564     case AtomicType::TYPE_UINT16: lConvert(uint16Val, up, Count(), forceVarying); break;
05565     case AtomicType::TYPE_INT32:  lConvert(int32Val,  up, Count(), forceVarying); break;
05566     case AtomicType::TYPE_UINT32: lConvert(uint32Val, up, Count(), forceVarying); break;
05567     case AtomicType::TYPE_FLOAT:  lConvert(floatVal,  up, Count(), forceVarying); break;
05568     case AtomicType::TYPE_DOUBLE: lConvert(doubleVal, up, Count(), forceVarying); break;
05569     case AtomicType::TYPE_INT64:  lConvert(int64Val,  up, Count(), forceVarying); break;
05570     case AtomicType::TYPE_UINT64: lConvert(uint64Val, up, Count(), forceVarying); break;
05571     default:
05572         FATAL("unimplemented const type");
05573     }
05574     return Count();
05575 }
05576 
05577 
05578 int
05579 ConstExpr::AsInt16(int16_t *ip, bool forceVarying) const {
05580     switch (getBasicType()) {
05581     case AtomicType::TYPE_BOOL:   lConvert(boolVal,   ip, Count(), forceVarying); break;
05582     case AtomicType::TYPE_INT8:   lConvert(int8Val,   ip, Count(), forceVarying); break;
05583     case AtomicType::TYPE_UINT8:  lConvert(uint8Val,  ip, Count(), forceVarying); break;
05584     case AtomicType::TYPE_INT16:  lConvert(int16Val,  ip, Count(), forceVarying); break;
05585     case AtomicType::TYPE_UINT16: lConvert(uint16Val, ip, Count(), forceVarying); break;
05586     case AtomicType::TYPE_INT32:  lConvert(int32Val,  ip, Count(), forceVarying); break;
05587     case AtomicType::TYPE_UINT32: lConvert(uint32Val, ip, Count(), forceVarying); break;
05588     case AtomicType::TYPE_FLOAT:  lConvert(floatVal,  ip, Count(), forceVarying); break;
05589     case AtomicType::TYPE_DOUBLE: lConvert(doubleVal, ip, Count(), forceVarying); break;
05590     case AtomicType::TYPE_INT64:  lConvert(int64Val,  ip, Count(), forceVarying); break;
05591     case AtomicType::TYPE_UINT64: lConvert(uint64Val, ip, Count(), forceVarying); break;
05592     default:
05593         FATAL("unimplemented const type");
05594     }
05595     return Count();
05596 }
05597 
05598 
05599 int
05600 ConstExpr::AsUInt16(uint16_t *up, bool forceVarying) const {
05601     switch (getBasicType()) {
05602     case AtomicType::TYPE_BOOL:   lConvert(boolVal,   up, Count(), forceVarying); break;
05603     case AtomicType::TYPE_INT8:   lConvert(int8Val,   up, Count(), forceVarying); break;
05604     case AtomicType::TYPE_UINT8:  lConvert(uint8Val,  up, Count(), forceVarying); break;
05605     case AtomicType::TYPE_INT16:  lConvert(int16Val,  up, Count(), forceVarying); break;
05606     case AtomicType::TYPE_UINT16: lConvert(uint16Val, up, Count(), forceVarying); break;
05607     case AtomicType::TYPE_INT32:  lConvert(int32Val,  up, Count(), forceVarying); break;
05608     case AtomicType::TYPE_UINT32: lConvert(uint32Val, up, Count(), forceVarying); break;
05609     case AtomicType::TYPE_FLOAT:  lConvert(floatVal,  up, Count(), forceVarying); break;
05610     case AtomicType::TYPE_DOUBLE: lConvert(doubleVal, up, Count(), forceVarying); break;
05611     case AtomicType::TYPE_INT64:  lConvert(int64Val,  up, Count(), forceVarying); break;
05612     case AtomicType::TYPE_UINT64: lConvert(uint64Val, up, Count(), forceVarying); break;
05613     default:
05614         FATAL("unimplemented const type");
05615     }
05616     return Count();
05617 }
05618 
05619 
05620 int
05621 ConstExpr::AsInt32(int32_t *ip, bool forceVarying) const {
05622     switch (getBasicType()) {
05623     case AtomicType::TYPE_BOOL:   lConvert(boolVal,   ip, Count(), forceVarying); break;
05624     case AtomicType::TYPE_INT8:   lConvert(int8Val,   ip, Count(), forceVarying); break;
05625     case AtomicType::TYPE_UINT8:  lConvert(uint8Val,  ip, Count(), forceVarying); break;
05626     case AtomicType::TYPE_INT16:  lConvert(int16Val,  ip, Count(), forceVarying); break;
05627     case AtomicType::TYPE_UINT16: lConvert(uint16Val, ip, Count(), forceVarying); break;
05628     case AtomicType::TYPE_INT32:  lConvert(int32Val,  ip, Count(), forceVarying); break;
05629     case AtomicType::TYPE_UINT32: lConvert(uint32Val, ip, Count(), forceVarying); break;
05630     case AtomicType::TYPE_FLOAT:  lConvert(floatVal,  ip, Count(), forceVarying); break;
05631     case AtomicType::TYPE_DOUBLE: lConvert(doubleVal, ip, Count(), forceVarying); break;
05632     case AtomicType::TYPE_INT64:  lConvert(int64Val,  ip, Count(), forceVarying); break;
05633     case AtomicType::TYPE_UINT64: lConvert(uint64Val, ip, Count(), forceVarying); break;
05634     default:
05635         FATAL("unimplemented const type");
05636     }
05637     return Count();
05638 }
05639 
05640 
05641 int
05642 ConstExpr::AsUInt32(uint32_t *up, bool forceVarying) const {
05643     switch (getBasicType()) {
05644     case AtomicType::TYPE_BOOL:   lConvert(boolVal,   up, Count(), forceVarying); break;
05645     case AtomicType::TYPE_INT8:   lConvert(int8Val,   up, Count(), forceVarying); break;
05646     case AtomicType::TYPE_UINT8:  lConvert(uint8Val,  up, Count(), forceVarying); break;
05647     case AtomicType::TYPE_INT16:  lConvert(int16Val,  up, Count(), forceVarying); break;
05648     case AtomicType::TYPE_UINT16: lConvert(uint16Val, up, Count(), forceVarying); break;
05649     case AtomicType::TYPE_INT32:  lConvert(int32Val,  up, Count(), forceVarying); break;
05650     case AtomicType::TYPE_UINT32: lConvert(uint32Val, up, Count(), forceVarying); break;
05651     case AtomicType::TYPE_FLOAT:  lConvert(floatVal,  up, Count(), forceVarying); break;
05652     case AtomicType::TYPE_DOUBLE: lConvert(doubleVal, up, Count(), forceVarying); break;
05653     case AtomicType::TYPE_INT64:  lConvert(int64Val,  up, Count(), forceVarying); break;
05654     case AtomicType::TYPE_UINT64: lConvert(uint64Val, up, Count(), forceVarying); break;
05655     default:
05656         FATAL("unimplemented const type");
05657     }
05658     return Count();
05659 }
05660 
05661 
05662 int
05663 ConstExpr::Count() const { 
05664     return GetType()->IsVaryingType() ? g->target.vectorWidth : 1; 
05665 }
05666 
05667 
05668 llvm::Constant *
05669 ConstExpr::GetConstant(const Type *type) const {
05670     // Caller shouldn't be trying to stuff a varying value here into a
05671     // constant type.
05672     if (type->IsUniformType())
05673         AssertPos(pos, Count() == 1);
05674 
05675     type = type->GetAsNonConstType();
05676     if (Type::Equal(type, AtomicType::UniformBool) || 
05677         Type::Equal(type, AtomicType::VaryingBool)) {
05678         bool bv[ISPC_MAX_NVEC];
05679         AsBool(bv, type->IsVaryingType());
05680         if (type->IsUniformType())
05681             return bv[0] ? LLVMTrue : LLVMFalse;
05682         else
05683             return LLVMBoolVector(bv);
05684     }
05685     else if (Type::Equal(type, AtomicType::UniformInt8) ||
05686              Type::Equal(type, AtomicType::VaryingInt8)) {
05687         int8_t iv[ISPC_MAX_NVEC];
05688         AsInt8(iv, type->IsVaryingType());
05689         if (type->IsUniformType())
05690             return LLVMInt8(iv[0]);
05691         else
05692             return LLVMInt8Vector(iv);
05693     }
05694     else if (Type::Equal(type, AtomicType::UniformUInt8) || 
05695              Type::Equal(type, AtomicType::VaryingUInt8)) {
05696         uint8_t uiv[ISPC_MAX_NVEC];
05697         AsUInt8(uiv, type->IsVaryingType());
05698         if (type->IsUniformType())
05699             return LLVMUInt8(uiv[0]);
05700         else
05701             return LLVMUInt8Vector(uiv);
05702     }
05703     else if (Type::Equal(type, AtomicType::UniformInt16) ||
05704              Type::Equal(type, AtomicType::VaryingInt16)) {
05705         int16_t iv[ISPC_MAX_NVEC];
05706         AsInt16(iv, type->IsVaryingType());
05707         if (type->IsUniformType())
05708             return LLVMInt16(iv[0]);
05709         else
05710             return LLVMInt16Vector(iv);
05711     }
05712     else if (Type::Equal(type, AtomicType::UniformUInt16) ||
05713              Type::Equal(type, AtomicType::VaryingUInt16)) {
05714         uint16_t uiv[ISPC_MAX_NVEC];
05715         AsUInt16(uiv, type->IsVaryingType());
05716         if (type->IsUniformType())
05717             return LLVMUInt16(uiv[0]);
05718         else
05719             return LLVMUInt16Vector(uiv);
05720     }
05721     else if (Type::Equal(type, AtomicType::UniformInt32) || 
05722              Type::Equal(type, AtomicType::VaryingInt32)) {
05723         int32_t iv[ISPC_MAX_NVEC];
05724         AsInt32(iv, type->IsVaryingType());
05725         if (type->IsUniformType())
05726             return LLVMInt32(iv[0]);
05727         else
05728             return LLVMInt32Vector(iv);
05729     }
05730     else if (Type::Equal(type, AtomicType::UniformUInt32) || 
05731              Type::Equal(type, AtomicType::VaryingUInt32) ||
05732              CastType<EnumType>(type) != NULL) {
05733         uint32_t uiv[ISPC_MAX_NVEC];
05734         AsUInt32(uiv, type->IsVaryingType());
05735         if (type->IsUniformType())
05736             return LLVMUInt32(uiv[0]);
05737         else
05738             return LLVMUInt32Vector(uiv);
05739     }
05740     else if (Type::Equal(type, AtomicType::UniformFloat) || 
05741              Type::Equal(type, AtomicType::VaryingFloat)) {
05742         float fv[ISPC_MAX_NVEC];
05743         AsFloat(fv, type->IsVaryingType());
05744         if (type->IsUniformType())
05745             return LLVMFloat(fv[0]);
05746         else
05747             return LLVMFloatVector(fv);
05748     }
05749     else if (Type::Equal(type, AtomicType::UniformInt64) || 
05750              Type::Equal(type, AtomicType::VaryingInt64)) {
05751         int64_t iv[ISPC_MAX_NVEC];
05752         AsInt64(iv, type->IsVaryingType());
05753         if (type->IsUniformType())
05754             return LLVMInt64(iv[0]);
05755         else
05756             return LLVMInt64Vector(iv);
05757     }
05758     else if (Type::Equal(type, AtomicType::UniformUInt64) ||
05759              Type::Equal(type, AtomicType::VaryingUInt64)) {
05760         uint64_t uiv[ISPC_MAX_NVEC];
05761         AsUInt64(uiv, type->IsVaryingType());
05762         if (type->IsUniformType())
05763             return LLVMUInt64(uiv[0]);
05764         else
05765             return LLVMUInt64Vector(uiv);
05766     }
05767     else if (Type::Equal(type, AtomicType::UniformDouble) ||
05768              Type::Equal(type, AtomicType::VaryingDouble)) {
05769         double dv[ISPC_MAX_NVEC];
05770         AsDouble(dv, type->IsVaryingType());
05771         if (type->IsUniformType())
05772             return LLVMDouble(dv[0]);
05773         else
05774             return LLVMDoubleVector(dv);
05775     }
05776     else if (CastType<PointerType>(type) != NULL) {
05777         // The only time we should get here is if we have an integer '0'
05778         // constant that should be turned into a NULL pointer of the
05779         // appropriate type.
05780         llvm::Type *llvmType = type->LLVMType(g->ctx);
05781         if (llvmType == NULL) {
05782             AssertPos(pos, m->errorCount > 0);
05783             return NULL;
05784         }
05785 
05786         int64_t iv[ISPC_MAX_NVEC];
05787         AsInt64(iv, type->IsVaryingType());
05788         for (int i = 0; i < Count(); ++i)
05789             if (iv[i] != 0)
05790                 // We'll issue an error about this later--trying to assign
05791                 // a constant int to a pointer, without a typecast.
05792                 return NULL;
05793 
05794         return llvm::Constant::getNullValue(llvmType);
05795     }
05796     else {
05797         Debug(pos, "Unable to handle type \"%s\" in ConstExpr::GetConstant().",
05798               type->GetString().c_str());
05799         return NULL;
05800     }
05801 }
05802 
05803 
05804 Expr *
05805 ConstExpr::Optimize() {
05806     return this;
05807 }
05808 
05809 
05810 Expr *
05811 ConstExpr::TypeCheck() {
05812     return this;
05813 }
05814 
05815 
05816 int
05817 ConstExpr::EstimateCost() const {
05818     return 0;
05819 }
05820 
05821 
05822 void
05823 ConstExpr::Print() const {
05824     printf("[%s] (", GetType()->GetString().c_str());
05825     for (int i = 0; i < Count(); ++i) {
05826         switch (getBasicType()) {
05827         case AtomicType::TYPE_BOOL:
05828             printf("%s", boolVal[i] ? "true" : "false");
05829             break;
05830         case AtomicType::TYPE_INT8:
05831             printf("%d", (int)int8Val[i]);
05832             break;
05833         case AtomicType::TYPE_UINT8:
05834             printf("%u", (int)uint8Val[i]);
05835             break;
05836         case AtomicType::TYPE_INT16:
05837             printf("%d", (int)int16Val[i]);
05838             break;
05839         case AtomicType::TYPE_UINT16:
05840             printf("%u", (int)uint16Val[i]);
05841             break;
05842         case AtomicType::TYPE_INT32:
05843             printf("%d", int32Val[i]);
05844             break;
05845         case AtomicType::TYPE_UINT32:
05846             printf("%u", uint32Val[i]);
05847             break;
05848         case AtomicType::TYPE_FLOAT:
05849             printf("%f", floatVal[i]);
05850             break;
05851         case AtomicType::TYPE_INT64:
05852             printf("%"PRId64, int64Val[i]);
05853             break;
05854         case AtomicType::TYPE_UINT64:
05855             printf("%"PRIu64, uint64Val[i]);
05856             break;
05857         case AtomicType::TYPE_DOUBLE:
05858             printf("%f", doubleVal[i]);
05859             break;
05860         default:
05861             FATAL("unimplemented const type");
05862         }
05863         if (i != Count() - 1)
05864             printf(", ");
05865     }
05866     printf(")");
05867     pos.Print();
05868 }
05869 
05870 
05871 ///////////////////////////////////////////////////////////////////////////
05872 // TypeCastExpr
05873 
05874 TypeCastExpr::TypeCastExpr(const Type *t, Expr *e, SourcePos p) 
05875   : Expr(p) {
05876     type = t;
05877     expr = e;
05878 }
05879 
05880 
05881 /** Handle all the grungy details of type conversion between atomic types.
05882     Given an input value in exprVal of type fromType, convert it to the
05883     llvm::Value with type toType.
05884  */
05885 static llvm::Value *
05886 lTypeConvAtomic(FunctionEmitContext *ctx, llvm::Value *exprVal, 
05887                 const AtomicType *toType, const AtomicType *fromType,
05888                 SourcePos pos) {
05889     llvm::Value *cast = NULL;
05890 
05891     std::string opName = exprVal->getName().str();
05892     switch (toType->basicType) {
05893     case AtomicType::TYPE_BOOL: opName += "_to_bool"; break;
05894     case AtomicType::TYPE_INT8: opName += "_to_int8"; break;
05895     case AtomicType::TYPE_UINT8: opName += "_to_uint8"; break;
05896     case AtomicType::TYPE_INT16: opName += "_to_int16"; break;
05897     case AtomicType::TYPE_UINT16: opName += "_to_uint16"; break;
05898     case AtomicType::TYPE_INT32: opName += "_to_int32"; break;
05899     case AtomicType::TYPE_UINT32: opName += "_to_uint32"; break;
05900     case AtomicType::TYPE_INT64: opName += "_to_int64"; break;
05901     case AtomicType::TYPE_UINT64: opName += "_to_uint64"; break;
05902     case AtomicType::TYPE_FLOAT: opName += "_to_float"; break;
05903     case AtomicType::TYPE_DOUBLE: opName += "_to_double"; break;
05904     default: FATAL("Unimplemented");
05905     }
05906     const char *cOpName = opName.c_str();
05907 
05908     switch (toType->basicType) {
05909     case AtomicType::TYPE_FLOAT: {
05910         llvm::Type *targetType = 
05911             fromType->IsUniformType() ? LLVMTypes::FloatType : 
05912                                         LLVMTypes::FloatVectorType;
05913         switch (fromType->basicType) {
05914         case AtomicType::TYPE_BOOL:
05915             if (fromType->IsVaryingType() && 
05916                 LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
05917                 // If we have a bool vector of i32 elements, first truncate
05918                 // down to a single bit
05919                 exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, cOpName);
05920             // And then do an unisgned int->float cast
05921             cast = ctx->CastInst(llvm::Instruction::UIToFP, // unsigned int
05922                                  exprVal, targetType, cOpName);
05923             break;
05924         case AtomicType::TYPE_INT8:
05925         case AtomicType::TYPE_INT16:
05926         case AtomicType::TYPE_INT32:
05927         case AtomicType::TYPE_INT64:
05928             cast = ctx->CastInst(llvm::Instruction::SIToFP, // signed int to float
05929                                  exprVal, targetType, cOpName);
05930             break;
05931         case AtomicType::TYPE_UINT8:
05932         case AtomicType::TYPE_UINT16:
05933         case AtomicType::TYPE_UINT32:
05934         case AtomicType::TYPE_UINT64:
05935             if (fromType->IsVaryingType() && g->target.isa != Target::GENERIC)
05936                 PerformanceWarning(pos, "Conversion from unsigned int to float is slow. "
05937                                    "Use \"int\" if possible");
05938             cast = ctx->CastInst(llvm::Instruction::UIToFP, // unsigned int to float
05939                                  exprVal, targetType, cOpName);
05940             break;
05941         case AtomicType::TYPE_FLOAT:
05942             // No-op cast.
05943             cast = exprVal;
05944             break;
05945         case AtomicType::TYPE_DOUBLE:
05946             cast = ctx->FPCastInst(exprVal, targetType, cOpName);
05947             break;
05948         default:
05949             FATAL("unimplemented");
05950         }
05951         break;
05952     }
05953     case AtomicType::TYPE_DOUBLE: {
05954         llvm::Type *targetType = 
05955             fromType->IsUniformType() ? LLVMTypes::DoubleType :
05956                                         LLVMTypes::DoubleVectorType;
05957         switch (fromType->basicType) {
05958         case AtomicType::TYPE_BOOL:
05959             if (fromType->IsVaryingType() && 
05960                 LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
05961                 // truncate i32 bool vector values to i1s
05962                 exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, cOpName);
05963             cast = ctx->CastInst(llvm::Instruction::UIToFP, // unsigned int to double
05964                                  exprVal, targetType, cOpName);
05965             break;
05966         case AtomicType::TYPE_INT8:
05967         case AtomicType::TYPE_INT16:
05968         case AtomicType::TYPE_INT32:
05969         case AtomicType::TYPE_INT64:
05970             cast = ctx->CastInst(llvm::Instruction::SIToFP, // signed int
05971                                  exprVal, targetType, cOpName);
05972             break;
05973         case AtomicType::TYPE_UINT8:
05974         case AtomicType::TYPE_UINT16:
05975         case AtomicType::TYPE_UINT32:
05976         case AtomicType::TYPE_UINT64:
05977             cast = ctx->CastInst(llvm::Instruction::UIToFP, // unsigned int
05978                                  exprVal, targetType, cOpName);
05979             break;
05980         case AtomicType::TYPE_FLOAT:
05981             cast = ctx->FPCastInst(exprVal, targetType, cOpName);
05982             break;
05983         case AtomicType::TYPE_DOUBLE:
05984             cast = exprVal;
05985             break;
05986         default:
05987             FATAL("unimplemented");
05988         }
05989         break;
05990     }
05991     case AtomicType::TYPE_INT8: {
05992         llvm::Type *targetType = 
05993             fromType->IsUniformType() ? LLVMTypes::Int8Type :
05994                                         LLVMTypes::Int8VectorType;
05995         switch (fromType->basicType) {
05996         case AtomicType::TYPE_BOOL:
05997             if (fromType->IsVaryingType() && 
05998                 LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
05999                 exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, cOpName);
06000             cast = ctx->ZExtInst(exprVal, targetType, cOpName);
06001             break;
06002         case AtomicType::TYPE_INT8:
06003         case AtomicType::TYPE_UINT8:
06004             cast = exprVal;
06005             break;
06006         case AtomicType::TYPE_INT16:
06007         case AtomicType::TYPE_UINT16:
06008         case AtomicType::TYPE_INT32:
06009         case AtomicType::TYPE_UINT32:
06010         case AtomicType::TYPE_INT64:
06011         case AtomicType::TYPE_UINT64:
06012             cast = ctx->TruncInst(exprVal, targetType, cOpName);
06013             break;
06014         case AtomicType::TYPE_FLOAT:
06015             cast = ctx->CastInst(llvm::Instruction::FPToSI, // signed int
06016                                  exprVal, targetType, cOpName);
06017             break;
06018         case AtomicType::TYPE_DOUBLE:
06019             cast = ctx->CastInst(llvm::Instruction::FPToSI, // signed int
06020                                  exprVal, targetType, cOpName);
06021             break;
06022         default:
06023             FATAL("unimplemented");
06024         }
06025         break;
06026     }
06027     case AtomicType::TYPE_UINT8: {
06028         llvm::Type *targetType = 
06029             fromType->IsUniformType() ? LLVMTypes::Int8Type :
06030                                         LLVMTypes::Int8VectorType;
06031         switch (fromType->basicType) {
06032         case AtomicType::TYPE_BOOL:
06033             if (fromType->IsVaryingType() && 
06034                 LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
06035                 exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, cOpName);
06036             cast = ctx->ZExtInst(exprVal, targetType, cOpName);
06037             break;
06038         case AtomicType::TYPE_INT8:
06039         case AtomicType::TYPE_UINT8:
06040             cast = exprVal;
06041             break;
06042         case AtomicType::TYPE_INT16:
06043         case AtomicType::TYPE_UINT16:
06044         case AtomicType::TYPE_INT32:
06045         case AtomicType::TYPE_UINT32:
06046         case AtomicType::TYPE_INT64:
06047         case AtomicType::TYPE_UINT64:
06048             cast = ctx->TruncInst(exprVal, targetType, cOpName);
06049             break;
06050         case AtomicType::TYPE_FLOAT:
06051             if (fromType->IsVaryingType() && g->target.isa != Target::GENERIC)
06052                 PerformanceWarning(pos, "Conversion from float to unsigned int is slow. "
06053                                    "Use \"int\" if possible");
06054             cast = ctx->CastInst(llvm::Instruction::FPToUI, // unsigned int
06055                                  exprVal, targetType, cOpName);
06056             break;
06057         case AtomicType::TYPE_DOUBLE:
06058             if (fromType->IsVaryingType() && g->target.isa != Target::GENERIC)
06059                 PerformanceWarning(pos, "Conversion from double to unsigned int is slow. "
06060                                    "Use \"int\" if possible");
06061             cast = ctx->CastInst(llvm::Instruction::FPToUI, // unsigned int
06062                                  exprVal, targetType, cOpName);
06063             break;
06064         default:
06065             FATAL("unimplemented");
06066         }
06067         break;
06068     }
06069     case AtomicType::TYPE_INT16: {
06070         llvm::Type *targetType = 
06071             fromType->IsUniformType() ? LLVMTypes::Int16Type :
06072                                         LLVMTypes::Int16VectorType;
06073         switch (fromType->basicType) {
06074         case AtomicType::TYPE_BOOL:
06075             if (fromType->IsVaryingType() && 
06076                 LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
06077                 exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, cOpName);
06078             cast = ctx->ZExtInst(exprVal, targetType, cOpName);
06079             break;
06080         case AtomicType::TYPE_INT8:
06081             cast = ctx->SExtInst(exprVal, targetType, cOpName);
06082             break;
06083         case AtomicType::TYPE_UINT8:
06084             cast = ctx->ZExtInst(exprVal, targetType, cOpName);
06085             break;
06086         case AtomicType::TYPE_INT16:
06087         case AtomicType::TYPE_UINT16:
06088             cast = exprVal;
06089             break;
06090         case AtomicType::TYPE_FLOAT:
06091             cast = ctx->CastInst(llvm::Instruction::FPToSI, // signed int
06092                                  exprVal, targetType, cOpName);
06093             break;
06094         case AtomicType::TYPE_INT32:
06095         case AtomicType::TYPE_UINT32:
06096         case AtomicType::TYPE_INT64:
06097         case AtomicType::TYPE_UINT64:
06098             cast = ctx->TruncInst(exprVal, targetType, cOpName);
06099             break;
06100         case AtomicType::TYPE_DOUBLE:
06101             cast = ctx->CastInst(llvm::Instruction::FPToSI, // signed int
06102                                  exprVal, targetType, cOpName);
06103             break;
06104         default:
06105             FATAL("unimplemented");
06106         }
06107         break;
06108     }
06109     case AtomicType::TYPE_UINT16: {
06110         llvm::Type *targetType = 
06111             fromType->IsUniformType() ? LLVMTypes::Int16Type :
06112                                         LLVMTypes::Int16VectorType;
06113         switch (fromType->basicType) {
06114         case AtomicType::TYPE_BOOL:
06115             if (fromType->IsVaryingType() && 
06116                 LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
06117                 exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, cOpName);
06118             cast = ctx->ZExtInst(exprVal, targetType, cOpName);
06119             break;
06120         case AtomicType::TYPE_INT8:
06121             cast = ctx->SExtInst(exprVal, targetType, cOpName);
06122             break;
06123         case AtomicType::TYPE_UINT8:
06124             cast = ctx->ZExtInst(exprVal, targetType, cOpName);
06125             break;            
06126         case AtomicType::TYPE_INT16:
06127         case AtomicType::TYPE_UINT16:
06128             cast = exprVal;
06129             break;
06130         case AtomicType::TYPE_FLOAT:
06131             if (fromType->IsVaryingType() && g->target.isa != Target::GENERIC)
06132                 PerformanceWarning(pos, "Conversion from float to unsigned int is slow. "
06133                                    "Use \"int\" if possible");
06134             cast = ctx->CastInst(llvm::Instruction::FPToUI, // unsigned int
06135                                  exprVal, targetType, cOpName);
06136             break;
06137         case AtomicType::TYPE_INT32:
06138         case AtomicType::TYPE_UINT32:
06139         case AtomicType::TYPE_INT64:
06140         case AtomicType::TYPE_UINT64:
06141             cast = ctx->TruncInst(exprVal, targetType, cOpName);
06142             break;
06143         case AtomicType::TYPE_DOUBLE:
06144             if (fromType->IsVaryingType() && g->target.isa != Target::GENERIC)
06145                 PerformanceWarning(pos, "Conversion from double to unsigned int is slow. "
06146                                    "Use \"int\" if possible");
06147             cast = ctx->CastInst(llvm::Instruction::FPToUI, // unsigned int
06148                                  exprVal, targetType, cOpName);
06149             break;
06150         default:
06151             FATAL("unimplemented");
06152         }
06153         break;
06154     }
06155     case AtomicType::TYPE_INT32: {
06156         llvm::Type *targetType = 
06157             fromType->IsUniformType() ? LLVMTypes::Int32Type :
06158                                         LLVMTypes::Int32VectorType;
06159         switch (fromType->basicType) {
06160         case AtomicType::TYPE_BOOL:
06161             if (fromType->IsVaryingType() && 
06162                 LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
06163                 exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, cOpName);
06164             cast = ctx->ZExtInst(exprVal, targetType, cOpName);
06165             break;
06166         case AtomicType::TYPE_INT8:
06167         case AtomicType::TYPE_INT16:
06168             cast = ctx->SExtInst(exprVal, targetType, cOpName);
06169             break;
06170         case AtomicType::TYPE_UINT8:
06171         case AtomicType::TYPE_UINT16:
06172             cast = ctx->ZExtInst(exprVal, targetType, cOpName);
06173             break;
06174         case AtomicType::TYPE_INT32:
06175         case AtomicType::TYPE_UINT32:
06176             cast = exprVal;
06177             break;
06178         case AtomicType::TYPE_FLOAT:
06179             cast = ctx->CastInst(llvm::Instruction::FPToSI, // signed int
06180                                  exprVal, targetType, cOpName);
06181             break;
06182         case AtomicType::TYPE_INT64:
06183         case AtomicType::TYPE_UINT64:
06184             cast = ctx->TruncInst(exprVal, targetType, cOpName);
06185             break;
06186         case AtomicType::TYPE_DOUBLE:
06187             cast = ctx->CastInst(llvm::Instruction::FPToSI, // signed int
06188                                  exprVal, targetType, cOpName);
06189             break;
06190         default:
06191             FATAL("unimplemented");
06192         }
06193         break;
06194     }
06195     case AtomicType::TYPE_UINT32: {
06196         llvm::Type *targetType = 
06197             fromType->IsUniformType() ? LLVMTypes::Int32Type :
06198                                         LLVMTypes::Int32VectorType;
06199         switch (fromType->basicType) {
06200         case AtomicType::TYPE_BOOL:
06201             if (fromType->IsVaryingType() && 
06202                 LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
06203                 exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, cOpName);
06204             cast = ctx->ZExtInst(exprVal, targetType, cOpName);
06205             break;
06206         case AtomicType::TYPE_INT8:
06207         case AtomicType::TYPE_INT16:
06208             cast = ctx->SExtInst(exprVal, targetType, cOpName);
06209             break;
06210         case AtomicType::TYPE_UINT8:
06211         case AtomicType::TYPE_UINT16:
06212             cast = ctx->ZExtInst(exprVal, targetType, cOpName);
06213             break;            
06214         case AtomicType::TYPE_INT32:
06215         case AtomicType::TYPE_UINT32:
06216             cast = exprVal;
06217             break;
06218         case AtomicType::TYPE_FLOAT:
06219             if (fromType->IsVaryingType() && g->target.isa != Target::GENERIC)
06220                 PerformanceWarning(pos, "Conversion from float to unsigned int is slow. "
06221                                    "Use \"int\" if possible");
06222             cast = ctx->CastInst(llvm::Instruction::FPToUI, // unsigned int
06223                                  exprVal, targetType, cOpName);
06224             break;
06225         case AtomicType::TYPE_INT64:
06226         case AtomicType::TYPE_UINT64:
06227             cast = ctx->TruncInst(exprVal, targetType, cOpName);
06228             break;
06229         case AtomicType::TYPE_DOUBLE:
06230             if (fromType->IsVaryingType() && g->target.isa != Target::GENERIC)
06231                 PerformanceWarning(pos, "Conversion from double to unsigned int is slow. "
06232                                    "Use \"int\" if possible");
06233             cast = ctx->CastInst(llvm::Instruction::FPToUI, // unsigned int
06234                                  exprVal, targetType, cOpName);
06235             break;
06236         default:
06237             FATAL("unimplemented");
06238         }
06239         break;
06240     }
06241     case AtomicType::TYPE_INT64: {
06242         llvm::Type *targetType = 
06243             fromType->IsUniformType() ? LLVMTypes::Int64Type : 
06244                                         LLVMTypes::Int64VectorType;
06245         switch (fromType->basicType) {
06246         case AtomicType::TYPE_BOOL:
06247             if (fromType->IsVaryingType() &&
06248                 LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
06249                 exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, cOpName);
06250             cast = ctx->ZExtInst(exprVal, targetType, cOpName);
06251             break;
06252         case AtomicType::TYPE_INT8:
06253         case AtomicType::TYPE_INT16:
06254         case AtomicType::TYPE_INT32:
06255             cast = ctx->SExtInst(exprVal, targetType, cOpName);
06256             break;
06257         case AtomicType::TYPE_UINT8:
06258         case AtomicType::TYPE_UINT16:
06259         case AtomicType::TYPE_UINT32:
06260             cast = ctx->ZExtInst(exprVal, targetType, cOpName);
06261             break;
06262         case AtomicType::TYPE_FLOAT:
06263             cast = ctx->CastInst(llvm::Instruction::FPToSI, // signed int
06264                                  exprVal, targetType, cOpName);
06265             break;
06266         case AtomicType::TYPE_INT64:
06267         case AtomicType::TYPE_UINT64:
06268             cast = exprVal;
06269             break;
06270         case AtomicType::TYPE_DOUBLE:
06271             cast = ctx->CastInst(llvm::Instruction::FPToSI, // signed int
06272                                  exprVal, targetType, cOpName);
06273             break;
06274         default:
06275             FATAL("unimplemented");
06276         }
06277         break;
06278     }
06279     case AtomicType::TYPE_UINT64: {
06280         llvm::Type *targetType = 
06281             fromType->IsUniformType() ? LLVMTypes::Int64Type : 
06282                                         LLVMTypes::Int64VectorType;
06283         switch (fromType->basicType) {
06284         case AtomicType::TYPE_BOOL:
06285             if (fromType->IsVaryingType() && 
06286                 LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType)
06287                 exprVal = ctx->TruncInst(exprVal, LLVMTypes::Int1VectorType, cOpName);
06288             cast = ctx->ZExtInst(exprVal, targetType, cOpName);
06289             break;
06290         case AtomicType::TYPE_INT8:
06291         case AtomicType::TYPE_INT16:
06292         case AtomicType::TYPE_INT32:
06293             cast = ctx->SExtInst(exprVal, targetType, cOpName);
06294             break;
06295         case AtomicType::TYPE_UINT8:
06296         case AtomicType::TYPE_UINT16:
06297         case AtomicType::TYPE_UINT32:
06298             cast = ctx->ZExtInst(exprVal, targetType, cOpName);
06299             break;
06300         case AtomicType::TYPE_FLOAT:
06301             if (fromType->IsVaryingType() && g->target.isa != Target::GENERIC)
06302                 PerformanceWarning(pos, "Conversion from float to unsigned int64 is slow. "
06303                                    "Use \"int64\" if possible");
06304             cast = ctx->CastInst(llvm::Instruction::FPToUI, // signed int
06305                                  exprVal, targetType, cOpName);
06306             break;
06307         case AtomicType::TYPE_INT64:
06308         case AtomicType::TYPE_UINT64:
06309             cast = exprVal;
06310             break;
06311         case AtomicType::TYPE_DOUBLE:
06312             if (fromType->IsVaryingType() && g->target.isa != Target::GENERIC)
06313                 PerformanceWarning(pos, "Conversion from double to unsigned int64 is slow. "
06314                                    "Use \"int64\" if possible");
06315             cast = ctx->CastInst(llvm::Instruction::FPToUI, // signed int
06316                                  exprVal, targetType, cOpName);
06317             break;
06318         default:
06319             FATAL("unimplemented");
06320         }
06321         break;
06322     }
06323     case AtomicType::TYPE_BOOL: {
06324         switch (fromType->basicType) {
06325         case AtomicType::TYPE_BOOL:
06326             cast = exprVal;
06327             break;
06328         case AtomicType::TYPE_INT8:
06329         case AtomicType::TYPE_UINT8: {
06330             llvm::Value *zero = fromType->IsUniformType() ? (llvm::Value *)LLVMInt8(0) : 
06331                 (llvm::Value *)LLVMInt8Vector((int8_t)0);
06332             cast = ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE,
06333                                 exprVal, zero, cOpName);
06334             break;
06335         }
06336         case AtomicType::TYPE_INT16:
06337         case AtomicType::TYPE_UINT16: {
06338             llvm::Value *zero = fromType->IsUniformType() ? (llvm::Value *)LLVMInt16(0) : 
06339                 (llvm::Value *)LLVMInt16Vector((int16_t)0);
06340             cast = ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE,
06341                                 exprVal, zero, cOpName);
06342             break;
06343         }
06344         case AtomicType::TYPE_INT32:
06345         case AtomicType::TYPE_UINT32: {
06346             llvm::Value *zero = fromType->IsUniformType() ? (llvm::Value *)LLVMInt32(0) : 
06347                 (llvm::Value *)LLVMInt32Vector(0);
06348             cast = ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE,
06349                                 exprVal, zero, cOpName);
06350             break;
06351         }
06352         case AtomicType::TYPE_FLOAT: {
06353             llvm::Value *zero = fromType->IsUniformType() ? (llvm::Value *)LLVMFloat(0.f) : 
06354                 (llvm::Value *)LLVMFloatVector(0.f);
06355             cast = ctx->CmpInst(llvm::Instruction::FCmp, llvm::CmpInst::FCMP_ONE,
06356                                 exprVal, zero, cOpName);
06357             break;
06358         }
06359         case AtomicType::TYPE_INT64:
06360         case AtomicType::TYPE_UINT64: {
06361             llvm::Value *zero = fromType->IsUniformType() ? (llvm::Value *)LLVMInt64(0) : 
06362                 (llvm::Value *)LLVMInt64Vector((int64_t)0);
06363             cast = ctx->CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE,
06364                                 exprVal, zero, cOpName);
06365             break;
06366         }
06367         case AtomicType::TYPE_DOUBLE: {
06368             llvm::Value *zero = fromType->IsUniformType() ? (llvm::Value *)LLVMDouble(0.) : 
06369                 (llvm::Value *)LLVMDoubleVector(0.);
06370             cast = ctx->CmpInst(llvm::Instruction::FCmp, llvm::CmpInst::FCMP_ONE,
06371                                 exprVal, zero, cOpName);
06372             break;
06373         }
06374         default:
06375             FATAL("unimplemented");
06376         }
06377 
06378         if (fromType->IsUniformType()) {
06379             if (toType->IsVaryingType() && 
06380                 LLVMTypes::BoolVectorType == LLVMTypes::Int32VectorType) {
06381                 // extend out to i32 bool values from i1 here.  then we'll
06382                 // turn into a vector below, the way it does for everyone
06383                 // else...
06384                 cast = ctx->SExtInst(cast, LLVMTypes::BoolVectorType->getElementType(),
06385                                      LLVMGetName(cast, "to_i32bool"));
06386             }
06387         }
06388         else
06389             // fromType->IsVaryingType())
06390             cast = ctx->I1VecToBoolVec(cast);
06391 
06392         break;
06393     }
06394     default:
06395         FATAL("unimplemented");
06396     }
06397 
06398     // If we also want to go from uniform to varying, replicate out the
06399     // value across the vector elements..
06400     if (toType->IsVaryingType() && fromType->IsUniformType())
06401         return ctx->SmearUniform(cast);
06402     else
06403         return cast;
06404 }
06405 
06406 
06407 // FIXME: fold this into the FunctionEmitContext::SmearUniform() method?
06408 
06409 /** Converts the given value of the given type to be the varying
06410     equivalent, returning the resulting value.
06411  */
06412 static llvm::Value *
06413 lUniformValueToVarying(FunctionEmitContext *ctx, llvm::Value *value,
06414                        const Type *type) {
06415     // nothing to do if it's already varying
06416     if (type->IsVaryingType())
06417         return value;
06418 
06419     // for structs/arrays/vectors, just recursively make their elements
06420     // varying (if needed) and populate the return value.
06421     const CollectionType *collectionType = CastType<CollectionType>(type);
06422     if (collectionType != NULL) {
06423         llvm::Type *llvmType = 
06424             type->GetAsVaryingType()->LLVMType(g->ctx);
06425         llvm::Value *retValue = llvm::UndefValue::get(llvmType);
06426 
06427         for (int i = 0; i < collectionType->GetElementCount(); ++i) {
06428             llvm::Value *v = ctx->ExtractInst(value, i, "get_element");
06429             v = lUniformValueToVarying(ctx, v, collectionType->GetElementType(i));
06430             retValue = ctx->InsertInst(retValue, v, i, "set_element");
06431         }
06432         return retValue;
06433     }
06434 
06435     // Otherwise we must have a uniform atomic or pointer type, so smear
06436     // its value across the vector lanes.
06437     Assert(CastType<AtomicType>(type) != NULL ||
06438            CastType<PointerType>(type) != NULL);
06439     return ctx->SmearUniform(value);
06440 }
06441 
06442 
06443 llvm::Value *
06444 TypeCastExpr::GetValue(FunctionEmitContext *ctx) const {
06445     if (!expr)
06446         return NULL;
06447 
06448     ctx->SetDebugPos(pos);
06449     const Type *toType = GetType(), *fromType = expr->GetType();
06450     if (toType == NULL || fromType == NULL) {
06451         AssertPos(pos, m->errorCount > 0);
06452         return NULL;
06453     }
06454 
06455     if (Type::Equal(toType, AtomicType::Void)) {
06456         // emit the code for the expression in case it has side-effects but
06457         // then we're done.
06458         (void)expr->GetValue(ctx);
06459         return NULL;
06460     }
06461 
06462     const PointerType *fromPointerType = CastType<PointerType>(fromType);
06463     const PointerType *toPointerType = CastType<PointerType>(toType);
06464     const ArrayType *toArrayType = CastType<ArrayType>(toType);
06465     const ArrayType *fromArrayType = CastType<ArrayType>(fromType);
06466     if (fromPointerType != NULL) {
06467         if (toArrayType != NULL) {
06468             return expr->GetValue(ctx);
06469         }
06470         else if (toPointerType != NULL) {
06471             llvm::Value *value = expr->GetValue(ctx);
06472             if (value == NULL)
06473                 return NULL;
06474 
06475             if (fromPointerType->IsSlice() == false &&
06476                 toPointerType->IsSlice() == true) {
06477                 // Convert from a non-slice pointer to a slice pointer by
06478                 // creating a slice pointer structure with zero offsets.
06479                 if (fromPointerType->IsUniformType())
06480                     value = ctx->MakeSlicePointer(value, LLVMInt32(0));
06481                 else
06482                     value = ctx->MakeSlicePointer(value, LLVMInt32Vector(0));
06483 
06484                 // FIXME: avoid error from unnecessary bitcast when all we
06485                 // need to do is the slice conversion and don't need to
06486                 // also do unif->varying conversions.  But this is really
06487                 // ugly logic.
06488                 if (value->getType() == toType->LLVMType(g->ctx))
06489                     return value;
06490             }
06491 
06492             if (fromType->IsUniformType() && toType->IsUniformType())
06493                 // bitcast to the actual pointer type
06494                 return ctx->BitCastInst(value, toType->LLVMType(g->ctx));
06495             else if (fromType->IsVaryingType() && toType->IsVaryingType()) {
06496                 // both are vectors of ints already, nothing to do at the IR
06497                 // level
06498                 return value;
06499             }
06500             else {
06501                 // Uniform -> varying pointer conversion
06502                 AssertPos(pos, fromType->IsUniformType() && toType->IsVaryingType());
06503                 if (fromPointerType->IsSlice()) {
06504                     // For slice pointers, we need to smear out both the
06505                     // pointer and the offset vector
06506                     AssertPos(pos, toPointerType->IsSlice());
06507                     llvm::Value *ptr = ctx->ExtractInst(value, 0);
06508                     llvm::Value *offset = ctx->ExtractInst(value, 1);
06509                     ptr = ctx->PtrToIntInst(ptr);
06510                     ptr = ctx->SmearUniform(ptr);
06511                     offset = ctx->SmearUniform(offset);
06512                     return ctx->MakeSlicePointer(ptr, offset);
06513                 }
06514                 else {
06515                     // Otherwise we just bitcast it to an int and smear it
06516                     // out to a vector
06517                     value = ctx->PtrToIntInst(value);
06518                     return ctx->SmearUniform(value);
06519                 }
06520             }
06521         }
06522         else {
06523