Represent variability with small helper class rather than an enum.
This provides part of the basis for representing SOA width in terms of variability, but there should be no functional changes in this checkin.
This commit is contained in:
33
decl.cpp
33
decl.cpp
@@ -93,15 +93,20 @@ lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) {
|
|||||||
const Type *unsignedType = type->GetAsUnsignedType();
|
const Type *unsignedType = type->GetAsUnsignedType();
|
||||||
if (unsignedType != NULL)
|
if (unsignedType != NULL)
|
||||||
type = unsignedType;
|
type = unsignedType;
|
||||||
else
|
else {
|
||||||
|
const Type *resolvedType =
|
||||||
|
type->ResolveUnboundVariability(Variability::Varying);
|
||||||
Error(pos, "\"unsigned\" qualifier is illegal with \"%s\" type.",
|
Error(pos, "\"unsigned\" qualifier is illegal with \"%s\" type.",
|
||||||
type->ResolveUnboundVariability(Type::Varying)->GetString().c_str());
|
resolvedType->GetString().c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((typeQualifiers & TYPEQUAL_SIGNED) != 0 && type->IsIntType() == false)
|
if ((typeQualifiers & TYPEQUAL_SIGNED) != 0 && type->IsIntType() == false) {
|
||||||
|
const Type *resolvedType =
|
||||||
|
type->ResolveUnboundVariability(Variability::Varying);
|
||||||
Error(pos, "\"signed\" qualifier is illegal with non-integer type "
|
Error(pos, "\"signed\" qualifier is illegal with non-integer type "
|
||||||
"\"%s\".",
|
"\"%s\".", resolvedType->GetString().c_str());
|
||||||
type->ResolveUnboundVariability(Type::Varying)->GetString().c_str());
|
}
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
@@ -290,13 +295,13 @@ Declarator::GetFunctionInfo(DeclSpecs *ds, std::vector<Symbol *> *funArgs) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sym->type = sym->type->ResolveUnboundVariability(Type::Varying);
|
sym->type = sym->type->ResolveUnboundVariability(Variability::Varying);
|
||||||
|
|
||||||
funArgs->push_back(sym);
|
funArgs->push_back(sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (funSym != NULL)
|
if (funSym != NULL)
|
||||||
funSym->type = funSym->type->ResolveUnboundVariability(Type::Varying);
|
funSym->type = funSym->type->ResolveUnboundVariability(Variability::Varying);
|
||||||
|
|
||||||
return funSym;
|
return funSym;
|
||||||
}
|
}
|
||||||
@@ -316,11 +321,11 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const {
|
|||||||
if (kind != DK_FUNCTION && isTask)
|
if (kind != DK_FUNCTION && isTask)
|
||||||
Error(pos, "\"task\" qualifier illegal in variable declaration.");
|
Error(pos, "\"task\" qualifier illegal in variable declaration.");
|
||||||
|
|
||||||
Type::Variability variability = Type::Unbound;
|
Variability variability(Variability::Unbound);
|
||||||
if (hasUniformQual)
|
if (hasUniformQual)
|
||||||
variability = Type::Uniform;
|
variability = Variability::Uniform;
|
||||||
else if (hasVaryingQual)
|
else if (hasVaryingQual)
|
||||||
variability = Type::Varying;
|
variability = Variability::Varying;
|
||||||
|
|
||||||
const Type *type = base;
|
const Type *type = base;
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
@@ -420,7 +425,7 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const {
|
|||||||
|
|
||||||
const Type *targetType = at->GetElementType();
|
const Type *targetType = at->GetElementType();
|
||||||
targetType =
|
targetType =
|
||||||
targetType->ResolveUnboundVariability(Type::Varying);
|
targetType->ResolveUnboundVariability(Variability::Varying);
|
||||||
sym->type = PointerType::GetUniform(targetType);
|
sym->type = PointerType::GetUniform(targetType);
|
||||||
|
|
||||||
// Make sure there are no unsized arrays (other than the
|
// Make sure there are no unsized arrays (other than the
|
||||||
@@ -499,7 +504,7 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const {
|
|||||||
const Type *functionType =
|
const Type *functionType =
|
||||||
new FunctionType(returnType, args, argNames, argDefaults,
|
new FunctionType(returnType, args, argNames, argDefaults,
|
||||||
argPos, isTask, isExported, isExternC);
|
argPos, isTask, isExported, isExternC);
|
||||||
functionType = functionType->ResolveUnboundVariability(Type::Varying);
|
functionType = functionType->ResolveUnboundVariability(Variability::Varying);
|
||||||
return child->GetType(functionType, ds);
|
return child->GetType(functionType, ds);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -587,7 +592,7 @@ Declaration::GetVariableDeclarations() const {
|
|||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
sym->type = sym->type->ResolveUnboundVariability(Type::Varying);
|
sym->type = sym->type->ResolveUnboundVariability(Variability::Varying);
|
||||||
|
|
||||||
if (Type::Equal(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.");
|
||||||
@@ -618,7 +623,7 @@ Declaration::DeclareFunctions() {
|
|||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
sym->type = sym->type->ResolveUnboundVariability(Type::Varying);
|
sym->type = sym->type->ResolveUnboundVariability(Variability::Varying);
|
||||||
|
|
||||||
if (dynamic_cast<const FunctionType *>(sym->type) == NULL)
|
if (dynamic_cast<const FunctionType *>(sym->type) == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
8
expr.cpp
8
expr.cpp
@@ -6250,7 +6250,7 @@ TypeCastExpr::TypeCheck() {
|
|||||||
expr, pos);
|
expr, pos);
|
||||||
return ::TypeCheck(tce);
|
return ::TypeCheck(tce);
|
||||||
}
|
}
|
||||||
type = toType = type->ResolveUnboundVariability(Type::Varying);
|
type = toType = type->ResolveUnboundVariability(Variability::Varying);
|
||||||
|
|
||||||
fromType = lDeconstifyType(fromType);
|
fromType = lDeconstifyType(fromType);
|
||||||
toType = lDeconstifyType(toType);
|
toType = lDeconstifyType(toType);
|
||||||
@@ -6718,7 +6718,7 @@ SizeOfExpr::SizeOfExpr(Expr *e, SourcePos p)
|
|||||||
SizeOfExpr::SizeOfExpr(const Type *t, SourcePos p)
|
SizeOfExpr::SizeOfExpr(const Type *t, SourcePos p)
|
||||||
: Expr(p), expr(NULL), type(t) {
|
: Expr(p), expr(NULL), type(t) {
|
||||||
if (type->HasUnboundVariability())
|
if (type->HasUnboundVariability())
|
||||||
type = type->ResolveUnboundVariability(Type::Varying);
|
type = type->ResolveUnboundVariability(Variability::Varying);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6884,7 +6884,7 @@ FunctionSymbolExpr::GetType() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return matchingFunc ?
|
return matchingFunc ?
|
||||||
new PointerType(matchingFunc->type, Type::Uniform, true) : NULL;
|
new PointerType(matchingFunc->type, Variability::Uniform, true) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -7439,7 +7439,7 @@ NewExpr::NewExpr(int typeQual, const Type *t, Expr *init, Expr *count,
|
|||||||
isVarying = (typeQual == 0) || (typeQual & TYPEQUAL_VARYING);
|
isVarying = (typeQual == 0) || (typeQual & TYPEQUAL_VARYING);
|
||||||
|
|
||||||
if (allocType != NULL && allocType->HasUnboundVariability())
|
if (allocType != NULL && allocType->HasUnboundVariability())
|
||||||
allocType = allocType->ResolveUnboundVariability(Type::Uniform);
|
allocType = allocType->ResolveUnboundVariability(Variability::Uniform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
12
parse.yy
12
parse.yy
@@ -746,7 +746,7 @@ struct_or_union_specifier
|
|||||||
GetStructTypesNamesPositions(*$4, &elementTypes, &elementNames,
|
GetStructTypesNamesPositions(*$4, &elementTypes, &elementNames,
|
||||||
&elementPositions);
|
&elementPositions);
|
||||||
StructType *st = new StructType($2, elementTypes, elementNames,
|
StructType *st = new StructType($2, elementTypes, elementNames,
|
||||||
elementPositions, false, Type::Unbound, @2);
|
elementPositions, false, Variability::Unbound, @2);
|
||||||
m->symbolTable->AddType($2, st, @2);
|
m->symbolTable->AddType($2, st, @2);
|
||||||
$$ = st;
|
$$ = st;
|
||||||
}
|
}
|
||||||
@@ -763,7 +763,7 @@ struct_or_union_specifier
|
|||||||
&elementPositions);
|
&elementPositions);
|
||||||
// FIXME: should be unbound
|
// FIXME: should be unbound
|
||||||
$$ = new StructType("", elementTypes, elementNames, elementPositions,
|
$$ = new StructType("", elementTypes, elementNames, elementPositions,
|
||||||
false, Type::Unbound, @1);
|
false, Variability::Unbound, @1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
@@ -849,7 +849,7 @@ specifier_qualifier_list
|
|||||||
else if ($1 == TYPEQUAL_SIGNED) {
|
else if ($1 == TYPEQUAL_SIGNED) {
|
||||||
if ($2->IsIntType() == false) {
|
if ($2->IsIntType() == false) {
|
||||||
Error(@1, "Can't apply \"signed\" qualifier to \"%s\" type.",
|
Error(@1, "Can't apply \"signed\" qualifier to \"%s\" type.",
|
||||||
$2->ResolveUnboundVariability(Type::Varying)->GetString().c_str());
|
$2->ResolveUnboundVariability(Variability::Varying)->GetString().c_str());
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -859,7 +859,7 @@ specifier_qualifier_list
|
|||||||
$$ = t;
|
$$ = t;
|
||||||
else {
|
else {
|
||||||
Error(@1, "Can't apply \"unsigned\" qualifier to \"%s\" type. Ignoring.",
|
Error(@1, "Can't apply \"unsigned\" qualifier to \"%s\" type. Ignoring.",
|
||||||
$2->ResolveUnboundVariability(Type::Varying)->GetString().c_str());
|
$2->ResolveUnboundVariability(Variability::Varying)->GetString().c_str());
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1827,7 +1827,7 @@ lAddDeclaration(DeclSpecs *ds, Declarator *decl) {
|
|||||||
if (sym->type == NULL)
|
if (sym->type == NULL)
|
||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
else
|
else
|
||||||
sym->type = sym->type->ResolveUnboundVariability(Type::Varying);
|
sym->type = sym->type->ResolveUnboundVariability(Variability::Varying);
|
||||||
bool isConst = (ds->typeQualifiers & TYPEQUAL_CONST) != 0;
|
bool isConst = (ds->typeQualifiers & TYPEQUAL_CONST) != 0;
|
||||||
m->AddGlobalVariable(sym, decl->initExpr, isConst);
|
m->AddGlobalVariable(sym, decl->initExpr, isConst);
|
||||||
}
|
}
|
||||||
@@ -1864,7 +1864,7 @@ lAddFunctionParams(Declarator *decl) {
|
|||||||
if (sym == NULL || sym->type == NULL)
|
if (sym == NULL || sym->type == NULL)
|
||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
else {
|
else {
|
||||||
sym->type = sym->type->ResolveUnboundVariability(Type::Varying);
|
sym->type = sym->type->ResolveUnboundVariability(Variability::Varying);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
bool ok = m->symbolTable->AddVariable(sym);
|
bool ok = m->symbolTable->AddVariable(sym);
|
||||||
if (ok == false)
|
if (ok == false)
|
||||||
|
|||||||
292
type.cpp
292
type.cpp
@@ -37,7 +37,6 @@
|
|||||||
|
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "util.h"
|
|
||||||
#include "sym.h"
|
#include "sym.h"
|
||||||
#include "llvmutil.h"
|
#include "llvmutil.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
@@ -67,56 +66,96 @@ lShouldPrintName(const std::string &name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Variability
|
||||||
|
|
||||||
|
std::string
|
||||||
|
Variability::GetString() const {
|
||||||
|
switch (type) {
|
||||||
|
case Uniform: return "uniform";
|
||||||
|
case Varying: return "varying";
|
||||||
|
case SOA: {
|
||||||
|
char buf[32];
|
||||||
|
sprintf(buf, "soa<%d>", soaWidth);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
case Unbound: return "/*unbound*/";
|
||||||
|
default:
|
||||||
|
FATAL("Unhandled variability");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string
|
||||||
|
Variability::MangleString() const {
|
||||||
|
switch (type) {
|
||||||
|
case Uniform:
|
||||||
|
return "un";
|
||||||
|
case Varying:
|
||||||
|
return "vy";
|
||||||
|
case SOA: {
|
||||||
|
char buf[32];
|
||||||
|
sprintf(buf, "soa<%d>", soaWidth);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
case Unbound:
|
||||||
|
FATAL("Unbound unexpected in Variability::MangleString()");
|
||||||
|
default:
|
||||||
|
FATAL("Unhandled variability");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// AtomicType
|
// AtomicType
|
||||||
|
|
||||||
|
|
||||||
const AtomicType *AtomicType::UniformBool =
|
const AtomicType *AtomicType::UniformBool =
|
||||||
new AtomicType(AtomicType::TYPE_BOOL, Uniform, false);
|
new AtomicType(AtomicType::TYPE_BOOL, Variability::Uniform, false);
|
||||||
const AtomicType *AtomicType::VaryingBool =
|
const AtomicType *AtomicType::VaryingBool =
|
||||||
new AtomicType(AtomicType::TYPE_BOOL, Varying, false);
|
new AtomicType(AtomicType::TYPE_BOOL, Variability::Varying, false);
|
||||||
const AtomicType *AtomicType::UniformInt8 =
|
const AtomicType *AtomicType::UniformInt8 =
|
||||||
new AtomicType(AtomicType::TYPE_INT8, Uniform, false);
|
new AtomicType(AtomicType::TYPE_INT8, Variability::Uniform, false);
|
||||||
const AtomicType *AtomicType::VaryingInt8 =
|
const AtomicType *AtomicType::VaryingInt8 =
|
||||||
new AtomicType(AtomicType::TYPE_INT8, Varying, false);
|
new AtomicType(AtomicType::TYPE_INT8, Variability::Varying, false);
|
||||||
const AtomicType *AtomicType::UniformUInt8 =
|
const AtomicType *AtomicType::UniformUInt8 =
|
||||||
new AtomicType(AtomicType::TYPE_UINT8, Uniform, false);
|
new AtomicType(AtomicType::TYPE_UINT8, Variability::Uniform, false);
|
||||||
const AtomicType *AtomicType::VaryingUInt8 =
|
const AtomicType *AtomicType::VaryingUInt8 =
|
||||||
new AtomicType(AtomicType::TYPE_UINT8, Varying, false);
|
new AtomicType(AtomicType::TYPE_UINT8, Variability::Varying, false);
|
||||||
const AtomicType *AtomicType::UniformInt16 =
|
const AtomicType *AtomicType::UniformInt16 =
|
||||||
new AtomicType(AtomicType::TYPE_INT16, Uniform, false);
|
new AtomicType(AtomicType::TYPE_INT16, Variability::Uniform, false);
|
||||||
const AtomicType *AtomicType::VaryingInt16 =
|
const AtomicType *AtomicType::VaryingInt16 =
|
||||||
new AtomicType(AtomicType::TYPE_INT16, Varying, false);
|
new AtomicType(AtomicType::TYPE_INT16, Variability::Varying, false);
|
||||||
const AtomicType *AtomicType::UniformUInt16 =
|
const AtomicType *AtomicType::UniformUInt16 =
|
||||||
new AtomicType(AtomicType::TYPE_UINT16, Uniform, false);
|
new AtomicType(AtomicType::TYPE_UINT16, Variability::Uniform, false);
|
||||||
const AtomicType *AtomicType::VaryingUInt16 =
|
const AtomicType *AtomicType::VaryingUInt16 =
|
||||||
new AtomicType(AtomicType::TYPE_UINT16, Varying, false);
|
new AtomicType(AtomicType::TYPE_UINT16, Variability::Varying, false);
|
||||||
const AtomicType *AtomicType::UniformInt32 =
|
const AtomicType *AtomicType::UniformInt32 =
|
||||||
new AtomicType(AtomicType::TYPE_INT32, Uniform, false);
|
new AtomicType(AtomicType::TYPE_INT32, Variability::Uniform, false);
|
||||||
const AtomicType *AtomicType::VaryingInt32 =
|
const AtomicType *AtomicType::VaryingInt32 =
|
||||||
new AtomicType(AtomicType::TYPE_INT32, Varying, false);
|
new AtomicType(AtomicType::TYPE_INT32, Variability::Varying, false);
|
||||||
const AtomicType *AtomicType::UniformUInt32 =
|
const AtomicType *AtomicType::UniformUInt32 =
|
||||||
new AtomicType(AtomicType::TYPE_UINT32, Uniform, false);
|
new AtomicType(AtomicType::TYPE_UINT32, Variability::Uniform, false);
|
||||||
const AtomicType *AtomicType::VaryingUInt32 =
|
const AtomicType *AtomicType::VaryingUInt32 =
|
||||||
new AtomicType(AtomicType::TYPE_UINT32, Varying, false);
|
new AtomicType(AtomicType::TYPE_UINT32, Variability::Varying, false);
|
||||||
const AtomicType *AtomicType::UniformFloat =
|
const AtomicType *AtomicType::UniformFloat =
|
||||||
new AtomicType(AtomicType::TYPE_FLOAT, Uniform, false);
|
new AtomicType(AtomicType::TYPE_FLOAT, Variability::Uniform, false);
|
||||||
const AtomicType *AtomicType::VaryingFloat =
|
const AtomicType *AtomicType::VaryingFloat =
|
||||||
new AtomicType(AtomicType::TYPE_FLOAT, Varying, false);
|
new AtomicType(AtomicType::TYPE_FLOAT, Variability::Varying, false);
|
||||||
const AtomicType *AtomicType::UniformInt64 =
|
const AtomicType *AtomicType::UniformInt64 =
|
||||||
new AtomicType(AtomicType::TYPE_INT64, Uniform, false);
|
new AtomicType(AtomicType::TYPE_INT64, Variability::Uniform, false);
|
||||||
const AtomicType *AtomicType::VaryingInt64 =
|
const AtomicType *AtomicType::VaryingInt64 =
|
||||||
new AtomicType(AtomicType::TYPE_INT64, Varying, false);
|
new AtomicType(AtomicType::TYPE_INT64, Variability::Varying, false);
|
||||||
const AtomicType *AtomicType::UniformUInt64 =
|
const AtomicType *AtomicType::UniformUInt64 =
|
||||||
new AtomicType(AtomicType::TYPE_UINT64, Uniform, false);
|
new AtomicType(AtomicType::TYPE_UINT64, Variability::Uniform, false);
|
||||||
const AtomicType *AtomicType::VaryingUInt64 =
|
const AtomicType *AtomicType::VaryingUInt64 =
|
||||||
new AtomicType(AtomicType::TYPE_UINT64, Varying, false);
|
new AtomicType(AtomicType::TYPE_UINT64, Variability::Varying, false);
|
||||||
const AtomicType *AtomicType::UniformDouble =
|
const AtomicType *AtomicType::UniformDouble =
|
||||||
new AtomicType(AtomicType::TYPE_DOUBLE, Uniform, false);
|
new AtomicType(AtomicType::TYPE_DOUBLE, Variability::Uniform, false);
|
||||||
const AtomicType *AtomicType::VaryingDouble =
|
const AtomicType *AtomicType::VaryingDouble =
|
||||||
new AtomicType(AtomicType::TYPE_DOUBLE, Varying, false);
|
new AtomicType(AtomicType::TYPE_DOUBLE, Variability::Varying, false);
|
||||||
const AtomicType *AtomicType::Void =
|
const AtomicType *AtomicType::Void =
|
||||||
new AtomicType(TYPE_VOID, Uniform, false);
|
new AtomicType(TYPE_VOID, Variability::Uniform, false);
|
||||||
|
|
||||||
|
|
||||||
AtomicType::AtomicType(BasicType bt, Variability v, bool ic)
|
AtomicType::AtomicType(BasicType bt, Variability v, bool ic)
|
||||||
@@ -124,7 +163,7 @@ AtomicType::AtomicType(BasicType bt, Variability v, bool ic)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Type::Variability
|
Variability
|
||||||
AtomicType::GetVariability() const {
|
AtomicType::GetVariability() const {
|
||||||
return variability;
|
return variability;
|
||||||
}
|
}
|
||||||
@@ -215,25 +254,27 @@ AtomicType::GetBaseType() const {
|
|||||||
const AtomicType *
|
const AtomicType *
|
||||||
AtomicType::GetAsVaryingType() const {
|
AtomicType::GetAsVaryingType() const {
|
||||||
Assert(Type::Equal(this, AtomicType::Void) == false);
|
Assert(Type::Equal(this, AtomicType::Void) == false);
|
||||||
if (variability == Varying)
|
if (variability == Variability::Varying)
|
||||||
return this;
|
return this;
|
||||||
return new AtomicType(basicType, Varying, isConst);
|
return new AtomicType(basicType, Variability::Varying, isConst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const AtomicType *
|
const AtomicType *
|
||||||
AtomicType::GetAsUniformType() const {
|
AtomicType::GetAsUniformType() const {
|
||||||
Assert(Type::Equal(this, AtomicType::Void) == false);
|
Assert(Type::Equal(this, AtomicType::Void) == false);
|
||||||
if (variability == Uniform)
|
if (variability == Variability::Uniform)
|
||||||
return this;
|
return this;
|
||||||
return new AtomicType(basicType, Uniform, isConst);
|
return new AtomicType(basicType, Variability::Uniform, isConst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const AtomicType *
|
const AtomicType *
|
||||||
AtomicType::GetAsUnboundVariabilityType() const {
|
AtomicType::GetAsUnboundVariabilityType() const {
|
||||||
Assert(Type::Equal(this, AtomicType::Void) == false);
|
Assert(Type::Equal(this, AtomicType::Void) == false);
|
||||||
if (variability == Unbound)
|
if (variability == Variability::Unbound)
|
||||||
|
return this;
|
||||||
|
return new AtomicType(basicType, Variability::Unbound, isConst);
|
||||||
return this;
|
return this;
|
||||||
return new AtomicType(basicType, Unbound, isConst);
|
return new AtomicType(basicType, Unbound, isConst);
|
||||||
}
|
}
|
||||||
@@ -241,8 +282,8 @@ AtomicType::GetAsUnboundVariabilityType() const {
|
|||||||
|
|
||||||
const AtomicType *
|
const AtomicType *
|
||||||
AtomicType::ResolveUnboundVariability(Variability v) const {
|
AtomicType::ResolveUnboundVariability(Variability v) const {
|
||||||
Assert(v != Unbound);
|
Assert(v != Variability::Unbound);
|
||||||
if (variability != Unbound)
|
if (variability != Variability::Unbound)
|
||||||
return this;
|
return this;
|
||||||
return new AtomicType(basicType, v, isConst);
|
return new AtomicType(basicType, v, isConst);
|
||||||
}
|
}
|
||||||
@@ -253,11 +294,8 @@ AtomicType::GetString() const {
|
|||||||
std::string ret;
|
std::string ret;
|
||||||
if (basicType != TYPE_VOID) {
|
if (basicType != TYPE_VOID) {
|
||||||
if (isConst) ret += "const ";
|
if (isConst) ret += "const ";
|
||||||
switch (variability) {
|
ret += variability.GetString();
|
||||||
case Uniform: ret += "uniform "; break;
|
ret += " ";
|
||||||
case Varying: ret += "varying "; break;
|
|
||||||
case Unbound: ret += "/*unbound*/ "; break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (basicType) {
|
switch (basicType) {
|
||||||
@@ -283,12 +321,7 @@ std::string
|
|||||||
AtomicType::Mangle() const {
|
AtomicType::Mangle() const {
|
||||||
std::string ret;
|
std::string ret;
|
||||||
if (isConst) ret += "C";
|
if (isConst) ret += "C";
|
||||||
switch (variability) {
|
ret += variability.MangleString();
|
||||||
case Uniform: ret += "uf"; break;
|
|
||||||
case Varying: ret += "vy"; break;
|
|
||||||
case Unbound: FATAL("Variability shoudln't be unbound in call to "
|
|
||||||
"AtomicType::Mangle().");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (basicType) {
|
switch (basicType) {
|
||||||
case TYPE_VOID: ret += "v"; break;
|
case TYPE_VOID: ret += "v"; break;
|
||||||
@@ -312,7 +345,8 @@ AtomicType::Mangle() const {
|
|||||||
std::string
|
std::string
|
||||||
AtomicType::GetCDeclaration(const std::string &name) const {
|
AtomicType::GetCDeclaration(const std::string &name) const {
|
||||||
std::string ret;
|
std::string ret;
|
||||||
if (variability != Uniform) {
|
if (variability != Variability::Uniform &&
|
||||||
|
variability != Variability::SOA) {
|
||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -344,8 +378,8 @@ AtomicType::GetCDeclaration(const std::string &name) const {
|
|||||||
|
|
||||||
LLVM_TYPE_CONST llvm::Type *
|
LLVM_TYPE_CONST llvm::Type *
|
||||||
AtomicType::LLVMType(llvm::LLVMContext *ctx) const {
|
AtomicType::LLVMType(llvm::LLVMContext *ctx) const {
|
||||||
Assert(variability != Unbound);
|
Assert(variability.type != Variability::Unbound);
|
||||||
bool isUniform = (variability == Uniform);
|
bool isUniform = (variability == Variability::Uniform);
|
||||||
|
|
||||||
switch (basicType) {
|
switch (basicType) {
|
||||||
case TYPE_VOID:
|
case TYPE_VOID:
|
||||||
@@ -377,8 +411,9 @@ AtomicType::LLVMType(llvm::LLVMContext *ctx) const {
|
|||||||
|
|
||||||
llvm::DIType
|
llvm::DIType
|
||||||
AtomicType::GetDIType(llvm::DIDescriptor scope) const {
|
AtomicType::GetDIType(llvm::DIDescriptor scope) const {
|
||||||
Assert(variability != Unbound);
|
Assert(variability.type != Variability::Unbound);
|
||||||
if (variability == Uniform) {
|
|
||||||
|
if (variability.type == Variability::Uniform) {
|
||||||
switch (basicType) {
|
switch (basicType) {
|
||||||
case TYPE_VOID:
|
case TYPE_VOID:
|
||||||
return llvm::DIType();
|
return llvm::DIType();
|
||||||
@@ -454,18 +489,18 @@ EnumType::EnumType(SourcePos p)
|
|||||||
: pos(p) {
|
: pos(p) {
|
||||||
// name = "/* (anonymous) */";
|
// name = "/* (anonymous) */";
|
||||||
isConst = false;
|
isConst = false;
|
||||||
variability = Unbound;
|
variability = Variability(Variability::Unbound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EnumType::EnumType(const char *n, SourcePos p)
|
EnumType::EnumType(const char *n, SourcePos p)
|
||||||
: pos(p), name(n) {
|
: pos(p), name(n) {
|
||||||
isConst = false;
|
isConst = false;
|
||||||
variability = Unbound;
|
variability = Variability(Variability::Unbound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Type::Variability
|
Variability
|
||||||
EnumType::GetVariability() const {
|
EnumType::GetVariability() const {
|
||||||
return variability;
|
return variability;
|
||||||
}
|
}
|
||||||
@@ -513,7 +548,7 @@ EnumType::GetAsUniformType() const {
|
|||||||
return this;
|
return this;
|
||||||
else {
|
else {
|
||||||
EnumType *enumType = new EnumType(*this);
|
EnumType *enumType = new EnumType(*this);
|
||||||
enumType->variability = Uniform;
|
enumType->variability = Variability::Uniform;
|
||||||
return enumType;
|
return enumType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -521,7 +556,7 @@ EnumType::GetAsUniformType() const {
|
|||||||
|
|
||||||
const EnumType *
|
const EnumType *
|
||||||
EnumType::ResolveUnboundVariability(Variability v) const {
|
EnumType::ResolveUnboundVariability(Variability v) const {
|
||||||
if (variability == v || variability != Unbound)
|
if (variability != Variability::Unbound)
|
||||||
return this;
|
return this;
|
||||||
else {
|
else {
|
||||||
EnumType *enumType = new EnumType(*this);
|
EnumType *enumType = new EnumType(*this);
|
||||||
@@ -537,7 +572,7 @@ EnumType::GetAsVaryingType() const {
|
|||||||
return this;
|
return this;
|
||||||
else {
|
else {
|
||||||
EnumType *enumType = new EnumType(*this);
|
EnumType *enumType = new EnumType(*this);
|
||||||
enumType->variability = Varying;
|
enumType->variability = Variability(Variability::Varying);
|
||||||
return enumType;
|
return enumType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -549,7 +584,7 @@ EnumType::GetAsUnboundVariabilityType() const {
|
|||||||
return this;
|
return this;
|
||||||
else {
|
else {
|
||||||
EnumType *enumType = new EnumType(*this);
|
EnumType *enumType = new EnumType(*this);
|
||||||
enumType->variability = Unbound;
|
enumType->variability = Variability(Variability::Unbound);
|
||||||
return enumType;
|
return enumType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -583,12 +618,7 @@ std::string
|
|||||||
EnumType::GetString() const {
|
EnumType::GetString() const {
|
||||||
std::string ret;
|
std::string ret;
|
||||||
if (isConst) ret += "const ";
|
if (isConst) ret += "const ";
|
||||||
|
ret += variability.GetString();
|
||||||
switch (variability) {
|
|
||||||
case Uniform: ret += "uniform "; break;
|
|
||||||
case Varying: /*ret += "varying ";*/ break;
|
|
||||||
case Unbound: ret += "/*unbound*/ "; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret += " enum ";
|
ret += " enum ";
|
||||||
if (name.size())
|
if (name.size())
|
||||||
@@ -599,21 +629,20 @@ EnumType::GetString() const {
|
|||||||
|
|
||||||
std::string
|
std::string
|
||||||
EnumType::Mangle() const {
|
EnumType::Mangle() const {
|
||||||
|
Assert(variability != Variability::Unbound);
|
||||||
|
|
||||||
std::string ret;
|
std::string ret;
|
||||||
|
if (isConst) ret += "C";
|
||||||
Assert(variability != Unbound);
|
ret += variability.MangleString();
|
||||||
if (variability == Uniform) ret += "uf";
|
|
||||||
else ret += "vy";
|
|
||||||
|
|
||||||
ret += std::string("enum[") + name + std::string("]");
|
ret += std::string("enum[") + name + std::string("]");
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
EnumType::GetCDeclaration(const std::string &varName) const {
|
EnumType::GetCDeclaration(const std::string &varName) const {
|
||||||
if (variability != Uniform) {
|
if (variability != Variability::Uniform &&
|
||||||
|
variability != Variability::SOA) {
|
||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -623,6 +652,7 @@ EnumType::GetCDeclaration(const std::string &varName) const {
|
|||||||
ret += "enum";
|
ret += "enum";
|
||||||
if (name.size())
|
if (name.size())
|
||||||
ret += std::string(" ") + name;
|
ret += std::string(" ") + name;
|
||||||
|
|
||||||
if (lShouldPrintName(varName)) {
|
if (lShouldPrintName(varName)) {
|
||||||
ret += " ";
|
ret += " ";
|
||||||
ret += varName;
|
ret += varName;
|
||||||
@@ -633,15 +663,22 @@ EnumType::GetCDeclaration(const std::string &varName) const {
|
|||||||
|
|
||||||
LLVM_TYPE_CONST llvm::Type *
|
LLVM_TYPE_CONST llvm::Type *
|
||||||
EnumType::LLVMType(llvm::LLVMContext *ctx) const {
|
EnumType::LLVMType(llvm::LLVMContext *ctx) const {
|
||||||
Assert(variability != Unbound);
|
Assert(variability != Variability::Unbound);
|
||||||
return (variability == Uniform) ? LLVMTypes::Int32Type :
|
|
||||||
LLVMTypes::Int32VectorType;
|
switch (variability.type) {
|
||||||
|
case Variability::Uniform:
|
||||||
|
return LLVMTypes::Int32Type;
|
||||||
|
case Variability::Varying:
|
||||||
|
return LLVMTypes::Int32VectorType;
|
||||||
|
default:
|
||||||
|
FATAL("Unexpected variability in EnumType::LLVMType()");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
llvm::DIType
|
llvm::DIType
|
||||||
EnumType::GetDIType(llvm::DIDescriptor scope) const {
|
EnumType::GetDIType(llvm::DIDescriptor scope) const {
|
||||||
Assert(variability != Unbound);
|
|
||||||
std::vector<llvm::Value *> enumeratorDescriptors;
|
std::vector<llvm::Value *> enumeratorDescriptors;
|
||||||
for (unsigned int i = 0; i < enumerators.size(); ++i) {
|
for (unsigned int i = 0; i < enumerators.size(); ++i) {
|
||||||
unsigned int enumeratorValue;
|
unsigned int enumeratorValue;
|
||||||
@@ -705,7 +742,9 @@ EnumType::GetEnumerator(int i) const {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// PointerType
|
// PointerType
|
||||||
|
|
||||||
PointerType *PointerType::Void = new PointerType(AtomicType::Void, Uniform, false);
|
PointerType *PointerType::Void =
|
||||||
|
new PointerType(AtomicType::Void, Variability(Variability::Uniform), false);
|
||||||
|
|
||||||
|
|
||||||
PointerType::PointerType(const Type *t, Variability v, bool ic)
|
PointerType::PointerType(const Type *t, Variability v, bool ic)
|
||||||
: variability(v), isConst(ic) {
|
: variability(v), isConst(ic) {
|
||||||
@@ -715,13 +754,13 @@ PointerType::PointerType(const Type *t, Variability v, bool ic)
|
|||||||
|
|
||||||
PointerType *
|
PointerType *
|
||||||
PointerType::GetUniform(const Type *t) {
|
PointerType::GetUniform(const Type *t) {
|
||||||
return new PointerType(t, Uniform, false);
|
return new PointerType(t, Variability(Variability::Uniform), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PointerType *
|
PointerType *
|
||||||
PointerType::GetVarying(const Type *t) {
|
PointerType::GetVarying(const Type *t) {
|
||||||
return new PointerType(t, Varying, false);
|
return new PointerType(t, Variability(Variability::Varying), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -732,7 +771,7 @@ PointerType::IsVoidPointer(const Type *t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Type::Variability
|
Variability
|
||||||
PointerType::GetVariability() const {
|
PointerType::GetVariability() const {
|
||||||
return variability;
|
return variability;
|
||||||
}
|
}
|
||||||
@@ -776,28 +815,28 @@ PointerType::GetBaseType() const {
|
|||||||
|
|
||||||
const PointerType *
|
const PointerType *
|
||||||
PointerType::GetAsVaryingType() const {
|
PointerType::GetAsVaryingType() const {
|
||||||
if (variability == Varying)
|
if (variability == Variability::Varying)
|
||||||
return this;
|
return this;
|
||||||
else
|
else
|
||||||
return new PointerType(baseType, Varying, isConst);
|
return new PointerType(baseType, Variability(Variability::Varying),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const PointerType *
|
const PointerType *
|
||||||
PointerType::GetAsUniformType() const {
|
PointerType::GetAsUniformType() const {
|
||||||
if (variability == Uniform)
|
if (variability == Variability::Uniform)
|
||||||
return this;
|
return this;
|
||||||
else
|
else
|
||||||
return new PointerType(baseType, Uniform, isConst);
|
return new PointerType(baseType, Variability(Variability::Uniform),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const PointerType *
|
const PointerType *
|
||||||
PointerType::GetAsUnboundVariabilityType() const {
|
PointerType::GetAsUnboundVariabilityType() const {
|
||||||
if (variability == Unbound)
|
if (variability == Variability::Unbound)
|
||||||
return this;
|
return this;
|
||||||
else
|
else
|
||||||
return new PointerType(baseType, Unbound, isConst);
|
return new PointerType(baseType, Variability(Variability::Unbound),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -808,10 +847,12 @@ PointerType::ResolveUnboundVariability(Variability v) const {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert(v != Unbound);
|
Assert(v != Variability::Unbound);
|
||||||
Variability ptrVariability = (variability == Unbound) ? v : variability;
|
Variability ptrVariability = (variability == Variability::Unbound) ? v :
|
||||||
const Type *resolvedBaseType = baseType->ResolveUnboundVariability(Uniform);
|
variability;
|
||||||
return new PointerType(resolvedBaseType, ptrVariability, isConst);
|
const Type *resolvedBaseType =
|
||||||
|
baseType->ResolveUnboundVariability(Variability::Uniform);
|
||||||
|
return new PointerType(resolvedBaseType, ptrVariability, isConst, isSlice,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -844,11 +885,7 @@ PointerType::GetString() const {
|
|||||||
|
|
||||||
ret += std::string(" * ");
|
ret += std::string(" * ");
|
||||||
if (isConst) ret += "const ";
|
if (isConst) ret += "const ";
|
||||||
switch (variability) {
|
ret += variability.GetString();
|
||||||
case Uniform: ret += " uniform"; break;
|
|
||||||
case Varying: ret += " varying"; break;
|
|
||||||
case Unbound: ret += " /*unbound*/"; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -856,14 +893,14 @@ PointerType::GetString() const {
|
|||||||
|
|
||||||
std::string
|
std::string
|
||||||
PointerType::Mangle() const {
|
PointerType::Mangle() const {
|
||||||
Assert(variability != Unbound);
|
Assert(variability != Variability::Unbound);
|
||||||
if (baseType == NULL) {
|
if (baseType == NULL) {
|
||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((variability == Uniform) ? std::string("uptr<") : std::string("vptr<")) +
|
std::string ret = variability.MangleString() + std::string("<");
|
||||||
baseType->Mangle() + std::string(">");
|
return ret + baseType->Mangle() + std::string(">");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -890,7 +927,6 @@ PointerType::GetCDeclaration(const std::string &name) const {
|
|||||||
|
|
||||||
LLVM_TYPE_CONST llvm::Type *
|
LLVM_TYPE_CONST llvm::Type *
|
||||||
PointerType::LLVMType(llvm::LLVMContext *ctx) const {
|
PointerType::LLVMType(llvm::LLVMContext *ctx) const {
|
||||||
Assert(variability != Unbound);
|
|
||||||
if (baseType == NULL) {
|
if (baseType == NULL) {
|
||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -947,7 +983,6 @@ lCreateDIArray(llvm::DIType eltType, int count) {
|
|||||||
|
|
||||||
llvm::DIType
|
llvm::DIType
|
||||||
PointerType::GetDIType(llvm::DIDescriptor scope) const {
|
PointerType::GetDIType(llvm::DIDescriptor scope) const {
|
||||||
Assert(variability != Unbound);
|
|
||||||
if (baseType == NULL) {
|
if (baseType == NULL) {
|
||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return llvm::DIType();
|
return llvm::DIType();
|
||||||
@@ -955,14 +990,19 @@ PointerType::GetDIType(llvm::DIDescriptor scope) const {
|
|||||||
|
|
||||||
llvm::DIType diTargetType = baseType->GetDIType(scope);
|
llvm::DIType diTargetType = baseType->GetDIType(scope);
|
||||||
int bitsSize = g->target.is32Bit ? 32 : 64;
|
int bitsSize = g->target.is32Bit ? 32 : 64;
|
||||||
if (variability == Uniform)
|
switch (variability.type) {
|
||||||
|
case Variability::Uniform:
|
||||||
return m->diBuilder->createPointerType(diTargetType, bitsSize);
|
return m->diBuilder->createPointerType(diTargetType, bitsSize);
|
||||||
else {
|
case Variability::Varying: {
|
||||||
// emit them as an array of pointers
|
// emit them as an array of pointers
|
||||||
llvm::DIType eltType = m->diBuilder->createPointerType(diTargetType,
|
llvm::DIType eltType = m->diBuilder->createPointerType(diTargetType,
|
||||||
bitsSize);
|
bitsSize);
|
||||||
return lCreateDIArray(eltType, g->target.vectorWidth);
|
return lCreateDIArray(eltType, g->target.vectorWidth);
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
FATAL("Unexpected variability in PointerType::GetDIType()");
|
||||||
|
return llvm::DIType();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1001,9 +1041,9 @@ ArrayType::LLVMType(llvm::LLVMContext *ctx) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Type::Variability
|
Variability
|
||||||
ArrayType::GetVariability() const {
|
ArrayType::GetVariability() const {
|
||||||
return child ? child->GetVariability() : Uniform;
|
return child ? child->GetVariability() : Variability(Variability::Uniform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1293,7 +1333,7 @@ VectorType::VectorType(const AtomicType *b, int a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Type::Variability
|
Variability
|
||||||
VectorType::GetVariability() const {
|
VectorType::GetVariability() const {
|
||||||
return base->GetVariability();
|
return base->GetVariability();
|
||||||
}
|
}
|
||||||
@@ -1487,7 +1527,7 @@ StructType::StructType(const std::string &n, const std::vector<const Type *> &el
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Type::Variability
|
Variability
|
||||||
StructType::GetVariability() const {
|
StructType::GetVariability() const {
|
||||||
return variability;
|
return variability;
|
||||||
}
|
}
|
||||||
@@ -1535,7 +1575,7 @@ StructType::GetAsVaryingType() const {
|
|||||||
return this;
|
return this;
|
||||||
else
|
else
|
||||||
return new StructType(name, elementTypes, elementNames, elementPositions,
|
return new StructType(name, elementTypes, elementNames, elementPositions,
|
||||||
isConst, Varying, pos);
|
isConst, Variability(Variability::Varying), pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1545,7 +1585,7 @@ StructType::GetAsUniformType() const {
|
|||||||
return this;
|
return this;
|
||||||
else
|
else
|
||||||
return new StructType(name, elementTypes, elementNames, elementPositions,
|
return new StructType(name, elementTypes, elementNames, elementPositions,
|
||||||
isConst, Uniform, pos);
|
isConst, Variability(Variability::Uniform), pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1555,21 +1595,23 @@ StructType::GetAsUnboundVariabilityType() const {
|
|||||||
return this;
|
return this;
|
||||||
else
|
else
|
||||||
return new StructType(name, elementTypes, elementNames, elementPositions,
|
return new StructType(name, elementTypes, elementNames, elementPositions,
|
||||||
isConst, Unbound, pos);
|
isConst, Variability(Variability::Unbound), pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const StructType *
|
const StructType *
|
||||||
StructType::ResolveUnboundVariability(Variability v) const {
|
StructType::ResolveUnboundVariability(Variability v) const {
|
||||||
Assert(v != Unbound);
|
Assert(v != Variability::Unbound);
|
||||||
|
|
||||||
|
if (variability != Variability::Unbound)
|
||||||
|
return this;
|
||||||
|
|
||||||
// We don't resolve the members here but leave them unbound, so that if
|
// We don't resolve the members here but leave them unbound, so that if
|
||||||
// resolve to varying but later want to get the uniform version of this
|
// resolve to varying but later want to get the uniform version of this
|
||||||
// type, for example, then we still have the information around about
|
// type, for example, then we still have the information around about
|
||||||
// which element types were originally unbound...
|
// which element types were originally unbound...
|
||||||
|
|
||||||
return new StructType(name, elementTypes, elementNames, elementPositions,
|
return new StructType(name, elementTypes, elementNames, elementPositions,
|
||||||
isConst, (variability != Unbound) ? variability : v,
|
isConst, v, pos);
|
||||||
pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1578,8 +1620,8 @@ StructType::GetAsConstType() const {
|
|||||||
if (IsConstType())
|
if (IsConstType())
|
||||||
return this;
|
return this;
|
||||||
else
|
else
|
||||||
return new StructType(name, elementTypes, elementNames,
|
return new StructType(name, elementTypes, elementNames, elementPositions,
|
||||||
elementPositions, true, variability, pos);
|
true, variability, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1597,12 +1639,8 @@ std::string
|
|||||||
StructType::GetString() const {
|
StructType::GetString() const {
|
||||||
std::string ret;
|
std::string ret;
|
||||||
if (isConst) ret += "const ";
|
if (isConst) ret += "const ";
|
||||||
|
ret += variability.GetString();
|
||||||
switch (variability) {
|
ret += " ";
|
||||||
case Uniform: ret += "uniform "; break;
|
|
||||||
case Varying: ret += "varying "; break;
|
|
||||||
case Unbound: ret += "/*unbound*/ "; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't print the entire struct declaration, just print the struct's name.
|
// Don't print the entire struct declaration, just print the struct's name.
|
||||||
// @todo Do we need a separate method that prints the declaration?
|
// @todo Do we need a separate method that prints the declaration?
|
||||||
@@ -1625,16 +1663,14 @@ StructType::GetString() const {
|
|||||||
|
|
||||||
std::string
|
std::string
|
||||||
StructType::Mangle() const {
|
StructType::Mangle() const {
|
||||||
Assert(variability != Unbound);
|
Assert(variability != Variability::Unbound);
|
||||||
|
|
||||||
std::string ret;
|
std::string ret;
|
||||||
ret += "s[";
|
ret += "s[";
|
||||||
if (isConst)
|
if (isConst)
|
||||||
ret += "_c_";
|
ret += "_c_";
|
||||||
if (variability == Uniform)
|
ret += variability.MangleString();
|
||||||
ret += "_u_";
|
|
||||||
else
|
|
||||||
ret += "_v_";
|
|
||||||
ret += name + std::string("]<");
|
ret += name + std::string("]<");
|
||||||
for (unsigned int i = 0; i < elementTypes.size(); ++i)
|
for (unsigned int i = 0; i < elementTypes.size(); ++i)
|
||||||
ret += GetElementType(i)->Mangle();
|
ret += GetElementType(i)->Mangle();
|
||||||
@@ -1727,7 +1763,7 @@ StructType::GetDIType(llvm::DIDescriptor scope) const {
|
|||||||
|
|
||||||
const Type *
|
const Type *
|
||||||
StructType::GetElementType(int i) const {
|
StructType::GetElementType(int i) const {
|
||||||
Assert(variability != Unbound);
|
Assert(variability != Variability::Unbound);
|
||||||
Assert(i < (int)elementTypes.size());
|
Assert(i < (int)elementTypes.size());
|
||||||
const Type *ret = elementTypes[i];
|
const Type *ret = elementTypes[i];
|
||||||
|
|
||||||
@@ -1765,11 +1801,11 @@ ReferenceType::ReferenceType(const Type *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Type::Variability
|
Variability
|
||||||
ReferenceType::GetVariability() const {
|
ReferenceType::GetVariability() const {
|
||||||
if (targetType == NULL) {
|
if (targetType == NULL) {
|
||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return Type::Unbound;
|
return Variability(Variability::Unbound);
|
||||||
}
|
}
|
||||||
return targetType->GetVariability();
|
return targetType->GetVariability();
|
||||||
}
|
}
|
||||||
@@ -2026,9 +2062,9 @@ FunctionType::FunctionType(const Type *r, const std::vector<const Type *> &a,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Type::Variability
|
Variability
|
||||||
FunctionType::GetVariability() const {
|
FunctionType::GetVariability() const {
|
||||||
return Uniform;
|
return Variability(Variability::Uniform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
56
type.h
56
type.h
@@ -39,12 +39,39 @@
|
|||||||
#define ISPC_TYPE_H 1
|
#define ISPC_TYPE_H 1
|
||||||
|
|
||||||
#include "ispc.h"
|
#include "ispc.h"
|
||||||
|
#include "util.h"
|
||||||
#include <llvm/Type.h>
|
#include <llvm/Type.h>
|
||||||
#include <llvm/DerivedTypes.h>
|
#include <llvm/DerivedTypes.h>
|
||||||
|
|
||||||
class ConstExpr;
|
class ConstExpr;
|
||||||
class StructType;
|
class StructType;
|
||||||
|
|
||||||
|
/** Types may have uniform, varying, SOA, or unbound variability; this
|
||||||
|
struct is used by Type implementations to record their variability.
|
||||||
|
*/
|
||||||
|
struct Variability {
|
||||||
|
enum VarType { Unbound, Uniform, Varying, SOA };
|
||||||
|
|
||||||
|
Variability(VarType t = Unbound, int w = 0) : type(t), soaWidth(w) { }
|
||||||
|
|
||||||
|
bool operator==(const Variability &v) const {
|
||||||
|
return v.type == type && v.soaWidth == soaWidth;
|
||||||
|
}
|
||||||
|
bool operator!=(const Variability &v) const {
|
||||||
|
return v.type != type || v.soaWidth != soaWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const VarType &t) const { return type == t; }
|
||||||
|
bool operator!=(const VarType &t) const { return type != t; }
|
||||||
|
|
||||||
|
std::string GetString() const;
|
||||||
|
std::string MangleString() const;
|
||||||
|
|
||||||
|
VarType type;
|
||||||
|
int soaWidth;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/** @brief Interface class that defines the type abstraction.
|
/** @brief Interface class that defines the type abstraction.
|
||||||
|
|
||||||
Abstract base class that defines the interface that must be implemented
|
Abstract base class that defines the interface that must be implemented
|
||||||
@@ -78,27 +105,32 @@ public:
|
|||||||
/** Returns true if the underlying type is a float or integer type. */
|
/** Returns true if the underlying type is a float or integer type. */
|
||||||
bool IsNumericType() const { return IsFloatType() || IsIntType(); }
|
bool IsNumericType() const { return IsFloatType() || IsIntType(); }
|
||||||
|
|
||||||
/** Types may have uniform, varying, or not-yet-determined variability;
|
|
||||||
this enumerant is used by Type implementations to record their
|
|
||||||
variability. */
|
|
||||||
enum Variability {
|
|
||||||
Uniform,
|
|
||||||
Varying,
|
|
||||||
Unbound
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Returns the variability of the type. */
|
/** Returns the variability of the type. */
|
||||||
virtual Variability GetVariability() const = 0;
|
virtual Variability GetVariability() const = 0;
|
||||||
|
|
||||||
/** Returns true if the underlying type is uniform */
|
/** Returns true if the underlying type is uniform */
|
||||||
bool IsUniformType() const { return GetVariability() == Uniform; }
|
bool IsUniformType() const {
|
||||||
|
return GetVariability() == Variability::Uniform;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns true if the underlying type is varying */
|
/** Returns true if the underlying type is varying */
|
||||||
bool IsVaryingType() const { return GetVariability() == Varying; }
|
bool IsVaryingType() const {
|
||||||
|
return GetVariability() == Variability::Varying;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns true if the type is laid out in "structure of arrays"
|
||||||
|
layout. */
|
||||||
|
bool IsSOAType() const { return GetVariability() == Variability::SOA; }
|
||||||
|
|
||||||
|
/** Returns the structure of arrays width for SOA types. This method
|
||||||
|
returns zero for types with non-SOA variability. */
|
||||||
|
int GetSOAWidth() const { return GetVariability().soaWidth; }
|
||||||
|
|
||||||
/** Returns true if the underlying type's uniform/varying-ness is
|
/** Returns true if the underlying type's uniform/varying-ness is
|
||||||
unbound. */
|
unbound. */
|
||||||
bool HasUnboundVariability() const { return GetVariability() == Unbound; }
|
bool HasUnboundVariability() const {
|
||||||
|
return GetVariability() == Variability::Unbound;
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns a type wherein any elements of the original type and
|
/* Returns a type wherein any elements of the original type and
|
||||||
contained types that have unbound variability have their variability
|
contained types that have unbound variability have their variability
|
||||||
|
|||||||
Reference in New Issue
Block a user