60 #include <llvm/ExecutionEngine/GenericValue.h> 61 #include <llvm/IR/CallingConv.h> 62 #include <llvm/IR/DerivedTypes.h> 63 #include <llvm/IR/Function.h> 64 #include <llvm/IR/InstIterator.h> 65 #include <llvm/IR/Instructions.h> 66 #include <llvm/IR/LLVMContext.h> 67 #include <llvm/IR/Module.h> 68 #include <llvm/IR/Type.h> 87 return std::pair<llvm::Constant *, bool>(NULL,
false);
102 lMaybeIssuePrecisionWarning(
const AtomicType *toAtomicType,
127 Warning(pos,
"Conversion from type \"%s\" to type \"%s\" for %s" 128 " may lose information.",
133 FATAL(
"logic error in lMaybeIssuePrecisionWarning()");
156 if (type == NULL || type->
IsIntType() ==
false)
166 return (vals[0] == 0);
168 for (
int i = 0; i < count; ++i)
179 AssertPos(pos, failureOk || errorMsgBase != NULL);
181 if (toType == NULL || fromType == NULL)
190 Error(pos,
"Can't convert from \"void\" to \"%s\" for %s.", toType->
GetString().c_str(), errorMsgBase);
196 Error(pos,
"Can't convert type \"%s\" to \"void\" for %s.", fromType->
GetString().c_str(), errorMsgBase);
200 if (CastType<FunctionType>(fromType)) {
201 if (CastType<PointerType>(toType) != NULL) {
213 Error(pos,
"Can't convert function type \"%s\" to \"%s\" for %s.", fromType->
GetString().c_str(),
214 toType->
GetString().c_str(), errorMsgBase);
218 if (CastType<FunctionType>(toType)) {
221 "Can't convert from type \"%s\" to function type \"%s\" " 232 "Can't convert between types \"%s\" and \"%s\" with " 233 "different SOA widths for %s.",
238 const ArrayType *toArrayType = CastType<ArrayType>(toType);
239 const ArrayType *fromArrayType = CastType<ArrayType>(fromType);
240 const VectorType *toVectorType = CastType<VectorType>(toType);
241 const VectorType *fromVectorType = CastType<VectorType>(fromType);
242 const StructType *toStructType = CastType<StructType>(toType);
243 const StructType *fromStructType = CastType<StructType>(fromType);
244 const EnumType *toEnumType = CastType<EnumType>(toType);
245 const EnumType *fromEnumType = CastType<EnumType>(fromType);
246 const AtomicType *toAtomicType = CastType<AtomicType>(toType);
247 const AtomicType *fromAtomicType = CastType<AtomicType>(fromType);
248 const PointerType *fromPointerType = CastType<PointerType>(fromType);
249 const PointerType *toPointerType = CastType<PointerType>(toType);
254 if (fromArrayType != NULL && toPointerType != NULL) {
261 const Type *eltType = fromArrayType->GetElementType();
262 if (toPointerType->GetBaseType()->IsConstType())
271 "Can't convert from incompatible array type \"%s\" " 272 "to pointer type \"%s\" for %s.",
280 Error(pos,
"Can't convert from type \"%s\" to type \"%s\" for %s.", fromType->
GetString().c_str(),
281 toType->
GetString().c_str(), errorMsgBase);
285 if (fromPointerType != NULL) {
286 if (CastType<AtomicType>(toType) != NULL && toType->
IsBoolType())
294 if (toPointerType == NULL) {
297 "Can't convert between from pointer type " 298 "\"%s\" to non-pointer type \"%s\" for %s.",
301 }
else if (fromPointerType->IsSlice() ==
true && toPointerType->IsSlice() ==
false) {
304 "Can't convert from pointer to SOA type " 305 "\"%s\" to pointer to non-SOA type \"%s\" for %s.",
306 fromPointerType->GetAsNonSlice()->GetString().c_str(), toType->
GetString().c_str(), errorMsgBase);
309 if (fromPointerType->GetBaseType()->IsConstType() && !(toPointerType->GetBaseType()->IsConstType())) {
311 Error(pos,
"Can't convert pointer to const \"%s\" to void pointer.",
312 fromPointerType->GetString().c_str());
322 }
else if (!
Type::Equal(fromPointerType->GetBaseType(), toPointerType->GetBaseType()) &&
323 !
Type::Equal(fromPointerType->GetBaseType()->GetAsConstType(), toPointerType->GetBaseType())) {
326 if (!
Type::Equal(fromPointerType->GetBaseType()->GetAsConstType(), toPointerType->GetBaseType())) {
328 "Converting from const pointer type \"%s\" to " 329 "pointer type \"%s\" for %s discards const qualifier.",
330 fromPointerType->GetString().c_str(), toPointerType->GetString().c_str(), errorMsgBase);
335 "Can't convert from pointer type \"%s\" to " 336 "incompatible pointer type \"%s\" for %s.",
337 fromPointerType->GetString().c_str(), toPointerType->GetString().c_str(), errorMsgBase);
346 if (toPointerType->IsSlice() ==
true && fromPointerType->IsSlice() ==
false)
353 if (toPointerType != NULL && fromAtomicType != NULL && fromAtomicType->IsIntType() && expr != NULL &&
369 if (toStructType && fromStructType && (toStructType->GetSOAWidth() != fromStructType->GetSOAWidth())) {
372 "Can't convert between incompatible struct types \"%s\" " 373 "and \"%s\" for %s.",
383 if (CastType<ReferenceType>(fromType)) {
384 if (CastType<ReferenceType>(toType)) {
398 "Can't convert between incompatible reference types \"%s\" " 399 "and \"%s\" for %s.",
415 }
else if (CastType<ReferenceType>(toType)) {
426 return lDoTypeConv(&rt, toType, NULL, failureOk, errorMsgBase, pos);
434 if (toArrayType && fromArrayType) {
445 Error(pos,
"Array type \"%s\" can't be converted to type \"%s\" for %s.", fromType->
GetString().c_str(),
446 toType->
GetString().c_str(), errorMsgBase);
451 if (toVectorType && fromVectorType) {
453 if (fromVectorType->GetElementCount() != toVectorType->GetElementCount()) {
456 "Can't convert between differently sized vector types " 457 "\"%s\" -> \"%s\" for %s.",
464 if (toStructType && fromStructType) {
465 if (!
Type::Equal(toStructType->GetAsUniformType()->GetAsConstType(),
466 fromStructType->GetAsUniformType()->GetAsConstType())) {
469 "Can't convert between different struct types " 470 "\"%s\" and \"%s\" for %s.",
471 fromStructType->GetString().c_str(), toStructType->GetString().c_str(), errorMsgBase);
477 if (toEnumType != NULL && fromEnumType != NULL) {
482 "Can't convert between different enum types " 483 "\"%s\" and \"%s\" for %s",
484 fromEnumType->GetString().c_str(), toEnumType->GetString().c_str(), errorMsgBase);
491 if (fromEnumType != NULL) {
493 if (toAtomicType == NULL && toVectorType == NULL) {
496 "Type conversion from \"%s\" to \"%s\" for %s is not " 506 if (fromAtomicType == NULL) {
509 "Type conversion from \"%s\" to \"%s\" for %s is not " 520 if (toAtomicType == NULL) {
523 "Type conversion from \"%s\" to \"%s\" for %s is " 532 "Can't convert between types \"%s\" and \"%s\" with " 533 "different SOA widths for %s.",
545 return lDoTypeConv(fromType, toType, NULL, errorMsgBase == NULL, errorMsgBase, pos);
559 if (
lDoTypeConv(fromType, toType, &e,
false, errorMsgBase, expr->
pos))
568 if (CastType<PointerType>(type) != NULL && (funcType = CastType<FunctionType>(type->
GetBaseType())) &&
574 std::vector<const Type *> paramTypes;
595 if (initExpr == NULL)
600 std::pair<llvm::Constant *, bool> constValPair = initExpr->
GetStorageConstant(symType);
601 llvm::Constant *constValue = constValPair.first;
602 if (constValue != NULL) {
610 if (llvmType == NULL) {
616 ctx->
StoreInst(constValue, ptr, symType);
618 llvm::Value *constPtr =
619 new llvm::GlobalVariable(*
m->
module, llvmType,
true , llvm::GlobalValue::InternalLinkage,
620 constValue,
"const_initializer");
631 if (llvm::dyn_cast<ExprList>(initExpr) == NULL) {
636 if (initExpr == NULL)
639 llvm::Value *initializerValue = initExpr->
GetValue(ctx);
640 if (initializerValue != NULL)
642 ctx->
StoreInst(initializerValue, ptr, symType);
652 if (elist->
exprs.size() == 1) {
657 "Expression list initializers with " 658 "multiple values can't be used with type \"%s\".",
670 "Initializer for reference type \"%s\" must have same " 671 "reference type itself. \"%s\" is incompatible.",
676 llvm::Value *initializerValue = initExpr->
GetValue(ctx);
677 if (initializerValue)
684 const CollectionType *collectionType = CastType<CollectionType>(symType);
685 if (collectionType != NULL || symType->
IsSOAType() ||
695 if (CastType<StructType>(symType) != NULL)
697 else if (CastType<ArrayType>(symType) != NULL)
699 else if (CastType<VectorType>(symType) != NULL)
704 FATAL(
"Unexpected CollectionType in InitSymbol()");
713 if (exprList != NULL) {
716 int nInits = exprList->
exprs.size();
717 if (nInits > nElements) {
719 "Initializer for %s type \"%s\" requires " 720 "no more than %d values; %d provided.",
721 name.c_str(), symType->
GetString().c_str(), nElements, nInits);
725 "Initializer for %s type \"%s\" requires " 726 "%d values; %d provided.",
727 name.c_str(), symType->
GetString().c_str(), nElements, nInits);
733 for (
int i = 0; i < nElements; ++i) {
736 const Type *elementType =
740 if (CastType<StructType>(symType) != NULL)
752 if (llvmType == NULL) {
757 llvm::Constant *zeroInit = llvm::Constant::getNullValue(llvmType);
758 ctx->
StoreInst(zeroInit, ep, elementType);
761 }
else if (collectionType) {
765 FATAL(
"CollectionType is NULL in InitSymbol()");
770 FATAL(
"Unexpected Type in InitSymbol()");
782 const VectorType *vt = CastType<VectorType>(type);
795 const AtomicType *atomicType = CastType<AtomicType>(type);
796 const EnumType *enumType = CastType<EnumType>(type);
797 const VectorType *vectorType = CastType<VectorType>(type);
798 const PointerType *pointerType = CastType<PointerType>(type);
802 Assert(atomicType != NULL || enumType != NULL || vectorType != NULL || pointerType != NULL);
804 if (atomicType != NULL || enumType != NULL) {
813 FATAL(
"can't get constant value for void type");
822 Assert((
double)i == value);
826 unsigned int i = (
unsigned int)value;
831 Assert((
double)i == value);
835 unsigned int i = (
unsigned int)value;
840 Assert((
double)i == value);
844 unsigned int i = (
unsigned int)value;
850 uint64_t i = (uint64_t)value;
851 Assert(value == (int64_t)i);
855 int64_t i = (int64_t)value;
856 Assert((
double)i == value);
862 FATAL(
"logic error in lLLVMConstantValue");
865 }
else if (pointerType != NULL) {
867 if (pointerType->IsUniformType())
876 llvm::Type *llvmVectorType = vectorType->LLVMType(ctx);
885 llvm::VectorType *lvt = llvm::dyn_cast<llvm::VectorType>(llvmVectorType);
887 std::vector<llvm::Constant *> vals;
888 for (
unsigned int i = 0; i < lvt->getNumElements(); ++i)
889 vals.push_back(constElement);
890 return llvm::ConstantVector::get(vals);
892 llvm::ArrayType *lat = llvm::dyn_cast<llvm::ArrayType>(llvmVectorType);
894 std::vector<llvm::Constant *> vals;
895 for (
unsigned int i = 0; i < lat->getNumElements(); ++i)
896 vals.push_back(constElement);
897 return llvm::ConstantArray::get(lat, vals);
906 if (CastType<PointerType>(baseSym->
type) != NULL || CastType<ReferenceType>(baseSym->
type) != NULL)
926 CastType<ReferenceType>(baseSym->
type) == NULL && CastType<PointerType>(baseSym->
type) == NULL) {
950 llvm::Value *lvalue = NULL, *rvalue = NULL;
951 const Type *lvalueType = NULL;
952 if (CastType<ReferenceType>(type) != NULL) {
965 if (lvalue == NULL) {
969 Error(pos,
"Can't %s-%s non-lvalues.", prepost, incdec);
976 llvm::Value *binop = NULL;
979 std::string opName = rvalue->getName().str();
985 if (CastType<PointerType>(type) != NULL) {
992 binop = ctx->
BinaryOperator(llvm::Instruction::FAdd, rvalue, dval, opName.c_str());
994 binop = ctx->
BinaryOperator(llvm::Instruction::Add, rvalue, dval, opName.c_str());
1011 llvm::Value *argVal = arg->
GetValue(ctx);
1012 if (type == NULL || argVal == NULL)
1018 llvm::Value *zero = llvm::ConstantFP::getZeroValueForNegation(type->
LLVMType(
g->
ctx));
1052 FATAL(
"logic error");
1087 for (
int i = 0; i < count; ++i)
1095 for (
int i = 0; i < count; ++i)
1104 if (constExpr == NULL)
1108 bool isEnumType = CastType<EnumType>(type) != NULL;
1121 return lOptimizeNegate<int64_t>(constExpr, type,
pos);
1124 return lOptimizeNegate<uint64_t>(constExpr, type,
pos);
1127 return lOptimizeNegate<int32_t>(constExpr, type,
pos);
1130 return lOptimizeNegate<uint32_t>(constExpr, type,
pos);
1133 return lOptimizeNegate<int16_t>(constExpr, type,
pos);
1136 return lOptimizeNegate<uint16_t>(constExpr, type,
pos);
1139 return lOptimizeNegate<int8_t>(constExpr, type,
pos);
1142 return lOptimizeNegate<uint8_t>(constExpr, type,
pos);
1149 for (
int i = 0; i < count; ++i)
1157 return lOptimizeBitNot<int8_t>(constExpr, type,
pos);
1160 return lOptimizeBitNot<uint8_t>(constExpr, type,
pos);
1163 return lOptimizeBitNot<int16_t>(constExpr, type,
pos);
1166 return lOptimizeBitNot<uint16_t>(constExpr, type,
pos);
1169 return lOptimizeBitNot<int32_t>(constExpr, type,
pos);
1172 return lOptimizeBitNot<uint32_t>(constExpr, type,
pos);
1175 return lOptimizeBitNot<int64_t>(constExpr, type,
pos);
1178 return lOptimizeBitNot<uint64_t>(constExpr, type,
pos);
1180 FATAL(
"unexpected type in UnaryExpr::Optimize() / BitNot case");
1187 for (
int i = 0; i < count; ++i)
1192 FATAL(
"unexpected op in UnaryExpr::Optimize()");
1204 Error(pos,
"Can't apply unary operator to SOA type \"%s\".", type->
GetString().c_str());
1211 "Can't assign to type \"%s\" on left-hand side of " 1220 const PointerType *pt = CastType<PointerType>(type);
1223 "Can only pre/post increment numeric and " 1224 "pointer types, not \"%s\".",
1233 if (CastType<UndefinedStructType>(pt->
GetBaseType())) {
1235 "Illegal to pre/post increment pointer to " 1236 "undefined struct type \"%s\".",
1245 if (CastType<ReferenceType>(type)) {
1263 "~ operator can only be used with integer types, " 1273 if (llvm::dyn_cast<ConstExpr>(
expr) != NULL)
1283 printf(
"[ %s ] (",
GetType()->GetString().c_str());
1349 FATAL(
"unimplemented case in lOpString()");
1359 llvm::Instruction::BinaryOps inst;
1362 inst = llvm::Instruction::Shl;
1366 inst = llvm::Instruction::LShr;
1368 inst = llvm::Instruction::AShr;
1371 inst = llvm::Instruction::And;
1374 inst = llvm::Instruction::Xor;
1377 inst = llvm::Instruction::Or;
1380 FATAL(
"logic error in lEmitBinaryBitOp()");
1390 const PointerType *ptrType = CastType<PointerType>(type0);
1398 if (CastType<PointerType>(type1) != NULL) {
1409 llvm::Value *soaScale =
LLVMIntAsType(soaWidth, majorDelta->getType());
1411 llvm::Value *majorScale =
1412 ctx->
BinaryOperator(llvm::Instruction::Mul, majorDelta, soaScale,
"major_soa_scaled");
1416 llvm::Value *minorDelta = ctx->
BinaryOperator(llvm::Instruction::Sub, m0, m1,
"minor_soa_delta");
1419 return ctx->
BinaryOperator(llvm::Instruction::Add, majorScale, minorDelta,
"soa_ptrdiff");
1429 llvm::Value *delta = ctx->
BinaryOperator(llvm::Instruction::Sub, value0, value1,
"ptr_diff");
1450 return ctx->
BinaryOperator(llvm::Instruction::SDiv, delta, size,
"element_diff");
1454 llvm::Value *negOffset = ctx->
BinaryOperator(llvm::Instruction::Sub, zero, value1,
"negate");
1460 FATAL(
"Logic error in lEmitBinaryArith() for pointer type case");
1470 const PointerType *ptrType = CastType<PointerType>(type0);
1472 if (ptrType != NULL)
1477 llvm::Instruction::BinaryOps inst;
1481 const char *opName = NULL;
1485 inst = isFloatOp ? llvm::Instruction::FAdd : llvm::Instruction::Add;
1489 inst = isFloatOp ? llvm::Instruction::FSub : llvm::Instruction::Sub;
1493 inst = isFloatOp ? llvm::Instruction::FMul : llvm::Instruction::Mul;
1499 "very inefficient.");
1500 inst = isFloatOp ? llvm::Instruction::FDiv
1501 : (isUnsignedOp ? llvm::Instruction::UDiv : llvm::Instruction::SDiv);
1507 "very inefficient.");
1508 inst = isFloatOp ? llvm::Instruction::FRem
1509 : (isUnsignedOp ? llvm::Instruction::URem : llvm::Instruction::SRem);
1512 FATAL(
"Invalid op type passed to lEmitBinaryArith()");
1528 llvm::CmpInst::Predicate pred;
1529 const char *opName = NULL;
1533 pred = isFloatOp ? llvm::CmpInst::FCMP_OLT : (isUnsignedOp ? llvm::CmpInst::ICMP_ULT : llvm::CmpInst::ICMP_SLT);
1537 pred = isFloatOp ? llvm::CmpInst::FCMP_OGT : (isUnsignedOp ? llvm::CmpInst::ICMP_UGT : llvm::CmpInst::ICMP_SGT);
1540 opName =
"lessequal";
1541 pred = isFloatOp ? llvm::CmpInst::FCMP_OLE : (isUnsignedOp ? llvm::CmpInst::ICMP_ULE : llvm::CmpInst::ICMP_SLE);
1544 opName =
"greaterequal";
1545 pred = isFloatOp ? llvm::CmpInst::FCMP_OGE : (isUnsignedOp ? llvm::CmpInst::ICMP_UGE : llvm::CmpInst::ICMP_SGE);
1549 pred = isFloatOp ? llvm::CmpInst::FCMP_OEQ : llvm::CmpInst::ICMP_EQ;
1552 opName =
"notequal";
1553 pred = isFloatOp ? llvm::CmpInst::FCMP_UNE : llvm::CmpInst::ICMP_NE;
1556 FATAL(
"error in lEmitBinaryCmp()");
1560 llvm::Value *cmp = ctx->
CmpInst(isFloatOp ? llvm::Instruction::FCmp : llvm::Instruction::ICmp, pred, e0Val, e1Val,
1577 if ((a0 == NULL) || (a1 == NULL)) {
1587 if (CastType<ReferenceType>(type0) != NULL) {
1591 if (CastType<ReferenceType>(type1) != NULL) {
1595 if ((type0 == NULL) || (type1 == NULL)) {
1598 if (CastType<StructType>(type0) != NULL || CastType<StructType>(type1) != NULL) {
1599 std::string opName = std::string(
"operator") +
lOpString(bop);
1600 std::vector<Symbol *> funs;
1602 if (funs.size() == 0) {
1603 Error(sp,
"operator %s(%s, %s) is not defined.", opName.c_str(), (type0->
GetString()).c_str(),
1609 args->exprs.push_back(arg0);
1610 args->exprs.push_back(arg1);
1634 if (type0 == NULL || type1 == NULL) {
1646 CastType<VectorType>(type0) != NULL || CastType<VectorType>(type1) != NULL);
1647 if (shortCircuit ==
false) {
1659 llvm::Value *value0 = arg0->
GetValue(ctx);
1660 llvm::Value *value1 = arg1->
GetValue(ctx);
1661 if (value0 == NULL || value1 == NULL) {
1667 return ctx->
BinaryOperator(llvm::Instruction::And, value0, value1,
"logical_and");
1670 return ctx->
BinaryOperator(llvm::Instruction::Or, value0, value1,
"logical_or");
1676 if (retType == NULL) {
1680 llvm::Value *retPtr = ctx->
AllocaInst(retType,
"logical_op_mem");
1683 llvm::BasicBlock *bbLogicalDone = ctx->
CreateBasicBlock(
"logical_op_done");
1686 llvm::Value *value0 = arg0->
GetValue(ctx);
1687 if (value0 == NULL) {
1694 llvm::Value *value0True = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ, value0,
LLVMTrue);
1699 ctx->
BranchInst(bbSkipEvalValue1, bbEvalValue1, value0True);
1705 ctx->
StoreInst(trueValue, retPtr, retType);
1712 ctx->
BranchInst(bbEvalValue1, bbSkipEvalValue1, value0True);
1718 ctx->
StoreInst(falseValue, retPtr, retType);
1732 llvm::Value *value1 = arg1->
GetValue(ctx);
1733 if (value1 == NULL) {
1744 return ctx->
LoadInst(retPtr, retType);
1753 if (type1->IsUniformType()) {
1763 llvm::Value *value0AndMask = ctx->
BinaryOperator(llvm::Instruction::And, value0, oldFullMask,
"op&mask");
1764 llvm::Value *equalsMask = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ, value0AndMask,
1765 oldFullMask,
"value0&mask==mask");
1767 llvm::Value *allMatch = ctx->
All(equalsMask);
1768 ctx->
BranchInst(bbSkipEvalValue1, bbEvalValue1, allMatch);
1784 llvm::Value *value1 = arg1->
GetValue(ctx);
1785 if (value1 == NULL) {
1794 llvm::Value *value1AndMask =
1796 llvm::Value *result = ctx->
BinaryOperator(llvm::Instruction::Or, value0AndMask, value1AndMask,
"or_result");
1797 ctx->
StoreInst(result, retPtr, retType);
1805 llvm::Value *notValue0 = ctx->
NotOperator(value0,
"not_value0");
1806 llvm::Value *notValue0AndMask =
1807 ctx->
BinaryOperator(llvm::Instruction::And, notValue0, oldFullMask,
"not_value0&mask");
1808 llvm::Value *equalsMask = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ, notValue0AndMask,
1809 oldFullMask,
"not_value0&mask==mask");
1811 llvm::Value *allMatch = ctx->
All(equalsMask);
1812 ctx->
BranchInst(bbSkipEvalValue1, bbEvalValue1, allMatch);
1827 llvm::Value *value1 = arg1->
GetValue(ctx);
1828 if (value1 == NULL) {
1836 llvm::Value *value0AndMask = ctx->
BinaryOperator(llvm::Instruction::And, value0, oldFullMask,
"op&mask");
1837 llvm::Value *value1AndMask =
1839 llvm::Value *result =
1840 ctx->
BinaryOperator(llvm::Instruction::And, value0AndMask, value1AndMask,
"or_result");
1841 ctx->
StoreInst(result, retPtr, retType);
1849 return ctx->
LoadInst(retPtr, retType);
1868 for (
int i = 1; i < count; ++i)
1869 if (amount[i] != amount[0])
1875 if (tce && tce->
expr) {
1897 if (value0 == NULL || value1 == NULL) {
1925 "varying shift amounts.");
1931 FATAL(
"logic error");
1941 if (type0 == NULL || type1 == NULL)
1949 AssertPos(pos, CastType<PointerType>(type1) == NULL);
1954 if (CastType<PointerType>(type0) != NULL) {
1958 else if (
op ==
Sub) {
1959 if (CastType<PointerType>(type1) != NULL) {
2006 FATAL(
"logic error in BinaryExpr::GetType()");
2011 #define FOLD_OP(O, E) \ 2013 for (int i = 0; i < count; ++i) \ 2014 result[i] = (v0[i] E v1[i]); \ 2017 #define FOLD_OP_REF(O, E, TRef) \ 2019 for (int i = 0; i < count; ++i) { \ 2020 result[i] = (v0[i] E v1[i]); \ 2021 TRef r = (TRef)v0[i] E(TRef) v1[i]; \ 2022 if (result[i] != r) \ 2023 Warning(pos, "Binary expression with type \"%s\" can't represent value.", \ 2024 carg0->GetType()->GetString().c_str()); \ 2031 template <
typename T,
typename TRef>
2034 int count = carg0->
Count();
2052 template <
typename T>
2055 int count = carg0->
Count();
2076 template <
typename T,
typename TRef>
2080 int count = carg0->
Count();
2087 for (
int i = 0; i < count; ++i) {
2089 Error(pos,
"Division by zero encountered in expression.");
2092 result[i] = (v0[i] / v1[i]);
2106 int count = carg0->
Count();
2127 template <
typename T>
2134 if ((ret = lConstFoldBinaryArithOp<T, T>(op, v0, v1, constArg0, pos)) != NULL)
2142 template <
typename T,
typename TRef>
2149 if ((ret = lConstFoldBinaryArithOp<T, TRef>(op, v0, v1, constArg0, pos)) != NULL)
2151 else if ((ret = lConstFoldBinaryIntOp<T, TRef>(op, v0, v1, constArg0, pos)) != NULL)
2184 for (
int i = 1; i < count; ++i)
2185 if (div[i] != div[0])
2195 return *divisor < 128;
2197 return *divisor < 256;
2211 if (
op ==
Div && constArg1 != NULL) {
2212 const Type *type1 = constArg1->GetType();
2216 int count = constArg1->GetValues(inv);
2217 for (
int i = 0; i < count; ++i)
2218 inv[i] = 1.f / inv[i];
2234 std::vector<Symbol *> rcpFuns;
2236 if (rcpFuns.size() > 0) {
2241 if (rcpCall == NULL)
2244 if (rcpCall == NULL)
2253 Warning(pos,
"rcp() not found from stdlib. Can't apply " 2254 "fast-math rcp optimization.");
2261 Debug(pos,
"Improving vector divide by constant %d", divisor);
2263 std::vector<Symbol *> idivFuns;
2265 if (idivFuns.size() == 0) {
2266 Warning(pos,
"Couldn't find __fast_idiv to optimize integer divide. " 2267 "Are you compiling with --nostdlib?");
2277 if (idivCall == NULL)
2287 if (constArg0 == NULL || constArg1 == NULL)
2293 return lConstFoldBinaryFPOp<float>(constArg0, constArg1,
op,
this,
pos);
2295 return lConstFoldBinaryFPOp<double>(constArg0, constArg1,
op,
this,
pos);
2297 return lConstFoldBinaryIntOp<int8_t, int64_t>(constArg0, constArg1,
op,
this,
pos);
2299 return lConstFoldBinaryIntOp<uint8_t, uint64_t>(constArg0, constArg1,
op,
this,
pos);
2301 return lConstFoldBinaryIntOp<int16_t, int64_t>(constArg0, constArg1,
op,
this,
pos);
2303 return lConstFoldBinaryIntOp<uint16_t, uint64_t>(constArg0, constArg1,
op,
this,
pos);
2305 return lConstFoldBinaryIntOp<int32_t, int64_t>(constArg0, constArg1,
op,
this,
pos);
2307 return lConstFoldBinaryIntOp<uint32_t, uint64_t>(constArg0, constArg1,
op,
this,
pos);
2309 return lConstFoldBinaryIntOp<int64_t, int64_t>(constArg0, constArg1,
op,
this,
pos);
2311 return lConstFoldBinaryIntOp<uint64_t, uint64_t>(constArg0, constArg1,
op,
this,
pos);
2315 constArg1->GetValues(v1);
2332 if (type0 == NULL || type1 == NULL)
2337 if (CastType<ReferenceType>(type0) != NULL) {
2342 if (CastType<ReferenceType>(type1) != NULL) {
2349 if (CastType<ArrayType>(type0) != NULL) {
2353 if (CastType<ArrayType>(type1) != NULL) {
2361 "Illegal to use binary operator %s with SOA type " 2366 if (type1->GetSOAWidth() > 0) {
2368 "Illegal to use binary operator %s with SOA type " 2374 const PointerType *pt0 = CastType<PointerType>(type0);
2375 const PointerType *pt1 = CastType<PointerType>(type1);
2376 if (pt0 != NULL && pt1 != NULL &&
op ==
Sub) {
2380 "Illegal to perform pointer arithmetic " 2387 "Illegal to perform pointer arithmetic " 2389 type1->GetString().c_str());
2392 if (CastType<UndefinedStructType>(pt0->
GetBaseType())) {
2394 "Illegal to perform pointer arithmetic " 2395 "on undefined struct type \"%s\".",
2399 if (CastType<UndefinedStructType>(pt1->GetBaseType())) {
2401 "Illegal to perform pointer arithmetic " 2402 "on undefined struct type \"%s\".",
2403 pt1->GetString().c_str());
2417 }
else if (((pt0 != NULL || pt1 != NULL) &&
op ==
Add) || (pt0 != NULL &&
op ==
Sub)) {
2419 if (pt0 != NULL && pt1 != NULL) {
2420 Error(pos,
"Illegal to add two pointer types \"%s\" and \"%s\".", pt0->
GetString().c_str(),
2421 pt1->GetString().c_str());
2423 }
else if (pt1 != NULL) {
2427 std::swap(type0, type1);
2428 std::swap(pt0, pt1);
2435 "Illegal to perform pointer arithmetic " 2440 if (CastType<UndefinedStructType>(pt0->
GetBaseType())) {
2442 "Illegal to perform pointer arithmetic " 2443 "on undefined struct type \"%s\".",
2451 if (type1->IsVaryingType()) {
2474 "First operand to binary operator \"%s\" must be " 2475 "an integer or bool.",
2479 if (!type1->IsIntType() && !type1->IsBoolType()) {
2481 "Second operand to binary operator \"%s\" must be " 2482 "an integer or bool.",
2488 bool isVarying = (type0->
IsVaryingType() || type1->IsVaryingType());
2500 if (promotedType == NULL)
2518 "First operand to binary operator \"%s\" is of " 2519 "invalid type \"%s\".",
2523 if (!type1->IsNumericType() || (
op ==
Mod && type1->IsFloatType())) {
2525 "First operand to binary operator \"%s\" is of " 2526 "invalid type \"%s\".",
2532 if (promotedType == NULL)
2547 const PointerType *pt0 = CastType<PointerType>(type0);
2548 const PointerType *pt1 = CastType<PointerType>(type1);
2555 pt1 = CastType<PointerType>(type1);
2559 pt0 = CastType<PointerType>(type0);
2562 if (pt0 == NULL && pt1 == NULL) {
2565 "First operand to operator \"%s\" is of " 2566 "non-comparable type \"%s\".",
2570 if (!type1->IsBoolType() && !type1->IsNumericType()) {
2572 "Second operand to operator \"%s\" is of " 2573 "non-comparable type \"%s\".",
2580 if (promotedType == NULL)
2597 const Type *destType0 = NULL, *destType1 = NULL;
2598 const VectorType *vtype0 = CastType<VectorType>(type0);
2599 const VectorType *vtype1 = CastType<VectorType>(type1);
2600 if (vtype0 && vtype1) {
2604 "Can't do logical operation \"%s\" between vector types of " 2605 "different sizes (%d vs. %d).",
2611 }
else if (vtype0 != NULL) {
2614 }
else if (vtype1 != NULL) {
2615 destType0 =
new VectorType(boolType0, vtype1->GetElementCount());
2616 destType1 =
new VectorType(boolType1, vtype1->GetElementCount());
2618 destType0 = boolType0;
2619 destType1 = boolType1;
2631 FATAL(
"logic error");
2638 if (CastType<PointerType>(t) != NULL) {
2647 if (llvm::dyn_cast<ConstExpr>(
arg0) != NULL && llvm::dyn_cast<ConstExpr>(
arg1) != NULL)
2657 printf(
"[ %s ] (",
GetType()->GetString().c_str());
2666 bool isStorageType) {
2675 return std::pair<llvm::Constant *, bool>(NULL,
false);
2684 if (!((op == BinaryExpr::Op::Add) || (op == BinaryExpr::Op::Sub)))
2685 return std::pair<llvm::Constant *, bool>(NULL,
false);
2686 if (op == BinaryExpr::Op::Sub) {
2689 if (CastType<PointerType>(arg1->
GetType()))
2690 return std::pair<llvm::Constant *, bool>(NULL,
false);
2701 bool isNotValidForMultiTargetGlobal =
false;
2703 std::pair<llvm::Constant *, bool> c1Pair;
2708 llvm::Constant *c1 = c1Pair.first;
2709 isNotValidForMultiTargetGlobal = isNotValidForMultiTargetGlobal || c1Pair.second;
2711 if ((cExpr == NULL) || (c1 == NULL))
2712 return std::pair<llvm::Constant *, bool>(NULL,
false);
2713 std::pair<llvm::Constant *, bool> c2Pair;
2718 llvm::Constant *c2 = c2Pair.first;
2719 isNotValidForMultiTargetGlobal = isNotValidForMultiTargetGlobal || c2Pair.second;
2720 if (op == BinaryExpr::Op::Sub)
2721 c2 = llvm::ConstantExpr::getNeg(c2);
2722 llvm::Constant *c = llvm::ConstantExpr::getGetElementPtr(
PTYPE(c1), c1, c2);
2723 return std::pair<llvm::Constant *, bool>(c, isNotValidForMultiTargetGlobal);
2725 std::pair<llvm::Constant *, bool> c1Pair;
2730 llvm::Constant *c1 = c1Pair.first;
2731 isNotValidForMultiTargetGlobal = isNotValidForMultiTargetGlobal || c1Pair.second;
2733 if ((cExpr == NULL) || (c1 == NULL))
2734 return std::pair<llvm::Constant *, bool>(NULL,
false);
2735 std::pair<llvm::Constant *, bool> c2Pair;
2740 llvm::Constant *c2 = c2Pair.first;
2741 isNotValidForMultiTargetGlobal = isNotValidForMultiTargetGlobal || c2Pair.second;
2742 llvm::Constant *c = llvm::ConstantExpr::getGetElementPtr(
PTYPE(c1), c1, c2);
2743 return std::pair<llvm::Constant *, bool>(c, isNotValidForMultiTargetGlobal);
2746 return std::pair<llvm::Constant *, bool>(NULL,
false);
2763 return "assignment operator";
2785 FATAL(
"Missing op in lOpstring");
2798 Error(pos,
"Can't assign to left-hand side of expression.");
2803 if (lvalueType == NULL || resultType == NULL)
2808 llvm::Value *rvalue = arg1->
GetValue(ctx);
2811 llvm::Value *oldLHS = ctx->
LoadInst(lv, mask, lvalueType);
2848 FATAL(
"logic error in lEmitOpAssign()");
2853 llvm::Value *newValue = NULL;
2870 FATAL(
"logic error in lEmitOpAssign");
2887 const Type *type = NULL;
2898 Error(
lvalue->
pos,
"Left hand side of assignment expression can't " 2904 if (ptrType == NULL || valueType == NULL) {
2910 if (value == NULL) {
2932 AssertPos(pos, !CastType<ArrayType>(type) && !CastType<StructType>(type));
2936 FATAL(
"logic error in AssignExpr::GetValue()");
2955 if (structType == initialType)
2957 "Illegal to assign to type \"%s\" due to element " 2958 "\"%s\" with type \"%s\".",
2962 "Illegal to assign to type \"%s\" in type \"%s\" " 2963 "due to element \"%s\" with type \"%s\".",
2969 const StructType *st = CastType<StructType>(t);
2980 bool lvalueIsReference = CastType<ReferenceType>(
lvalue->
GetType()) != NULL;
2981 if (lvalueIsReference)
2985 Error(pos,
"Unable to find overloaded function for function " 2986 "pointer assignment.");
2991 if (lhsType == NULL) {
2998 "Can't assign to type \"%s\" on left-hand side of " 3004 if (CastType<PointerType>(lhsType) != NULL) {
3008 "Illegal to perform pointer arithmetic on \"%s\" " 3024 }
else if (CastType<ArrayType>(lhsType) != NULL) {
3036 "Illegal to use %s operator with floating-point " 3042 const StructType *st = CastType<StructType>(lhsType);
3050 "Assignment operator \"%s\" is illegal with struct " 3072 printf(
"[%s] assign (",
GetType()->GetString().c_str());
3095 llvm::Value *resultPtr = ctx->
AllocaInst(type,
"selectexpr_tmp");
3096 Assert(resultPtr != NULL);
3102 return ctx->
LoadInst(resultPtr, type,
"selectexpr_final");
3106 llvm::Value *fullMask,
Expr *expr, llvm::Value *exprPtr) {
3112 llvm::Value *testAndFullMask = ctx->
BinaryOperator(llvm::Instruction::And, testVal, fullMask,
"test&mask");
3113 llvm::Value *anyOn = ctx->
Any(testAndFullMask);
3117 llvm::Value *testAndMask = ctx->
BinaryOperator(llvm::Instruction::And, testVal, oldMask,
"test&mask");
3119 llvm::Value *exprVal = expr->
GetValue(ctx);
3149 ctx->
BranchInst(testTrue, testFalse, testVal);
3166 llvm::PHINode *ret = ctx->
PhiNode(expr1Val->getType(), 2,
"select");
3167 ret->addIncoming(expr1Val, truePred);
3168 ret->addIncoming(expr2Val, falsePred);
3170 }
else if (CastType<VectorType>(testType) == NULL) {
3180 bool shortCircuit1 =
3182 bool shortCircuit2 =
3185 Debug(
expr1->
pos,
"%sshort circuiting evaluation for select expr", shortCircuit1 ?
"" :
"Not ");
3186 Debug(
expr2->
pos,
"%sshort circuiting evaluation for select expr", shortCircuit2 ?
"" :
"Not ");
3202 if (shortCircuit2) {
3224 const VectorType *vt = CastType<VectorType>(type);
3227 AssertPos(pos, CastType<VectorType>(testType) != NULL &&
3228 (CastType<VectorType>(testType)->GetElementCount() == vt->
GetElementCount()));
3231 llvm::Value *result = llvm::UndefValue::get(type->
LLVMType(
g->
ctx));
3236 llvm::Value *sel = NULL;
3255 if (!testType || !expr1Type || !expr2Type)
3260 int testVecSize = CastType<VectorType>(testType) != NULL ? CastType<VectorType>(testType)->GetElementCount() : 0;
3261 int expr1VecSize = CastType<VectorType>(expr1Type) != NULL ? CastType<VectorType>(expr1Type)->GetElementCount() : 0;
3262 AssertPos(pos, !(testVecSize != 0 && expr1VecSize != 0 && testVecSize != expr1VecSize));
3264 int vectorSize = std::max(testVecSize, expr1VecSize);
3266 becomesVarying, vectorSize);
3269 template <
typename T>
3276 for (
int i = 0; i < count; ++i)
3277 result[i] = bv[i] ? v1[i] : v2[i];
3278 return new ConstExpr(exprType, result, pos);
3286 if (constTest == NULL)
3300 bool mismatch =
false;
3301 for (
int i = 0; i < count; ++i)
3302 if (bv[i] != first) {
3306 if (mismatch ==
false)
3314 if (constExpr1 == NULL || constExpr2 == NULL)
3322 return lConstFoldSelect<int8_t>(bv, constExpr1, constExpr2, exprType,
pos);
3324 return lConstFoldSelect<uint8_t>(bv, constExpr1, constExpr2, exprType,
pos);
3326 return lConstFoldSelect<int16_t>(bv, constExpr1, constExpr2, exprType,
pos);
3328 return lConstFoldSelect<uint16_t>(bv, constExpr1, constExpr2, exprType,
pos);
3330 return lConstFoldSelect<int32_t>(bv, constExpr1, constExpr2, exprType,
pos);
3332 return lConstFoldSelect<uint32_t>(bv, constExpr1, constExpr2, exprType,
pos);
3334 return lConstFoldSelect<int64_t>(bv, constExpr1, constExpr2, exprType,
pos);
3336 return lConstFoldSelect<uint64_t>(bv, constExpr1, constExpr2, exprType,
pos);
3338 return lConstFoldSelect<float>(bv, constExpr1, constExpr2, exprType,
pos);
3340 return lConstFoldSelect<bool>(bv, constExpr1, constExpr2, exprType,
pos);
3342 return lConstFoldSelect<double>(bv, constExpr1, constExpr2, exprType,
pos);
3354 if (!type1 || !type2)
3357 if (
const ArrayType *at1 = CastType<ArrayType>(type1)) {
3363 if (
const ArrayType *at2 = CastType<ArrayType>(type2)) {
3371 if (testType == NULL)
3378 int testVecSize = CastType<VectorType>(testType) ? CastType<VectorType>(testType)->GetElementCount() : 0;
3384 if (CastType<ReferenceType>(promotedType) != NULL)
3387 if (promotedType == NULL)
3404 printf(
"[%s] (",
GetType()->GetString().c_str());
3437 const FunctionType *ftype = CastType<FunctionType>(type);
3438 if (ftype == NULL) {
3440 if (CastType<PointerType>(type) != NULL)
3441 ftype = CastType<FunctionType>(type->
GetBaseType());
3454 if (callee == NULL) {
3467 std::vector<Expr *> callargs =
args->
exprs;
3476 for (
unsigned int i = 0; i < callargs.size(); ++i) {
3477 Expr *argExpr = callargs[i];
3478 if (argExpr == NULL)
3484 if (argLValueType != NULL && CastType<PointerType>(argLValueType) != NULL && argLValueType->
IsVaryingType() &&
3485 CastType<ReferenceType>(paramType) != NULL) {
3487 "Illegal to pass a \"varying\" lvalue to a " 3488 "reference parameter of type \"%s\".",
3494 argExpr =
TypeConvertExpr(argExpr, paramType,
"function call argument");
3495 if (argExpr == NULL)
3497 callargs[i] = argExpr;
3510 callargs.push_back(d);
3514 std::vector<llvm::Value *> argVals;
3515 for (
unsigned int i = 0; i < callargs.size(); ++i) {
3516 Expr *argExpr = callargs[i];
3517 if (argExpr == NULL)
3521 llvm::Value *argValue = argExpr->
GetValue(ctx);
3522 if (argValue == NULL)
3527 argVals.push_back(argValue);
3530 llvm::Value *retVal = NULL;
3537 if (launchCount[0] != NULL)
3538 ctx->
LaunchInst(callee, argVals, launchCount);
3540 retVal = ctx->
CallInst(callee, ft, argVals, isVoidFunc ?
"" :
"calltmp");
3559 std::vector<bool> *argCouldBeNULL, std::vector<bool> *argIsConstant) {
3560 for (
unsigned int i = 0; i < args->
exprs.size(); ++i) {
3567 argTypes->push_back(t);
3568 argCouldBeNULL->push_back(
lIsAllIntZeros(expr) || llvm::dyn_cast<NullPointerExpr>(expr));
3569 argIsConstant->push_back(llvm::dyn_cast<ConstExpr>(expr) || llvm::dyn_cast<NullPointerExpr>(expr));
3575 std::vector<const Type *> argTypes;
3576 std::vector<bool> argCouldBeNULL, argIsConstant;
3608 std::vector<const Type *> argTypes;
3609 std::vector<bool> argCouldBeNULL, argIsConstant;
3628 ft = (pt == NULL) ? NULL : CastType<FunctionType>(pt->
GetBaseType());
3632 Error(pos,
"Valid function name must be used for function call.");
3638 Error(pos,
"\"launch\" expression needed to call function " 3639 "with \"task\" qualifier.");
3640 for (
int k = 0; k < 3; k++) {
3650 Error(pos,
"\"launch\" expression illegal with non-\"task\"-" 3651 "qualified function.");
3659 if (fptrType == NULL)
3664 if (CastType<PointerType>(fptrType) == NULL ||
3665 (funcType = CastType<FunctionType>(fptrType->
GetBaseType())) == NULL) {
3666 Error(
func->
pos,
"Must provide function name or function pointer for " 3667 "function call expression.");
3674 "Too many parameter values provided in " 3675 "function call (%d provided, %d expected).",
3685 "Too few parameter values provided in " 3686 "function call (%d provided, %d expected).",
3693 for (
int i = 0; i < (int)argTypes.size(); ++i) {
3694 if (i < funcType->GetNumParameters()) {
3698 !(argCouldBeNULL[i] ==
true && CastType<PointerType>(paramType) != NULL)) {
3700 "Can't convert argument of " 3701 "type \"%s\" to type \"%s\" for function call " 3703 argTypes[i]->GetString().c_str(), paramType->
GetString().c_str());
3717 "Illegal to call a varying function pointer that " 3718 "points to a function with a uniform return type \"%s\".",
3738 const PointerType *pt = CastType<PointerType>(type);
3742 const FunctionType *ftype = CastType<FunctionType>(type);
3756 printf(
"[%s] funcall %s ",
GetType()->GetString().c_str(),
isLaunch ?
"launch" :
"");
3768 FATAL(
"ExprList::GetValue() should never be called");
3773 FATAL(
"ExprList::GetType() should never be called");
3782 bool isStorageType) {
3783 std::vector<Expr *> exprs = eList->
exprs;
3785 bool isVaryingInit =
false;
3786 bool isNotValidForMultiTargetGlobal =
false;
3787 if (exprs.size() == 1 && (CastType<AtomicType>(type) != NULL || CastType<EnumType>(type) != NULL ||
3788 CastType<PointerType>(type) != NULL)) {
3790 return exprs[0]->GetStorageConstant(type);
3792 return exprs[0]->GetConstant(type);
3795 const CollectionType *collectionType = CastType<CollectionType>(type);
3796 if (collectionType == NULL) {
3798 isVaryingInit =
true;
3800 return std::pair<llvm::Constant *, bool>(NULL,
false);
3804 if (CastType<StructType>(type) != NULL)
3806 else if (CastType<ArrayType>(type) != NULL)
3808 else if (CastType<VectorType>(type) != NULL)
3810 else if (isVaryingInit ==
true)
3813 FATAL(
"Unexpected CollectionType in lGetExprListConstant");
3816 if ((
int)exprs.size() > elementCount) {
3817 const Type *errType = (isVaryingInit ==
true) ? type : collectionType;
3819 "Initializer list for %s \"%s\" must have no more than %d " 3820 "elements (has %d).",
3821 name.c_str(), errType->
GetString().c_str(), elementCount, (int)exprs.size());
3822 return std::pair<llvm::Constant *, bool>(NULL,
false);
3823 }
else if ((isVaryingInit ==
true) && ((int)exprs.size() < elementCount)) {
3825 "Initializer list for %s \"%s\" must have %d " 3826 "elements (has %d).",
3827 name.c_str(), type->
GetString().c_str(), elementCount, (int)exprs.size());
3828 return std::pair<llvm::Constant *, bool>(NULL,
false);
3831 std::vector<llvm::Constant *> cv;
3832 for (
unsigned int i = 0; i < exprs.size(); ++i) {
3833 if (exprs[i] == NULL)
3834 return std::pair<llvm::Constant *, bool>(NULL,
false);
3835 const Type *elementType =
3838 Expr *expr = exprs[i];
3840 if (llvm::dyn_cast<ExprList>(expr) == NULL) {
3847 return std::pair<llvm::Constant *, bool>(NULL,
false);
3852 std::pair<llvm::Constant *, bool> cPair;
3857 llvm::Constant *c = cPair.first;
3861 return std::pair<llvm::Constant *, bool>(NULL,
false);
3862 isNotValidForMultiTargetGlobal = isNotValidForMultiTargetGlobal || cPair.second;
3867 if (isVaryingInit ==
false) {
3868 for (
int i = (
int)exprs.size(); i < collectionType->
GetElementCount(); ++i) {
3870 if (elementType == NULL) {
3872 return std::pair<llvm::Constant *, bool>(NULL,
false);
3875 if (llvmType == NULL) {
3877 return std::pair<llvm::Constant *, bool>(NULL,
false);
3880 llvm::Constant *c = llvm::Constant::getNullValue(llvmType);
3885 if (CastType<StructType>(type) != NULL) {
3886 llvm::StructType *llvmStructType = llvm::dyn_cast<llvm::StructType>(collectionType->
LLVMType(
g->
ctx));
3888 return std::pair<llvm::Constant *, bool>(llvm::ConstantStruct::get(llvmStructType, cv),
3889 isNotValidForMultiTargetGlobal);
3892 llvm::ArrayType *lat = llvm::dyn_cast<llvm::ArrayType>(lt);
3894 return std::pair<llvm::Constant *, bool>(llvm::ConstantArray::get(lat, cv), isNotValidForMultiTargetGlobal);
3897 llvm::VectorType *lvt = llvm::dyn_cast<llvm::VectorType>(lt);
3901 while ((cv.size() % vectorWidth) != 0) {
3902 cv.push_back(llvm::UndefValue::get(lvt->getElementType()));
3905 return std::pair<llvm::Constant *, bool>(llvm::ConstantVector::get(cv), isNotValidForMultiTargetGlobal);
3910 llvm::VectorType *lvt = llvm::dyn_cast<llvm::VectorType>(lt);
3916 const VectorType *vt = CastType<VectorType>(type);
3919 while ((cv.size() % vectorWidth) != 0) {
3920 cv.push_back(llvm::UndefValue::get(lvt->getElementType()));
3923 return std::pair<llvm::Constant *, bool>(llvm::ConstantVector::get(cv), isNotValidForMultiTargetGlobal);
3926 return std::pair<llvm::Constant *, bool>(NULL,
false);
3939 printf(
"expr list (");
3940 for (
unsigned int i = 0; i < exprs.size(); ++i) {
3941 if (exprs[i] != NULL)
3943 printf(
"%s", (i == exprs.size() - 1) ?
")" :
", ");
3978 if (CastType<ReferenceType>(ptrRefType) != NULL)
3982 const PointerType *ptrType = CastType<PointerType>(ptrRefType);
4012 if (CastType<VectorType>(type) != NULL || CastType<ReferenceType>(type) != NULL)
4037 if (eltType == NULL) {
4042 if (CastType<StructType>(eltType) != NULL) {
4051 "Gather operation is impossible due to the presence of " 4052 "struct member \"%s\" with uniform type \"%s\" in the " 4053 "varying struct type \"%s\".",
4063 const Type *indexType, *returnType;
4065 ((returnType =
GetType()) == NULL)) {
4079 llvm::Value *mask = NULL;
4087 if (baseExprType == NULL || val == NULL) {
4092 llvm::Value *tmpPtr = ctx->
AllocaInst(baseExprType,
"array_tmp");
4093 ctx->
StoreInst(val, tmpPtr, baseExprType);
4096 const SequentialType *st = CastType<SequentialType>(baseExprType);
4110 if (llvm::dyn_cast<FunctionCallExpr>(
baseExpr) == NULL && llvm::dyn_cast<BinaryExpr>(
baseExpr) == NULL) {
4118 return ctx->
LoadInst(ptr, mask, lvType);
4125 const Type *baseExprType, *indexType;
4130 const Type *elementType = NULL;
4131 const PointerType *pointerType = CastType<PointerType>(baseExprType);
4132 if (pointerType != NULL)
4171 llvm::Type *llvmSlicePtrType = slicePtrType->
LLVMType(
g->
ctx);
4172 llvm::StructType *sliceStructType = llvm::dyn_cast<llvm::StructType>(llvmSlicePtrType);
4173 Assert(sliceStructType != NULL && sliceStructType->getElementType(0) == ptr->getType());
4177 llvm::Value *result = llvm::Constant::getNullValue(sliceStructType);
4187 const SequentialType *seqType = CastType<SequentialType>(baseExprType);
4188 if (seqType == NULL)
4201 nElements *= soaWidth;
4209 for (
int i = 0; i < count; ++i) {
4210 if (indices[i] < 0 || indices[i] >= nElements)
4212 "Array index \"%d\" may be out of bounds for %d " 4214 indices[i], nElements);
4223 const PointerType *ptrType = CastType<PointerType>(*type);
4226 if (convertToSlice ==
false)
4234 const Type *baseExprType;
4242 if (indexValue == NULL) {
4248 if (CastType<PointerType>(baseExprType) != NULL) {
4251 if (basePtrValue == NULL) {
4267 llvm::Value *basePtr = NULL;
4269 if (CastType<ArrayType>(baseExprType) || CastType<VectorType>(baseExprType)) {
4276 AssertPos(pos, CastType<ArrayType>(baseExprType) || CastType<VectorType>(baseExprType));
4301 const Type *baseExprType, *baseExprLValueType, *indexType;
4307 if (CastType<ReferenceType>(baseExprLValueType) != NULL) {
4311 AssertPos(pos, CastType<PointerType>(baseExprLValueType) != NULL);
4314 const Type *elementType;
4334 if (CastType<PointerType>(baseExprType) != NULL)
4362 const Type *indexType;
4369 if (baseExprType == NULL) {
4375 if (
const PointerType *pt = CastType<PointerType>(baseExprType)) {
4376 if (pt->GetBaseType()->IsVoidType()) {
4377 Error(pos,
"Illegal to dereference void pointer type \"%s\".", baseExprType->
GetString().c_str());
4382 "Trying to index into non-array, vector, or pointer " 4434 (CastType<PointerType>(baseExprType) != NULL && baseExprType->
IsVaryingType()))
4446 printf(
"[%s] index ",
GetType()->GetString().c_str());
4493 int getElementNumber()
const;
4494 const Type *getElementType()
const;
4518 if (elementType == NULL) {
4525 bool isSlice = (CastType<PointerType>(
lvalueType) && CastType<PointerType>(lvalueType)->IsSlice());
4558 if (exprLValueType == NULL) {
4573 if (CastType<PointerType>(exprLValueType) && CastType<PointerType>(exprLValueType)->IsSlice())
4582 if (structType == NULL)
4586 if (elementNumber == -1)
4590 return elementNumber;
4595 if (structType == NULL)
4608 const Type *structType;
4618 const StructType *ret = CastType<StructType>(structType);
4651 const PointerType *pt = CastType<PointerType>(exprType);
4655 AssertPos(pos, CastType<ReferenceType>(exprType) != NULL);
4674 if (lvType != NULL) {
4675 bool isSlice = (CastType<PointerType>(lvType) && CastType<PointerType>(lvType)->IsSlice());
4708 if (exprLValueType == NULL)
4712 if (CastType<ReferenceType>(exprLValueType) != NULL)
4715 vt = CastType<VectorType>(exprLValueType->
GetBaseType());
4720 const Type *elementType = vt->GetElementType();
4721 if (CastType<ReferenceType>(exprLValueType) != NULL)
4727 if (CastType<PointerType>(exprLValueType) && CastType<PointerType>(exprLValueType)->IsSlice())
4740 std::vector<int> indices;
4742 for (
size_t i = 0; i <
identifier.size(); ++i) {
4747 indices.push_back(idx);
4750 llvm::Value *basePtr = NULL;
4751 const Type *basePtrType = NULL;
4760 if (basePtr == NULL || basePtrType == NULL) {
4765 if (basePtr == NULL || basePtrType == NULL) {
4779 const Type *elementPtrType = NULL;
4780 if (CastType<ReferenceType>(basePtrType) != NULL)
4787 for (
size_t i = 0; i <
identifier.size(); ++i) {
4789 llvm::Value *elementPtr =
4791 llvm::Value *elementValue = ctx->
LoadInst(elementPtr, elementMask, elementPtrType);
4793 const char *resultName =
LLVMGetName(resultPtr, idStr);
4795 ctx->
StoreInst(elementValue, ptmp, elementPtrType);
4804 if (elementNumber == -1)
4805 Error(pos,
"Vector element identifier \"%s\" unknown.",
identifier.c_str());
4806 return elementNumber;
4818 const Type *exprType;
4819 if (e == NULL || (exprType = e->
GetType()) == NULL)
4822 const ReferenceType *referenceType = CastType<ReferenceType>(exprType);
4823 if (referenceType != NULL) {
4826 Assert(exprType != NULL);
4829 const PointerType *pointerType = CastType<PointerType>(exprType);
4830 if (pointerType != NULL)
4833 if (derefLValue ==
true && pointerType == NULL) {
4835 if (CastType<StructType>(targetType) != NULL)
4837 "Member operator \"->\" can't be applied to non-pointer " 4838 "type \"%s\". Did you mean to use \".\"?",
4842 "Member operator \"->\" can't be applied to non-struct " 4843 "pointer type \"%s\".",
4847 if (derefLValue ==
false && pointerType != NULL && CastType<StructType>(pointerType->
GetBaseType()) != NULL) {
4849 "Member operator \".\" can't be applied to pointer " 4850 "type \"%s\". Did you mean to use \"->\"?",
4854 if (CastType<StructType>(exprType) != NULL) {
4855 const StructType *st = CastType<StructType>(exprType);
4860 "Member operator \"%s\" can't be applied to declared " 4861 "struct \"%s\" containing an undefined struct type.",
4862 derefLValue ?
"->" :
".", exprType->
GetString().c_str());
4865 }
else if (CastType<VectorType>(exprType) != NULL)
4867 else if (CastType<UndefinedStructType>(exprType)) {
4869 "Member operator \"%s\" can't be applied to declared " 4870 "but not defined struct type \"%s\".",
4871 derefLValue ?
"->" :
".", exprType->
GetString().c_str());
4875 "Member operator \"%s\" can't be used with expression of " 4877 derefLValue ?
"->" :
".", exprType->
GetString().c_str());
4897 llvm::Value *mask = NULL;
4898 if (lvalue == NULL) {
4912 llvm::Value *ptr = ctx->
AllocaInst(exprType,
"struct_tmp");
4916 if (elementNumber == -1)
4929 std::string suffix = std::string(
"_") +
identifier;
4940 const Type *exprType;
4950 if (elementNumber == -1)
4955 llvm::Value *ptr = ctx->
AddElementOffset(basePtr, elementNumber, exprLValueType, basePtr->getName().str().c_str());
4982 printf(
"[%s] member (",
GetType()->GetString().c_str());
4997 std::vector<std::string> elementNames;
5001 if (!alternates.size())
5004 std::string ret =
" Did you mean ";
5005 for (
unsigned int i = 0; i < alternates.size(); ++i) {
5006 ret += std::string(
"\"") + alternates[i] + std::string(
"\"");
5007 if (i < alternates.size() - 1)
5029 for (
int j = 0; j <
Count(); ++j)
5045 for (
int j = 0; j <
Count(); ++j)
5061 for (
int j = 0; j <
Count(); ++j)
5077 for (
int j = 0; j <
Count(); ++j)
5093 for (
int j = 0; j <
Count(); ++j)
5110 (CastType<EnumType>(
type) != NULL));
5111 for (
int j = 0; j <
Count(); ++j)
5127 for (
int j = 0; j <
Count(); ++j)
5143 for (
int j = 0; j <
Count(); ++j)
5159 for (
int j = 0; j <
Count(); ++j)
5175 for (
int j = 0; j <
Count(); ++j)
5191 for (
int j = 0; j <
Count(); ++j)
5200 switch (basicType) {
5202 for (
int i = 0; i <
Count(); ++i)
5206 for (
int i = 0; i <
Count(); ++i)
5210 for (
int i = 0; i <
Count(); ++i)
5214 for (
int i = 0; i <
Count(); ++i)
5218 for (
int i = 0; i <
Count(); ++i)
5222 for (
int i = 0; i <
Count(); ++i)
5226 for (
int i = 0; i <
Count(); ++i)
5230 for (
int i = 0; i <
Count(); ++i)
5234 for (
int i = 0; i <
Count(); ++i)
5240 FATAL(
"fixme; we need another constructor so that we're not trying to pass " 5241 "double values to init an int64 type...");
5243 FATAL(
"unimplemented const type");
5252 switch (basicType) {
5287 FATAL(
"unimplemented const type");
5309 switch (basicType) {
5336 FATAL(
"unimplemented const type");
5346 template <
typename From,
typename To>
static inline void lConvertElement(From from, To *to) { *to = (To)from; }
5351 template <
typename To>
static inline void lConvertElement(
bool from, To *to) { *to = from ? (To)1 : (To)0; }
5355 template <
typename From>
static inline void lConvertElement(From from,
bool *to) { *to = (from != 0); }
5362 template <
typename From,
typename To>
static void lConvert(
const From *from, To *to,
int count,
bool forceVarying) {
5363 for (
int i = 0; i < count; ++i)
5366 if (forceVarying && count == 1)
5407 FATAL(
"unimplemented const type");
5448 FATAL(
"unimplemented const type");
5489 FATAL(
"unimplemented const type");
5530 FATAL(
"unimplemented const type");
5571 FATAL(
"unimplemented const type");
5612 FATAL(
"unimplemented const type");
5653 FATAL(
"unimplemented const type");
5694 FATAL(
"unimplemented const type");
5735 FATAL(
"unimplemented const type");
5776 FATAL(
"unimplemented const type");
5817 FATAL(
"unimplemented const type");
5825 bool isStorageType) {
5829 bool isNotValidForMultiTargetGlobal =
false;
5840 isNotValidForMultiTargetGlobal);
5842 return std::pair<llvm::Constant *, bool>(bv[0] ?
LLVMTrue :
LLVMFalse, isNotValidForMultiTargetGlobal);
5847 return std::pair<llvm::Constant *, bool>(
LLVMBoolVector(bv), isNotValidForMultiTargetGlobal);
5853 return std::pair<llvm::Constant *, bool>(
LLVMInt8(iv[0]), isNotValidForMultiTargetGlobal);
5855 return std::pair<llvm::Constant *, bool>(
LLVMInt8Vector(iv), isNotValidForMultiTargetGlobal);
5860 return std::pair<llvm::Constant *, bool>(
LLVMUInt8(uiv[0]), isNotValidForMultiTargetGlobal);
5862 return std::pair<llvm::Constant *, bool>(
LLVMUInt8Vector(uiv), isNotValidForMultiTargetGlobal);
5867 return std::pair<llvm::Constant *, bool>(
LLVMInt16(iv[0]), isNotValidForMultiTargetGlobal);
5869 return std::pair<llvm::Constant *, bool>(
LLVMInt16Vector(iv), isNotValidForMultiTargetGlobal);
5874 return std::pair<llvm::Constant *, bool>(
LLVMUInt16(uiv[0]), isNotValidForMultiTargetGlobal);
5876 return std::pair<llvm::Constant *, bool>(
LLVMUInt16Vector(uiv), isNotValidForMultiTargetGlobal);
5881 return std::pair<llvm::Constant *, bool>(
LLVMInt32(iv[0]), isNotValidForMultiTargetGlobal);
5883 return std::pair<llvm::Constant *, bool>(
LLVMInt32Vector(iv), isNotValidForMultiTargetGlobal);
5885 CastType<EnumType>(constType) != NULL) {
5889 return std::pair<llvm::Constant *, bool>(
LLVMUInt32(uiv[0]), isNotValidForMultiTargetGlobal);
5891 return std::pair<llvm::Constant *, bool>(
LLVMUInt32Vector(uiv), isNotValidForMultiTargetGlobal);
5896 return std::pair<llvm::Constant *, bool>(
LLVMFloat(fv[0]), isNotValidForMultiTargetGlobal);
5898 return std::pair<llvm::Constant *, bool>(
LLVMFloatVector(fv), isNotValidForMultiTargetGlobal);
5903 return std::pair<llvm::Constant *, bool>(
LLVMInt64(iv[0]), isNotValidForMultiTargetGlobal);
5905 return std::pair<llvm::Constant *, bool>(
LLVMInt64Vector(iv), isNotValidForMultiTargetGlobal);
5910 return std::pair<llvm::Constant *, bool>(
LLVMUInt64(uiv[0]), isNotValidForMultiTargetGlobal);
5912 return std::pair<llvm::Constant *, bool>(
LLVMUInt64Vector(uiv), isNotValidForMultiTargetGlobal);
5917 return std::pair<llvm::Constant *, bool>(
LLVMDouble(dv[0]), isNotValidForMultiTargetGlobal);
5919 return std::pair<llvm::Constant *, bool>(
LLVMDoubleVector(dv), isNotValidForMultiTargetGlobal);
5920 }
else if (CastType<PointerType>(constType) != NULL) {
5925 if (llvmType == NULL) {
5927 return std::pair<llvm::Constant *, bool>(NULL,
false);
5932 for (
int i = 0; i < cExpr->
Count(); ++i)
5936 return std::pair<llvm::Constant *, bool>(NULL,
false);
5938 return std::pair<llvm::Constant *, bool>(llvm::Constant::getNullValue(llvmType),
5939 isNotValidForMultiTargetGlobal);
5941 Debug(pos,
"Unable to handle type \"%s\" in ConstExpr::GetConstant().", constType->
GetString().c_str());
5942 return std::pair<llvm::Constant *, bool>(NULL, isNotValidForMultiTargetGlobal);
5960 printf(
"[%s] (",
GetType()->GetString().c_str());
5961 for (
int i = 0; i <
Count(); ++i) {
5964 printf(
"%s",
boolVal[i] ?
"true" :
"false");
5967 printf(
"%d", (
int)
int8Val[i]);
5997 FATAL(
"unimplemented const type");
5999 if (i !=
Count() - 1)
6020 llvm::Value *cast = NULL;
6022 std::string opName = exprVal->getName().str();
6025 opName +=
"_to_bool";
6028 opName +=
"_to_int8";
6031 opName +=
"_to_uint8";
6034 opName +=
"_to_int16";
6037 opName +=
"_to_uint16";
6040 opName +=
"_to_int32";
6043 opName +=
"_to_uint32";
6046 opName +=
"_to_int64";
6049 opName +=
"_to_uint64";
6052 opName +=
"_to_float";
6055 opName +=
"_to_double";
6058 FATAL(
"Unimplemented");
6060 const char *cOpName = opName.c_str();
6072 cast = ctx->
CastInst(llvm::Instruction::UIToFP,
6073 exprVal, targetType, cOpName);
6079 cast = ctx->
CastInst(llvm::Instruction::SIToFP,
6080 exprVal, targetType, cOpName);
6088 "Use \"int\" if possible");
6089 cast = ctx->
CastInst(llvm::Instruction::UIToFP,
6090 exprVal, targetType, cOpName);
6097 cast = ctx->
FPCastInst(exprVal, targetType, cOpName);
6100 FATAL(
"unimplemented");
6111 cast = ctx->
CastInst(llvm::Instruction::UIToFP,
6112 exprVal, targetType, cOpName);
6118 cast = ctx->
CastInst(llvm::Instruction::SIToFP,
6119 exprVal, targetType, cOpName);
6125 cast = ctx->
CastInst(llvm::Instruction::UIToFP,
6126 exprVal, targetType, cOpName);
6129 cast = ctx->
FPCastInst(exprVal, targetType, cOpName);
6135 FATAL(
"unimplemented");
6145 cast = ctx->
ZExtInst(exprVal, targetType, cOpName);
6157 cast = ctx->
TruncInst(exprVal, targetType, cOpName);
6161 cast = ctx->
CastInst(llvm::Instruction::FPToSI,
6162 exprVal, targetType, cOpName);
6165 FATAL(
"unimplemented");
6175 cast = ctx->
ZExtInst(exprVal, targetType, cOpName);
6187 cast = ctx->
TruncInst(exprVal, targetType, cOpName);
6192 "Use \"int\" if possible");
6193 cast = ctx->
CastInst(llvm::Instruction::FPToUI,
6194 exprVal, targetType, cOpName);
6199 "Use \"int\" if possible");
6200 cast = ctx->
CastInst(llvm::Instruction::FPToUI,
6201 exprVal, targetType, cOpName);
6204 FATAL(
"unimplemented");
6214 cast = ctx->
ZExtInst(exprVal, targetType, cOpName);
6217 cast = ctx->
SExtInst(exprVal, targetType, cOpName);
6220 cast = ctx->
ZExtInst(exprVal, targetType, cOpName);
6230 cast = ctx->
TruncInst(exprVal, targetType, cOpName);
6234 cast = ctx->
CastInst(llvm::Instruction::FPToSI,
6235 exprVal, targetType, cOpName);
6238 FATAL(
"unimplemented");
6248 cast = ctx->
ZExtInst(exprVal, targetType, cOpName);
6251 cast = ctx->
SExtInst(exprVal, targetType, cOpName);
6254 cast = ctx->
ZExtInst(exprVal, targetType, cOpName);
6263 "Use \"int\" if possible");
6264 cast = ctx->
CastInst(llvm::Instruction::FPToUI,
6265 exprVal, targetType, cOpName);
6271 cast = ctx->
TruncInst(exprVal, targetType, cOpName);
6276 "Use \"int\" if possible");
6277 cast = ctx->
CastInst(llvm::Instruction::FPToUI,
6278 exprVal, targetType, cOpName);
6281 FATAL(
"unimplemented");
6291 cast = ctx->
ZExtInst(exprVal, targetType, cOpName);
6295 cast = ctx->
SExtInst(exprVal, targetType, cOpName);
6299 cast = ctx->
ZExtInst(exprVal, targetType, cOpName);
6307 cast = ctx->
TruncInst(exprVal, targetType, cOpName);
6311 cast = ctx->
CastInst(llvm::Instruction::FPToSI,
6312 exprVal, targetType, cOpName);
6315 FATAL(
"unimplemented");
6325 cast = ctx->
ZExtInst(exprVal, targetType, cOpName);
6329 cast = ctx->
SExtInst(exprVal, targetType, cOpName);
6333 cast = ctx->
ZExtInst(exprVal, targetType, cOpName);
6342 "Use \"int\" if possible");
6343 cast = ctx->
CastInst(llvm::Instruction::FPToUI,
6344 exprVal, targetType, cOpName);
6348 cast = ctx->
TruncInst(exprVal, targetType, cOpName);
6353 "Use \"int\" if possible");
6354 cast = ctx->
CastInst(llvm::Instruction::FPToUI,
6355 exprVal, targetType, cOpName);
6358 FATAL(
"unimplemented");
6368 cast = ctx->
ZExtInst(exprVal, targetType, cOpName);
6373 cast = ctx->
SExtInst(exprVal, targetType, cOpName);
6378 cast = ctx->
ZExtInst(exprVal, targetType, cOpName);
6386 cast = ctx->
CastInst(llvm::Instruction::FPToSI,
6387 exprVal, targetType, cOpName);
6390 FATAL(
"unimplemented");
6400 cast = ctx->
ZExtInst(exprVal, targetType, cOpName);
6405 cast = ctx->
SExtInst(exprVal, targetType, cOpName);
6410 cast = ctx->
ZExtInst(exprVal, targetType, cOpName);
6415 "Use \"int64\" if possible");
6416 cast = ctx->
CastInst(llvm::Instruction::FPToUI,
6417 exprVal, targetType, cOpName);
6426 "Use \"int64\" if possible");
6427 cast = ctx->
CastInst(llvm::Instruction::FPToUI,
6428 exprVal, targetType, cOpName);
6431 FATAL(
"unimplemented");
6448 cast = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE, exprVal, zero, cOpName);
6455 cast = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE, exprVal, zero, cOpName);
6462 cast = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE, exprVal, zero, cOpName);
6468 cast = ctx->
CmpInst(llvm::Instruction::FCmp, llvm::CmpInst::FCMP_ONE, exprVal, zero, cOpName);
6475 cast = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE, exprVal, zero, cOpName);
6481 cast = ctx->
CmpInst(llvm::Instruction::FCmp, llvm::CmpInst::FCMP_ONE, exprVal, zero, cOpName);
6485 FATAL(
"unimplemented");
6502 FATAL(
"unimplemented");
6527 if (collectionType != NULL) {
6529 llvm::Value *retValue = llvm::UndefValue::get(llvmType);
6534 llvm::Value *v = ctx->
ExtractInst(value, i,
"get_element");
6541 if ((elemType->
IsBoolType()) && (CastType<AtomicType>(elemType) != NULL)) {
6547 if ((elemType->
IsBoolType()) && (CastType<AtomicType>(elemType) != NULL)) {
6551 retValue = ctx->
InsertInst(retValue, v, i,
"set_element");
6558 if (CastType<AtomicType>(type)) {
6563 Assert(CastType<PointerType>(type) != NULL);
6573 if (toType == NULL || fromType == NULL) {
6585 const PointerType *fromPointerType = CastType<PointerType>(fromType);
6586 const PointerType *toPointerType = CastType<PointerType>(toType);
6587 const ArrayType *toArrayType = CastType<ArrayType>(toType);
6588 const ArrayType *fromArrayType = CastType<ArrayType>(fromType);
6589 if (fromPointerType != NULL) {
6590 if (toArrayType != NULL) {
6592 }
else if (toPointerType != NULL) {
6597 if (fromPointerType->
IsSlice() ==
false && toPointerType->IsSlice() ==
true) {
6616 else if (fromType->IsVaryingType() && toType->
IsVaryingType()) {
6623 if (fromPointerType->
IsSlice()) {
6626 AssertPos(pos, toPointerType->IsSlice());
6641 AssertPos(pos, CastType<AtomicType>(toType) != NULL);
6644 llvm::Type *lfu = fromType->GetAsUniformType()->LLVMType(
g->
ctx);
6645 llvm::PointerType *llvmFromUnifType = llvm::dyn_cast<llvm::PointerType>(lfu);
6647 llvm::Value *nullPtrValue = llvm::ConstantPointerNull::get(llvmFromUnifType);
6648 if (fromType->IsVaryingType())
6653 ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE, exprVal, nullPtrValue,
"ptr_ne_NULL");
6656 if (fromType->IsUniformType())
6672 if (llvmToType == NULL)
6674 return ctx->
PtrToIntInst(value, llvmToType,
"ptr_typecast");
6684 if (fromArrayType != NULL && toPointerType != NULL) {
6691 arrayAsPtr =
new TypeCastExpr(toPointerType, arrayAsPtr, pos);
6704 if (toArrayType != NULL && fromArrayType != NULL) {
6707 if (toArrayType->GetElementCount() != 0 && (toArrayType->GetElementCount() != fromArrayType->GetElementCount()))
6708 Warning(pos,
"Type-converting array of length %d to length %d", fromArrayType->GetElementCount(),
6709 toArrayType->GetElementCount());
6716 const ReferenceType *toReference = CastType<ReferenceType>(toType);
6717 const ReferenceType *fromReference = CastType<ReferenceType>(fromType);
6718 if (toReference && fromReference) {
6722 const ArrayType *toArray = CastType<ArrayType>(toTarget);
6723 const ArrayType *fromArray = CastType<ArrayType>(fromTarget);
6724 if (toArray && fromArray) {
6728 Warning(pos,
"Type-converting array of length %d to length %d", fromArray->GetElementCount(),
6741 const StructType *toStruct = CastType<StructType>(toType);
6742 const StructType *fromStruct = CastType<StructType>(fromType);
6743 if (toStruct && fromStruct) {
6755 const VectorType *toVector = CastType<VectorType>(toType);
6756 const VectorType *fromVector = CastType<VectorType>(fromType);
6757 if (toVector && fromVector) {
6791 const EnumType *fromEnum = CastType<EnumType>(fromType);
6792 const EnumType *toEnum = CastType<EnumType>(toType);
6800 const AtomicType *fromAtomic = CastType<AtomicType>(fromType);
6810 llvm::Value *cast = NULL;
6812 if (llvm::isa<llvm::VectorType>(toTypeLLVM)) {
6815 }
else if (llvm::isa<llvm::ArrayType>(toTypeLLVM)) {
6828 FATAL(
"TypeCastExpr::GetValue: problem with cast");
6832 }
else if (toPointerType != NULL) {
6838 if (llvmToType == NULL)
6841 return ctx->
IntToPtrInst(exprVal, llvmToType,
"int_to_ptr");
6843 const AtomicType *toAtomic = CastType<AtomicType>(toType);
6865 if (toType == NULL || fromType == NULL)
6868 if (fromType->IsUniformType()) {
6880 if (CastType<PointerType>(
GetType()) != NULL) {
6900 if (toType == NULL || fromType == NULL)
6916 if (fromType->IsVoidType() || (fromType->IsVaryingType() && toType->
IsUniformType())) {
6917 Error(pos,
"Can't type cast from type \"%s\" to type \"%s\"", fromType->GetString().c_str(),
6923 const PointerType *fromPtr = CastType<PointerType>(fromType);
6924 const PointerType *toPtr = CastType<PointerType>(toType);
6925 if (fromPtr != NULL && toPtr != NULL)
6929 const ReferenceType *fromRef = CastType<ReferenceType>(fromType);
6930 const ReferenceType *toRef = CastType<ReferenceType>(toType);
6931 if (fromRef != NULL && toRef != NULL) {
6937 const AtomicType *fromAtomic = CastType<AtomicType>(fromType);
6938 const AtomicType *toAtomic = CastType<AtomicType>(toType);
6939 const EnumType *fromEnum = CastType<EnumType>(fromType);
6940 const EnumType *toEnum = CastType<EnumType>(toType);
6941 if ((fromAtomic || fromEnum) && (toAtomic || toEnum))
6946 if (fromPtr != NULL && toAtomic != NULL && toAtomic->
IsIntType()) {
6952 if (safeCast ==
false)
6954 "Pointer type cast of type \"%s\" to integer type " 6955 "\"%s\" may lose information.",
6956 fromType->GetString().c_str(), toType->
GetString().c_str());
6961 if (fromAtomic != NULL && fromAtomic->
IsIntType() && toPtr != NULL)
6975 if (constExpr == NULL)
6980 const AtomicType *toAtomic = CastType<AtomicType>(toType);
6981 const EnumType *toEnum = CastType<EnumType>(toType);
6985 if (toAtomic == NULL && toEnum == NULL)
6994 switch (basicType) {
7051 FATAL(
"unimplemented");
7057 if (llvm::dyn_cast<ConstExpr>(
expr) != NULL)
7065 printf(
"[%s] type cast (",
GetType()->GetString().c_str());
7083 std::vector<llvm::Constant *> smear;
7084 for (
int i = 0; i < count; ++i)
7085 smear.push_back(intPtr);
7088 return llvm::ConstantVector::get(smear);
7091 return llvm::ConstantArray::get(at, smear);
7109 if ((CastType<PointerType>(constType) == NULL) && (llvm::dyn_cast<SizeOfExpr>(
expr) == NULL))
7110 return std::pair<llvm::Constant *, bool>(NULL,
false);
7112 llvm::Value *ptr = NULL;
7116 if (ptr && llvm::dyn_cast<llvm::GlobalVariable>(ptr)) {
7118 if (llvm::Constant *c = llvm::dyn_cast<llvm::Constant>(ptr)) {
7120 llvm::ArrayRef<llvm::Value *> arrayRef(&offsets[0], &offsets[2]);
7121 llvm::Value *resultPtr = llvm::ConstantExpr::getGetElementPtr(
PTYPE(c), c, arrayRef);
7122 if (resultPtr->getType() == constType->
LLVMType(
g->
ctx)) {
7123 llvm::Constant *ret = llvm::dyn_cast<llvm::Constant>(resultPtr);
7124 return std::pair<llvm::Constant *, bool>(ret,
false);
7131 llvm::Constant *c = cPair.first;
7154 llvm::Type *llvmType;
7161 if (value == NULL) {
7213 printf(
"[%s] &(",
GetType()->GetString().c_str());
7244 return ctx->
LoadInst(ptr, mask, type);
7278 AssertPos(pos, CastType<PointerType>(type) != NULL);
7293 if (
const PointerType *pt = CastType<PointerType>(type)) {
7294 if (pt->GetBaseType()->IsVoidType()) {
7295 Error(pos,
"Illegal to dereference void pointer type \"%s\".", type->
GetString().c_str());
7299 Error(pos,
"Illegal to dereference non-pointer type \"%s\".", type->
GetString().c_str());
7325 printf(
"[%s] *(",
GetType()->GetString().c_str());
7343 AssertPos(pos, CastType<ReferenceType>(type) != NULL);
7357 AssertPos(pos, CastType<ReferenceType>(type) != NULL);
7373 printf(
"[%s] deref-reference (",
GetType()->GetString().c_str());
7390 if (CastType<ReferenceType>(exprType) != NULL || CastType<FunctionType>(exprType) != NULL)
7401 if (CastType<ReferenceType>(exprType) != NULL)
7435 printf(
"NULL expr");
7441 const Type *exprType;
7447 if (CastType<ReferenceType>(exprType) != NULL || CastType<FunctionType>(exprType) != NULL) {
7454 Error(
expr->
pos,
"Illegal to take address of non-lvalue or function.");
7463 const Type *exprType;
7466 return std::pair<llvm::Constant *, bool>(NULL,
false);
7469 const PointerType *pt = CastType<PointerType>(type);
7471 return std::pair<llvm::Constant *, bool>(NULL,
false);
7473 bool isNotValidForMultiTargetGlobal =
false;
7474 const FunctionType *ft = CastType<FunctionType>(pt->GetBaseType());
7477 llvm::Constant *c = cPair.first;
7480 llvm::Value *ptr = NULL;
7483 if (ptr && llvm::dyn_cast<llvm::GlobalVariable>(ptr)) {
7486 if (llvm::dyn_cast<SymbolExpr>(
expr) != NULL) {
7487 return std::pair<llvm::Constant *, bool>(llvm::cast<llvm::Constant>(ptr),
7488 isNotValidForMultiTargetGlobal);
7490 }
else if (
IndexExpr *IExpr = llvm::dyn_cast<IndexExpr>(
expr)) {
7491 std::vector<llvm::Value *> gepIndex;
7492 Expr *mBaseExpr = NULL;
7494 std::pair<llvm::Constant *, bool> cIndexPair = IExpr->index->
GetConstant(IExpr->index->GetType());
7495 llvm::Constant *cIndex = cIndexPair.first;
7497 return std::pair<llvm::Constant *, bool>(NULL,
false);
7498 gepIndex.insert(gepIndex.begin(), cIndex);
7499 mBaseExpr = IExpr->baseExpr;
7500 IExpr = llvm::dyn_cast<
IndexExpr>(mBaseExpr);
7501 isNotValidForMultiTargetGlobal = isNotValidForMultiTargetGlobal || cIndexPair.second;
7505 if (llvm::dyn_cast<SymbolExpr>(mBaseExpr) == NULL)
7506 return std::pair<llvm::Constant *, bool>(NULL,
false);
7507 gepIndex.insert(gepIndex.begin(),
LLVMInt64(0));
7508 llvm::Constant *c = llvm::cast<llvm::Constant>(ptr);
7509 llvm::Constant *c1 = llvm::ConstantExpr::getGetElementPtr(
PTYPE(c), c, gepIndex);
7510 return std::pair<llvm::Constant *, bool>(c1, isNotValidForMultiTargetGlobal);
7514 return std::pair<llvm::Constant *, bool>(NULL,
false);
7533 if (llvmType == NULL)
7550 printf(
" [type %s]", t->
GetString().c_str());
7557 if (
type != NULL && CastType<UndefinedStructType>(
type) != NULL) {
7559 "Can't compute the size of declared but not defined " 7560 "struct type \"%s\".",
7575 return std::pair<llvm::Constant *, bool>(NULL,
false);
7577 bool isNotValidForMultiTargetGlobal =
false;
7579 isNotValidForMultiTargetGlobal =
true;
7582 if (llvmType == NULL)
7583 return std::pair<llvm::Constant *, bool>(NULL,
false);
7586 return std::pair<llvm::Constant *, bool>(NULL,
false);
7588 return std::pair<llvm::Constant *, bool>(llvm::ConstantInt::get(rtype->
LLVMType(
g->
ctx), byteSize),
7589 isNotValidForMultiTargetGlobal);
7603 std::string loadName =
symbol->
name + std::string(
"_load");
7618 if (CastType<ReferenceType>(
symbol->
type) != NULL)
7661 matchingFunc = (candidates.size() == 1) ? candidates[0] : NULL;
7667 Error(pos,
"Ambiguous use of overloaded function \"%s\".",
name.c_str());
7696 return std::pair<llvm::Constant *, bool>(NULL,
false);
7700 return std::pair<llvm::Constant *, bool>(NULL,
false);
7704 "Type of function symbol \"%s\" doesn't match expected type " 7707 return std::pair<llvm::Constant *, bool>(NULL,
false);
7714 const std::vector<const Type *> &argTypes,
7715 const std::vector<bool> *argCouldBeNULL) {
7716 std::string message =
"Passed types: (";
7717 for (
unsigned int i = 0; i < argTypes.size(); ++i) {
7718 if (argTypes[i] != NULL)
7719 message += argTypes[i]->GetString();
7721 message +=
"(unknown type)";
7722 message += (i < argTypes.size() - 1) ?
", " :
")\n";
7725 for (
unsigned int i = 0; i < funcs.size(); ++i) {
7726 const FunctionType *ft = CastType<FunctionType>(funcs[i]->type);
7728 message +=
"Candidate: ";
7730 if (i < funcs.size() - 1)
7741 const AtomicType *callAt = CastType<AtomicType>(callType);
7742 const AtomicType *funcAt = CastType<AtomicType>(funcArgType);
7743 if (callAt == NULL || funcAt == NULL)
7771 FATAL(
"Unhandled atomic type");
7780 std::vector<Symbol *> ret;
7801 if (CastType<PointerType>(type) != NULL)
7809 return (CastType<PointerType>(t) != NULL);
7818 const std::vector<bool> *argCouldBeNULL,
7819 const std::vector<bool> *argIsConstant,
int *cost) {
7825 for (
int i = 0; i < (int)argTypes.size(); ++i) {
7832 int costScale = argTypes.size() + 1;
7835 const Type *callType = argTypes[i];
7850 if (argIsConstant == NULL || (*argIsConstant)[i] ==
false)
7853 if (CastType<ReferenceType>(fargType)) {
7863 cost[i] += 2 * costScale;
7873 cost[i] += 2 * costScale;
7876 const Type *callTypeNP = callType;
7877 if (CastType<ReferenceType>(callType)) {
7881 cost[i] += 2 * costScale;
7893 cost[i] += 1 * costScale;
7899 cost[i] += 8 * costScale;
7908 cost[i] += 16 * costScale;
7915 cost[i] += 128 * costScale;
7920 cost[i] += 128 * costScale;
7926 cost[i] += 64 * costScale;
7933 for (
int i = 0; i < (int)argTypes.size(); ++i) {
7934 costSum = costSum + cost[i];
7940 const std::vector<bool> *argCouldBeNULL,
7941 const std::vector<bool> *argIsConstant) {
7955 bool exactMatchOnly = (
name.substr(0, 2) ==
"__");
7963 int bestMatchCost = 1 << 30;
7964 std::vector<Symbol *> matches;
7965 std::vector<int> candidateCosts;
7966 std::vector<int *> candidateExpandCosts;
7968 if (actualCandidates.size() == 0)
7972 for (
int i = 0; i < (int)actualCandidates.size(); ++i) {
7973 const FunctionType *ft = CastType<FunctionType>(actualCandidates[i]->type);
7975 int *cost =
new int[argTypes.size()];
7976 candidateCosts.push_back(
computeOverloadCost(ft, argTypes, argCouldBeNULL, argIsConstant, cost));
7977 candidateExpandCosts.push_back(cost);
7982 for (
int i = 0; i < (int)candidateCosts.size(); ++i) {
7983 if (candidateCosts[i] != -1 && candidateCosts[i] < bestMatchCost)
7984 bestMatchCost = candidateCosts[i];
7987 if (bestMatchCost == (1 << 30))
7989 for (
int i = 0; i < (int)candidateCosts.size(); ++i) {
7990 if (candidateCosts[i] == bestMatchCost) {
7991 for (
int j = 0; j < (int)candidateCosts.size(); ++j) {
7992 for (
int k = 0; k < argTypes.size(); k++) {
7993 if (candidateCosts[j] != -1 && candidateExpandCosts[j][k] < candidateExpandCosts[i][k]) {
7994 std::vector<Symbol *> temp;
7995 temp.push_back(actualCandidates[i]);
7996 temp.push_back(actualCandidates[j]);
7999 "call to \"%s\" is ambiguous. " 8000 "This warning will be turned into error in the next ispc release.\n" 8001 "Please add explicit cast to arguments to have unambiguous match." 8003 funName, candidateMessage.c_str());
8007 matches.push_back(actualCandidates[i]);
8010 for (
int i = 0; i < (int)candidateExpandCosts.size(); ++i) {
8011 delete[] candidateExpandCosts[i];
8014 if (matches.size() == 1) {
8018 }
else if (matches.size() > 1) {
8022 "Multiple overloaded functions matched call to function " 8024 funName, exactMatchOnly ?
" only considering exact matches" :
"", candidateMessage.c_str());
8031 "Unable to find any matching overload for call to function " 8033 funName, exactMatchOnly ?
" only considering exact matches" :
"", candidateMessage.c_str());
8076 const PointerType *pt = CastType<PointerType>(type);
8078 return std::pair<llvm::Constant *, bool>(NULL,
false);
8081 if (llvmType == NULL) {
8083 return std::pair<llvm::Constant *, bool>(NULL,
false);
8086 return std::pair<llvm::Constant *, bool>(llvm::Constant::getNullValue(llvmType),
false);
8109 Error(tqPos,
"Illegal type qualifiers in \"new\" expression (only " 8110 "\"uniform\" and \"varying\" are allowed.");
8113 Error(tqPos,
"Illegal to provide both \"uniform\" and \"varying\" " 8114 "qualifiers to \"new\" expression.");
8119 isVarying = (typeQual == 0) || (typeQual & TYPEQUAL_VARYING);
8130 llvm::Value *countValue;
8133 if (countValue == NULL) {
8157 llvm::Value *allocSize = ctx->
BinaryOperator(llvm::Instruction::Mul, countValue, eltSize,
"alloc_size");
8161 llvm::Function *func;
8164 func =
m->
module->getFunction(
"__new_varying32_32rt");
8166 func =
m->
module->getFunction(
"__new_varying32_64rt");
8168 func =
m->
module->getFunction(
"__new_varying64_64rt");
8175 func =
m->
module->getFunction(
"__new_uniform_32rt");
8177 func =
m->
module->getFunction(
"__new_uniform_64rt");
8183 llvm::Value *ptrValue = ctx->
CallInst(func, NULL, allocSize,
"new");
8187 if (retType == NULL)
8209 llvm::Value *nonNull =
8210 ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE, p, nullValue,
"non_null");
8253 if (CastType<UndefinedStructType>(
allocType) != NULL) {
8255 "Can't dynamically allocate storage for declared " 8256 "but not defined type \"%s\".",
8263 "Can't dynamically allocate storage for declared " 8264 "type \"%s\" containing undefined member type.",
8275 const Type *countType;
8280 Error(pos,
"Illegal to provide \"varying\" allocation count with " 8281 "\"uniform new\" expression.");
const Function * GetFunction() const
llvm::Constant * LLVMIntAsType(int64_t val, llvm::Type *type)
virtual bool IsIntType() const =0
static const AtomicType * VaryingInt32
static llvm::Type * FloatType
llvm::Value * Any(llvm::Value *mask)
Symbol * GetMatchingFunction()
llvm::Value * lEmitLogicalOp(BinaryExpr::Op op, Expr *arg0, Expr *arg1, FunctionEmitContext *ctx, SourcePos pos)
virtual const Type * GetAsVaryingType() const =0
bool IsReferenceType() const
Common base class that provides shared functionality for PtrDerefExpr and RefDerefExpr.
std::pair< llvm::Constant *, bool > GetConstant(const Type *constType) const
static const AtomicType * VaryingInt16
bool IsUniformType() const
llvm::Value * GetLValue(FunctionEmitContext *ctx) const
llvm::Function * function
llvm::Constant * LLVMUInt64Vector(uint64_t ival)
llvm::Value * GetValue(FunctionEmitContext *ctx) const
std::pair< llvm::Constant *, bool > GetConstant(const Type *type) const
const Type * GetType() const
const Type * GetLValueType() const
std::string GetString() const
llvm::Value * PtrToIntInst(llvm::Value *value, const char *name=NULL)
llvm::Constant * LLVMUInt32Vector(uint32_t ival)
llvm::ConstantInt * LLVMUInt32(uint32_t ival)
virtual int getElementNumber() const =0
llvm::Value * AddElementOffset(llvm::Value *basePtr, int elementNum, const Type *ptrType, const char *name=NULL, const PointerType **resultPtrType=NULL)
llvm::Value * ProgramIndexVector(bool is32bits=true)
StructMemberExpr(Expr *e, const char *id, SourcePos p, SourcePos idpos, bool derefLValue)
void SetInternalMask(llvm::Value *val)
llvm::Instruction * FPCastInst(llvm::Value *value, llvm::Type *type, const char *name=NULL)
const Type * GetReturnType() const
DerefExpr(Expr *e, SourcePos p, unsigned scid=DerefExprID)
int8_t int8Val[ISPC_MAX_NVEC]
Declaration of the FunctionEmitContext class
virtual const Type * ResolveUnboundVariability(Variability v) const =0
const Type * GetType() const
llvm::Value * GetValue(FunctionEmitContext *ctx) const
llvm::Constant * LLVMBoolVector(bool b)
static int lIdentifierToVectorElement(char id)
static const AtomicType * VaryingUInt64
static llvm::Type * DoubleType
bool SafeToRunWithMaskAllOff(ASTNode *root)
static llvm::Value * lTypeConvAtomic(FunctionEmitContext *ctx, llvm::Value *exprVal, const AtomicType *toType, const AtomicType *fromType, SourcePos pos)
bool IsVaryingType() const
void SetInternalMaskAnd(llvm::Value *oldMask, llvm::Value *val)
void BranchInst(llvm::BasicBlock *block)
static PointerType * Void
llvm::Value * GetValue(FunctionEmitContext *ctx) const
static void lCheckIndicesVersusBounds(const Type *baseExprType, Expr *index)
llvm::ConstantInt * LLVMInt8(int8_t ival)
llvm::Instruction * ZExtInst(llvm::Value *value, llvm::Type *type, const char *name=NULL)
#define AssertPos(pos, expr)
Expression that represents taking a reference of a (non-reference) variable.
llvm::Constant * LLVMInt64Vector(int64_t ival)
An expression that represents a NULL pointer.
SourcePos Union(const SourcePos &p1, const SourcePos &p2)
llvm::Value * GetValue(FunctionEmitContext *ctx) const
std::pair< llvm::Constant *, bool > GetStorageConstant(const Type *type) const
llvm::ConstantInt * LLVMUInt8(uint8_t ival)
llvm::Value * NotOperator(llvm::Value *v, const char *name=NULL)
std::string GetString() const
llvm::Type * LLVMStorageType(llvm::LLVMContext *ctx) const
llvm::Value * SizeOf(llvm::Type *type, llvm::BasicBlock *insertAtEnd)
const Type * GetType() const
llvm::Value * LoadInst(llvm::Value *ptr, llvm::Value *mask, const Type *ptrType, const char *name=NULL, bool one_elem=false)
static llvm::VectorType * VoidPointerVectorType
static llvm::VectorType * BoolVectorType
int16_t int16Val[ISPC_MAX_NVEC]
AtomicType::BasicType getBasicType() const
ASTNode * TypeCheck(ASTNode *root)
llvm::Value * GetValue(FunctionEmitContext *ctx) const
static const AtomicType * VaryingDouble
virtual std::pair< llvm::Constant *, bool > GetStorageConstant(const Type *type) const
const char * LLVMGetName(llvm::Value *v, const char *s)
llvm::Instruction * TruncInst(llvm::Value *value, llvm::Type *type, const char *name=NULL)
static bool lIsMatchWithTypeWidening(const Type *callType, const Type *funcArgType)
llvm::Constant * LLVMMaskAllOn
static void lStoreAssignResult(llvm::Value *value, llvm::Value *ptr, const Type *valueType, const Type *ptrType, FunctionEmitContext *ctx, Symbol *baseSym)
llvm::Value * AllocaInst(llvm::Type *llvmType, const char *name=NULL, int align=0, bool atEntryBlock=true)
Expression representing a compile-time constant value.
Abstract base class for types that represent sequences.
static bool classof(ASTNode const *N)
SymbolExpr(Symbol *s, SourcePos p)
std::string GetString() const
TypeCastExpr(const Type *t, Expr *e, SourcePos p)
Symbol * GetBaseSymbol() const
Symbol * GetBaseSymbol() const
int getVectorMemoryCount() const
llvm::Value * CmpInst(llvm::Instruction::OtherOps inst, llvm::CmpInst::Predicate pred, llvm::Value *v0, llvm::Value *v1, const char *name=NULL)
const PointerType * lvalueType
Expr * MakeBinaryExpr(BinaryExpr::Op o, Expr *a, Expr *b, SourcePos p)
std::string GetString() const
const Type * GetLValueType() const
static llvm::Type * BoolType
llvm::Value * LaunchInst(llvm::Value *callee, std::vector< llvm::Value *> &argVals, llvm::Value *launchCount[3])
static void lConvertElement(From from, To *to)
bool FullResolveOverloads(Expr *func, ExprList *args, std::vector< const Type *> *argTypes, std::vector< bool > *argCouldBeNULL, std::vector< bool > *argIsConstant)
const Type * GetType() const
const Type * GetElementType() const
llvm::ConstantInt * LLVMInt16(int16_t ival)
std::string getCandidateNearMatches() const
BinaryExpr(Op o, Expr *a, Expr *b, SourcePos p)
const Type * GetLValueType() const
virtual Expr * Optimize()=0
llvm::Value * GetValue(FunctionEmitContext *ctx) const
const Type * GetLValueType() const
const Type * GetType() const
static llvm::VectorType * Int32VectorType
Expr * TypeConvertExpr(Expr *expr, const Type *toType, const char *errorMsgBase)
bool PossiblyResolveFunctionOverloads(Expr *expr, const Type *type)
static const AtomicType * UniformUInt32
const Type * GetLValueType() const
int GetElementNumber(const std::string &name) const
static ConstExpr * lConstFoldBoolBinaryOp(BinaryExpr::Op op, const bool *v0, const bool *v1, ConstExpr *carg0)
std::pair< llvm::Constant *, bool > GetConstant(const Type *type) const
static llvm::VectorType * BoolVectorStorageType
static const char * lOpString(BinaryExpr::Op op)
static PointerType * GetVarying(const Type *t)
llvm::Constant * LLVMFalseInStorage
ReferenceExpr(Expr *e, SourcePos p)
llvm::Value * GetFullMask()
const Type * GetType() const
PtrDerefExpr(Expr *e, SourcePos p)
int VaryingCFDepth() const
virtual std::pair< llvm::Constant *, bool > GetConstant(const Type *type) const
llvm::Value * MakeSlicePointer(llvm::Value *ptr, llvm::Value *offset)
int GetNumParameters() const
const Type * GetType() const
SelectExpr(Expr *test, Expr *a, Expr *b, SourcePos p)
llvm::Value * SwitchBoolSize(llvm::Value *value, llvm::Type *fromType, llvm::Type *toType, const char *name=NULL)
Symbol * GetBaseSymbol() const
static llvm::Value * lEmitPrePostIncDec(UnaryExpr::Op op, Expr *expr, SourcePos pos, FunctionEmitContext *ctx)
llvm::Value * GetLValue(FunctionEmitContext *ctx) const
const Type * GetType() const
static std::string lGetOverloadCandidateMessage(const std::vector< Symbol *> &funcs, const std::vector< const Type *> &argTypes, const std::vector< bool > *argCouldBeNULL)
const Type * GetType() const
Type implementation for pointers to other types.
static bool lDoTypeConv(const Type *fromType, const Type *toType, Expr **expr, bool failureOk, const char *errorMsgBase, SourcePos pos)
const Type * GetType() const
llvm::Value * GetValue(FunctionEmitContext *ctx) const
std::pair< llvm::Constant *, bool > GetStorageConstant(const Type *type) const
static llvm::Constant * lLLVMConstantValue(const Type *type, llvm::LLVMContext *ctx, double value)
static llvm::Type * Int16Type
VectorMemberExpr(Expr *e, const char *id, SourcePos p, SourcePos idpos, bool derefLValue)
const StructType * GetAsVaryingType() const
static bool lCheckForConstStructMember(SourcePos pos, const StructType *structType, const StructType *initialType)
llvm::Value * GetLValue(FunctionEmitContext *ctx) const
virtual void Print() const =0
static llvm::Value * lEmitNegate(Expr *arg, SourcePos pos, FunctionEmitContext *ctx)
const Type * GetType() const
Symbol * GetBaseSymbol() const
AssignExpr(Op o, Expr *a, Expr *b, SourcePos p)
llvm::BasicBlock * GetCurrentBasicBlock()
static const AtomicType * UniformUInt16
std::vector< std::string > MatchStrings(const std::string &str, const std::vector< std::string > &options)
static PointerType * GetUniform(const Type *t, bool isSlice=false)
FunctionCallExpr(Expr *func, ExprList *args, SourcePos p, bool isLaunch=false, Expr *launchCountExpr[3]=NULL)
virtual llvm::Value * GetValue(FunctionEmitContext *ctx) const =0
bool boolVal[ISPC_MAX_NVEC]
llvm::Value * GetLValue(FunctionEmitContext *ctx) const
static llvm::VectorType * Int1VectorType
const VectorType * memberType
llvm::Value * CallInst(llvm::Value *func, const FunctionType *funcType, const std::vector< llvm::Value *> &args, const char *name=NULL)
llvm::BasicBlock * CreateBasicBlock(const char *name)
const Type * GetLValueType() const
llvm::Value * GetValue(FunctionEmitContext *ctx) const
std::pair< llvm::Constant *, bool > GetStorageConstant(const Type *type) const
virtual llvm::Type * LLVMType(llvm::LLVMContext *ctx) const =0
header file with declarations for symbol and symbol table classes.
static const AtomicType * UniformBool
llvm::Value * BroadcastValue(llvm::Value *v, llvm::Type *vecType, const char *name=NULL)
std::pair< llvm::Constant *, bool > GetConstant(const Type *type) const
Type representing a reference to another (non-reference) type.
llvm::Constant * LLVMFloatVector(float fval)
virtual const Type * GetReferenceTarget() const
uint8_t uint8Val[ISPC_MAX_NVEC]
bool disableMaskAllOnOptimizations
RefDerefExpr(Expr *e, SourcePos p)
std::string GetString() const
virtual llvm::Value * GetLValue(FunctionEmitContext *ctx) const
static bool IsVoidPointer(const Type *t)
Expr * GetParameterDefault(int i) const
llvm::Constant * LLVMDoubleVector(double dval)
void StoreInst(llvm::Value *value, llvm::Value *ptr, const Type *ptrType=NULL)
static bool lIsAllIntZeros(Expr *expr)
void PerformanceWarning(SourcePos p, const char *fmt,...)
Expression representing a type cast of the given expression to a probably-different type...
static const AtomicType * UniformUInt64
uint32_t uint32Val[ISPC_MAX_NVEC]
Symbol * GetBaseSymbol() const
static llvm::VectorType * Int8VectorType
const Type * GetType() const
llvm::Value * GetValue(FunctionEmitContext *ctx) const
llvm::Constant * LLVMInt32Vector(int32_t ival)
Abstract base class for nodes in the abstract syntax tree (AST).
llvm::Value * GetElementPtrInst(llvm::Value *basePtr, llvm::Value *index, const Type *ptrType, const char *name=NULL)
llvm::Value * GetValue(FunctionEmitContext *ctx) const
llvm::Value * GetLValue(FunctionEmitContext *ctx) const
SizeOfExpr(Expr *e, SourcePos p)
Symbol * GetBaseSymbol() const
virtual int GetElementCount() const =0
const Type * GetType() const
std::pair< llvm::Constant *, bool > GetConstant(const Type *type) const
llvm::Value * GetLValue(FunctionEmitContext *ctx) const
bool LookupFunction(const char *name, std::vector< Symbol *> *matches=NULL)
float floatVal[ISPC_MAX_NVEC]
static int computeOverloadCost(const FunctionType *ftype, const std::vector< const Type *> &argTypes, const std::vector< bool > *argCouldBeNULL, const std::vector< bool > *argIsConstant, int *cost)
llvm::Constant * LLVMTrue
unsigned getValueID() const
static llvm::Value * lEmitBinaryCmp(BinaryExpr::Op op, llvm::Value *e0Val, llvm::Value *e1Val, const Type *type, FunctionEmitContext *ctx, SourcePos pos)
static llvm::VectorType * FloatVectorType
const Type * GetReferenceTarget() const
static bool lCanImproveVectorDivide(Expr *arg0, Expr *arg1, int *divisor)
virtual bool IsBoolType() const =0
static ConstExpr * lConstFoldBinaryIntOp(BinaryExpr::Op op, const T *v0, const T *v1, ConstExpr *carg0, SourcePos pos)
static bool lVaryingStructHasUniformMember(const Type *type, SourcePos pos)
virtual const Type * GetLValueType() const
static llvm::Type * Int64Type
static llvm::Type * Int8Type
static const Type * MoreGeneralType(const Type *type0, const Type *type1, SourcePos pos, const char *reason, bool forceVarying=false, int vecSize=0)
void MemcpyInst(llvm::Value *dest, llvm::Value *src, llvm::Value *count, llvm::Value *align=NULL)
llvm::PHINode * PhiNode(llvm::Type *type, int count, const char *name=NULL)
Representation of a structure holding a number of members.
void InitSymbol(llvm::Value *ptr, const Type *symType, Expr *initExpr, FunctionEmitContext *ctx, SourcePos pos)
std::pair< llvm::Constant *, bool > GetConstant(const Type *type) const
int GetValues(bool *, bool forceVarying=false) const
static bool lIsDifficultShiftAmount(Expr *expr)
static llvm::VectorType * Int64VectorType
Header file with declarations for various LLVM utility stuff.
virtual bool IsFloatType() const =0
llvm::Value * GetValue(FunctionEmitContext *ctx) const
const std::string & GetElementName(int i) const
const Type * GetLValueType() const
void MatchIntegerTypes(llvm::Value **v0, llvm::Value **v1)
const Type * GetBaseType() const
static llvm::Value * lConvertPtrToSliceIfNeeded(FunctionEmitContext *ctx, llvm::Value *ptr, const Type **type)
bool IsGenericTypeLayoutIndeterminate(llvm::Type *type)
static bool IsBasicType(const Type *type)
llvm::ConstantInt * LLVMUInt64(uint64_t ival)
virtual const Type * GetType() const =0
llvm::Constant * LLVMBoolVectorInStorage(bool b)
const Type * GetType() const
AtomicType represents basic types like floats, ints, etc.
int getElementNumber() const
static void lEmitSelectExprCode(FunctionEmitContext *ctx, llvm::Value *testVal, llvm::Value *oldMask, llvm::Value *fullMask, Expr *expr, llvm::Value *exprPtr)
static bool classof(ASTNode const *N)
llvm::Value * GetValue(FunctionEmitContext *ctx) const
static void lConvert(const From *from, To *to, int count, bool forceVarying)
AddressOfExpr(Expr *e, SourcePos p)
llvm::Constant * LLVMMaskAllOff
StorageClass storageClass
Representation of a range of positions in a source file.
Expression representing a function symbol in the program (generally used for a function call)...
bool disableUniformMemoryOptimizations
llvm::Value * GetValue(FunctionEmitContext *ctx) const
llvm::Value * GetValue(FunctionEmitContext *ctx) const
uint64_t uint64Val[ISPC_MAX_NVEC]
llvm::Value * GetValue(FunctionEmitContext *ctx) const
llvm::ConstantInt * LLVMInt32(int32_t ival)
bool CanConvertTypes(const Type *fromType, const Type *toType, const char *errorMsgBase, SourcePos pos)
Type implementation for enumerated types.
virtual const Type * GetAsNonConstType() const =0
const Type * GetType() const
static const AtomicType * VaryingBool
virtual std::string GetString() const =0
Expr * lCreateBinaryOperatorCall(const BinaryExpr::Op bop, Expr *a0, Expr *a1, const SourcePos &sp)
Abstract base class for types that represent collections of other types.
bool force32BitAddressing
static ConstExpr * lConstFoldBinaryLogicalOp(BinaryExpr::Op op, const T *v0, const T *v1, ConstExpr *carg0)
static Expr * lOptimizeBitNot(ConstExpr *constExpr, const Type *type, SourcePos pos)
FunctionSymbolExpr(const char *name, const std::vector< Symbol *> &candFuncs, SourcePos pos)
int GetElementCount() const
int getElementNumber() const
static Expr * lArrayToPointer(Expr *expr)
llvm::Instruction * SExtInst(llvm::Value *value, llvm::Type *type, const char *name=NULL)
std::vector< Symbol * > candidateFunctions
llvm::Constant * LLVMUInt8Vector(uint8_t ival)
static std::pair< llvm::Constant *, bool > lGetBinaryExprStorageConstant(const Type *type, const BinaryExpr *bExpr, bool isStorageType)
const BasicType basicType
int64_t int64Val[ISPC_MAX_NVEC]
static llvm::Type * PointerIntType
static llvm::PointerType * VoidPointerType
static const AtomicType * VaryingInt64
llvm::Constant * LLVMFloat(float fval)
void Error(SourcePos p, const char *fmt,...)
UnaryExpr(Op op, Expr *expr, SourcePos pos)
int getVectorWidth() const
const StructType * getStructType() const
const PointerType * GetAsSlice() const
bool IsPointerType() const
llvm::Constant * LLVMDouble(double dval)
const AtomicType * GetElementType() const
static const Type * lDeconstifyType(const Type *t)
A (short) vector of atomic types.
llvm::Value * InsertInst(llvm::Value *v, llvm::Value *eltVal, int elt, const char *name=NULL)
static llvm::Value * lEmitBinaryArith(BinaryExpr::Op op, llvm::Value *value0, llvm::Value *value1, const Type *type0, const Type *type1, FunctionEmitContext *ctx, SourcePos pos)
Expr * launchCountExpr[3]
static llvm::Value * lEmitBinaryPointerArith(BinaryExpr::Op op, llvm::Value *value0, llvm::Value *value1, const Type *type0, const Type *type1, FunctionEmitContext *ctx, SourcePos pos)
static const Type * lMatchingBoolType(const Type *type)
static const AtomicType * UniformUInt8
const Type * GetElementType(const std::string &name) const
static llvm::Type * Int32Type
llvm::Value * GetValue(FunctionEmitContext *ctx) const
const llvm::DataLayout * getDataLayout() const
void SetDebugPos(SourcePos pos)
virtual const Type * GetAsUniformType() const =0
std::vector< Symbol * > getCandidateFunctions(int argCount) const
llvm::Value * GetLValue(FunctionEmitContext *ctx) const
static llvm::Value * lEmitOpAssign(AssignExpr::Op op, Expr *arg0, Expr *arg1, const Type *type, Symbol *baseSym, SourcePos pos, FunctionEmitContext *ctx)
bool ResolveOverloads(SourcePos argPos, const std::vector< const Type *> &argTypes, const std::vector< bool > *argCouldBeNULL=NULL, const std::vector< bool > *argIsConstant=NULL)
llvm::Value * GetValue(FunctionEmitContext *ctx) const
llvm::Value * GetValue(FunctionEmitContext *ctx) const
bool disableMaskedStoreToStore
static bool classof(StructMemberExpr const *)
virtual const Type * GetElementType() const =0
static bool Equal(const Type *a, const Type *b)
static const AtomicType * VaryingUInt16
Expression representing member selection ("foo.bar").
llvm::Value * GetValue(FunctionEmitContext *ctx) const
std::vector< Expr * > exprs
const Type * getElementType() const
static std::pair< llvm::Constant *, bool > lGetExprListConstant(const Type *type, const ExprList *eList, bool isStorageType)
static bool lArgIsPointerType(const Type *type)
static const AtomicType * UniformFloat
static const AtomicType * VaryingInt8
const PointerType * GetAsFrozenSlice() const
llvm::Value * GetInternalMask()
virtual bool IsUnsignedType() const =0
const Type * GetParameterType(int i) const
llvm::Value * BitCastInst(llvm::Value *value, llvm::Type *type, const char *name=NULL)
static const AtomicType * UniformInt32
void SetInternalMaskAndNot(llvm::Value *oldMask, llvm::Value *test)
static llvm::Value * lConvertToSlicePointer(FunctionEmitContext *ctx, llvm::Value *ptr, const PointerType *slicePtrType)
llvm::Constant * LLVMFalse
Expression representing indexing into something with an integer offset.
static MemberExpr * create(Expr *expr, const char *identifier, SourcePos pos, SourcePos identifierPos, bool derefLvalue)
static Expr * lOptimizeNegate(ConstExpr *constExpr, const Type *type, SourcePos pos)
Type representing a function (return type + argument types)
Representation of a program symbol.
llvm::Value * ExtractInst(llvm::Value *v, int elt, const char *name=NULL)
const PointerType * GetAsNonSlice() const
static std::pair< llvm::Constant *, bool > lGetConstExprConstant(const Type *constType, const ConstExpr *cExpr, bool isStorageType)
static llvm::Value * lEmitBinaryBitOp(BinaryExpr::Op op, llvm::Value *arg0Val, llvm::Value *arg1Val, bool isUnsigned, FunctionEmitContext *ctx)
virtual bool IsConstType() const =0
Interface class that defines the type abstraction.
static const AtomicType * UniformDouble
virtual Variability GetVariability() const =0
llvm::Constant * LLVMInt16Vector(int16_t ival)
Expr abstract base class and expression implementations.
static const AtomicType * Void
void SetCurrentBasicBlock(llvm::BasicBlock *bblock)
const VectorType * exprVectorType
virtual const Type * GetAsConstType() const =0
static llvm::VectorType * MaskType
llvm::Instruction * SelectInst(llvm::Value *test, llvm::Value *val0, llvm::Value *val1, const char *name=NULL)
void Debug(SourcePos p, const char *fmt,...)
llvm::Type * LLVMType(llvm::LLVMContext *ctx) const
llvm::ConstantInt * LLVMUInt16(uint16_t ival)
const Type * GetLValueType() const
int GetElementCount() const
const Type * GetType() const
Expr is the abstract base class that defines the interface that all expression types must implement...
llvm::Value * IntToPtrInst(llvm::Value *value, llvm::Type *type, const char *name=NULL)
const Function * parentFunction
static llvm::VectorType * DoubleVectorType
const Type * GetType() const
double doubleVal[ISPC_MAX_NVEC]
MemberExpr(Expr *expr, const char *identifier, SourcePos pos, SourcePos identifierPos, bool derefLValue, unsigned scid)
static bool classof(VectorMemberExpr const *)
Symbol * GetBaseSymbol() const
llvm::Value * All(llvm::Value *mask)
llvm::Constant * LLVMInt8Vector(int8_t ival)
ASTNode * Optimize(ASTNode *root)
llvm::Constant * LLVMUInt16Vector(uint16_t ival)
llvm::ConstantInt * LLVMInt64(int64_t ival)
ConstExpr(const Type *t, int8_t i, SourcePos p)
Expression that represents dereferencing a reference to get its value.
IndexExpr(Expr *baseExpr, Expr *index, SourcePos p)
const Type * GetType() const
virtual const Type * GetBaseType() const =0
llvm::Value * SmearUniform(llvm::Value *value, const char *name=NULL)
const Type * getElementType() const
static llvm::Value * lUniformValueToVarying(FunctionEmitContext *ctx, llvm::Value *value, const Type *type, SourcePos pos)
static llvm::VectorType * Int16VectorType
std::pair< llvm::Constant *, bool > GetConstant(const Type *type) const
virtual Symbol * GetBaseSymbol() const
const Type * GetType() const
Variability GetVariability() const
static llvm::Value * lMaskForSymbol(Symbol *baseSym, FunctionEmitContext *ctx)
int32_t int32Val[ISPC_MAX_NVEC]
static Expr * lConstFoldBinaryFPOp(ConstExpr *constArg0, ConstExpr *constArg1, BinaryExpr::Op op, BinaryExpr *origExpr, SourcePos pos)
static const AtomicType * VaryingUInt8
const Type * GetBaseType() const
int GetElementCount() const
std::pair< llvm::Constant *, bool > GetConstant(const Type *type) const
const Type * GetLValueType() const
Declaration of the Module class, which is the ispc-side representation of the results of compiling a ...
static const AtomicType * UniformInt64
Symbol * GetBaseSymbol() const
static const AtomicType * UniformInt16
static llvm::Value * lAddVaryingOffsetsIfNeeded(FunctionEmitContext *ctx, llvm::Value *ptr, const Type *ptrRefType)
static const FunctionType * lGetFunctionType(Expr *func)
const Type * GetType() const
uint16_t uint16Val[ISPC_MAX_NVEC]
Expr * lConstFoldSelect(const bool bv[], ConstExpr *constExpr1, ConstExpr *constExpr2, const Type *exprType, SourcePos pos)
std::string GetString() const
void Warning(SourcePos p, const char *fmt,...)
static llvm::Value * lEmitVaryingSelect(FunctionEmitContext *ctx, llvm::Value *test, llvm::Value *expr1, llvm::Value *expr2, const Type *type)
static bool EqualIgnoringConst(const Type *a, const Type *b)
static ConstExpr * lConstFoldBinaryArithOp(BinaryExpr::Op op, const T *v0, const T *v1, ConstExpr *carg0, SourcePos pos)
const Type * GetType() const
llvm::Instruction * CastInst(llvm::Instruction::CastOps op, llvm::Value *value, llvm::Type *type, const char *name=NULL)
virtual Expr * TypeCheck()=0
bool IsNumericType() const
#define FOLD_OP_REF(O, E, TRef)
const Type * GetType() const
const SourcePos identifierPos
llvm::Value * GetValue(FunctionEmitContext *ctx) const
static const AtomicType * VaryingUInt32
llvm::Value * BinaryOperator(llvm::Instruction::BinaryOps inst, llvm::Value *v0, llvm::Value *v1, const char *name=NULL)
static const AtomicType * VaryingFloat
virtual llvm::Type * LLVMStorageType(llvm::LLVMContext *ctx) const
Expression representing a function call.
SymbolTable * symbolTable
static const AtomicType * UniformInt8
bool HasUnboundVariability() const
File with declarations for classes related to type representation.
llvm::Value * I1VecToBoolVec(llvm::Value *b)
const Type * GetLValueType() const
NewExpr(int typeQual, const Type *type, Expr *initializer, Expr *count, SourcePos tqPos, SourcePos p)
static llvm::Constant * lConvertPointerConstant(llvm::Constant *c, const Type *constType)
llvm::Constant * LLVMTrueInStorage
virtual const Type * GetElementType(int index) const =0
One-dimensional array type.