Improvements to constant folding.
We can now do constant folding with all basic datatypes (the previous implementation handled int32 well, but had limited, if any, coverage for other datatypes.) Reduced a bit of repeated code in the constant folding implementation through template helper functions.
This commit is contained in:
2
ast.cpp
2
ast.cpp
@@ -446,7 +446,7 @@ lCheckAllOffSafety(ASTNode *node, void *data) {
|
||||
}
|
||||
|
||||
int32_t indices[ISPC_MAX_NVEC];
|
||||
int count = ce->AsInt32(indices);
|
||||
int count = ce->GetValues(indices);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (indices[i] < 0 || indices[i] >= nElements) {
|
||||
// Index is out of bounds -> not safe
|
||||
|
||||
445
expr.cpp
445
expr.cpp
@@ -180,7 +180,7 @@ lIsAllIntZeros(Expr *expr) {
|
||||
return false;
|
||||
|
||||
uint64_t vals[ISPC_MAX_NVEC];
|
||||
int count = ce->AsUInt64(vals);
|
||||
int count = ce->GetValues(vals);
|
||||
if (count == 1)
|
||||
return (vals[0] == 0);
|
||||
else {
|
||||
@@ -1161,6 +1161,16 @@ UnaryExpr::GetType() const {
|
||||
}
|
||||
|
||||
|
||||
template <typename T> static Expr *
|
||||
lOptimizeBitNot(ConstExpr *constExpr, const Type *type, SourcePos pos) {
|
||||
T v[ISPC_MAX_NVEC];
|
||||
int count = constExpr->GetValues(v);
|
||||
for (int i = 0; i < count; ++i)
|
||||
v[i] = ~v[i];
|
||||
return new ConstExpr(type, v, pos);
|
||||
}
|
||||
|
||||
|
||||
Expr *
|
||||
UnaryExpr::Optimize() {
|
||||
ConstExpr *constExpr = dynamic_cast<ConstExpr *>(expr);
|
||||
@@ -1172,17 +1182,6 @@ UnaryExpr::Optimize() {
|
||||
const Type *type = constExpr->GetType();
|
||||
bool isEnumType = CastType<EnumType>(type) != NULL;
|
||||
|
||||
const Type *baseType = type->GetAsNonConstType()->GetAsUniformType();
|
||||
if (Type::Equal(baseType, AtomicType::UniformInt8) ||
|
||||
Type::Equal(baseType, AtomicType::UniformUInt8) ||
|
||||
Type::Equal(baseType, AtomicType::UniformInt16) ||
|
||||
Type::Equal(baseType, AtomicType::UniformUInt16) ||
|
||||
Type::Equal(baseType, AtomicType::UniformInt64) ||
|
||||
Type::Equal(baseType, AtomicType::UniformUInt64))
|
||||
// FIXME: should handle these at some point; for now we only do
|
||||
// constant folding for bool, int32 and float types...
|
||||
return this;
|
||||
|
||||
switch (op) {
|
||||
case PreInc:
|
||||
case PreDec:
|
||||
@@ -1192,42 +1191,76 @@ UnaryExpr::Optimize() {
|
||||
// An error will be issued elsewhere...
|
||||
return this;
|
||||
case Negate: {
|
||||
// Since we currently only handle int32, floats, and doubles here,
|
||||
// it's safe to stuff whatever we have into a double, do the negate
|
||||
// as a double, and then return a ConstExpr with the same type as
|
||||
// the original...
|
||||
double v[ISPC_MAX_NVEC];
|
||||
int count = constExpr->AsDouble(v);
|
||||
for (int i = 0; i < count; ++i)
|
||||
v[i] = -v[i];
|
||||
return new ConstExpr(constExpr, v);
|
||||
if (Type::EqualIgnoringConst(type, AtomicType::UniformInt64) ||
|
||||
Type::EqualIgnoringConst(type, AtomicType::VaryingInt64)) {
|
||||
int64_t v[ISPC_MAX_NVEC];
|
||||
int count = constExpr->GetValues(v);
|
||||
for (int i = 0; i < count; ++i)
|
||||
v[i] = -v[i];
|
||||
return new ConstExpr(type, v, pos);
|
||||
}
|
||||
else if (Type::EqualIgnoringConst(type, AtomicType::UniformUInt64) ||
|
||||
Type::EqualIgnoringConst(type, AtomicType::VaryingUInt64)) {
|
||||
uint64_t v[ISPC_MAX_NVEC];
|
||||
int count = constExpr->GetValues(v);
|
||||
for (int i = 0; i < count; ++i)
|
||||
v[i] = -v[i];
|
||||
return new ConstExpr(type, v, pos);
|
||||
}
|
||||
else {
|
||||
// For all the other types, it's safe to stuff whatever we have
|
||||
// into a double, do the negate as a double, and then return a
|
||||
// ConstExpr with the same type as the original...
|
||||
double v[ISPC_MAX_NVEC];
|
||||
int count = constExpr->GetValues(v);
|
||||
for (int i = 0; i < count; ++i)
|
||||
v[i] = -v[i];
|
||||
return new ConstExpr(constExpr, v);
|
||||
}
|
||||
}
|
||||
case BitNot: {
|
||||
if (Type::EqualIgnoringConst(type, AtomicType::UniformInt32) ||
|
||||
Type::EqualIgnoringConst(type, AtomicType::VaryingInt32)) {
|
||||
int32_t v[ISPC_MAX_NVEC];
|
||||
int count = constExpr->AsInt32(v);
|
||||
for (int i = 0; i < count; ++i)
|
||||
v[i] = ~v[i];
|
||||
return new ConstExpr(type, v, pos);
|
||||
if (Type::EqualIgnoringConst(type, AtomicType::UniformInt8) ||
|
||||
Type::EqualIgnoringConst(type, AtomicType::VaryingInt8)) {
|
||||
return lOptimizeBitNot<int8_t>(constExpr, type, pos);
|
||||
}
|
||||
else if (Type::EqualIgnoringConst(type, AtomicType::UniformUInt8) ||
|
||||
Type::EqualIgnoringConst(type, AtomicType::VaryingUInt8)) {
|
||||
return lOptimizeBitNot<uint8_t>(constExpr, type, pos);
|
||||
}
|
||||
else if (Type::EqualIgnoringConst(type, AtomicType::UniformInt16) ||
|
||||
Type::EqualIgnoringConst(type, AtomicType::VaryingInt16)) {
|
||||
return lOptimizeBitNot<int16_t>(constExpr, type, pos);
|
||||
}
|
||||
else if (Type::EqualIgnoringConst(type, AtomicType::UniformUInt16) ||
|
||||
Type::EqualIgnoringConst(type, AtomicType::VaryingUInt16)) {
|
||||
return lOptimizeBitNot<uint16_t>(constExpr, type, pos);
|
||||
}
|
||||
else if (Type::EqualIgnoringConst(type, AtomicType::UniformInt32) ||
|
||||
Type::EqualIgnoringConst(type, AtomicType::VaryingInt32)) {
|
||||
return lOptimizeBitNot<int32_t>(constExpr, type, pos);
|
||||
}
|
||||
else if (Type::EqualIgnoringConst(type, AtomicType::UniformUInt32) ||
|
||||
Type::EqualIgnoringConst(type, AtomicType::VaryingUInt32) ||
|
||||
isEnumType == true) {
|
||||
uint32_t v[ISPC_MAX_NVEC];
|
||||
int count = constExpr->AsUInt32(v);
|
||||
for (int i = 0; i < count; ++i)
|
||||
v[i] = ~v[i];
|
||||
return new ConstExpr(type, v, pos);
|
||||
return lOptimizeBitNot<uint32_t>(constExpr, type, pos);
|
||||
}
|
||||
else if (Type::EqualIgnoringConst(type, AtomicType::UniformInt64) ||
|
||||
Type::EqualIgnoringConst(type, AtomicType::VaryingInt64)) {
|
||||
return lOptimizeBitNot<int64_t>(constExpr, type, pos);
|
||||
}
|
||||
else if (Type::EqualIgnoringConst(type, AtomicType::UniformUInt64) ||
|
||||
Type::EqualIgnoringConst(type, AtomicType::VaryingUInt64) ||
|
||||
isEnumType == true) {
|
||||
return lOptimizeBitNot<uint64_t>(constExpr, type, pos);
|
||||
}
|
||||
else
|
||||
FATAL("unexpected type in UnaryExpr::Optimize() / BitNot case");
|
||||
}
|
||||
case LogicalNot: {
|
||||
AssertPos(pos, Type::EqualIgnoringConst(type, AtomicType::UniformBool) ||
|
||||
Type::EqualIgnoringConst(type, AtomicType::VaryingBool));
|
||||
Type::EqualIgnoringConst(type, AtomicType::VaryingBool));
|
||||
bool v[ISPC_MAX_NVEC];
|
||||
int count = constExpr->AsBool(v);
|
||||
int count = constExpr->GetValues(v);
|
||||
for (int i = 0; i < count; ++i)
|
||||
v[i] = !v[i];
|
||||
return new ConstExpr(type, v, pos);
|
||||
@@ -2016,25 +2049,37 @@ BinaryExpr::GetType() const {
|
||||
|
||||
#define FOLD_OP(O, E) \
|
||||
case O: \
|
||||
for (int i = 0; i < count; ++i) \
|
||||
result[i] = (v0[i] E v1[i]); \
|
||||
break
|
||||
for (int i = 0; i < count; ++i) \
|
||||
result[i] = (v0[i] E v1[i]); \
|
||||
break
|
||||
|
||||
#define FOLD_OP_REF(O, E, TRef) \
|
||||
case O: \
|
||||
for (int i = 0; i < count; ++i) { \
|
||||
result[i] = (v0[i] E v1[i]); \
|
||||
TRef r = (TRef)v0[i] E (TRef)v1[i]; \
|
||||
if (result[i] != r) \
|
||||
Warning(pos, "Binary expression with type \"%s\" can't represent value.", \
|
||||
carg0->GetType()->GetString().c_str()); \
|
||||
} \
|
||||
break
|
||||
|
||||
/** Constant fold the binary integer operations that aren't also applicable
|
||||
to floating-point types.
|
||||
*/
|
||||
template <typename T> static ConstExpr *
|
||||
lConstFoldBinIntOp(BinaryExpr::Op op, const T *v0, const T *v1, ConstExpr *carg0) {
|
||||
template <typename T, typename TRef> static ConstExpr *
|
||||
lConstFoldBinaryIntOp(BinaryExpr::Op op, const T *v0, const T *v1, ConstExpr *carg0,
|
||||
SourcePos pos) {
|
||||
T result[ISPC_MAX_NVEC];
|
||||
int count = carg0->Count();
|
||||
|
||||
switch (op) {
|
||||
FOLD_OP(BinaryExpr::Mod, %);
|
||||
FOLD_OP(BinaryExpr::Shl, <<);
|
||||
FOLD_OP(BinaryExpr::Shr, >>);
|
||||
FOLD_OP(BinaryExpr::BitAnd, &);
|
||||
FOLD_OP(BinaryExpr::BitXor, ^);
|
||||
FOLD_OP(BinaryExpr::BitOr, |);
|
||||
FOLD_OP_REF(BinaryExpr::Mod, %, TRef);
|
||||
FOLD_OP_REF(BinaryExpr::Shl, <<, TRef);
|
||||
FOLD_OP_REF(BinaryExpr::Shr, >>, TRef);
|
||||
FOLD_OP_REF(BinaryExpr::BitAnd, &, TRef);
|
||||
FOLD_OP_REF(BinaryExpr::BitXor, ^, TRef);
|
||||
FOLD_OP_REF(BinaryExpr::BitOr, |, TRef);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@@ -2046,7 +2091,8 @@ lConstFoldBinIntOp(BinaryExpr::Op op, const T *v0, const T *v1, ConstExpr *carg0
|
||||
/** Constant fold the binary logical ops.
|
||||
*/
|
||||
template <typename T> static ConstExpr *
|
||||
lConstFoldBinLogicalOp(BinaryExpr::Op op, const T *v0, const T *v1, ConstExpr *carg0) {
|
||||
lConstFoldBinaryLogicalOp(BinaryExpr::Op op, const T *v0, const T *v1,
|
||||
ConstExpr *carg0) {
|
||||
bool result[ISPC_MAX_NVEC];
|
||||
int count = carg0->Count();
|
||||
|
||||
@@ -2071,16 +2117,16 @@ lConstFoldBinLogicalOp(BinaryExpr::Op op, const T *v0, const T *v1, ConstExpr *c
|
||||
|
||||
/** Constant fold binary arithmetic ops.
|
||||
*/
|
||||
template <typename T> static ConstExpr *
|
||||
lConstFoldBinArithOp(BinaryExpr::Op op, const T *v0, const T *v1, ConstExpr *carg0,
|
||||
SourcePos pos) {
|
||||
template <typename T, typename TRef> static ConstExpr *
|
||||
lConstFoldBinaryArithOp(BinaryExpr::Op op, const T *v0, const T *v1, ConstExpr *carg0,
|
||||
SourcePos pos) {
|
||||
T result[ISPC_MAX_NVEC];
|
||||
int count = carg0->Count();
|
||||
|
||||
switch (op) {
|
||||
FOLD_OP(BinaryExpr::Add, +);
|
||||
FOLD_OP(BinaryExpr::Sub, -);
|
||||
FOLD_OP(BinaryExpr::Mul, *);
|
||||
FOLD_OP_REF(BinaryExpr::Add, +, TRef);
|
||||
FOLD_OP_REF(BinaryExpr::Sub, -, TRef);
|
||||
FOLD_OP_REF(BinaryExpr::Mul, *, TRef);
|
||||
case BinaryExpr::Div:
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (v1[i] == 0) {
|
||||
@@ -2102,8 +2148,8 @@ lConstFoldBinArithOp(BinaryExpr::Op op, const T *v0, const T *v1, ConstExpr *car
|
||||
/** Constant fold the various boolean binary ops.
|
||||
*/
|
||||
static ConstExpr *
|
||||
lConstFoldBoolBinOp(BinaryExpr::Op op, const bool *v0, const bool *v1,
|
||||
ConstExpr *carg0) {
|
||||
lConstFoldBoolBinaryOp(BinaryExpr::Op op, const bool *v0, const bool *v1,
|
||||
ConstExpr *carg0) {
|
||||
bool result[ISPC_MAX_NVEC];
|
||||
int count = carg0->Count();
|
||||
|
||||
@@ -2127,6 +2173,40 @@ lConstFoldBoolBinOp(BinaryExpr::Op op, const bool *v0, const bool *v1,
|
||||
}
|
||||
|
||||
|
||||
template <typename T> static Expr *
|
||||
lConstFoldBinaryFPOp(ConstExpr *constArg0, ConstExpr *constArg1,
|
||||
BinaryExpr::Op op, BinaryExpr *origExpr, SourcePos pos) {
|
||||
T v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
|
||||
constArg0->GetValues(v0);
|
||||
constArg1->GetValues(v1);
|
||||
ConstExpr *ret;
|
||||
if ((ret = lConstFoldBinaryArithOp<T, T>(op, v0, v1, constArg0, pos)) != NULL)
|
||||
return ret;
|
||||
else if ((ret = lConstFoldBinaryLogicalOp(op, v0, v1, constArg0)) != NULL)
|
||||
return ret;
|
||||
else
|
||||
return origExpr;
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename TRef> static Expr *
|
||||
lConstFoldBinaryIntOp(ConstExpr *constArg0, ConstExpr *constArg1,
|
||||
BinaryExpr::Op op, BinaryExpr *origExpr, SourcePos pos) {
|
||||
T v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
|
||||
constArg0->GetValues(v0);
|
||||
constArg1->GetValues(v1);
|
||||
ConstExpr *ret;
|
||||
if ((ret = lConstFoldBinaryArithOp<T, TRef>(op, v0, v1, constArg0, pos)) != NULL)
|
||||
return ret;
|
||||
else if ((ret = lConstFoldBinaryIntOp<T, TRef>(op, v0, v1, constArg0, pos)) != NULL)
|
||||
return ret;
|
||||
else if ((ret = lConstFoldBinaryLogicalOp(op, v0, v1, constArg0)) != NULL)
|
||||
return ret;
|
||||
else
|
||||
return origExpr;
|
||||
}
|
||||
|
||||
|
||||
Expr *
|
||||
BinaryExpr::Optimize() {
|
||||
if (arg0 == NULL || arg1 == NULL)
|
||||
@@ -2144,7 +2224,7 @@ BinaryExpr::Optimize() {
|
||||
if (Type::EqualIgnoringConst(type1, AtomicType::UniformFloat) ||
|
||||
Type::EqualIgnoringConst(type1, AtomicType::VaryingFloat)) {
|
||||
float inv[ISPC_MAX_NVEC];
|
||||
int count = constArg1->AsFloat(inv);
|
||||
int count = constArg1->GetValues(inv);
|
||||
for (int i = 0; i < count; ++i)
|
||||
inv[i] = 1.f / inv[i];
|
||||
Expr *einv = new ConstExpr(type1, inv, constArg1->pos);
|
||||
@@ -2198,70 +2278,53 @@ BinaryExpr::Optimize() {
|
||||
const Type *type = arg0->GetType()->GetAsNonConstType();
|
||||
if (Type::Equal(type, AtomicType::UniformFloat) ||
|
||||
Type::Equal(type, AtomicType::VaryingFloat)) {
|
||||
float v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
|
||||
constArg0->AsFloat(v0);
|
||||
constArg1->AsFloat(v1);
|
||||
ConstExpr *ret;
|
||||
if ((ret = lConstFoldBinArithOp(op, v0, v1, constArg0, pos)) != NULL)
|
||||
return ret;
|
||||
else if ((ret = lConstFoldBinLogicalOp(op, v0, v1, constArg0)) != NULL)
|
||||
return ret;
|
||||
else
|
||||
return this;
|
||||
return lConstFoldBinaryFPOp<float>(constArg0, constArg1, op, this, pos);
|
||||
}
|
||||
if (Type::Equal(type, AtomicType::UniformDouble) ||
|
||||
Type::Equal(type, AtomicType::VaryingDouble)) {
|
||||
double v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
|
||||
constArg0->AsDouble(v0);
|
||||
constArg1->AsDouble(v1);
|
||||
ConstExpr *ret;
|
||||
if ((ret = lConstFoldBinArithOp(op, v0, v1, constArg0, pos)) != NULL)
|
||||
return ret;
|
||||
else if ((ret = lConstFoldBinLogicalOp(op, v0, v1, constArg0)) != NULL)
|
||||
return ret;
|
||||
else
|
||||
return this;
|
||||
else if (Type::Equal(type, AtomicType::UniformDouble) ||
|
||||
Type::Equal(type, AtomicType::VaryingDouble)) {
|
||||
return lConstFoldBinaryFPOp<double>(constArg0, constArg1, op, this, pos);
|
||||
}
|
||||
if (Type::Equal(type, AtomicType::UniformInt32) ||
|
||||
Type::Equal(type, AtomicType::VaryingInt32)) {
|
||||
int32_t v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
|
||||
constArg0->AsInt32(v0);
|
||||
constArg1->AsInt32(v1);
|
||||
ConstExpr *ret;
|
||||
if ((ret = lConstFoldBinArithOp(op, v0, v1, constArg0, pos)) != NULL)
|
||||
return ret;
|
||||
else if ((ret = lConstFoldBinIntOp(op, v0, v1, constArg0)) != NULL)
|
||||
return ret;
|
||||
else if ((ret = lConstFoldBinLogicalOp(op, v0, v1, constArg0)) != NULL)
|
||||
return ret;
|
||||
else
|
||||
return this;
|
||||
else if (Type::Equal(type, AtomicType::UniformInt8) ||
|
||||
Type::Equal(type, AtomicType::VaryingInt8)) {
|
||||
return lConstFoldBinaryIntOp<int8_t, int64_t>(constArg0, constArg1, op, this, pos);
|
||||
}
|
||||
else if (Type::Equal(type, AtomicType::UniformUInt8) ||
|
||||
Type::Equal(type, AtomicType::VaryingUInt8)) {
|
||||
return lConstFoldBinaryIntOp<uint8_t, uint64_t>(constArg0, constArg1, op, this, pos);
|
||||
}
|
||||
else if (Type::Equal(type, AtomicType::UniformInt16) ||
|
||||
Type::Equal(type, AtomicType::VaryingInt16)) {
|
||||
return lConstFoldBinaryIntOp<int16_t, int64_t>(constArg0, constArg1, op, this, pos);
|
||||
}
|
||||
else if (Type::Equal(type, AtomicType::UniformUInt16) ||
|
||||
Type::Equal(type, AtomicType::VaryingUInt16)) {
|
||||
return lConstFoldBinaryIntOp<uint16_t, uint64_t>(constArg0, constArg1, op, this, pos);
|
||||
}
|
||||
else if (Type::Equal(type, AtomicType::UniformInt32) ||
|
||||
Type::Equal(type, AtomicType::VaryingInt32)) {
|
||||
return lConstFoldBinaryIntOp<int32_t, int64_t>(constArg0, constArg1, op, this, pos);
|
||||
}
|
||||
else if (Type::Equal(type, AtomicType::UniformUInt32) ||
|
||||
Type::Equal(type, AtomicType::VaryingUInt32) ||
|
||||
CastType<EnumType>(type) != NULL) {
|
||||
uint32_t v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
|
||||
constArg0->AsUInt32(v0);
|
||||
constArg1->AsUInt32(v1);
|
||||
ConstExpr *ret;
|
||||
if ((ret = lConstFoldBinArithOp(op, v0, v1, constArg0, pos)) != NULL)
|
||||
return ret;
|
||||
else if ((ret = lConstFoldBinIntOp(op, v0, v1, constArg0)) != NULL)
|
||||
return ret;
|
||||
else if ((ret = lConstFoldBinLogicalOp(op, v0, v1, constArg0)) != NULL)
|
||||
return ret;
|
||||
else
|
||||
return this;
|
||||
Type::Equal(type, AtomicType::VaryingUInt32)) {
|
||||
return lConstFoldBinaryIntOp<uint32_t, uint64_t>(constArg0, constArg1, op, this, pos);
|
||||
}
|
||||
else if (Type::Equal(type, AtomicType::UniformInt64) ||
|
||||
Type::Equal(type, AtomicType::VaryingInt64)) {
|
||||
return lConstFoldBinaryIntOp<int64_t, int64_t>(constArg0, constArg1, op, this, pos);
|
||||
}
|
||||
else if (Type::Equal(type, AtomicType::UniformUInt64) ||
|
||||
Type::Equal(type, AtomicType::VaryingUInt64)) {
|
||||
return lConstFoldBinaryIntOp<uint64_t, uint64_t>(constArg0, constArg1, op, this, pos);
|
||||
}
|
||||
else if (Type::Equal(type, AtomicType::UniformBool) ||
|
||||
Type::Equal(type, AtomicType::VaryingBool)) {
|
||||
bool v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
|
||||
constArg0->AsBool(v0);
|
||||
constArg1->AsBool(v1);
|
||||
constArg0->GetValues(v0);
|
||||
constArg1->GetValues(v1);
|
||||
ConstExpr *ret;
|
||||
if ((ret = lConstFoldBoolBinOp(op, v0, v1, constArg0)) != NULL)
|
||||
if ((ret = lConstFoldBoolBinaryOp(op, v0, v1, constArg0)) != NULL)
|
||||
return ret;
|
||||
else if ((ret = lConstFoldBinLogicalOp(op, v0, v1, constArg0)) != NULL)
|
||||
else if ((ret = lConstFoldBinaryLogicalOp(op, v0, v1, constArg0)) != NULL)
|
||||
return ret;
|
||||
else
|
||||
return this;
|
||||
@@ -3159,6 +3222,19 @@ SelectExpr::GetType() const {
|
||||
}
|
||||
|
||||
|
||||
template <typename T> Expr *
|
||||
lConstFoldSelect(const bool bv[], ConstExpr *constExpr1, ConstExpr *constExpr2,
|
||||
const Type *exprType, SourcePos pos) {
|
||||
T v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
|
||||
T result[ISPC_MAX_NVEC];
|
||||
int count = constExpr1->GetValues(v1);
|
||||
constExpr2->GetValues(v2);
|
||||
for (int i = 0; i < count; ++i)
|
||||
result[i] = bv[i] ? v1[i] : v2[i];
|
||||
return new ConstExpr(exprType, result, pos);
|
||||
}
|
||||
|
||||
|
||||
Expr *
|
||||
SelectExpr::Optimize() {
|
||||
if (test == NULL || expr1 == NULL || expr2 == NULL)
|
||||
@@ -3171,7 +3247,7 @@ SelectExpr::Optimize() {
|
||||
// The test is a constant; see if we can resolve to one of the
|
||||
// expressions..
|
||||
bool bv[ISPC_MAX_NVEC];
|
||||
int count = constTest->AsBool(bv);
|
||||
int count = constTest->GetValues(bv);
|
||||
if (count == 1)
|
||||
// Uniform test value; return the corresponding expression
|
||||
return (bv[0] == true) ? expr1 : expr2;
|
||||
@@ -3200,71 +3276,38 @@ SelectExpr::Optimize() {
|
||||
const Type *exprType = constExpr1->GetType()->GetAsNonConstType();
|
||||
AssertPos(pos, exprType->IsVaryingType());
|
||||
|
||||
// FIXME: it's annoying to have to have all of this replicated code.
|
||||
// FIXME: for completeness, it would also be nice to handle 8 and
|
||||
// 16 bit types...
|
||||
if (Type::Equal(exprType, AtomicType::VaryingInt32)) {
|
||||
int32_t v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
|
||||
int32_t result[ISPC_MAX_NVEC];
|
||||
constExpr1->AsInt32(v1);
|
||||
constExpr2->AsInt32(v2);
|
||||
for (int i = 0; i < count; ++i)
|
||||
result[i] = bv[i] ? v1[i] : v2[i];
|
||||
return new ConstExpr(exprType, result, pos);
|
||||
if (Type::Equal(exprType, AtomicType::VaryingInt8)) {
|
||||
return lConstFoldSelect<int8_t>(bv, constExpr1, constExpr2, exprType, pos);
|
||||
}
|
||||
if (Type::Equal(exprType, AtomicType::VaryingUInt32)) {
|
||||
uint32_t v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
|
||||
uint32_t result[ISPC_MAX_NVEC];
|
||||
constExpr1->AsUInt32(v1);
|
||||
constExpr2->AsUInt32(v2);
|
||||
for (int i = 0; i < count; ++i)
|
||||
result[i] = bv[i] ? v1[i] : v2[i];
|
||||
return new ConstExpr(exprType, result, pos);
|
||||
else if (Type::Equal(exprType, AtomicType::VaryingUInt8)) {
|
||||
return lConstFoldSelect<uint8_t>(bv, constExpr1, constExpr2, exprType, pos);
|
||||
}
|
||||
else if (Type::Equal(exprType, AtomicType::VaryingInt16)) {
|
||||
return lConstFoldSelect<int16_t>(bv, constExpr1, constExpr2, exprType, pos);
|
||||
}
|
||||
else if (Type::Equal(exprType, AtomicType::VaryingUInt16)) {
|
||||
return lConstFoldSelect<uint16_t>(bv, constExpr1, constExpr2, exprType, pos);
|
||||
}
|
||||
else if (Type::Equal(exprType, AtomicType::VaryingInt32)) {
|
||||
return lConstFoldSelect<int32_t>(bv, constExpr1, constExpr2, exprType, pos);
|
||||
}
|
||||
else if (Type::Equal(exprType, AtomicType::VaryingUInt32)) {
|
||||
return lConstFoldSelect<uint32_t>(bv, constExpr1, constExpr2, exprType, pos);
|
||||
}
|
||||
else if (Type::Equal(exprType, AtomicType::VaryingInt64)) {
|
||||
int64_t v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
|
||||
int64_t result[ISPC_MAX_NVEC];
|
||||
constExpr1->AsInt64(v1);
|
||||
constExpr2->AsInt64(v2);
|
||||
for (int i = 0; i < count; ++i)
|
||||
result[i] = bv[i] ? v1[i] : v2[i];
|
||||
return new ConstExpr(exprType, result, pos);
|
||||
return lConstFoldSelect<int64_t>(bv, constExpr1, constExpr2, exprType, pos);
|
||||
}
|
||||
else if (Type::Equal(exprType, AtomicType::VaryingUInt64)) {
|
||||
uint64_t v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
|
||||
uint64_t result[ISPC_MAX_NVEC];
|
||||
constExpr1->AsUInt64(v1);
|
||||
constExpr2->AsUInt64(v2);
|
||||
for (int i = 0; i < count; ++i)
|
||||
result[i] = bv[i] ? v1[i] : v2[i];
|
||||
return new ConstExpr(exprType, result, pos);
|
||||
return lConstFoldSelect<uint64_t>(bv, constExpr1, constExpr2, exprType, pos);
|
||||
}
|
||||
else if (Type::Equal(exprType, AtomicType::VaryingFloat)) {
|
||||
float v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
|
||||
float result[ISPC_MAX_NVEC];
|
||||
constExpr1->AsFloat(v1);
|
||||
constExpr2->AsFloat(v2);
|
||||
for (int i = 0; i < count; ++i)
|
||||
result[i] = bv[i] ? v1[i] : v2[i];
|
||||
return new ConstExpr(exprType, result, pos);
|
||||
return lConstFoldSelect<float>(bv, constExpr1, constExpr2, exprType, pos);
|
||||
}
|
||||
else if (Type::Equal(exprType, AtomicType::VaryingDouble)) {
|
||||
double v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
|
||||
double result[ISPC_MAX_NVEC];
|
||||
constExpr1->AsDouble(v1);
|
||||
constExpr2->AsDouble(v2);
|
||||
for (int i = 0; i < count; ++i)
|
||||
result[i] = bv[i] ? v1[i] : v2[i];
|
||||
return new ConstExpr(exprType, result, pos);
|
||||
return lConstFoldSelect<bool>(bv, constExpr1, constExpr2, exprType, pos);
|
||||
}
|
||||
else if (Type::Equal(exprType, AtomicType::VaryingBool)) {
|
||||
bool v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
|
||||
bool result[ISPC_MAX_NVEC];
|
||||
constExpr1->AsBool(v1);
|
||||
constExpr2->AsBool(v2);
|
||||
for (int i = 0; i < count; ++i)
|
||||
result[i] = bv[i] ? v1[i] : v2[i];
|
||||
return new ConstExpr(exprType, result, pos);
|
||||
return lConstFoldSelect<double>(bv, constExpr1, constExpr2, exprType, pos);
|
||||
}
|
||||
|
||||
return this;
|
||||
@@ -4171,7 +4214,7 @@ lCheckIndicesVersusBounds(const Type *baseExprType, Expr *index) {
|
||||
return;
|
||||
|
||||
int32_t indices[ISPC_MAX_NVEC];
|
||||
int count = ce->AsInt32(indices);
|
||||
int count = ce->GetValues(indices);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (indices[i] < 0 || indices[i] >= nElements)
|
||||
Warning(index->pos, "Array index \"%d\" may be out of bounds for %d "
|
||||
@@ -5532,7 +5575,7 @@ lConvert(const From *from, To *to, int count, bool forceVarying) {
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsInt64(int64_t *ip, bool forceVarying) const {
|
||||
ConstExpr::GetValues(int64_t *ip, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, ip, Count(), forceVarying); break;
|
||||
@@ -5553,7 +5596,7 @@ ConstExpr::AsInt64(int64_t *ip, bool forceVarying) const {
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsUInt64(uint64_t *up, bool forceVarying) const {
|
||||
ConstExpr::GetValues(uint64_t *up, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, up, Count(), forceVarying); break;
|
||||
@@ -5574,7 +5617,7 @@ ConstExpr::AsUInt64(uint64_t *up, bool forceVarying) const {
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsDouble(double *d, bool forceVarying) const {
|
||||
ConstExpr::GetValues(double *d, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, d, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, d, Count(), forceVarying); break;
|
||||
@@ -5595,7 +5638,7 @@ ConstExpr::AsDouble(double *d, bool forceVarying) const {
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsFloat(float *fp, bool forceVarying) const {
|
||||
ConstExpr::GetValues(float *fp, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, fp, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, fp, Count(), forceVarying); break;
|
||||
@@ -5616,7 +5659,7 @@ ConstExpr::AsFloat(float *fp, bool forceVarying) const {
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsBool(bool *b, bool forceVarying) const {
|
||||
ConstExpr::GetValues(bool *b, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, b, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, b, Count(), forceVarying); break;
|
||||
@@ -5637,7 +5680,7 @@ ConstExpr::AsBool(bool *b, bool forceVarying) const {
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsInt8(int8_t *ip, bool forceVarying) const {
|
||||
ConstExpr::GetValues(int8_t *ip, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, ip, Count(), forceVarying); break;
|
||||
@@ -5658,7 +5701,7 @@ ConstExpr::AsInt8(int8_t *ip, bool forceVarying) const {
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsUInt8(uint8_t *up, bool forceVarying) const {
|
||||
ConstExpr::GetValues(uint8_t *up, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, up, Count(), forceVarying); break;
|
||||
@@ -5679,7 +5722,7 @@ ConstExpr::AsUInt8(uint8_t *up, bool forceVarying) const {
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsInt16(int16_t *ip, bool forceVarying) const {
|
||||
ConstExpr::GetValues(int16_t *ip, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, ip, Count(), forceVarying); break;
|
||||
@@ -5700,7 +5743,7 @@ ConstExpr::AsInt16(int16_t *ip, bool forceVarying) const {
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsUInt16(uint16_t *up, bool forceVarying) const {
|
||||
ConstExpr::GetValues(uint16_t *up, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, up, Count(), forceVarying); break;
|
||||
@@ -5721,7 +5764,7 @@ ConstExpr::AsUInt16(uint16_t *up, bool forceVarying) const {
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsInt32(int32_t *ip, bool forceVarying) const {
|
||||
ConstExpr::GetValues(int32_t *ip, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, ip, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, ip, Count(), forceVarying); break;
|
||||
@@ -5742,7 +5785,7 @@ ConstExpr::AsInt32(int32_t *ip, bool forceVarying) const {
|
||||
|
||||
|
||||
int
|
||||
ConstExpr::AsUInt32(uint32_t *up, bool forceVarying) const {
|
||||
ConstExpr::GetValues(uint32_t *up, bool forceVarying) const {
|
||||
switch (getBasicType()) {
|
||||
case AtomicType::TYPE_BOOL: lConvert(boolVal, up, Count(), forceVarying); break;
|
||||
case AtomicType::TYPE_INT8: lConvert(int8Val, up, Count(), forceVarying); break;
|
||||
@@ -5779,7 +5822,7 @@ ConstExpr::GetConstant(const Type *type) const {
|
||||
if (Type::Equal(type, AtomicType::UniformBool) ||
|
||||
Type::Equal(type, AtomicType::VaryingBool)) {
|
||||
bool bv[ISPC_MAX_NVEC];
|
||||
AsBool(bv, type->IsVaryingType());
|
||||
GetValues(bv, type->IsVaryingType());
|
||||
if (type->IsUniformType())
|
||||
return bv[0] ? LLVMTrue : LLVMFalse;
|
||||
else
|
||||
@@ -5788,7 +5831,7 @@ ConstExpr::GetConstant(const Type *type) const {
|
||||
else if (Type::Equal(type, AtomicType::UniformInt8) ||
|
||||
Type::Equal(type, AtomicType::VaryingInt8)) {
|
||||
int8_t iv[ISPC_MAX_NVEC];
|
||||
AsInt8(iv, type->IsVaryingType());
|
||||
GetValues(iv, type->IsVaryingType());
|
||||
if (type->IsUniformType())
|
||||
return LLVMInt8(iv[0]);
|
||||
else
|
||||
@@ -5797,7 +5840,7 @@ ConstExpr::GetConstant(const Type *type) const {
|
||||
else if (Type::Equal(type, AtomicType::UniformUInt8) ||
|
||||
Type::Equal(type, AtomicType::VaryingUInt8)) {
|
||||
uint8_t uiv[ISPC_MAX_NVEC];
|
||||
AsUInt8(uiv, type->IsVaryingType());
|
||||
GetValues(uiv, type->IsVaryingType());
|
||||
if (type->IsUniformType())
|
||||
return LLVMUInt8(uiv[0]);
|
||||
else
|
||||
@@ -5806,7 +5849,7 @@ ConstExpr::GetConstant(const Type *type) const {
|
||||
else if (Type::Equal(type, AtomicType::UniformInt16) ||
|
||||
Type::Equal(type, AtomicType::VaryingInt16)) {
|
||||
int16_t iv[ISPC_MAX_NVEC];
|
||||
AsInt16(iv, type->IsVaryingType());
|
||||
GetValues(iv, type->IsVaryingType());
|
||||
if (type->IsUniformType())
|
||||
return LLVMInt16(iv[0]);
|
||||
else
|
||||
@@ -5815,7 +5858,7 @@ ConstExpr::GetConstant(const Type *type) const {
|
||||
else if (Type::Equal(type, AtomicType::UniformUInt16) ||
|
||||
Type::Equal(type, AtomicType::VaryingUInt16)) {
|
||||
uint16_t uiv[ISPC_MAX_NVEC];
|
||||
AsUInt16(uiv, type->IsVaryingType());
|
||||
GetValues(uiv, type->IsVaryingType());
|
||||
if (type->IsUniformType())
|
||||
return LLVMUInt16(uiv[0]);
|
||||
else
|
||||
@@ -5824,7 +5867,7 @@ ConstExpr::GetConstant(const Type *type) const {
|
||||
else if (Type::Equal(type, AtomicType::UniformInt32) ||
|
||||
Type::Equal(type, AtomicType::VaryingInt32)) {
|
||||
int32_t iv[ISPC_MAX_NVEC];
|
||||
AsInt32(iv, type->IsVaryingType());
|
||||
GetValues(iv, type->IsVaryingType());
|
||||
if (type->IsUniformType())
|
||||
return LLVMInt32(iv[0]);
|
||||
else
|
||||
@@ -5834,7 +5877,7 @@ ConstExpr::GetConstant(const Type *type) const {
|
||||
Type::Equal(type, AtomicType::VaryingUInt32) ||
|
||||
CastType<EnumType>(type) != NULL) {
|
||||
uint32_t uiv[ISPC_MAX_NVEC];
|
||||
AsUInt32(uiv, type->IsVaryingType());
|
||||
GetValues(uiv, type->IsVaryingType());
|
||||
if (type->IsUniformType())
|
||||
return LLVMUInt32(uiv[0]);
|
||||
else
|
||||
@@ -5843,7 +5886,7 @@ ConstExpr::GetConstant(const Type *type) const {
|
||||
else if (Type::Equal(type, AtomicType::UniformFloat) ||
|
||||
Type::Equal(type, AtomicType::VaryingFloat)) {
|
||||
float fv[ISPC_MAX_NVEC];
|
||||
AsFloat(fv, type->IsVaryingType());
|
||||
GetValues(fv, type->IsVaryingType());
|
||||
if (type->IsUniformType())
|
||||
return LLVMFloat(fv[0]);
|
||||
else
|
||||
@@ -5852,7 +5895,7 @@ ConstExpr::GetConstant(const Type *type) const {
|
||||
else if (Type::Equal(type, AtomicType::UniformInt64) ||
|
||||
Type::Equal(type, AtomicType::VaryingInt64)) {
|
||||
int64_t iv[ISPC_MAX_NVEC];
|
||||
AsInt64(iv, type->IsVaryingType());
|
||||
GetValues(iv, type->IsVaryingType());
|
||||
if (type->IsUniformType())
|
||||
return LLVMInt64(iv[0]);
|
||||
else
|
||||
@@ -5861,7 +5904,7 @@ ConstExpr::GetConstant(const Type *type) const {
|
||||
else if (Type::Equal(type, AtomicType::UniformUInt64) ||
|
||||
Type::Equal(type, AtomicType::VaryingUInt64)) {
|
||||
uint64_t uiv[ISPC_MAX_NVEC];
|
||||
AsUInt64(uiv, type->IsVaryingType());
|
||||
GetValues(uiv, type->IsVaryingType());
|
||||
if (type->IsUniformType())
|
||||
return LLVMUInt64(uiv[0]);
|
||||
else
|
||||
@@ -5870,7 +5913,7 @@ ConstExpr::GetConstant(const Type *type) const {
|
||||
else if (Type::Equal(type, AtomicType::UniformDouble) ||
|
||||
Type::Equal(type, AtomicType::VaryingDouble)) {
|
||||
double dv[ISPC_MAX_NVEC];
|
||||
AsDouble(dv, type->IsVaryingType());
|
||||
GetValues(dv, type->IsVaryingType());
|
||||
if (type->IsUniformType())
|
||||
return LLVMDouble(dv[0]);
|
||||
else
|
||||
@@ -5887,7 +5930,7 @@ ConstExpr::GetConstant(const Type *type) const {
|
||||
}
|
||||
|
||||
int64_t iv[ISPC_MAX_NVEC];
|
||||
AsInt64(iv, type->IsVaryingType());
|
||||
GetValues(iv, type->IsVaryingType());
|
||||
for (int i = 0; i < Count(); ++i)
|
||||
if (iv[i] != 0)
|
||||
// We'll issue an error about this later--trying to assign
|
||||
@@ -6976,64 +7019,64 @@ TypeCastExpr::Optimize() {
|
||||
bool forceVarying = toType->IsVaryingType();
|
||||
|
||||
// All of the type conversion smarts we need is already in the
|
||||
// ConstExpr::AsBool(), etc., methods, so we just need to call the
|
||||
// ConstExpr::GetValues(), etc., methods, so we just need to call the
|
||||
// appropriate one for the type that this cast is converting to.
|
||||
AtomicType::BasicType basicType = toAtomic ? toAtomic->basicType :
|
||||
AtomicType::TYPE_UINT32;
|
||||
switch (basicType) {
|
||||
case AtomicType::TYPE_BOOL: {
|
||||
bool bv[ISPC_MAX_NVEC];
|
||||
constExpr->AsBool(bv, forceVarying);
|
||||
constExpr->GetValues(bv, forceVarying);
|
||||
return new ConstExpr(toType, bv, pos);
|
||||
}
|
||||
case AtomicType::TYPE_INT8: {
|
||||
int8_t iv[ISPC_MAX_NVEC];
|
||||
constExpr->AsInt8(iv, forceVarying);
|
||||
constExpr->GetValues(iv, forceVarying);
|
||||
return new ConstExpr(toType, iv, pos);
|
||||
}
|
||||
case AtomicType::TYPE_UINT8: {
|
||||
uint8_t uv[ISPC_MAX_NVEC];
|
||||
constExpr->AsUInt8(uv, forceVarying);
|
||||
constExpr->GetValues(uv, forceVarying);
|
||||
return new ConstExpr(toType, uv, pos);
|
||||
}
|
||||
case AtomicType::TYPE_INT16: {
|
||||
int16_t iv[ISPC_MAX_NVEC];
|
||||
constExpr->AsInt16(iv, forceVarying);
|
||||
constExpr->GetValues(iv, forceVarying);
|
||||
return new ConstExpr(toType, iv, pos);
|
||||
}
|
||||
case AtomicType::TYPE_UINT16: {
|
||||
uint16_t uv[ISPC_MAX_NVEC];
|
||||
constExpr->AsUInt16(uv, forceVarying);
|
||||
constExpr->GetValues(uv, forceVarying);
|
||||
return new ConstExpr(toType, uv, pos);
|
||||
}
|
||||
case AtomicType::TYPE_INT32: {
|
||||
int32_t iv[ISPC_MAX_NVEC];
|
||||
constExpr->AsInt32(iv, forceVarying);
|
||||
constExpr->GetValues(iv, forceVarying);
|
||||
return new ConstExpr(toType, iv, pos);
|
||||
}
|
||||
case AtomicType::TYPE_UINT32: {
|
||||
uint32_t uv[ISPC_MAX_NVEC];
|
||||
constExpr->AsUInt32(uv, forceVarying);
|
||||
constExpr->GetValues(uv, forceVarying);
|
||||
return new ConstExpr(toType, uv, pos);
|
||||
}
|
||||
case AtomicType::TYPE_FLOAT: {
|
||||
float fv[ISPC_MAX_NVEC];
|
||||
constExpr->AsFloat(fv, forceVarying);
|
||||
constExpr->GetValues(fv, forceVarying);
|
||||
return new ConstExpr(toType, fv, pos);
|
||||
}
|
||||
case AtomicType::TYPE_INT64: {
|
||||
int64_t iv[ISPC_MAX_NVEC];
|
||||
constExpr->AsInt64(iv, forceVarying);
|
||||
constExpr->GetValues(iv, forceVarying);
|
||||
return new ConstExpr(toType, iv, pos);
|
||||
}
|
||||
case AtomicType::TYPE_UINT64: {
|
||||
uint64_t uv[ISPC_MAX_NVEC];
|
||||
constExpr->AsUInt64(uv, forceVarying);
|
||||
constExpr->GetValues(uv, forceVarying);
|
||||
return new ConstExpr(toType, uv, pos);
|
||||
}
|
||||
case AtomicType::TYPE_DOUBLE: {
|
||||
double dv[ISPC_MAX_NVEC];
|
||||
constExpr->AsDouble(dv, forceVarying);
|
||||
constExpr->GetValues(dv, forceVarying);
|
||||
return new ConstExpr(toType, dv, pos);
|
||||
}
|
||||
default:
|
||||
|
||||
81
expr.h
81
expr.h
@@ -409,71 +409,22 @@ public:
|
||||
Expr *Optimize();
|
||||
int EstimateCost() const;
|
||||
|
||||
/** Return the ConstExpr's values as booleans, doing type conversion
|
||||
from the actual type if needed. If forceVarying is true, then type
|
||||
convert to 'varying' so as to always return a number of values
|
||||
equal to the target vector width into the given pointer. */
|
||||
int AsBool(bool *, bool forceVarying = false) const;
|
||||
|
||||
/** Return the ConstExpr's values as int8s, doing type conversion
|
||||
from the actual type if needed. If forceVarying is true, then type
|
||||
convert to 'varying' so as to always return a number of values
|
||||
equal to the target vector width into the given pointer. */
|
||||
int AsInt8(int8_t *, bool forceVarying = false) const;
|
||||
|
||||
/** Return the ConstExpr's values as uint8s, doing type conversion
|
||||
from the actual type if needed. If forceVarying is true, then type
|
||||
convert to 'varying' so as to always return a number of values
|
||||
equal to the target vector width into the given pointer. */
|
||||
int AsUInt8(uint8_t *, bool forceVarying = false) const;
|
||||
|
||||
/** Return the ConstExpr's values as int16s, doing type conversion
|
||||
from the actual type if needed. If forceVarying is true, then type
|
||||
convert to 'varying' so as to always return a number of values
|
||||
equal to the target vector width into the given pointer. */
|
||||
int AsInt16(int16_t *, bool forceVarying = false) const;
|
||||
|
||||
/** Return the ConstExpr's values as uint16s, doing type conversion
|
||||
from the actual type if needed. If forceVarying is true, then type
|
||||
convert to 'varying' so as to always return a number of values
|
||||
equal to the target vector width into the given pointer. */
|
||||
int AsUInt16(uint16_t *, bool forceVarying = false) const;
|
||||
|
||||
/** Return the ConstExpr's values as int32s, doing type conversion
|
||||
from the actual type if needed. If forceVarying is true, then type
|
||||
convert to 'varying' so as to always return a number of values
|
||||
equal to the target vector width into the given pointer. */
|
||||
int AsInt32(int32_t *, bool forceVarying = false) const;
|
||||
|
||||
/** Return the ConstExpr's values as uint32s, doing type conversion
|
||||
from the actual type if needed. If forceVarying is true, then type
|
||||
convert to 'varying' so as to always return a number of values
|
||||
equal to the target vector width into the given pointer. */
|
||||
int AsUInt32(uint32_t *, bool forceVarying = false) const;
|
||||
|
||||
/** Return the ConstExpr's values as floats, doing type conversion
|
||||
from the actual type if needed. If forceVarying is true, then type
|
||||
convert to 'varying' so as to always return a number of values
|
||||
equal to the target vector width into the given pointer. */
|
||||
int AsFloat(float *, bool forceVarying = false) const;
|
||||
|
||||
/** Return the ConstExpr's values as int64s, doing type conversion
|
||||
from the actual type if needed. If forceVarying is true, then type
|
||||
convert to 'varying' so as to always return a number of values
|
||||
equal to the target vector width into the given pointer. */
|
||||
int AsInt64(int64_t *, bool forceVarying = false) const;
|
||||
|
||||
/** Return the ConstExpr's values as uint64s, doing type conversion
|
||||
from the actual type if needed. If forceVarying is true, then type
|
||||
convert to 'varying' so as to always return a number of values
|
||||
equal to the target vector width into the given pointer. */
|
||||
int AsUInt64(uint64_t *, bool forceVarying = false) const;
|
||||
|
||||
/** Return the ConstExpr's values as doubles, doing type conversion
|
||||
from the actual type if needed. If forceVarying is true, then type
|
||||
convert to 'varying' so as to always return a number of values
|
||||
equal to the target vector width into the given pointer. */
|
||||
int AsDouble(double *, bool forceVarying = false) const;
|
||||
/** Return the ConstExpr's values as the given pointer type, doing type
|
||||
conversion from the actual type if needed. If forceVarying is
|
||||
true, then type convert to 'varying' so as to always return a
|
||||
number of values equal to the target vector width into the given
|
||||
pointer. */
|
||||
int GetValues(bool *, bool forceVarying = false) const;
|
||||
int GetValues(int8_t *, bool forceVarying = false) const;
|
||||
int GetValues(uint8_t *, bool forceVarying = false) const;
|
||||
int GetValues(int16_t *, bool forceVarying = false) const;
|
||||
int GetValues(uint16_t *, bool forceVarying = false) const;
|
||||
int GetValues(int32_t *, bool forceVarying = false) const;
|
||||
int GetValues(uint32_t *, bool forceVarying = false) const;
|
||||
int GetValues(float *, bool forceVarying = false) const;
|
||||
int GetValues(int64_t *, bool forceVarying = false) const;
|
||||
int GetValues(uint64_t *, bool forceVarying = false) const;
|
||||
int GetValues(double *, bool forceVarying = false) const;
|
||||
|
||||
/** Return the number of values in the ConstExpr; should be either 1,
|
||||
if it has uniform type, or the target's vector width if it's
|
||||
|
||||
@@ -1196,7 +1196,7 @@ lEmitEnumDecls(const std::vector<const EnumType *> &enumTypes, FILE *file) {
|
||||
const Symbol *e = enumTypes[i]->GetEnumerator(j);
|
||||
Assert(e->constValue != NULL);
|
||||
unsigned int enumValue;
|
||||
int count = e->constValue->AsUInt32(&enumValue);
|
||||
int count = e->constValue->GetValues(&enumValue);
|
||||
Assert(count == 1);
|
||||
|
||||
// Always print an initializer to set the value. We could be
|
||||
|
||||
2
parse.yy
2
parse.yy
@@ -2287,7 +2287,7 @@ lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums,
|
||||
enums[i]->type = enumType;
|
||||
if (enums[i]->constValue != NULL) {
|
||||
/* Already has a value, so first update nextVal with it. */
|
||||
int count = enums[i]->constValue->AsUInt32(&nextVal);
|
||||
int count = enums[i]->constValue->GetValues(&nextVal);
|
||||
AssertPos(enums[i]->pos, count == 1);
|
||||
++nextVal;
|
||||
|
||||
|
||||
3
tests_errors/const-too-large.ispc
Normal file
3
tests_errors/const-too-large.ispc
Normal file
@@ -0,0 +1,3 @@
|
||||
// Binary expression with type "const uniform int8" can't represent value.
|
||||
|
||||
int8 v = (int8)64 * (int8)32;
|
||||
2
type.cpp
2
type.cpp
@@ -804,7 +804,7 @@ EnumType::GetDIType(llvm::DIDescriptor scope) const {
|
||||
for (unsigned int i = 0; i < enumerators.size(); ++i) {
|
||||
unsigned int enumeratorValue;
|
||||
Assert(enumerators[i]->constValue != NULL);
|
||||
int count = enumerators[i]->constValue->AsUInt32(&enumeratorValue);
|
||||
int count = enumerators[i]->constValue->GetValues(&enumeratorValue);
|
||||
Assert(count == 1);
|
||||
|
||||
llvm::Value *descriptor =
|
||||
|
||||
Reference in New Issue
Block a user