Require Type::Equal() for all type equality comparisons.

Previously, we uniqued AtomicTypes, so that they could be compared
by pointer equality, but with forthcoming SOA variability changes,
this would become too unwieldy (lacking a more general / ubiquitous
type uniquing implementation.)
This commit is contained in:
Matt Pharr
2012-03-05 06:40:34 -08:00
parent e482d29951
commit 3082ea4765
11 changed files with 299 additions and 462 deletions

View File

@@ -627,7 +627,8 @@ AddBitcodeToModule(const unsigned char *bitcode, int length,
static void static void
lDefineConstantInt(const char *name, int val, llvm::Module *module, lDefineConstantInt(const char *name, int val, llvm::Module *module,
SymbolTable *symbolTable) { SymbolTable *symbolTable) {
Symbol *pw = new Symbol(name, SourcePos(), AtomicType::UniformConstInt32, Symbol *pw =
new Symbol(name, SourcePos(), AtomicType::UniformInt32->GetAsConstType(),
SC_STATIC); SC_STATIC);
pw->constValue = new ConstExpr(pw->type, val, SourcePos()); pw->constValue = new ConstExpr(pw->type, val, SourcePos());
LLVM_TYPE_CONST llvm::Type *ltype = LLVMTypes::Int32Type; LLVM_TYPE_CONST llvm::Type *ltype = LLVMTypes::Int32Type;
@@ -661,8 +662,9 @@ lDefineConstantIntFunc(const char *name, int val, llvm::Module *module,
static void static void
lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable) { lDefineProgramIndex(llvm::Module *module, SymbolTable *symbolTable) {
Symbol *pidx = new Symbol("programIndex", SourcePos(), Symbol *pidx =
AtomicType::VaryingConstInt32, SC_STATIC); new Symbol("programIndex", SourcePos(),
AtomicType::VaryingInt32->GetAsConstType(), SC_STATIC);
int pi[ISPC_MAX_NVEC]; int pi[ISPC_MAX_NVEC];
for (int i = 0; i < g->target.vectorWidth; ++i) for (int i = 0; i < g->target.vectorWidth; ++i)

32
ctx.cpp
View File

@@ -246,7 +246,7 @@ FunctionEmitContext::FunctionEmitContext(Function *func, Symbol *funSym,
launchGroupHandlePtr); launchGroupHandlePtr);
const Type *returnType = function->GetReturnType(); const Type *returnType = function->GetReturnType();
if (!returnType || returnType == AtomicType::Void) if (!returnType || Type::Equal(returnType, AtomicType::Void))
returnValuePtr = NULL; returnValuePtr = NULL;
else { else {
LLVM_TYPE_CONST llvm::Type *ftype = returnType->LLVMType(g->ctx); LLVM_TYPE_CONST llvm::Type *ftype = returnType->LLVMType(g->ctx);
@@ -1144,7 +1144,7 @@ FunctionEmitContext::GetLabeledBasicBlock(const std::string &label) {
void void
FunctionEmitContext::CurrentLanesReturned(Expr *expr, bool doCoherenceCheck) { FunctionEmitContext::CurrentLanesReturned(Expr *expr, bool doCoherenceCheck) {
const Type *returnType = function->GetReturnType(); const Type *returnType = function->GetReturnType();
if (returnType == AtomicType::Void) { if (Type::Equal(returnType, AtomicType::Void)) {
if (expr != NULL) if (expr != NULL)
Error(expr->pos, "Can't return non-void type \"%s\" from void function.", Error(expr->pos, "Can't return non-void type \"%s\" from void function.",
expr->GetType()->GetString().c_str()); expr->GetType()->GetString().c_str());
@@ -2325,7 +2325,7 @@ FunctionEmitContext::maskedStore(llvm::Value *value, llvm::Value *ptr,
else else
maskedStoreFunc = m->module->getFunction("__pseudo_masked_store_64"); maskedStoreFunc = m->module->getFunction("__pseudo_masked_store_64");
} }
else if (valueType == AtomicType::VaryingBool && else if (Type::Equal(valueType, AtomicType::VaryingBool) &&
g->target.maskBitCount == 1) { g->target.maskBitCount == 1) {
llvm::Value *notMask = BinaryOperator(llvm::Instruction::Xor, mask, llvm::Value *notMask = BinaryOperator(llvm::Instruction::Xor, mask,
LLVMMaskAllOn, "~mask"); LLVMMaskAllOn, "~mask");
@@ -2339,35 +2339,35 @@ FunctionEmitContext::maskedStore(llvm::Value *value, llvm::Value *ptr,
StoreInst(final, ptr); StoreInst(final, ptr);
return; return;
} }
else if (valueType == AtomicType::VaryingDouble || else if (Type::Equal(valueType, AtomicType::VaryingDouble) ||
valueType == AtomicType::VaryingInt64 || Type::Equal(valueType, AtomicType::VaryingInt64) ||
valueType == AtomicType::VaryingUInt64) { Type::Equal(valueType, AtomicType::VaryingUInt64)) {
maskedStoreFunc = m->module->getFunction("__pseudo_masked_store_64"); maskedStoreFunc = m->module->getFunction("__pseudo_masked_store_64");
ptr = BitCastInst(ptr, LLVMTypes::Int64VectorPointerType, ptr = BitCastInst(ptr, LLVMTypes::Int64VectorPointerType,
"ptr_to_int64vecptr"); "ptr_to_int64vecptr");
value = BitCastInst(value, LLVMTypes::Int64VectorType, value = BitCastInst(value, LLVMTypes::Int64VectorType,
"value_to_int64"); "value_to_int64");
} }
else if (valueType == AtomicType::VaryingFloat || else if (Type::Equal(valueType, AtomicType::VaryingFloat) ||
valueType == AtomicType::VaryingBool || Type::Equal(valueType, AtomicType::VaryingBool) ||
valueType == AtomicType::VaryingInt32 || Type::Equal(valueType, AtomicType::VaryingInt32) ||
valueType == AtomicType::VaryingUInt32 || Type::Equal(valueType, AtomicType::VaryingUInt32) ||
dynamic_cast<const EnumType *>(valueType) != NULL) { dynamic_cast<const EnumType *>(valueType) != NULL) {
maskedStoreFunc = m->module->getFunction("__pseudo_masked_store_32"); maskedStoreFunc = m->module->getFunction("__pseudo_masked_store_32");
ptr = BitCastInst(ptr, LLVMTypes::Int32VectorPointerType, ptr = BitCastInst(ptr, LLVMTypes::Int32VectorPointerType,
"ptr_to_int32vecptr"); "ptr_to_int32vecptr");
if (valueType == AtomicType::VaryingFloat) if (Type::Equal(valueType, AtomicType::VaryingFloat))
value = BitCastInst(value, LLVMTypes::Int32VectorType, value = BitCastInst(value, LLVMTypes::Int32VectorType,
"value_to_int32"); "value_to_int32");
} }
else if (valueType == AtomicType::VaryingInt16 || else if (Type::Equal(valueType, AtomicType::VaryingInt16) ||
valueType == AtomicType::VaryingUInt16) { Type::Equal(valueType, AtomicType::VaryingUInt16)) {
maskedStoreFunc = m->module->getFunction("__pseudo_masked_store_16"); maskedStoreFunc = m->module->getFunction("__pseudo_masked_store_16");
ptr = BitCastInst(ptr, LLVMTypes::Int16VectorPointerType, ptr = BitCastInst(ptr, LLVMTypes::Int16VectorPointerType,
"ptr_to_int16vecptr"); "ptr_to_int16vecptr");
} }
else if (valueType == AtomicType::VaryingInt8 || else if (Type::Equal(valueType, AtomicType::VaryingInt8) ||
valueType == AtomicType::VaryingUInt8) { Type::Equal(valueType, AtomicType::VaryingUInt8)) {
maskedStoreFunc = m->module->getFunction("__pseudo_masked_store_8"); maskedStoreFunc = m->module->getFunction("__pseudo_masked_store_8");
ptr = BitCastInst(ptr, LLVMTypes::Int8VectorPointerType, ptr = BitCastInst(ptr, LLVMTypes::Int8VectorPointerType,
"ptr_to_int8vecptr"); "ptr_to_int8vecptr");
@@ -2892,7 +2892,7 @@ FunctionEmitContext::ReturnInst() {
rinst = llvm::ReturnInst::Create(*g->ctx, retVal, bblock); rinst = llvm::ReturnInst::Create(*g->ctx, retVal, bblock);
} }
else { else {
Assert(function->GetReturnType() == AtomicType::Void); Assert(Type::Equal(function->GetReturnType(), AtomicType::Void));
rinst = llvm::ReturnInst::Create(*g->ctx, bblock); rinst = llvm::ReturnInst::Create(*g->ctx, bblock);
} }

View File

@@ -70,19 +70,19 @@ lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) {
type = type->GetAsConstType(); type = type->GetAsConstType();
if ((typeQualifiers & TYPEQUAL_UNIFORM) != 0) { if ((typeQualifiers & TYPEQUAL_UNIFORM) != 0) {
if (type == AtomicType::Void) if (Type::Equal(type, AtomicType::Void))
Error(pos, "\"uniform\" qualifier is illegal with \"void\" type."); Error(pos, "\"uniform\" qualifier is illegal with \"void\" type.");
else else
type = type->GetAsUniformType(); type = type->GetAsUniformType();
} }
else if ((typeQualifiers & TYPEQUAL_VARYING) != 0) { else if ((typeQualifiers & TYPEQUAL_VARYING) != 0) {
if (type == AtomicType::Void) if (Type::Equal(type, AtomicType::Void))
Error(pos, "\"varying\" qualifier is illegal with \"void\" type."); Error(pos, "\"varying\" qualifier is illegal with \"void\" type.");
else else
type = type->GetAsVaryingType(); type = type->GetAsVaryingType();
} }
else else
if (type != AtomicType::Void) if (Type::Equal(type, AtomicType::Void) == false)
type = type->GetAsUnboundVariabilityType(); type = type->GetAsUnboundVariabilityType();
if ((typeQualifiers & TYPEQUAL_UNSIGNED) != 0) { if ((typeQualifiers & TYPEQUAL_UNSIGNED) != 0) {
@@ -121,24 +121,25 @@ DeclSpecs::DeclSpecs(const Type *t, StorageClass sc, int tq) {
const Type * const Type *
DeclSpecs::GetBaseType(SourcePos pos) const { DeclSpecs::GetBaseType(SourcePos pos) const {
const Type *bt = baseType; const Type *retType = baseType;
if (bt == NULL) { if (retType == NULL) {
Warning(pos, "No type specified in declaration. Assuming int32."); Warning(pos, "No type specified in declaration. Assuming int32.");
bt = AtomicType::UnboundInt32; retType = AtomicType::UniformInt32->GetAsUnboundVariabilityType();
} }
if (vectorSize > 0) { if (vectorSize > 0) {
const AtomicType *atomicType = dynamic_cast<const AtomicType *>(bt); const AtomicType *atomicType = dynamic_cast<const AtomicType *>(retType);
if (atomicType == NULL) { if (atomicType == NULL) {
Error(pos, "Only atomic types (int, float, ...) are legal for vector " Error(pos, "Only atomic types (int, float, ...) are legal for vector "
"types."); "types.");
return NULL; return NULL;
} }
bt = new VectorType(atomicType, vectorSize); retType = new VectorType(atomicType, vectorSize);
} }
return lApplyTypeQualifiers(typeQualifiers, bt, pos); retType = lApplyTypeQualifiers(typeQualifiers, retType, pos);
return retType;
} }
@@ -360,7 +361,7 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const {
break; break;
case DK_ARRAY: case DK_ARRAY:
if (type == AtomicType::Void) { if (Type::Equal(type, AtomicType::Void)) {
Error(pos, "Arrays of \"void\" type are illegal."); Error(pos, "Arrays of \"void\" type are illegal.");
return NULL; return NULL;
} }
@@ -396,7 +397,7 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const {
"function parameter declaration for parameter \"%s\".", "function parameter declaration for parameter \"%s\".",
lGetStorageClassName(d->declSpecs->storageClass), lGetStorageClassName(d->declSpecs->storageClass),
sym->name.c_str()); sym->name.c_str());
if (sym->type == AtomicType::Void) { if (Type::Equal(sym->type, AtomicType::Void)) {
Error(sym->pos, "Parameter with type \"void\" illegal in function " Error(sym->pos, "Parameter with type \"void\" illegal in function "
"parameter list."); "parameter list.");
sym->type = NULL; sym->type = NULL;
@@ -588,7 +589,7 @@ Declaration::GetVariableDeclarations() const {
} }
sym->type = sym->type->ResolveUnboundVariability(Type::Varying); sym->type = sym->type->ResolveUnboundVariability(Type::Varying);
if (sym->type == AtomicType::Void) if (Type::Equal(sym->type, AtomicType::Void))
Error(sym->pos, "\"void\" type variable illegal in declaration."); Error(sym->pos, "\"void\" type variable illegal in declaration.");
else if (dynamic_cast<const FunctionType *>(sym->type) == NULL) { else if (dynamic_cast<const FunctionType *>(sym->type) == NULL) {
m->symbolTable->AddVariable(sym); m->symbolTable->AddVariable(sym);
@@ -664,7 +665,7 @@ GetStructTypesNamesPositions(const std::vector<StructDeclaration *> &sd,
Symbol *sym = d->GetSymbol(); Symbol *sym = d->GetSymbol();
if (sym->type == AtomicType::Void) if (Type::Equal(sym->type, AtomicType::Void))
Error(d->pos, "\"void\" type illegal for struct member."); Error(d->pos, "\"void\" type illegal for struct member.");
const ArrayType *arrayType = const ArrayType *arrayType =

188
expr.cpp
View File

@@ -197,14 +197,14 @@ lDoTypeConv(const Type *fromType, const Type *toType, Expr **expr,
if (Type::Equal(toType, fromType)) if (Type::Equal(toType, fromType))
return true; return true;
if (fromType == AtomicType::Void) { if (Type::Equal(fromType, AtomicType::Void)) {
if (!failureOk) if (!failureOk)
Error(pos, "Can't convert from \"void\" to \"%s\" for %s.", Error(pos, "Can't convert from \"void\" to \"%s\" for %s.",
toType->GetString().c_str(), errorMsgBase); toType->GetString().c_str(), errorMsgBase);
return false; return false;
} }
if (toType == AtomicType::Void) { if (Type::Equal(toType, AtomicType::Void)) {
if (!failureOk) if (!failureOk)
Error(pos, "Can't convert type \"%s\" to \"void\" for %s.", Error(pos, "Can't convert type \"%s\" to \"void\" for %s.",
fromType->GetString().c_str(), errorMsgBase); fromType->GetString().c_str(), errorMsgBase);
@@ -1078,12 +1078,12 @@ UnaryExpr::Optimize() {
bool isEnumType = dynamic_cast<const EnumType *>(type) != NULL; bool isEnumType = dynamic_cast<const EnumType *>(type) != NULL;
const Type *baseType = type->GetAsNonConstType()->GetAsUniformType(); const Type *baseType = type->GetAsNonConstType()->GetAsUniformType();
if (baseType == AtomicType::UniformInt8 || if (Type::Equal(baseType, AtomicType::UniformInt8) ||
baseType == AtomicType::UniformUInt8 || Type::Equal(baseType, AtomicType::UniformUInt8) ||
baseType == AtomicType::UniformInt16 || Type::Equal(baseType, AtomicType::UniformInt16) ||
baseType == AtomicType::UniformUInt16 || Type::Equal(baseType, AtomicType::UniformUInt16) ||
baseType == AtomicType::UniformInt64 || Type::Equal(baseType, AtomicType::UniformInt64) ||
baseType == AtomicType::UniformUInt64) Type::Equal(baseType, AtomicType::UniformUInt64))
// FIXME: should handle these at some point; for now we only do // FIXME: should handle these at some point; for now we only do
// constant folding for bool, int32 and float types... // constant folding for bool, int32 and float types...
return this; return this;
@@ -1108,20 +1108,16 @@ UnaryExpr::Optimize() {
return new ConstExpr(constExpr, v); return new ConstExpr(constExpr, v);
} }
case BitNot: { case BitNot: {
if (type == AtomicType::UniformInt32 || if (Type::EqualIgnoringConst(type, AtomicType::UniformInt32) ||
type == AtomicType::VaryingInt32 || Type::EqualIgnoringConst(type, AtomicType::VaryingInt32)) {
type == AtomicType::UniformConstInt32 ||
type == AtomicType::VaryingConstInt32) {
int32_t v[ISPC_MAX_NVEC]; int32_t v[ISPC_MAX_NVEC];
int count = constExpr->AsInt32(v); int count = constExpr->AsInt32(v);
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
v[i] = ~v[i]; v[i] = ~v[i];
return new ConstExpr(type, v, pos); return new ConstExpr(type, v, pos);
} }
else if (type == AtomicType::UniformUInt32 || else if (Type::EqualIgnoringConst(type, AtomicType::UniformUInt32) ||
type == AtomicType::VaryingUInt32 || Type::EqualIgnoringConst(type, AtomicType::VaryingUInt32) ||
type == AtomicType::UniformConstUInt32 ||
type == AtomicType::VaryingConstUInt32 ||
isEnumType == true) { isEnumType == true) {
uint32_t v[ISPC_MAX_NVEC]; uint32_t v[ISPC_MAX_NVEC];
int count = constExpr->AsUInt32(v); int count = constExpr->AsUInt32(v);
@@ -1133,10 +1129,8 @@ UnaryExpr::Optimize() {
FATAL("unexpected type in UnaryExpr::Optimize() / BitNot case"); FATAL("unexpected type in UnaryExpr::Optimize() / BitNot case");
} }
case LogicalNot: { case LogicalNot: {
Assert(type == AtomicType::UniformBool || Assert(Type::EqualIgnoringConst(type, AtomicType::UniformBool) ||
type == AtomicType::VaryingBool || Type::EqualIgnoringConst(type, AtomicType::VaryingBool));
type == AtomicType::UniformConstBool ||
type == AtomicType::VaryingConstBool);
bool v[ISPC_MAX_NVEC]; bool v[ISPC_MAX_NVEC];
int count = constExpr->AsBool(v); int count = constExpr->AsBool(v);
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
@@ -1983,10 +1977,8 @@ BinaryExpr::Optimize() {
// transform x / const -> x * (1/const) // transform x / const -> x * (1/const)
if (op == Div && constArg1 != NULL) { if (op == Div && constArg1 != NULL) {
const Type *type1 = constArg1->GetType(); const Type *type1 = constArg1->GetType();
if (Type::Equal(type1, AtomicType::UniformFloat) || if (Type::EqualIgnoringConst(type1, AtomicType::UniformFloat) ||
Type::Equal(type1, AtomicType::VaryingFloat) || Type::EqualIgnoringConst(type1, AtomicType::VaryingFloat)) {
Type::Equal(type1, AtomicType::UniformConstFloat) ||
Type::Equal(type1, AtomicType::VaryingConstFloat)) {
float inv[ISPC_MAX_NVEC]; float inv[ISPC_MAX_NVEC];
int count = constArg1->AsFloat(inv); int count = constArg1->AsFloat(inv);
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
@@ -2003,10 +1995,8 @@ BinaryExpr::Optimize() {
// transform x / y -> x * rcp(y) // transform x / y -> x * rcp(y)
if (op == Div) { if (op == Div) {
const Type *type1 = arg1->GetType(); const Type *type1 = arg1->GetType();
if (Type::Equal(type1, AtomicType::UniformFloat) || if (Type::EqualIgnoringConst(type1, AtomicType::UniformFloat) ||
Type::Equal(type1, AtomicType::VaryingFloat) || Type::EqualIgnoringConst(type1, AtomicType::VaryingFloat)) {
Type::Equal(type1, AtomicType::UniformConstFloat) ||
Type::Equal(type1, AtomicType::VaryingConstFloat)) {
// Get the symbol for the appropriate builtin // Get the symbol for the appropriate builtin
std::vector<Symbol *> rcpFuns; std::vector<Symbol *> rcpFuns;
m->symbolTable->LookupFunction("rcp", &rcpFuns); m->symbolTable->LookupFunction("rcp", &rcpFuns);
@@ -2043,7 +2033,8 @@ BinaryExpr::Optimize() {
Assert(Type::EqualIgnoringConst(arg0->GetType(), arg1->GetType())); Assert(Type::EqualIgnoringConst(arg0->GetType(), arg1->GetType()));
const Type *type = arg0->GetType()->GetAsNonConstType(); const Type *type = arg0->GetType()->GetAsNonConstType();
if (type == AtomicType::UniformFloat || type == AtomicType::VaryingFloat) { if (Type::Equal(type, AtomicType::UniformFloat) ||
Type::Equal(type, AtomicType::VaryingFloat)) {
float v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC]; float v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
constArg0->AsFloat(v0); constArg0->AsFloat(v0);
constArg1->AsFloat(v1); constArg1->AsFloat(v1);
@@ -2055,7 +2046,8 @@ BinaryExpr::Optimize() {
else else
return this; return this;
} }
if (type == AtomicType::UniformDouble || type == AtomicType::VaryingDouble) { if (Type::Equal(type, AtomicType::UniformDouble) ||
Type::Equal(type, AtomicType::VaryingDouble)) {
double v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC]; double v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
constArg0->AsDouble(v0); constArg0->AsDouble(v0);
constArg1->AsDouble(v1); constArg1->AsDouble(v1);
@@ -2067,7 +2059,8 @@ BinaryExpr::Optimize() {
else else
return this; return this;
} }
if (type == AtomicType::UniformInt32 || type == AtomicType::VaryingInt32) { if (Type::Equal(type, AtomicType::UniformInt32) ||
Type::Equal(type, AtomicType::VaryingInt32)) {
int32_t v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC]; int32_t v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
constArg0->AsInt32(v0); constArg0->AsInt32(v0);
constArg1->AsInt32(v1); constArg1->AsInt32(v1);
@@ -2081,7 +2074,8 @@ BinaryExpr::Optimize() {
else else
return this; return this;
} }
else if (type == AtomicType::UniformUInt32 || type == AtomicType::VaryingUInt32 || else if (Type::Equal(type, AtomicType::UniformUInt32) ||
Type::Equal(type, AtomicType::VaryingUInt32) ||
dynamic_cast<const EnumType *>(type) != NULL) { dynamic_cast<const EnumType *>(type) != NULL) {
uint32_t v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC]; uint32_t v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
constArg0->AsUInt32(v0); constArg0->AsUInt32(v0);
@@ -2096,7 +2090,8 @@ BinaryExpr::Optimize() {
else else
return this; return this;
} }
else if (type == AtomicType::UniformBool || type == AtomicType::VaryingBool) { else if (Type::Equal(type, AtomicType::UniformBool) ||
Type::Equal(type, AtomicType::VaryingBool)) {
bool v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC]; bool v0[ISPC_MAX_NVEC], v1[ISPC_MAX_NVEC];
constArg0->AsBool(v0); constArg0->AsBool(v0);
constArg1->AsBool(v1); constArg1->AsBool(v1);
@@ -2802,12 +2797,12 @@ SelectExpr::GetValue(FunctionEmitContext *ctx) const {
const Type *testType = test->GetType()->GetAsNonConstType(); const Type *testType = test->GetType()->GetAsNonConstType();
// This should be taken care of during typechecking // This should be taken care of during typechecking
Assert(testType->GetBaseType() == AtomicType::UniformBool || Assert(Type::Equal(testType->GetBaseType(), AtomicType::UniformBool) ||
testType->GetBaseType() == AtomicType::VaryingBool); Type::Equal(testType->GetBaseType(), AtomicType::VaryingBool));
const Type *type = expr1->GetType(); const Type *type = expr1->GetType();
if (testType == AtomicType::UniformBool) { if (Type::Equal(testType, AtomicType::UniformBool)) {
// Simple case of a single uniform bool test expression; we just // Simple case of a single uniform bool test expression; we just
// want one of the two expressions. In this case, we can be // want one of the two expressions. In this case, we can be
// careful to evaluate just the one of the expressions that we need // careful to evaluate just the one of the expressions that we need
@@ -2992,13 +2987,13 @@ SelectExpr::Optimize() {
if (constExpr1 == NULL || constExpr2 == NULL) if (constExpr1 == NULL || constExpr2 == NULL)
return this; return this;
Assert(constExpr1->GetType() == constExpr2->GetType()); Assert(Type::Equal(constExpr1->GetType(), constExpr2->GetType()));
const Type *exprType = constExpr1->GetType()->GetAsNonConstType(); const Type *exprType = constExpr1->GetType()->GetAsNonConstType();
Assert(exprType->IsVaryingType()); Assert(exprType->IsVaryingType());
// FIXME: it's annoying to have to have all of this replicated code. // FIXME: it's annoying to have to have all of this replicated code.
if (exprType == AtomicType::VaryingInt32 || if (Type::Equal(exprType, AtomicType::VaryingInt32) ||
exprType == AtomicType::VaryingUInt32) { Type::Equal(exprType, AtomicType::VaryingUInt32)) {
int32_t v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC]; int32_t v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
int32_t result[ISPC_MAX_NVEC]; int32_t result[ISPC_MAX_NVEC];
constExpr1->AsInt32(v1); constExpr1->AsInt32(v1);
@@ -3007,8 +3002,8 @@ SelectExpr::Optimize() {
result[i] = bv[i] ? v1[i] : v2[i]; result[i] = bv[i] ? v1[i] : v2[i];
return new ConstExpr(exprType, result, pos); return new ConstExpr(exprType, result, pos);
} }
else if (exprType == AtomicType::VaryingInt64 || else if (Type::Equal(exprType, AtomicType::VaryingInt64) ||
exprType == AtomicType::VaryingUInt64) { Type::Equal(exprType, AtomicType::VaryingUInt64)) {
int64_t v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC]; int64_t v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
int64_t result[ISPC_MAX_NVEC]; int64_t result[ISPC_MAX_NVEC];
constExpr1->AsInt64(v1); constExpr1->AsInt64(v1);
@@ -3017,7 +3012,7 @@ SelectExpr::Optimize() {
result[i] = bv[i] ? v1[i] : v2[i]; result[i] = bv[i] ? v1[i] : v2[i];
return new ConstExpr(exprType, result, pos); return new ConstExpr(exprType, result, pos);
} }
else if (exprType == AtomicType::VaryingFloat) { else if (Type::Equal(exprType, AtomicType::VaryingFloat)) {
float v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC]; float v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
float result[ISPC_MAX_NVEC]; float result[ISPC_MAX_NVEC];
constExpr1->AsFloat(v1); constExpr1->AsFloat(v1);
@@ -3026,7 +3021,7 @@ SelectExpr::Optimize() {
result[i] = bv[i] ? v1[i] : v2[i]; result[i] = bv[i] ? v1[i] : v2[i];
return new ConstExpr(exprType, result, pos); return new ConstExpr(exprType, result, pos);
} }
else if (exprType == AtomicType::VaryingDouble) { else if (Type::Equal(exprType, AtomicType::VaryingDouble)) {
double v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC]; double v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
double result[ISPC_MAX_NVEC]; double result[ISPC_MAX_NVEC];
constExpr1->AsDouble(v1); constExpr1->AsDouble(v1);
@@ -3035,7 +3030,7 @@ SelectExpr::Optimize() {
result[i] = bv[i] ? v1[i] : v2[i]; result[i] = bv[i] ? v1[i] : v2[i];
return new ConstExpr(exprType, result, pos); return new ConstExpr(exprType, result, pos);
} }
else if (exprType == AtomicType::VaryingBool) { else if (Type::Equal(exprType, AtomicType::VaryingBool)) {
bool v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC]; bool v1[ISPC_MAX_NVEC], v2[ISPC_MAX_NVEC];
bool result[ISPC_MAX_NVEC]; bool result[ISPC_MAX_NVEC];
constExpr1->AsBool(v1); constExpr1->AsBool(v1);
@@ -3164,7 +3159,7 @@ FunctionCallExpr::GetValue(FunctionEmitContext *ctx) const {
const FunctionType *ft = lGetFunctionType(func); const FunctionType *ft = lGetFunctionType(func);
Assert(ft != NULL); Assert(ft != NULL);
bool isVoidFunc = (ft->GetReturnType() == AtomicType::Void); bool isVoidFunc = Type::Equal(ft->GetReturnType(), AtomicType::Void);
// Automatically convert function call args to references if needed. // Automatically convert function call args to references if needed.
// FIXME: this should move to the TypeCheck() method... (but the // FIXME: this should move to the TypeCheck() method... (but the
@@ -4550,7 +4545,7 @@ ConstExpr::ConstExpr(const Type *t, int8_t i, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstInt8); Assert(Type::Equal(type, AtomicType::UniformInt8->GetAsConstType()));
int8Val[0] = i; int8Val[0] = i;
} }
@@ -4559,8 +4554,8 @@ ConstExpr::ConstExpr(const Type *t, int8_t *i, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstInt8 || Assert(Type::Equal(type, AtomicType::UniformInt8->GetAsConstType()) ||
type == AtomicType::VaryingConstInt8); Type::Equal(type, AtomicType::VaryingInt8->GetAsConstType()));
for (int j = 0; j < Count(); ++j) for (int j = 0; j < Count(); ++j)
int8Val[j] = i[j]; int8Val[j] = i[j];
} }
@@ -4570,7 +4565,7 @@ ConstExpr::ConstExpr(const Type *t, uint8_t u, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstUInt8); Assert(Type::Equal(type, AtomicType::UniformUInt8->GetAsConstType()));
uint8Val[0] = u; uint8Val[0] = u;
} }
@@ -4579,8 +4574,8 @@ ConstExpr::ConstExpr(const Type *t, uint8_t *u, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstUInt8 || Assert(Type::Equal(type, AtomicType::UniformUInt8->GetAsConstType()) ||
type == AtomicType::VaryingConstUInt8); Type::Equal(type, AtomicType::VaryingUInt8->GetAsConstType()));
for (int j = 0; j < Count(); ++j) for (int j = 0; j < Count(); ++j)
uint8Val[j] = u[j]; uint8Val[j] = u[j];
} }
@@ -4590,7 +4585,7 @@ ConstExpr::ConstExpr(const Type *t, int16_t i, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstInt16); Assert(Type::Equal(type, AtomicType::UniformInt16->GetAsConstType()));
int16Val[0] = i; int16Val[0] = i;
} }
@@ -4599,8 +4594,8 @@ ConstExpr::ConstExpr(const Type *t, int16_t *i, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstInt16 || Assert(Type::Equal(type, AtomicType::UniformInt16->GetAsConstType()) ||
type == AtomicType::VaryingConstInt16); Type::Equal(type, AtomicType::VaryingInt16->GetAsConstType()));
for (int j = 0; j < Count(); ++j) for (int j = 0; j < Count(); ++j)
int16Val[j] = i[j]; int16Val[j] = i[j];
} }
@@ -4610,7 +4605,7 @@ ConstExpr::ConstExpr(const Type *t, uint16_t u, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstUInt16); Assert(Type::Equal(type, AtomicType::UniformUInt16->GetAsConstType()));
uint16Val[0] = u; uint16Val[0] = u;
} }
@@ -4619,8 +4614,8 @@ ConstExpr::ConstExpr(const Type *t, uint16_t *u, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstUInt16 || Assert(Type::Equal(type, AtomicType::UniformUInt16->GetAsConstType()) ||
type == AtomicType::VaryingConstUInt16); Type::Equal(type, AtomicType::VaryingUInt16->GetAsConstType()));
for (int j = 0; j < Count(); ++j) for (int j = 0; j < Count(); ++j)
uint16Val[j] = u[j]; uint16Val[j] = u[j];
} }
@@ -4630,7 +4625,7 @@ ConstExpr::ConstExpr(const Type *t, int32_t i, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstInt32); Assert(Type::Equal(type, AtomicType::UniformInt32->GetAsConstType()));
int32Val[0] = i; int32Val[0] = i;
} }
@@ -4639,8 +4634,8 @@ ConstExpr::ConstExpr(const Type *t, int32_t *i, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstInt32 || Assert(Type::Equal(type, AtomicType::UniformInt32->GetAsConstType()) ||
type == AtomicType::VaryingConstInt32); Type::Equal(type, AtomicType::VaryingInt32->GetAsConstType()));
for (int j = 0; j < Count(); ++j) for (int j = 0; j < Count(); ++j)
int32Val[j] = i[j]; int32Val[j] = i[j];
} }
@@ -4650,7 +4645,7 @@ ConstExpr::ConstExpr(const Type *t, uint32_t u, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstUInt32 || Assert(Type::Equal(type, AtomicType::UniformUInt32->GetAsConstType()) ||
(dynamic_cast<const EnumType *>(type) != NULL && (dynamic_cast<const EnumType *>(type) != NULL &&
type->IsUniformType())); type->IsUniformType()));
uint32Val[0] = u; uint32Val[0] = u;
@@ -4661,8 +4656,8 @@ ConstExpr::ConstExpr(const Type *t, uint32_t *u, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstUInt32 || Assert(Type::Equal(type, AtomicType::UniformUInt32->GetAsConstType()) ||
type == AtomicType::VaryingConstUInt32 || Type::Equal(type, AtomicType::VaryingUInt32->GetAsConstType()) ||
(dynamic_cast<const EnumType *>(type) != NULL)); (dynamic_cast<const EnumType *>(type) != NULL));
for (int j = 0; j < Count(); ++j) for (int j = 0; j < Count(); ++j)
uint32Val[j] = u[j]; uint32Val[j] = u[j];
@@ -4673,7 +4668,7 @@ ConstExpr::ConstExpr(const Type *t, float f, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstFloat); Assert(Type::Equal(type, AtomicType::UniformFloat->GetAsConstType()));
floatVal[0] = f; floatVal[0] = f;
} }
@@ -4682,8 +4677,8 @@ ConstExpr::ConstExpr(const Type *t, float *f, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstFloat || Assert(Type::Equal(type, AtomicType::UniformFloat->GetAsConstType()) ||
type == AtomicType::VaryingConstFloat); Type::Equal(type, AtomicType::VaryingFloat->GetAsConstType()));
for (int j = 0; j < Count(); ++j) for (int j = 0; j < Count(); ++j)
floatVal[j] = f[j]; floatVal[j] = f[j];
} }
@@ -4693,7 +4688,7 @@ ConstExpr::ConstExpr(const Type *t, int64_t i, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstInt64); Assert(Type::Equal(type, AtomicType::UniformInt64->GetAsConstType()));
int64Val[0] = i; int64Val[0] = i;
} }
@@ -4702,8 +4697,8 @@ ConstExpr::ConstExpr(const Type *t, int64_t *i, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstInt64 || Assert(Type::Equal(type, AtomicType::UniformInt64->GetAsConstType()) ||
type == AtomicType::VaryingConstInt64); Type::Equal(type, AtomicType::VaryingInt64->GetAsConstType()));
for (int j = 0; j < Count(); ++j) for (int j = 0; j < Count(); ++j)
int64Val[j] = i[j]; int64Val[j] = i[j];
} }
@@ -4713,7 +4708,7 @@ ConstExpr::ConstExpr(const Type *t, uint64_t u, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstUInt64); Assert(Type::Equal(type, AtomicType::UniformUInt64->GetAsConstType()));
uint64Val[0] = u; uint64Val[0] = u;
} }
@@ -4722,8 +4717,8 @@ ConstExpr::ConstExpr(const Type *t, uint64_t *u, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstUInt64 || Assert(Type::Equal(type, AtomicType::UniformUInt64->GetAsConstType()) ||
type == AtomicType::VaryingConstUInt64); Type::Equal(type, AtomicType::VaryingUInt64->GetAsConstType()));
for (int j = 0; j < Count(); ++j) for (int j = 0; j < Count(); ++j)
uint64Val[j] = u[j]; uint64Val[j] = u[j];
} }
@@ -4733,7 +4728,7 @@ ConstExpr::ConstExpr(const Type *t, double f, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstDouble); Assert(Type::Equal(type, AtomicType::UniformDouble->GetAsConstType()));
doubleVal[0] = f; doubleVal[0] = f;
} }
@@ -4742,8 +4737,8 @@ ConstExpr::ConstExpr(const Type *t, double *f, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstDouble || Assert(Type::Equal(type, AtomicType::UniformDouble->GetAsConstType()) ||
type == AtomicType::VaryingConstDouble); Type::Equal(type, AtomicType::VaryingDouble->GetAsConstType()));
for (int j = 0; j < Count(); ++j) for (int j = 0; j < Count(); ++j)
doubleVal[j] = f[j]; doubleVal[j] = f[j];
} }
@@ -4753,7 +4748,7 @@ ConstExpr::ConstExpr(const Type *t, bool b, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstBool); Assert(Type::Equal(type, AtomicType::UniformBool->GetAsConstType()));
boolVal[0] = b; boolVal[0] = b;
} }
@@ -4762,8 +4757,8 @@ ConstExpr::ConstExpr(const Type *t, bool *b, SourcePos p)
: Expr(p) { : Expr(p) {
type = t; type = t;
type = type->GetAsConstType(); type = type->GetAsConstType();
Assert(type == AtomicType::UniformConstBool || Assert(Type::Equal(type, AtomicType::UniformBool->GetAsConstType()) ||
type == AtomicType::VaryingConstBool); Type::Equal(type, AtomicType::VaryingBool->GetAsConstType()));
for (int j = 0; j < Count(); ++j) for (int j = 0; j < Count(); ++j)
boolVal[j] = b[j]; boolVal[j] = b[j];
} }
@@ -5231,7 +5226,8 @@ ConstExpr::GetConstant(const Type *type) const {
Assert(Count() == 1); Assert(Count() == 1);
type = type->GetAsNonConstType(); type = type->GetAsNonConstType();
if (type == AtomicType::UniformBool || type == AtomicType::VaryingBool) { if (Type::Equal(type, AtomicType::UniformBool) ||
Type::Equal(type, AtomicType::VaryingBool)) {
bool bv[ISPC_MAX_NVEC]; bool bv[ISPC_MAX_NVEC];
AsBool(bv, type->IsVaryingType()); AsBool(bv, type->IsVaryingType());
if (type->IsUniformType()) if (type->IsUniformType())
@@ -5239,7 +5235,8 @@ ConstExpr::GetConstant(const Type *type) const {
else else
return LLVMBoolVector(bv); return LLVMBoolVector(bv);
} }
else if (type == AtomicType::UniformInt8 || type == AtomicType::VaryingInt8) { else if (Type::Equal(type, AtomicType::UniformInt8) ||
Type::Equal(type, AtomicType::VaryingInt8)) {
int8_t iv[ISPC_MAX_NVEC]; int8_t iv[ISPC_MAX_NVEC];
AsInt8(iv, type->IsVaryingType()); AsInt8(iv, type->IsVaryingType());
if (type->IsUniformType()) if (type->IsUniformType())
@@ -5247,7 +5244,8 @@ ConstExpr::GetConstant(const Type *type) const {
else else
return LLVMInt8Vector(iv); return LLVMInt8Vector(iv);
} }
else if (type == AtomicType::UniformUInt8 || type == AtomicType::VaryingUInt8) { else if (Type::Equal(type, AtomicType::UniformUInt8) ||
Type::Equal(type, AtomicType::VaryingUInt8)) {
uint8_t uiv[ISPC_MAX_NVEC]; uint8_t uiv[ISPC_MAX_NVEC];
AsUInt8(uiv, type->IsVaryingType()); AsUInt8(uiv, type->IsVaryingType());
if (type->IsUniformType()) if (type->IsUniformType())
@@ -5255,7 +5253,8 @@ ConstExpr::GetConstant(const Type *type) const {
else else
return LLVMUInt8Vector(uiv); return LLVMUInt8Vector(uiv);
} }
else if (type == AtomicType::UniformInt16 || type == AtomicType::VaryingInt16) { else if (Type::Equal(type, AtomicType::UniformInt16) ||
Type::Equal(type, AtomicType::VaryingInt16)) {
int16_t iv[ISPC_MAX_NVEC]; int16_t iv[ISPC_MAX_NVEC];
AsInt16(iv, type->IsVaryingType()); AsInt16(iv, type->IsVaryingType());
if (type->IsUniformType()) if (type->IsUniformType())
@@ -5263,7 +5262,8 @@ ConstExpr::GetConstant(const Type *type) const {
else else
return LLVMInt16Vector(iv); return LLVMInt16Vector(iv);
} }
else if (type == AtomicType::UniformUInt16 || type == AtomicType::VaryingUInt16) { else if (Type::Equal(type, AtomicType::UniformUInt16) ||
Type::Equal(type, AtomicType::VaryingUInt16)) {
uint16_t uiv[ISPC_MAX_NVEC]; uint16_t uiv[ISPC_MAX_NVEC];
AsUInt16(uiv, type->IsVaryingType()); AsUInt16(uiv, type->IsVaryingType());
if (type->IsUniformType()) if (type->IsUniformType())
@@ -5271,7 +5271,8 @@ ConstExpr::GetConstant(const Type *type) const {
else else
return LLVMUInt16Vector(uiv); return LLVMUInt16Vector(uiv);
} }
else if (type == AtomicType::UniformInt32 || type == AtomicType::VaryingInt32) { else if (Type::Equal(type, AtomicType::UniformInt32) ||
Type::Equal(type, AtomicType::VaryingInt32)) {
int32_t iv[ISPC_MAX_NVEC]; int32_t iv[ISPC_MAX_NVEC];
AsInt32(iv, type->IsVaryingType()); AsInt32(iv, type->IsVaryingType());
if (type->IsUniformType()) if (type->IsUniformType())
@@ -5279,7 +5280,8 @@ ConstExpr::GetConstant(const Type *type) const {
else else
return LLVMInt32Vector(iv); return LLVMInt32Vector(iv);
} }
else if (type == AtomicType::UniformUInt32 || type == AtomicType::VaryingUInt32 || else if (Type::Equal(type, AtomicType::UniformUInt32) ||
Type::Equal(type, AtomicType::VaryingUInt32) ||
dynamic_cast<const EnumType *>(type) != NULL) { dynamic_cast<const EnumType *>(type) != NULL) {
uint32_t uiv[ISPC_MAX_NVEC]; uint32_t uiv[ISPC_MAX_NVEC];
AsUInt32(uiv, type->IsVaryingType()); AsUInt32(uiv, type->IsVaryingType());
@@ -5288,7 +5290,8 @@ ConstExpr::GetConstant(const Type *type) const {
else else
return LLVMUInt32Vector(uiv); return LLVMUInt32Vector(uiv);
} }
else if (type == AtomicType::UniformFloat || type == AtomicType::VaryingFloat) { else if (Type::Equal(type, AtomicType::UniformFloat) ||
Type::Equal(type, AtomicType::VaryingFloat)) {
float fv[ISPC_MAX_NVEC]; float fv[ISPC_MAX_NVEC];
AsFloat(fv, type->IsVaryingType()); AsFloat(fv, type->IsVaryingType());
if (type->IsUniformType()) if (type->IsUniformType())
@@ -5296,7 +5299,8 @@ ConstExpr::GetConstant(const Type *type) const {
else else
return LLVMFloatVector(fv); return LLVMFloatVector(fv);
} }
else if (type == AtomicType::UniformInt64 || type == AtomicType::VaryingInt64) { else if (Type::Equal(type, AtomicType::UniformInt64) ||
Type::Equal(type, AtomicType::VaryingInt64)) {
int64_t iv[ISPC_MAX_NVEC]; int64_t iv[ISPC_MAX_NVEC];
AsInt64(iv, type->IsVaryingType()); AsInt64(iv, type->IsVaryingType());
if (type->IsUniformType()) if (type->IsUniformType())
@@ -5304,7 +5308,8 @@ ConstExpr::GetConstant(const Type *type) const {
else else
return LLVMInt64Vector(iv); return LLVMInt64Vector(iv);
} }
else if (type == AtomicType::UniformUInt64 || type == AtomicType::VaryingUInt64) { else if (Type::Equal(type, AtomicType::UniformUInt64) ||
Type::Equal(type, AtomicType::VaryingUInt64)) {
uint64_t uiv[ISPC_MAX_NVEC]; uint64_t uiv[ISPC_MAX_NVEC];
AsUInt64(uiv, type->IsVaryingType()); AsUInt64(uiv, type->IsVaryingType());
if (type->IsUniformType()) if (type->IsUniformType())
@@ -5312,7 +5317,8 @@ ConstExpr::GetConstant(const Type *type) const {
else else
return LLVMUInt64Vector(uiv); return LLVMUInt64Vector(uiv);
} }
else if (type == AtomicType::UniformDouble || type == AtomicType::VaryingDouble) { else if (Type::Equal(type, AtomicType::UniformDouble) ||
Type::Equal(type, AtomicType::VaryingDouble)) {
double dv[ISPC_MAX_NVEC]; double dv[ISPC_MAX_NVEC];
AsDouble(dv, type->IsVaryingType()); AsDouble(dv, type->IsVaryingType());
if (type->IsUniformType()) if (type->IsUniformType())
@@ -5976,8 +5982,8 @@ TypeCastExpr::GetValue(FunctionEmitContext *ctx) const {
ctx->SetDebugPos(pos); ctx->SetDebugPos(pos);
const Type *toType = GetType(), *fromType = expr->GetType(); const Type *toType = GetType(), *fromType = expr->GetType();
if (!toType || !fromType || toType == AtomicType::Void || if (!toType || !fromType || Type::Equal(toType, AtomicType::Void) ||
fromType == AtomicType::Void) Type::Equal(fromType, AtomicType::Void))
// an error should have been issued elsewhere in this case // an error should have been issued elsewhere in this case
return NULL; return NULL;

View File

@@ -355,7 +355,7 @@ Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
// issue a warning. Also need to warn if it's the entry block for // issue a warning. Also need to warn if it's the entry block for
// the function (in which case it will not have predeccesors but is // the function (in which case it will not have predeccesors but is
// still reachable.) // still reachable.)
if (type->GetReturnType() != AtomicType::Void && if (Type::Equal(type->GetReturnType(), AtomicType::Void) == false &&
(pred_begin(ec.bblock) != pred_end(ec.bblock) || (ec.bblock == entryBBlock))) (pred_begin(ec.bblock) != pred_end(ec.bblock) || (ec.bblock == entryBBlock)))
Warning(sym->pos, "Missing return statement in function returning \"%s\".", Warning(sym->pos, "Missing return statement in function returning \"%s\".",
type->rType->GetString().c_str()); type->rType->GetString().c_str());

View File

@@ -224,8 +224,6 @@ int main(int Argc, char *Argv[]) {
LLVMInitializeX86TargetMC(); LLVMInitializeX86TargetMC();
#endif #endif
AtomicType::Init();
char *file = NULL; char *file = NULL;
const char *headerFileName = NULL; const char *headerFileName = NULL;
const char *outFileName = NULL; const char *outFileName = NULL;

View File

@@ -241,7 +241,7 @@ Module::AddGlobalVariable(Symbol *sym, Expr *initExpr, bool isConst) {
return; return;
} }
if (sym->type == AtomicType::Void) { if (Type::Equal(sym->type, AtomicType::Void)) {
Error(sym->pos, "\"void\" type global variable is illegal."); Error(sym->pos, "\"void\" type global variable is illegal.");
return; return;
} }
@@ -515,7 +515,8 @@ Module::AddFunctionDeclaration(Symbol *funSym, bool isInline) {
Error(funSym->pos, "Illegal to return a \"varying\" type from exported " Error(funSym->pos, "Illegal to return a \"varying\" type from exported "
"function \"%s\"", funSym->name.c_str()); "function \"%s\"", funSym->name.c_str());
if (functionType->isTask && (functionType->GetReturnType() != AtomicType::Void)) if (functionType->isTask &&
Type::Equal(functionType->GetReturnType(), AtomicType::Void) == false)
Error(funSym->pos, "Task-qualified functions must have void return type."); Error(funSym->pos, "Task-qualified functions must have void return type.");
if (functionType->isExported || functionType->isExternC) if (functionType->isExported || functionType->isExternC)

View File

@@ -267,25 +267,30 @@ primary_expression
} }
} }
| TOKEN_INT32_CONSTANT { | TOKEN_INT32_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformConstInt32, (int32_t)yylval.intVal, @1); $$ = new ConstExpr(AtomicType::UniformInt32->GetAsConstType(),
(int32_t)yylval.intVal, @1);
} }
| TOKEN_UINT32_CONSTANT { | TOKEN_UINT32_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformConstUInt32, (uint32_t)yylval.intVal, @1); $$ = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
(uint32_t)yylval.intVal, @1);
} }
| TOKEN_INT64_CONSTANT { | TOKEN_INT64_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformConstInt64, (int64_t)yylval.intVal, @1); $$ = new ConstExpr(AtomicType::UniformInt64->GetAsConstType(),
(int64_t)yylval.intVal, @1);
} }
| TOKEN_UINT64_CONSTANT { | TOKEN_UINT64_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformConstUInt64, (uint64_t)yylval.intVal, @1); $$ = new ConstExpr(AtomicType::UniformUInt64->GetAsConstType(),
(uint64_t)yylval.intVal, @1);
} }
| TOKEN_FLOAT_CONSTANT { | TOKEN_FLOAT_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformConstFloat, (float)yylval.floatVal, @1); $$ = new ConstExpr(AtomicType::UniformFloat->GetAsConstType(),
(float)yylval.floatVal, @1);
} }
| TOKEN_TRUE { | TOKEN_TRUE {
$$ = new ConstExpr(AtomicType::UniformConstBool, true, @1); $$ = new ConstExpr(AtomicType::UniformBool->GetAsConstType(), true, @1);
} }
| TOKEN_FALSE { | TOKEN_FALSE {
$$ = new ConstExpr(AtomicType::UniformConstBool, false, @1); $$ = new ConstExpr(AtomicType::UniformBool->GetAsConstType(), false, @1);
} }
| TOKEN_NULL { | TOKEN_NULL {
$$ = new NullPointerExpr(@1); $$ = new NullPointerExpr(@1);
@@ -477,7 +482,7 @@ rate_qualified_new_type
{ {
if ($2 == NULL) if ($2 == NULL)
$$ = NULL; $$ = NULL;
else if ($2 == AtomicType::Void) { else if (Type::Equal($2, AtomicType::Void)) {
Error(@1, "\"uniform\" qualifier is illegal with \"void\" type."); Error(@1, "\"uniform\" qualifier is illegal with \"void\" type.");
$$ = NULL; $$ = NULL;
} }
@@ -488,7 +493,7 @@ rate_qualified_new_type
{ {
if ($2 == NULL) if ($2 == NULL)
$$ = NULL; $$ = NULL;
else if ($2 == AtomicType::Void) { else if (Type::Equal($2, AtomicType::Void)) {
Error(@1, "\"varying\" qualifier is illegal with \"void\" type."); Error(@1, "\"varying\" qualifier is illegal with \"void\" type.");
$$ = NULL; $$ = NULL;
} }
@@ -710,13 +715,13 @@ type_specifier
atomic_var_type_specifier atomic_var_type_specifier
: TOKEN_VOID { $$ = AtomicType::Void; } : TOKEN_VOID { $$ = AtomicType::Void; }
| TOKEN_BOOL { $$ = AtomicType::UnboundBool; } | TOKEN_BOOL { $$ = AtomicType::UniformBool->GetAsUnboundVariabilityType(); }
| TOKEN_INT8 { $$ = AtomicType::UnboundInt8; } | TOKEN_INT8 { $$ = AtomicType::UniformInt8->GetAsUnboundVariabilityType(); }
| TOKEN_INT16 { $$ = AtomicType::UnboundInt16; } | TOKEN_INT16 { $$ = AtomicType::UniformInt16->GetAsUnboundVariabilityType(); }
| TOKEN_INT { $$ = AtomicType::UnboundInt32; } | TOKEN_INT { $$ = AtomicType::UniformInt32->GetAsUnboundVariabilityType(); }
| TOKEN_FLOAT { $$ = AtomicType::UnboundFloat; } | TOKEN_FLOAT { $$ = AtomicType::UniformFloat->GetAsUnboundVariabilityType(); }
| TOKEN_DOUBLE { $$ = AtomicType::UnboundDouble; } | TOKEN_DOUBLE { $$ = AtomicType::UniformDouble->GetAsUnboundVariabilityType(); }
| TOKEN_INT64 { $$ = AtomicType::UnboundInt64; } | TOKEN_INT64 { $$ = AtomicType::UniformInt64->GetAsUnboundVariabilityType(); }
; ;
short_vec_specifier short_vec_specifier
@@ -824,7 +829,7 @@ specifier_qualifier_list
{ {
if ($2 != NULL) { if ($2 != NULL) {
if ($1 == TYPEQUAL_UNIFORM) { if ($1 == TYPEQUAL_UNIFORM) {
if ($2 == AtomicType::Void) { if (Type::Equal($2, AtomicType::Void)) {
Error(@1, "\"uniform\" qualifier is illegal with \"void\" type."); Error(@1, "\"uniform\" qualifier is illegal with \"void\" type.");
$$ = NULL; $$ = NULL;
} }
@@ -832,7 +837,7 @@ specifier_qualifier_list
$$ = $2->GetAsUniformType(); $$ = $2->GetAsUniformType();
} }
else if ($1 == TYPEQUAL_VARYING) { else if ($1 == TYPEQUAL_VARYING) {
if ($2 == AtomicType::Void) { if (Type::Equal($2, AtomicType::Void)) {
Error(@1, "\"varying\" qualifier is illegal with \"void\" type."); Error(@1, "\"varying\" qualifier is illegal with \"void\" type.");
$$ = NULL; $$ = NULL;
} }
@@ -986,7 +991,7 @@ enumerator
if ($1 != NULL && $3 != NULL && if ($1 != NULL && $3 != NULL &&
lGetConstantInt($3, &value, @3, "Enumerator value")) { lGetConstantInt($3, &value, @3, "Enumerator value")) {
Symbol *sym = new Symbol($1, @1); Symbol *sym = new Symbol($1, @1);
sym->constValue = new ConstExpr(AtomicType::UniformConstUInt32, sym->constValue = new ConstExpr(AtomicType::UniformUInt32->GetAsConstType(),
(uint32_t)value, @3); (uint32_t)value, @3);
$$ = sym; $$ = sym;
} }
@@ -1491,7 +1496,7 @@ foreach_tiled_scope
foreach_identifier foreach_identifier
: TOKEN_IDENTIFIER : TOKEN_IDENTIFIER
{ {
$$ = new Symbol(yytext, @1, AtomicType::VaryingConstInt32); $$ = new Symbol(yytext, @1, AtomicType::VaryingInt32->GetAsConstType());
} }
; ;
@@ -1878,7 +1883,8 @@ lAddFunctionParams(Declarator *decl) {
/** Add a symbol for the built-in mask variable to the symbol table */ /** Add a symbol for the built-in mask variable to the symbol table */
static void lAddMaskToSymbolTable(SourcePos pos) { static void lAddMaskToSymbolTable(SourcePos pos) {
const Type *t = g->target.maskBitCount == 1 ? const Type *t = g->target.maskBitCount == 1 ?
AtomicType::VaryingConstBool : AtomicType::VaryingConstUInt32; AtomicType::VaryingBool : AtomicType::VaryingUInt32;
t = t->GetAsConstType();
Symbol *maskSymbol = new Symbol("__mask", pos, t); Symbol *maskSymbol = new Symbol("__mask", pos, t);
m->symbolTable->AddVariable(maskSymbol); m->symbolTable->AddVariable(maskSymbol);
} }
@@ -1887,16 +1893,18 @@ static void lAddMaskToSymbolTable(SourcePos pos) {
/** Add the thread index and thread count variables to the symbol table /** Add the thread index and thread count variables to the symbol table
(this should only be done for 'task'-qualified functions. */ (this should only be done for 'task'-qualified functions. */
static void lAddThreadIndexCountToSymbolTable(SourcePos pos) { static void lAddThreadIndexCountToSymbolTable(SourcePos pos) {
Symbol *threadIndexSym = new Symbol("threadIndex", pos, AtomicType::UniformConstUInt32); const Type *type = AtomicType::UniformUInt32->GetAsConstType();
Symbol *threadIndexSym = new Symbol("threadIndex", pos, type);
m->symbolTable->AddVariable(threadIndexSym); m->symbolTable->AddVariable(threadIndexSym);
Symbol *threadCountSym = new Symbol("threadCount", pos, AtomicType::UniformConstUInt32); Symbol *threadCountSym = new Symbol("threadCount", pos, type);
m->symbolTable->AddVariable(threadCountSym); m->symbolTable->AddVariable(threadCountSym);
Symbol *taskIndexSym = new Symbol("taskIndex", pos, AtomicType::UniformConstUInt32); Symbol *taskIndexSym = new Symbol("taskIndex", pos, type);
m->symbolTable->AddVariable(taskIndexSym); m->symbolTable->AddVariable(taskIndexSym);
Symbol *taskCountSym = new Symbol("taskCount", pos, AtomicType::UniformConstUInt32); Symbol *taskCountSym = new Symbol("taskCount", pos, type);
m->symbolTable->AddVariable(taskCountSym); m->symbolTable->AddVariable(taskCountSym);
} }

View File

@@ -2124,10 +2124,10 @@ SwitchStmt::TypeCheck() {
const Type *toType = NULL; const Type *toType = NULL;
exprType = exprType->GetAsConstType(); exprType = exprType->GetAsConstType();
bool is64bit = (exprType->GetAsUniformType() == bool is64bit = (Type::EqualIgnoringConst(exprType->GetAsUniformType(),
AtomicType::UniformConstUInt64 || AtomicType::UniformUInt64) ||
exprType->GetAsUniformType() == Type::EqualIgnoringConst(exprType->GetAsUniformType(),
AtomicType::UniformConstInt64); AtomicType::UniformInt64));
if (exprType->IsUniformType()) { if (exprType->IsUniformType()) {
if (is64bit) toType = AtomicType::UniformInt64; if (is64bit) toType = AtomicType::UniformInt64;
@@ -2381,20 +2381,20 @@ PrintStmt::PrintStmt(const std::string &f, Expr *v, SourcePos p)
*/ */
static char static char
lEncodeType(const Type *t) { lEncodeType(const Type *t) {
if (t == AtomicType::UniformBool) return 'b'; if (Type::Equal(t, AtomicType::UniformBool)) return 'b';
if (t == AtomicType::VaryingBool) return 'B'; if (Type::Equal(t, AtomicType::VaryingBool)) return 'B';
if (t == AtomicType::UniformInt32) return 'i'; if (Type::Equal(t, AtomicType::UniformInt32)) return 'i';
if (t == AtomicType::VaryingInt32) return 'I'; if (Type::Equal(t, AtomicType::VaryingInt32)) return 'I';
if (t == AtomicType::UniformUInt32) return 'u'; if (Type::Equal(t, AtomicType::UniformUInt32)) return 'u';
if (t == AtomicType::VaryingUInt32) return 'U'; if (Type::Equal(t, AtomicType::VaryingUInt32)) return 'U';
if (t == AtomicType::UniformFloat) return 'f'; if (Type::Equal(t, AtomicType::UniformFloat)) return 'f';
if (t == AtomicType::VaryingFloat) return 'F'; if (Type::Equal(t, AtomicType::VaryingFloat)) return 'F';
if (t == AtomicType::UniformInt64) return 'l'; if (Type::Equal(t, AtomicType::UniformInt64)) return 'l';
if (t == AtomicType::VaryingInt64) return 'L'; if (Type::Equal(t, AtomicType::VaryingInt64)) return 'L';
if (t == AtomicType::UniformUInt64) return 'v'; if (Type::Equal(t, AtomicType::UniformUInt64)) return 'v';
if (t == AtomicType::VaryingUInt64) return 'V'; if (Type::Equal(t, AtomicType::VaryingUInt64)) return 'V';
if (t == AtomicType::UniformDouble) return 'd'; if (Type::Equal(t, AtomicType::UniformDouble)) return 'd';
if (t == AtomicType::VaryingDouble) return 'D'; if (Type::Equal(t, AtomicType::VaryingDouble)) return 'D';
if (dynamic_cast<const PointerType *>(t) != NULL) { if (dynamic_cast<const PointerType *>(t) != NULL) {
if (t->IsUniformType()) if (t->IsUniformType())
return 'p'; return 'p';
@@ -2424,10 +2424,10 @@ lProcessPrintArg(Expr *expr, FunctionEmitContext *ctx, std::string &argTypes) {
// Just int8 and int16 types to int32s... // Just int8 and int16 types to int32s...
const Type *baseType = type->GetAsNonConstType()->GetAsUniformType(); const Type *baseType = type->GetAsNonConstType()->GetAsUniformType();
if (baseType == AtomicType::UniformInt8 || if (Type::Equal(baseType, AtomicType::UniformInt8) ||
baseType == AtomicType::UniformUInt8 || Type::Equal(baseType, AtomicType::UniformUInt8) ||
baseType == AtomicType::UniformInt16 || Type::Equal(baseType, AtomicType::UniformInt16) ||
baseType == AtomicType::UniformUInt16) { Type::Equal(baseType, AtomicType::UniformUInt16)) {
expr = new TypeCastExpr(type->IsUniformType() ? AtomicType::UniformInt32 : expr = new TypeCastExpr(type->IsUniformType() ? AtomicType::UniformInt32 :
AtomicType::VaryingInt32, AtomicType::VaryingInt32,
expr, expr->pos); expr, expr->pos);

354
type.cpp
View File

@@ -70,233 +70,53 @@ lShouldPrintName(const std::string &name) {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// AtomicType // AtomicType
// All of the details of the layout of this array are used implicitly in
// the AtomicType implementation below; reoder it with care! For example,
// the fact that for signed integer types, the unsigned equivalent integer
// type follows in the next major array element is used in the routine to
// get unsigned types.
const AtomicType *AtomicType::typeTable[AtomicType::NUM_BASIC_TYPES][3][2] = { const AtomicType *AtomicType::UniformBool =
{ { NULL, NULL }, {NULL, NULL}, {NULL,NULL} }, /* NULL type */ new AtomicType(AtomicType::TYPE_BOOL, Uniform, false);
{ { new AtomicType(AtomicType::TYPE_BOOL, Type::Uniform, false), const AtomicType *AtomicType::VaryingBool =
new AtomicType(AtomicType::TYPE_BOOL, Type::Uniform, true), }, new AtomicType(AtomicType::TYPE_BOOL, Varying, false);
{ new AtomicType(AtomicType::TYPE_BOOL, Type::Varying, false), const AtomicType *AtomicType::UniformInt8 =
new AtomicType(AtomicType::TYPE_BOOL, Type::Varying, true), }, new AtomicType(AtomicType::TYPE_INT8, Uniform, false);
{ new AtomicType(AtomicType::TYPE_BOOL, Type::Unbound, false), const AtomicType *AtomicType::VaryingInt8 =
new AtomicType(AtomicType::TYPE_BOOL, Type::Unbound, true), } }, new AtomicType(AtomicType::TYPE_INT8, Varying, false);
{ { new AtomicType(AtomicType::TYPE_INT8, Type::Uniform, false), const AtomicType *AtomicType::UniformUInt8 =
new AtomicType(AtomicType::TYPE_INT8, Type::Uniform, true), }, new AtomicType(AtomicType::TYPE_UINT8, Uniform, false);
{ new AtomicType(AtomicType::TYPE_INT8, Type::Varying, false), const AtomicType *AtomicType::VaryingUInt8 =
new AtomicType(AtomicType::TYPE_INT8, Type::Varying, true), }, new AtomicType(AtomicType::TYPE_UINT8, Varying, false);
{ new AtomicType(AtomicType::TYPE_INT8, Type::Unbound, false), const AtomicType *AtomicType::UniformInt16 =
new AtomicType(AtomicType::TYPE_INT8, Type::Unbound, true), } }, new AtomicType(AtomicType::TYPE_INT16, Uniform, false);
{ { new AtomicType(AtomicType::TYPE_UINT8, Type::Uniform, false), const AtomicType *AtomicType::VaryingInt16 =
new AtomicType(AtomicType::TYPE_UINT8, Type::Uniform, true), }, new AtomicType(AtomicType::TYPE_INT16, Varying, false);
{ new AtomicType(AtomicType::TYPE_UINT8, Type::Varying, false), const AtomicType *AtomicType::UniformUInt16 =
new AtomicType(AtomicType::TYPE_UINT8, Type::Varying, true), }, new AtomicType(AtomicType::TYPE_UINT16, Uniform, false);
{ new AtomicType(AtomicType::TYPE_UINT8, Type::Unbound, false), const AtomicType *AtomicType::VaryingUInt16 =
new AtomicType(AtomicType::TYPE_UINT8, Type::Unbound, true), } }, new AtomicType(AtomicType::TYPE_UINT16, Varying, false);
{ { new AtomicType(AtomicType::TYPE_INT16, Type::Uniform, false), const AtomicType *AtomicType::UniformInt32 =
new AtomicType(AtomicType::TYPE_INT16, Type::Uniform, true), }, new AtomicType(AtomicType::TYPE_INT32, Uniform, false);
{ new AtomicType(AtomicType::TYPE_INT16, Type::Varying, false), const AtomicType *AtomicType::VaryingInt32 =
new AtomicType(AtomicType::TYPE_INT16, Type::Varying, true), }, new AtomicType(AtomicType::TYPE_INT32, Varying, false);
{ new AtomicType(AtomicType::TYPE_INT16, Type::Unbound, false), const AtomicType *AtomicType::UniformUInt32 =
new AtomicType(AtomicType::TYPE_INT16, Type::Unbound, true), } }, new AtomicType(AtomicType::TYPE_UINT32, Uniform, false);
{ { new AtomicType(AtomicType::TYPE_UINT16, Type::Uniform, false), const AtomicType *AtomicType::VaryingUInt32 =
new AtomicType(AtomicType::TYPE_UINT16, Type::Uniform, true), }, new AtomicType(AtomicType::TYPE_UINT32, Varying, false);
{ new AtomicType(AtomicType::TYPE_UINT16, Type::Varying, false), const AtomicType *AtomicType::UniformFloat =
new AtomicType(AtomicType::TYPE_UINT16, Type::Varying, true), }, new AtomicType(AtomicType::TYPE_FLOAT, Uniform, false);
{ new AtomicType(AtomicType::TYPE_UINT16, Type::Unbound, false), const AtomicType *AtomicType::VaryingFloat =
new AtomicType(AtomicType::TYPE_UINT16, Type::Unbound, true), } }, new AtomicType(AtomicType::TYPE_FLOAT, Varying, false);
{ { new AtomicType(AtomicType::TYPE_INT32, Type::Uniform, false), const AtomicType *AtomicType::UniformInt64 =
new AtomicType(AtomicType::TYPE_INT32, Type::Uniform, true), }, new AtomicType(AtomicType::TYPE_INT64, Uniform, false);
{ new AtomicType(AtomicType::TYPE_INT32, Type::Varying, false), const AtomicType *AtomicType::VaryingInt64 =
new AtomicType(AtomicType::TYPE_INT32, Type::Varying, true), }, new AtomicType(AtomicType::TYPE_INT64, Varying, false);
{ new AtomicType(AtomicType::TYPE_INT32, Type::Unbound, false), const AtomicType *AtomicType::UniformUInt64 =
new AtomicType(AtomicType::TYPE_INT32, Type::Unbound, true), } }, new AtomicType(AtomicType::TYPE_UINT64, Uniform, false);
{ { new AtomicType(AtomicType::TYPE_UINT32, Type::Uniform, false), const AtomicType *AtomicType::VaryingUInt64 =
new AtomicType(AtomicType::TYPE_UINT32, Type::Uniform, true), }, new AtomicType(AtomicType::TYPE_UINT64, Varying, false);
{ new AtomicType(AtomicType::TYPE_UINT32, Type::Varying, false), const AtomicType *AtomicType::UniformDouble =
new AtomicType(AtomicType::TYPE_UINT32, Type::Varying, true), }, new AtomicType(AtomicType::TYPE_DOUBLE, Uniform, false);
{ new AtomicType(AtomicType::TYPE_UINT32, Type::Unbound, false), const AtomicType *AtomicType::VaryingDouble =
new AtomicType(AtomicType::TYPE_UINT32, Type::Unbound, true), } }, new AtomicType(AtomicType::TYPE_DOUBLE, Varying, false);
{ { new AtomicType(AtomicType::TYPE_FLOAT, Type::Uniform, false), const AtomicType *AtomicType::Void =
new AtomicType(AtomicType::TYPE_FLOAT, Type::Uniform, true), }, new AtomicType(TYPE_VOID, Uniform, false);
{ new AtomicType(AtomicType::TYPE_FLOAT, Type::Varying, false),
new AtomicType(AtomicType::TYPE_FLOAT, Type::Varying, true), },
{ new AtomicType(AtomicType::TYPE_FLOAT, Type::Unbound, false),
new AtomicType(AtomicType::TYPE_FLOAT, Type::Unbound, true), } },
{ { new AtomicType(AtomicType::TYPE_INT64, Type::Uniform, false),
new AtomicType(AtomicType::TYPE_INT64, Type::Uniform, true), },
{ new AtomicType(AtomicType::TYPE_INT64, Type::Varying, false),
new AtomicType(AtomicType::TYPE_INT64, Type::Varying, true), },
{ new AtomicType(AtomicType::TYPE_INT64, Type::Unbound, false),
new AtomicType(AtomicType::TYPE_INT64, Type::Unbound, true), } },
{ { new AtomicType(AtomicType::TYPE_UINT64, Type::Uniform, false),
new AtomicType(AtomicType::TYPE_UINT64, Type::Uniform, true), },
{ new AtomicType(AtomicType::TYPE_UINT64, Type::Varying, false),
new AtomicType(AtomicType::TYPE_UINT64, Type::Varying, true), },
{ new AtomicType(AtomicType::TYPE_UINT64, Type::Unbound, false),
new AtomicType(AtomicType::TYPE_UINT64, Type::Unbound, true), } },
{ { new AtomicType(AtomicType::TYPE_DOUBLE, Type::Uniform, false),
new AtomicType(AtomicType::TYPE_DOUBLE, Type::Uniform, true), },
{ new AtomicType(AtomicType::TYPE_DOUBLE, Type::Varying, false),
new AtomicType(AtomicType::TYPE_DOUBLE, Type::Varying, true), },
{ new AtomicType(AtomicType::TYPE_DOUBLE, Type::Unbound, false),
new AtomicType(AtomicType::TYPE_DOUBLE, Type::Unbound, true), } }
};
const AtomicType *AtomicType::UniformBool;
const AtomicType *AtomicType::VaryingBool;
const AtomicType *AtomicType::UnboundBool;
const AtomicType *AtomicType::UniformInt8;
const AtomicType *AtomicType::VaryingInt8;
const AtomicType *AtomicType::UnboundInt8;
const AtomicType *AtomicType::UniformUInt8;
const AtomicType *AtomicType::VaryingUInt8;
const AtomicType *AtomicType::UnboundUInt8;
const AtomicType *AtomicType::UniformInt16;
const AtomicType *AtomicType::VaryingInt16;
const AtomicType *AtomicType::UnboundInt16;
const AtomicType *AtomicType::UniformUInt16;
const AtomicType *AtomicType::VaryingUInt16;
const AtomicType *AtomicType::UnboundUInt16;
const AtomicType *AtomicType::UniformInt32;
const AtomicType *AtomicType::VaryingInt32;
const AtomicType *AtomicType::UnboundInt32;
const AtomicType *AtomicType::UniformUInt32;
const AtomicType *AtomicType::VaryingUInt32;
const AtomicType *AtomicType::UnboundUInt32;
const AtomicType *AtomicType::UniformFloat;
const AtomicType *AtomicType::VaryingFloat;
const AtomicType *AtomicType::UnboundFloat;
const AtomicType *AtomicType::UniformInt64;
const AtomicType *AtomicType::VaryingInt64;
const AtomicType *AtomicType::UnboundInt64;
const AtomicType *AtomicType::UniformUInt64;
const AtomicType *AtomicType::VaryingUInt64;
const AtomicType *AtomicType::UnboundUInt64;
const AtomicType *AtomicType::UniformDouble;
const AtomicType *AtomicType::VaryingDouble;
const AtomicType *AtomicType::UnboundDouble;
const AtomicType *AtomicType::UniformConstBool;
const AtomicType *AtomicType::VaryingConstBool;
const AtomicType *AtomicType::UnboundConstBool;
const AtomicType *AtomicType::UniformConstInt8;
const AtomicType *AtomicType::VaryingConstInt8;
const AtomicType *AtomicType::UnboundConstInt8;
const AtomicType *AtomicType::UniformConstUInt8;
const AtomicType *AtomicType::VaryingConstUInt8;
const AtomicType *AtomicType::UnboundConstUInt8;
const AtomicType *AtomicType::UniformConstInt16;
const AtomicType *AtomicType::VaryingConstInt16;
const AtomicType *AtomicType::UnboundConstInt16;
const AtomicType *AtomicType::UniformConstUInt16;
const AtomicType *AtomicType::VaryingConstUInt16;
const AtomicType *AtomicType::UnboundConstUInt16;
const AtomicType *AtomicType::UniformConstInt32;
const AtomicType *AtomicType::VaryingConstInt32;
const AtomicType *AtomicType::UnboundConstInt32;
const AtomicType *AtomicType::UniformConstUInt32;
const AtomicType *AtomicType::VaryingConstUInt32;
const AtomicType *AtomicType::UnboundConstUInt32;
const AtomicType *AtomicType::UniformConstFloat;
const AtomicType *AtomicType::VaryingConstFloat;
const AtomicType *AtomicType::UnboundConstFloat;
const AtomicType *AtomicType::UniformConstInt64;
const AtomicType *AtomicType::VaryingConstInt64;
const AtomicType *AtomicType::UnboundConstInt64;
const AtomicType *AtomicType::UniformConstUInt64;
const AtomicType *AtomicType::VaryingConstUInt64;
const AtomicType *AtomicType::UnboundConstUInt64;
const AtomicType *AtomicType::UniformConstDouble;
const AtomicType *AtomicType::VaryingConstDouble;
const AtomicType *AtomicType::UnboundConstDouble;
const AtomicType *AtomicType::Void = new AtomicType(TYPE_VOID, Type::Uniform, false);
void AtomicType::Init() {
UniformBool = typeTable[TYPE_BOOL][Type::Uniform][0];
VaryingBool = typeTable[TYPE_BOOL][Type::Varying][0];
UnboundBool = typeTable[TYPE_BOOL][Type::Unbound][0];
UniformInt8 = typeTable[TYPE_INT8][Type::Uniform][0];
VaryingInt8 = typeTable[TYPE_INT8][Type::Varying][0];
UnboundInt8 = typeTable[TYPE_INT8][Type::Unbound][0];
UniformUInt8 = typeTable[TYPE_UINT8][Type::Uniform][0];
VaryingUInt8 = typeTable[TYPE_UINT8][Type::Varying][0];
UnboundUInt8 = typeTable[TYPE_UINT8][Type::Unbound][0];
UniformInt16 = typeTable[TYPE_INT16][Type::Uniform][0];
VaryingInt16 = typeTable[TYPE_INT16][Type::Varying][0];
UnboundInt16 = typeTable[TYPE_INT16][Type::Unbound][0];
UniformUInt16 = typeTable[TYPE_UINT16][Type::Uniform][0];
VaryingUInt16 = typeTable[TYPE_UINT16][Type::Varying][0];
UnboundUInt16 = typeTable[TYPE_UINT16][Type::Unbound][0];
UniformInt32 = typeTable[TYPE_INT32][Type::Uniform][0];
VaryingInt32 = typeTable[TYPE_INT32][Type::Varying][0];
UnboundInt32 = typeTable[TYPE_INT32][Type::Unbound][0];
UniformUInt32 = typeTable[TYPE_UINT32][Type::Uniform][0];
VaryingUInt32 = typeTable[TYPE_UINT32][Type::Varying][0];
UnboundUInt32 = typeTable[TYPE_UINT32][Type::Unbound][0];
UniformFloat = typeTable[TYPE_FLOAT][Type::Uniform][0];
VaryingFloat = typeTable[TYPE_FLOAT][Type::Varying][0];
UnboundFloat = typeTable[TYPE_FLOAT][Type::Unbound][0];
UniformInt64 = typeTable[TYPE_INT64][Type::Uniform][0];
VaryingInt64 = typeTable[TYPE_INT64][Type::Varying][0];
UnboundInt64 = typeTable[TYPE_INT64][Type::Unbound][0];
UniformUInt64 = typeTable[TYPE_UINT64][Type::Uniform][0];
VaryingUInt64 = typeTable[TYPE_UINT64][Type::Varying][0];
UnboundUInt64 = typeTable[TYPE_UINT64][Type::Unbound][0];
UniformDouble = typeTable[TYPE_DOUBLE][Type::Uniform][0];
VaryingDouble = typeTable[TYPE_DOUBLE][Type::Varying][0];
UnboundDouble = typeTable[TYPE_DOUBLE][Type::Unbound][0];
UniformConstBool = typeTable[TYPE_BOOL][Type::Uniform][1];
VaryingConstBool = typeTable[TYPE_BOOL][Type::Varying][1];
UnboundConstBool = typeTable[TYPE_BOOL][Type::Unbound][1];
UniformConstInt8 = typeTable[TYPE_INT8][Type::Uniform][1];
VaryingConstInt8 = typeTable[TYPE_INT8][Type::Varying][1];
UnboundConstInt8 = typeTable[TYPE_INT8][Type::Unbound][1];
UniformConstUInt8 = typeTable[TYPE_UINT8][Type::Uniform][1];
VaryingConstUInt8 = typeTable[TYPE_UINT8][Type::Varying][1];
UnboundConstUInt8 = typeTable[TYPE_UINT8][Type::Unbound][1];
UniformConstInt16 = typeTable[TYPE_INT16][Type::Uniform][1];
VaryingConstInt16 = typeTable[TYPE_INT16][Type::Varying][1];
UnboundConstInt16 = typeTable[TYPE_INT16][Type::Unbound][1];
UniformConstUInt16 = typeTable[TYPE_UINT16][Type::Uniform][1];
VaryingConstUInt16 = typeTable[TYPE_UINT16][Type::Varying][1];
UnboundConstUInt16 = typeTable[TYPE_UINT16][Type::Unbound][1];
UniformConstInt32 = typeTable[TYPE_INT32][Type::Uniform][1];
VaryingConstInt32 = typeTable[TYPE_INT32][Type::Varying][1];
UnboundConstInt32 = typeTable[TYPE_INT32][Type::Unbound][1];
UniformConstUInt32 = typeTable[TYPE_UINT32][Type::Uniform][1];
VaryingConstUInt32 = typeTable[TYPE_UINT32][Type::Varying][1];
UnboundConstUInt32 = typeTable[TYPE_UINT32][Type::Unbound][1];
UniformConstFloat = typeTable[TYPE_FLOAT][Type::Uniform][1];
VaryingConstFloat = typeTable[TYPE_FLOAT][Type::Varying][1];
UnboundConstFloat = typeTable[TYPE_FLOAT][Type::Unbound][1];
UniformConstInt64 = typeTable[TYPE_INT64][Type::Uniform][1];
VaryingConstInt64 = typeTable[TYPE_INT64][Type::Varying][1];
UnboundConstInt64 = typeTable[TYPE_INT64][Type::Unbound][1];
UniformConstUInt64 = typeTable[TYPE_UINT64][Type::Uniform][1];
VaryingConstUInt64 = typeTable[TYPE_UINT64][Type::Varying][1];
UnboundConstUInt64 = typeTable[TYPE_UINT64][Type::Unbound][1];
UniformConstDouble = typeTable[TYPE_DOUBLE][Type::Uniform][1];
VaryingConstDouble = typeTable[TYPE_DOUBLE][Type::Varying][1];
UnboundConstDouble = typeTable[TYPE_DOUBLE][Type::Unbound][1];
}
AtomicType::AtomicType(BasicType bt, Variability v, bool ic) AtomicType::AtomicType(BasicType bt, Variability v, bool ic)
@@ -352,25 +172,37 @@ AtomicType::GetAsUnsignedType() const {
if (IsIntType() == false) if (IsIntType() == false)
return NULL; return NULL;
return typeTable[basicType + 1][variability][isConst ? 1 : 0]; switch (basicType) {
case TYPE_INT8:
return new AtomicType(TYPE_UINT8, variability, isConst);
case TYPE_INT16:
return new AtomicType(TYPE_UINT16, variability, isConst);
case TYPE_INT32:
return new AtomicType(TYPE_UINT32, variability, isConst);
case TYPE_INT64:
return new AtomicType(TYPE_UINT64, variability, isConst);
default:
FATAL("Unexpected basicType in GetAsUnsignedType()");
return NULL;
}
} }
const AtomicType * const AtomicType *
AtomicType::GetAsConstType() const { AtomicType::GetAsConstType() const {
if (this == AtomicType::Void) if (Type::Equal(this, AtomicType::Void) || isConst == true)
return this; return this;
return typeTable[basicType][variability][1]; return new AtomicType(basicType, variability, true);
} }
const AtomicType * const AtomicType *
AtomicType::GetAsNonConstType() const { AtomicType::GetAsNonConstType() const {
if (this == AtomicType::Void) if (Type::Equal(this, AtomicType::Void) || isConst == false)
return this; return this;
return typeTable[basicType][variability][0]; return new AtomicType(basicType, variability, false);
} }
@@ -382,22 +214,28 @@ AtomicType::GetBaseType() const {
const AtomicType * const AtomicType *
AtomicType::GetAsVaryingType() const { AtomicType::GetAsVaryingType() const {
Assert(this != AtomicType::Void); Assert(Type::Equal(this, AtomicType::Void) == false);
return typeTable[basicType][Varying][isConst ? 1 : 0]; if (variability == Varying)
return this;
return new AtomicType(basicType, Varying, isConst);
} }
const AtomicType * const AtomicType *
AtomicType::GetAsUniformType() const { AtomicType::GetAsUniformType() const {
Assert(this != AtomicType::Void); Assert(Type::Equal(this, AtomicType::Void) == false);
return typeTable[basicType][Uniform][isConst ? 1 : 0]; if (variability == Uniform)
return this;
return new AtomicType(basicType, Uniform, isConst);
} }
const AtomicType * const AtomicType *
AtomicType::GetAsUnboundVariabilityType() const { AtomicType::GetAsUnboundVariabilityType() const {
Assert(this != AtomicType::Void); Assert(Type::Equal(this, AtomicType::Void) == false);
return typeTable[basicType][Unbound][isConst ? 1 : 0]; if (variability == Unbound)
return this;
return new AtomicType(basicType, Unbound, isConst);
} }
@@ -406,7 +244,7 @@ AtomicType::ResolveUnboundVariability(Variability v) const {
Assert(v != Unbound); Assert(v != Unbound);
if (variability != Unbound) if (variability != Unbound)
return this; return this;
return typeTable[basicType][v][isConst ? 1 : 0]; return new AtomicType(basicType, v, isConst);
} }
@@ -1071,7 +909,7 @@ PointerType::LLVMType(llvm::LLVMContext *ctx) const {
// exported functions. // exported functions.
ptype = llvm::PointerType::get(ftype->LLVMFunctionType(ctx, true), 0); ptype = llvm::PointerType::get(ftype->LLVMFunctionType(ctx, true), 0);
else { else {
if (baseType == AtomicType::Void) if (Type::Equal(baseType, AtomicType::Void))
ptype = LLVMTypes::VoidPointerType; ptype = LLVMTypes::VoidPointerType;
else else
ptype = llvm::PointerType::get(baseType->LLVMType(ctx), 0); ptype = llvm::PointerType::get(baseType->LLVMType(ctx), 0);
@@ -1143,7 +981,7 @@ ArrayType::ArrayType(const Type *c, int a)
: child(c), numElements(a) { : child(c), numElements(a) {
// 0 -> unsized array. // 0 -> unsized array.
Assert(numElements >= 0); Assert(numElements >= 0);
Assert(c != AtomicType::Void); Assert(Type::Equal(c, AtomicType::Void) == false);
} }
@@ -1623,9 +1461,9 @@ VectorType::getVectorMemoryCount() const {
return numElements; return numElements;
else { else {
int nativeWidth = g->target.nativeVectorWidth; int nativeWidth = g->target.nativeVectorWidth;
if (base->GetAsUniformType() == AtomicType::UniformInt64 || if (Type::Equal(base->GetAsUniformType(), AtomicType::UniformInt64) ||
base->GetAsUniformType() == AtomicType::UniformUInt64 || Type::Equal(base->GetAsUniformType(), AtomicType::UniformUInt64) ||
base->GetAsUniformType() == AtomicType::UniformDouble) Type::Equal(base->GetAsUniformType(), AtomicType::UniformDouble))
// target.nativeVectorWidth should be in terms of 32-bit // target.nativeVectorWidth should be in terms of 32-bit
// values, so for the 64-bit guys, it takes half as many of // values, so for the 64-bit guys, it takes half as many of
// them to fill the native width // them to fill the native width
@@ -2382,7 +2220,7 @@ FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool includeMask) const {
Assert(m->errorCount > 0); Assert(m->errorCount > 0);
return NULL; return NULL;
} }
Assert(paramTypes[i] != AtomicType::Void); Assert(Type::Equal(paramTypes[i], AtomicType::Void) == false);
LLVM_TYPE_CONST llvm::Type *t = paramTypes[i]->LLVMType(ctx); LLVM_TYPE_CONST llvm::Type *t = paramTypes[i]->LLVMType(ctx);
if (t == NULL) { if (t == NULL) {
@@ -2664,14 +2502,15 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
if (dynamic_cast<const FunctionType *>(b) == NULL) if (dynamic_cast<const FunctionType *>(b) == NULL)
b = b->GetAsNonConstType(); b = b->GetAsNonConstType();
} }
else if (a->IsConstType() != b->IsConstType())
return false;
// We can compare AtomicTypes with pointer equality, since the const AtomicType *ata = dynamic_cast<const AtomicType *>(a);
// AtomicType constructor is private so that there isonly the single const AtomicType *atb = dynamic_cast<const AtomicType *>(b);
// canonical instance of the AtomicTypes (AtomicType::UniformInt32, if (ata != NULL && atb != NULL) {
// etc.) return ((ata->basicType == atb->basicType) &&
if (dynamic_cast<const AtomicType *>(a) != NULL && (ata->GetVariability() == atb->GetVariability()));
dynamic_cast<const AtomicType *>(b) != NULL) }
return a == b;
// For all of the other types, we need to see if we have the same two // For all of the other types, we need to see if we have the same two
// general types. If so, then we dig into the details of the type and // general types. If so, then we dig into the details of the type and
@@ -2681,14 +2520,13 @@ lCheckTypeEquality(const Type *a, const Type *b, bool ignoreConst) {
if (eta != NULL && etb != NULL) if (eta != NULL && etb != NULL)
// Kind of goofy, but this sufficies to check // Kind of goofy, but this sufficies to check
return (eta->pos == etb->pos && return (eta->pos == etb->pos &&
eta->IsUniformType() == etb->IsUniformType() && eta->GetVariability() == etb->GetVariability());
eta->IsConstType() == etb->IsConstType());
const ArrayType *ata = dynamic_cast<const ArrayType *>(a); const ArrayType *arta = dynamic_cast<const ArrayType *>(a);
const ArrayType *atb = dynamic_cast<const ArrayType *>(b); const ArrayType *artb = dynamic_cast<const ArrayType *>(b);
if (ata != NULL && atb != NULL) if (arta != NULL && artb != NULL)
return (ata->GetElementCount() == atb->GetElementCount() && return (arta->GetElementCount() == artb->GetElementCount() &&
lCheckTypeEquality(ata->GetElementType(), atb->GetElementType(), lCheckTypeEquality(arta->GetElementType(), artb->GetElementType(),
ignoreConst)); ignoreConst));
const VectorType *vta = dynamic_cast<const VectorType *>(a); const VectorType *vta = dynamic_cast<const VectorType *>(a);

39
type.h
View File

@@ -251,37 +251,20 @@ public:
const BasicType basicType; const BasicType basicType;
static const AtomicType *UniformBool, *VaryingBool, *UnboundBool; static const AtomicType *UniformBool, *VaryingBool;
static const AtomicType *UniformInt8, *VaryingInt8, *UnboundInt8; static const AtomicType *UniformInt8, *VaryingInt8;
static const AtomicType *UniformInt16, *VaryingInt16, *UnboundInt16; static const AtomicType *UniformInt16, *VaryingInt16;
static const AtomicType *UniformInt32, *VaryingInt32, *UnboundInt32; static const AtomicType *UniformInt32, *VaryingInt32;
static const AtomicType *UniformUInt8, *VaryingUInt8, *UnboundUInt8; static const AtomicType *UniformUInt8, *VaryingUInt8;
static const AtomicType *UniformUInt16, *VaryingUInt16, *UnboundUInt16; static const AtomicType *UniformUInt16, *VaryingUInt16;
static const AtomicType *UniformUInt32, *VaryingUInt32, *UnboundUInt32; static const AtomicType *UniformUInt32, *VaryingUInt32;
static const AtomicType *UniformFloat, *VaryingFloat, *UnboundFloat; static const AtomicType *UniformFloat, *VaryingFloat;
static const AtomicType *UniformInt64, *VaryingInt64, *UnboundInt64; static const AtomicType *UniformInt64, *VaryingInt64;
static const AtomicType *UniformUInt64, *VaryingUInt64, *UnboundUInt64; static const AtomicType *UniformUInt64, *VaryingUInt64;
static const AtomicType *UniformDouble, *VaryingDouble, *UnboundDouble; static const AtomicType *UniformDouble, *VaryingDouble;
static const AtomicType *UniformConstBool, *VaryingConstBool, *UnboundConstBool;
static const AtomicType *UniformConstInt8, *VaryingConstInt8, *UnboundConstInt8;
static const AtomicType *UniformConstInt16, *VaryingConstInt16, *UnboundConstInt16;
static const AtomicType *UniformConstInt32, *VaryingConstInt32, *UnboundConstInt32;
static const AtomicType *UniformConstUInt8, *VaryingConstUInt8, *UnboundConstUInt8;
static const AtomicType *UniformConstUInt16, *VaryingConstUInt16, *UnboundConstUInt16;
static const AtomicType *UniformConstUInt32, *VaryingConstUInt32, *UnboundConstUInt32;
static const AtomicType *UniformConstFloat, *VaryingConstFloat, *UnboundConstFloat;
static const AtomicType *UniformConstInt64, *VaryingConstInt64, *UnboundConstInt64;
static const AtomicType *UniformConstUInt64, *VaryingConstUInt64, *UnboundConstUInt64;
static const AtomicType *UniformConstDouble, *VaryingConstDouble, *UnboundConstDouble;
static const AtomicType *Void; static const AtomicType *Void;
/** This function must be called before any of the above static const
AtomicType values is used; in practice, we do it early in
main(). */
static void Init();
private: private:
static const AtomicType *typeTable[NUM_BASIC_TYPES][3][2];
const Variability variability; const Variability variability;
const bool isConst; const bool isConst;
AtomicType(BasicType basicType, Variability v, bool isConst); AtomicType(BasicType basicType, Variability v, bool isConst);