|
Intel SPMD Program Compiler
1.3.0
|
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