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:
10
builtins.cpp
10
builtins.cpp
@@ -627,8 +627,9 @@ 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 =
|
||||||
SC_STATIC);
|
new Symbol(name, SourcePos(), AtomicType::UniformInt32->GetAsConstType(),
|
||||||
|
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;
|
||||||
llvm::Constant *linit = LLVMInt32(val);
|
llvm::Constant *linit = LLVMInt32(val);
|
||||||
@@ -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
32
ctx.cpp
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
27
decl.cpp
27
decl.cpp
@@ -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
188
expr.cpp
@@ -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;
|
||||||
|
|
||||||
|
|||||||
2
func.cpp
2
func.cpp
@@ -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());
|
||||||
|
|||||||
2
main.cpp
2
main.cpp
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
58
parse.yy
58
parse.yy
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
44
stmt.cpp
44
stmt.cpp
@@ -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
354
type.cpp
@@ -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
39
type.h
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user