Add notion of "unbound" variability to the type system.

Now, when a type is declared without an explicit "uniform" or "varying"
qualifier, its variability is unbound; depending on the context of the
declaration, the variability is later finalized.

Currently, in almost all cases, types with unbound variability are
resolved to varying types; the one exception is typecasts like:
"(int)1"; in this case, the fact that (int) has unbound variability
carries through to the TypeCastExpr, which in turn notices that the
expression being type cast has uniform type and in turn will resolve
(int) to (uniform int).

Fixes issue #127.
This commit is contained in:
Matt Pharr
2012-01-06 11:52:58 -08:00
parent 71317e6aa6
commit 15cc812e37
10 changed files with 782 additions and 349 deletions

126
decl.cpp
View File

@@ -46,6 +46,18 @@
#include <stdio.h>
#include <set>
static void
lPrintTypeQualifiers(int typeQualifiers) {
if (typeQualifiers & TYPEQUAL_INLINE) printf("inline ");
if (typeQualifiers & TYPEQUAL_CONST) printf("const ");
if (typeQualifiers & TYPEQUAL_UNIFORM) printf("uniform ");
if (typeQualifiers & TYPEQUAL_VARYING) printf("varying ");
if (typeQualifiers & TYPEQUAL_TASK) printf("task ");
if (typeQualifiers & TYPEQUAL_SIGNED) printf("signed ");
if (typeQualifiers & TYPEQUAL_UNSIGNED) printf("unsigned ");
}
/** Given a Type and a set of type qualifiers, apply the type qualifiers to
the type, returning the type that is the result.
*/
@@ -54,6 +66,16 @@ lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) {
if (type == NULL)
return NULL;
if ((typeQualifiers & TYPEQUAL_CONST) != 0)
type = type->GetAsConstType();
if ((typeQualifiers & TYPEQUAL_UNIFORM) != 0)
type = type->GetAsUniformType();
else if ((typeQualifiers & TYPEQUAL_VARYING) != 0)
type = type->GetAsVaryingType();
else
type = type->GetAsUnboundVariabilityType();
if ((typeQualifiers & TYPEQUAL_UNSIGNED) != 0) {
if ((typeQualifiers & TYPEQUAL_SIGNED) != 0)
Error(pos, "Illegal to apply both \"signed\" and \"unsigned\" "
@@ -64,29 +86,13 @@ lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) {
type = unsignedType;
else
Error(pos, "\"unsigned\" qualifier is illegal with \"%s\" type.",
type->GetString().c_str());
type->ResolveUnboundVariability(Type::Varying)->GetString().c_str());
}
if ((typeQualifiers & TYPEQUAL_SIGNED) != 0 && type->IsIntType() == false)
Error(pos, "\"signed\" qualifier is illegal with non-integer type "
"\"%s\".", type->GetString().c_str());
if ((typeQualifiers & TYPEQUAL_CONST) != 0)
type = type->GetAsConstType();
if ((typeQualifiers & TYPEQUAL_UNIFORM) != 0)
type = type->GetAsUniformType();
else if ((typeQualifiers & TYPEQUAL_VARYING) != 0)
type = type->GetAsVaryingType();
else {
// otherwise, structs are uniform by default and everything
// else is varying by default
if (dynamic_cast<const StructType *>(type->GetBaseType()) != NULL)
type = type->GetAsUniformType();
else
type = type->GetAsVaryingType();
}
"\"%s\".",
type->ResolveUnboundVariability(Type::Varying)->GetString().c_str());
return type;
}
@@ -138,21 +144,14 @@ lGetStorageClassName(StorageClass storageClass) {
void
DeclSpecs::Print() const {
printf("%s ", lGetStorageClassName(storageClass));
printf("Declspecs: [%s ", lGetStorageClassName(storageClass));
if (soaWidth > 0) printf("soa<%d> ", soaWidth);
if (typeQualifiers & TYPEQUAL_INLINE) printf("inline ");
if (typeQualifiers & TYPEQUAL_CONST) printf("const ");
if (typeQualifiers & TYPEQUAL_UNIFORM) printf("uniform ");
if (typeQualifiers & TYPEQUAL_VARYING) printf("varying ");
if (typeQualifiers & TYPEQUAL_TASK) printf("task ");
if (typeQualifiers & TYPEQUAL_SIGNED) printf("signed ");
if (typeQualifiers & TYPEQUAL_UNSIGNED) printf("unsigned ");
printf("%s", baseType->GetString().c_str());
lPrintTypeQualifiers(typeQualifiers);
printf("base type: %s", baseType->GetString().c_str());
if (vectorSize > 0) printf("<%d>", vectorSize);
printf("]");
}
@@ -192,19 +191,46 @@ Declarator::GetSymbol() const {
void
Declarator::Print() const {
Declarator::Print(int indent) const {
printf("%*cdeclarator: [", indent, ' ');
pos.Print();
lPrintTypeQualifiers(typeQualifiers);
Symbol *sym = GetSymbol();
if (sym != NULL)
printf("%s", sym->name.c_str());
else
printf("(null symbol)");
printf(", array size = %d", arraySize);
printf(", kind = ");
switch (kind) {
case DK_BASE: printf("base"); break;
case DK_POINTER: printf("pointer"); break;
case DK_REFERENCE: printf("reference"); break;
case DK_ARRAY: printf("array"); break;
case DK_FUNCTION: printf("function"); break;
default: FATAL("Unhandled declarator kind");
}
if (initExpr != NULL) {
printf(" = (");
initExpr->Print();
printf(")");
}
pos.Print();
if (functionParams.size() > 0) {
for (unsigned int i = 0; i < functionParams.size(); ++i) {
printf("\n%*cfunc param %d:\n", indent, ' ', i);
functionParams[i]->Print(indent+4);
}
}
if (child != NULL)
child->Print(indent + 4);
printf("]\n");
}
@@ -237,9 +263,14 @@ Declarator::GetFunctionInfo(DeclSpecs *ds, std::vector<Symbol *> *funArgs) {
for (unsigned int i = 0; i < d->functionParams.size(); ++i) {
Declaration *pdecl = d->functionParams[i];
Assert(pdecl->declarators.size() == 1);
funArgs->push_back(pdecl->declarators[0]->GetSymbol());
Symbol *sym = pdecl->declarators[0]->GetSymbol();
sym->type = sym->type->ResolveUnboundVariability(Type::Varying);
funArgs->push_back(sym);
}
funSym->type = funSym->type->ResolveUnboundVariability(Type::Varying);
return funSym;
}
@@ -258,6 +289,12 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const {
if (kind != DK_FUNCTION && isTask)
Error(pos, "\"task\" qualifier illegal in variable declaration.");
Type::Variability variability = Type::Unbound;
if (hasUniformQual)
variability = Type::Uniform;
else if (hasVaryingQual)
variability = Type::Varying;
const Type *type = base;
switch (kind) {
case DK_BASE:
@@ -268,7 +305,7 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const {
return type;
case DK_POINTER:
type = new PointerType(type, hasUniformQual, isConst);
type = new PointerType(type, variability, isConst);
if (child != NULL)
return child->GetType(type, ds);
else
@@ -418,9 +455,10 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const {
return NULL;
}
Type *functionType =
new FunctionType(returnType, args, pos, argNames, argDefaults,
const Type *functionType =
new FunctionType(returnType, args, argNames, argDefaults,
argPos, isTask, isExported, isExternC);
functionType = functionType->ResolveUnboundVariability(Type::Varying);
return child->GetType(functionType, ds);
}
default:
@@ -497,6 +535,8 @@ Declaration::GetVariableDeclarations() const {
continue;
Symbol *sym = decl->GetSymbol();
sym->type = sym->type->ResolveUnboundVariability(Type::Varying);
if (dynamic_cast<const FunctionType *>(sym->type) != NULL) {
// function declaration
m->symbolTable->AddFunction(sym);
@@ -511,14 +551,12 @@ Declaration::GetVariableDeclarations() const {
void
Declaration::Print() const {
printf("Declaration: specs [");
Declaration::Print(int indent) const {
printf("%*cDeclaration: specs [", indent, ' ');
declSpecs->Print();
printf("], declarators [");
for (unsigned int i = 0 ; i < declarators.size(); ++i) {
declarators[i]->Print();
printf("%s", (i == declarators.size() - 1) ? "]" : ", ");
}
printf("], declarators:\n");
for (unsigned int i = 0 ; i < declarators.size(); ++i)
declarators[i]->Print(indent+4);
}
///////////////////////////////////////////////////////////////////////////
@@ -539,7 +577,7 @@ GetStructTypesNamesPositions(const std::vector<StructDeclaration *> &sd,
DeclSpecs ds(type);
if (type->IsUniformType())
ds.typeQualifiers |= TYPEQUAL_UNIFORM;
else
else if (type->IsVaryingType())
ds.typeQualifiers |= TYPEQUAL_VARYING;
for (unsigned int j = 0; j < sd[i]->declarators->size(); ++j) {

4
decl.h
View File

@@ -156,7 +156,7 @@ public:
/** Returns the symbol associated with the declarator. */
Symbol *GetSymbol() const;
void Print() const;
void Print(int indent) const;
/** Position of the declarator in the source program. */
const SourcePos pos;
@@ -199,7 +199,7 @@ public:
Declaration(DeclSpecs *ds, std::vector<Declarator *> *dlist = NULL);
Declaration(DeclSpecs *ds, Declarator *d);
void Print() const;
void Print(int indent) const;
/** This method walks through all of the Declarators in a declaration
and returns a fully-initialized Symbol and (possibly) and

View File

@@ -36,6 +36,7 @@
*/
#include "expr.h"
#include "ast.h"
#include "type.h"
#include "sym.h"
#include "ctx.h"
@@ -224,7 +225,7 @@ lDoTypeConv(const Type *fromType, const Type *toType, Expr **expr,
eltType = eltType->GetAsConstType();
if (Type::Equal(toPointerType,
new PointerType(eltType,
toPointerType->IsUniformType(),
toPointerType->GetVariability(),
toPointerType->IsConstType())))
goto typecast_ok;
else {
@@ -466,7 +467,7 @@ lDoTypeConv(const Type *fromType, const Type *toType, Expr **expr,
typecast_ok:
if (expr != NULL)
*expr = new TypeCastExpr(toType, *expr, false, pos);
*expr = new TypeCastExpr(toType, *expr, pos);
return true;
}
@@ -2709,7 +2710,7 @@ FunctionCallExpr::TypeCheck() {
!(argCouldBeNULL[i] == true &&
dynamic_cast<const PointerType *>(paramType) != NULL)) {
Error(args->exprs[i]->pos, "Can't convert argument of "
"type \"%s\" to type \"%s\" for funcion call "
"type \"%s\" to type \"%s\" for function call "
"argument.", argTypes[i]->GetString().c_str(),
paramType->GetString().c_str());
return NULL;
@@ -3525,6 +3526,12 @@ VectorMemberExpr::getElementType() const {
MemberExpr *
MemberExpr::create(Expr *e, const char *id, SourcePos p, SourcePos idpos,
bool derefLValue) {
// FIXME: we need to call TypeCheck() here so that we can call
// e->GetType() in the following. But really we just shouldn't try to
// resolve this now but just have a generic MemberExpr type that
// handles all cases so that this is unnecessary.
e = ::TypeCheck(e);
const Type *exprType;
if (e == NULL || (exprType = e->GetType()) == NULL)
return NULL;
@@ -4566,11 +4573,10 @@ ConstExpr::Print() const {
///////////////////////////////////////////////////////////////////////////
// TypeCastExpr
TypeCastExpr::TypeCastExpr(const Type *t, Expr *e, bool pu, SourcePos p)
TypeCastExpr::TypeCastExpr(const Type *t, Expr *e, SourcePos p)
: Expr(p) {
type = t;
expr = e;
preserveUniformity = pu;
}
@@ -5213,7 +5219,7 @@ TypeCastExpr::GetValue(FunctionEmitContext *ctx) const {
if (Type::EqualIgnoringConst(arrayAsPtr->GetType(), toPointerType) == false) {
Assert(Type::EqualIgnoringConst(arrayAsPtr->GetType()->GetAsVaryingType(),
toPointerType) == true);
arrayAsPtr = new TypeCastExpr(toPointerType, arrayAsPtr, false, pos);
arrayAsPtr = new TypeCastExpr(toPointerType, arrayAsPtr, pos);
arrayAsPtr = ::TypeCheck(arrayAsPtr);
Assert(arrayAsPtr != NULL);
arrayAsPtr = ::Optimize(arrayAsPtr);
@@ -5364,6 +5370,7 @@ TypeCastExpr::GetValue(FunctionEmitContext *ctx) const {
const Type *
TypeCastExpr::GetType() const {
Assert(type->HasUnboundVariability() == false);
return type;
}
@@ -5373,7 +5380,7 @@ lDeconstifyType(const Type *t) {
const PointerType *pt = dynamic_cast<const PointerType *>(t);
if (pt != NULL)
return new PointerType(lDeconstifyType(pt->GetBaseType()),
pt->IsUniformType(), false);
pt->GetVariability(), false);
else
return t->GetAsNonConstType();
}
@@ -5384,16 +5391,16 @@ TypeCastExpr::TypeCheck() {
if (expr == NULL)
return NULL;
const Type *toType = GetType(), *fromType = expr->GetType();
const Type *toType = type, *fromType = expr->GetType();
if (toType == NULL || fromType == NULL)
return NULL;
if (preserveUniformity == true && fromType->IsUniformType() &&
toType->IsVaryingType()) {
if (toType->HasUnboundVariability() && fromType->IsUniformType()) {
TypeCastExpr *tce = new TypeCastExpr(toType->GetAsUniformType(),
expr, false, pos);
expr, pos);
return ::TypeCheck(tce);
}
type = toType = type->ResolveUnboundVariability(Type::Varying);
fromType = lDeconstifyType(fromType);
toType = lDeconstifyType(toType);
@@ -5862,6 +5869,8 @@ SizeOfExpr::SizeOfExpr(Expr *e, SourcePos p)
SizeOfExpr::SizeOfExpr(const Type *t, SourcePos p)
: Expr(p), expr(NULL), type(t) {
if (type->HasUnboundVariability())
type = type->ResolveUnboundVariability(Type::Varying);
}
@@ -6026,7 +6035,8 @@ FunctionSymbolExpr::GetType() const {
return NULL;
}
return matchingFunc ? new PointerType(matchingFunc->type, true, true) : NULL;
return matchingFunc ?
new PointerType(matchingFunc->type, Type::Uniform, true) : NULL;
}

4
expr.h
View File

@@ -493,8 +493,7 @@ private:
probably-different type. */
class TypeCastExpr : public Expr {
public:
TypeCastExpr(const Type *t, Expr *e, bool preserveUniformity,
SourcePos p);
TypeCastExpr(const Type *t, Expr *e, SourcePos p);
llvm::Value *GetValue(FunctionEmitContext *ctx) const;
const Type *GetType() const;
@@ -507,7 +506,6 @@ public:
const Type *type;
Expr *expr;
bool preserveUniformity;
};

View File

@@ -38,6 +38,7 @@
#include "ispc.h"
#include "module.h"
#include "util.h"
#include "type.h"
#include <stdio.h>
#include <stdlib.h>
#include <llvm/Support/PrettyStackTrace.h>
@@ -188,6 +189,8 @@ int main(int Argc, char *Argv[]) {
LLVMInitializeX86TargetMC();
#endif
AtomicType::Init();
char *file = NULL;
const char *headerFileName = NULL;
const char *outFileName = NULL;

View File

@@ -362,13 +362,7 @@ cast_expression
: unary_expression
| '(' type_name ')' cast_expression
{
// Pass true here to try to preserve uniformity
// so that things like:
// uniform int y = ...;
// uniform float x = 1. / (float)y;
// don't issue an error due to (float)y being inadvertently
// and undesirably-to-the-user "varying"...
$$ = new TypeCastExpr($2, $4, true, Union(@1,@4));
$$ = new TypeCastExpr($2, $4, Union(@1,@4));
}
;
@@ -638,13 +632,13 @@ type_specifier
atomic_var_type_specifier
: TOKEN_VOID { $$ = AtomicType::Void; }
| TOKEN_BOOL { $$ = AtomicType::VaryingBool; }
| TOKEN_INT8 { $$ = AtomicType::VaryingInt8; }
| TOKEN_INT16 { $$ = AtomicType::VaryingInt16; }
| TOKEN_INT { $$ = AtomicType::VaryingInt32; }
| TOKEN_FLOAT { $$ = AtomicType::VaryingFloat; }
| TOKEN_DOUBLE { $$ = AtomicType::VaryingDouble; }
| TOKEN_INT64 { $$ = AtomicType::VaryingInt64; }
| TOKEN_BOOL { $$ = AtomicType::UnboundBool; }
| TOKEN_INT8 { $$ = AtomicType::UnboundInt8; }
| TOKEN_INT16 { $$ = AtomicType::UnboundInt16; }
| TOKEN_INT { $$ = AtomicType::UnboundInt32; }
| TOKEN_FLOAT { $$ = AtomicType::UnboundFloat; }
| TOKEN_DOUBLE { $$ = AtomicType::UnboundDouble; }
| TOKEN_INT64 { $$ = AtomicType::UnboundInt64; }
;
short_vec_specifier
@@ -670,7 +664,7 @@ struct_or_union_specifier
GetStructTypesNamesPositions(*$4, &elementTypes, &elementNames,
&elementPositions);
StructType *st = new StructType($2, elementTypes, elementNames,
elementPositions, false, true, @2);
elementPositions, false, Type::Unbound, @2);
m->symbolTable->AddType($2, st, @2);
$$ = st;
}
@@ -681,8 +675,9 @@ struct_or_union_specifier
std::vector<SourcePos> elementPositions;
GetStructTypesNamesPositions(*$3, &elementTypes, &elementNames,
&elementPositions);
// FIXME: should be unbound
$$ = new StructType("", elementTypes, elementNames, elementPositions,
false, true, @1);
false, Type::Unbound, @1);
}
| struct_or_union '{' '}'
{
@@ -748,7 +743,7 @@ specifier_qualifier_list
else if ($1 == TYPEQUAL_SIGNED) {
if ($2->IsIntType() == false) {
Error(@1, "Can't apply \"signed\" qualifier to \"%s\" type.",
$2->GetString().c_str());
$2->ResolveUnboundVariability(Type::Varying)->GetString().c_str());
$$ = $2;
}
}
@@ -758,7 +753,7 @@ specifier_qualifier_list
$$ = t;
else {
Error(@1, "Can't apply \"unsigned\" qualifier to \"%s\" type. Ignoring.",
$2->GetString().c_str());
$2->ResolveUnboundVariability(Type::Varying)->GetString().c_str());
$$ = $2;
}
}
@@ -775,8 +770,11 @@ specifier_qualifier_list
else
FATAL("Unhandled type qualifier in parser.");
}
else
else {
if (m->errorCount == 0)
Error(@1, "Lost type qualifier in parser.");
$$ = NULL;
}
}
;
@@ -1558,19 +1556,21 @@ lAddDeclaration(DeclSpecs *ds, Declarator *decl) {
const Type *t = decl->GetType(ds);
if (t == NULL)
return;
Symbol *sym = decl->GetSymbol();
Assert(sym != NULL);
const FunctionType *ft = dynamic_cast<const FunctionType *>(t);
if (ft != NULL) {
Symbol *funSym = decl->GetSymbol();
Assert(funSym != NULL);
funSym->type = ft;
funSym->storageClass = ds->storageClass;
sym->type = ft;
sym->storageClass = ds->storageClass;
bool isInline = (ds->typeQualifiers & TYPEQUAL_INLINE);
m->AddFunctionDeclaration(funSym, isInline);
m->AddFunctionDeclaration(sym, isInline);
}
else {
sym->type = sym->type->ResolveUnboundVariability(Type::Varying);
bool isConst = (ds->typeQualifiers & TYPEQUAL_CONST) != 0;
m->AddGlobalVariable(sym, decl->initExpr, isConst);
}
else
m->AddGlobalVariable(decl->GetSymbol(), decl->initExpr,
(ds->typeQualifiers & TYPEQUAL_CONST) != 0);
}
}
@@ -1596,6 +1596,7 @@ lAddFunctionParams(Declarator *decl) {
continue;
Assert(pdecl->declarators.size() == 1);
Symbol *sym = pdecl->declarators[0]->GetSymbol();
sym->type = sym->type->ResolveUnboundVariability(Type::Varying);
#ifndef NDEBUG
bool ok = m->symbolTable->AddVariable(sym);
if (ok == false)
@@ -1761,7 +1762,7 @@ lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums,
the actual enum type here and optimize it, which will have
us end up with a ConstExpr with the desired EnumType... */
Expr *castExpr = new TypeCastExpr(enumType, enums[i]->constValue,
false, enums[i]->pos);
enums[i]->pos);
castExpr = Optimize(castExpr);
enums[i]->constValue = dynamic_cast<ConstExpr *>(castExpr);
Assert(enums[i]->constValue != NULL);

View File

@@ -1133,7 +1133,7 @@ DoStmt::TypeCheck() {
!lHasVaryingBreakOrContinue(bodyStmts));
testExpr = new TypeCastExpr(uniformTest ? AtomicType::UniformBool :
AtomicType::VaryingBool,
testExpr, false, testExpr->pos);
testExpr, testExpr->pos);
}
return this;
@@ -1318,8 +1318,7 @@ ForStmt::TypeCheck() {
!g->opt.disableUniformControlFlow &&
!lHasVaryingBreakOrContinue(stmts));
test = new TypeCastExpr(uniformTest ? AtomicType::UniformBool :
AtomicType::VaryingBool,
test, false, test->pos);
AtomicType::VaryingBool, test, test->pos);
test = ::TypeCheck(test);
if (test == NULL)
return NULL;
@@ -2147,7 +2146,7 @@ lProcessPrintArg(Expr *expr, FunctionEmitContext *ctx, std::string &argTypes) {
baseType == AtomicType::UniformUInt16) {
expr = new TypeCastExpr(type->IsUniformType() ? AtomicType::UniformInt32 :
AtomicType::VaryingInt32,
expr, false, expr->pos);
expr, expr->pos);
type = expr->GetType();
}
@@ -2350,7 +2349,7 @@ AssertStmt::TypeCheck() {
}
expr = new TypeCastExpr(isUniform ? AtomicType::UniformBool :
AtomicType::VaryingBool,
expr, false, expr->pos);
expr, expr->pos);
expr = ::TypeCheck(expr);
}
return this;

View File

@@ -1,4 +1,4 @@
// Can't convert argument of type "void * const uniform" to type "float" for funcion call argument.
// Can't convert argument of type "void * uniform" to type "float" for function call argument.
float bar(float a, float b);

735
type.cpp

File diff suppressed because it is too large Load Diff

151
type.h
View File

@@ -78,20 +78,44 @@ public:
/** Returns true if the underlying type is a float or integer type. */
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. */
virtual Variability GetVariability() const = 0;
/** Returns true if the underlying type is uniform */
virtual bool IsUniformType() const = 0;
bool IsUniformType() const { return GetVariability() == Uniform; }
/** Returns true if the underlying type is varying */
bool IsVaryingType() const { return !IsUniformType(); }
bool IsVaryingType() const { return GetVariability() == Varying; }
/** Returns true if the underlying type's uniform/varying-ness is
unbound. */
bool HasUnboundVariability() const { return GetVariability() == Unbound; }
/* Returns a type wherein any elements of the original type and
contained types that have unbound variability have their variability
set to the given variability. */
virtual const Type *ResolveUnboundVariability(Variability v) const = 0;
/** Return a "uniform" instance of this type. If the type is already
uniform, its "this" pointer will be returned. */
virtual const Type *GetAsUniformType() const = 0;
/** Return a "varying" instance of this type. If the type is already
uniform, its "this" pointer will be returned. */
varying, its "this" pointer will be returned. */
virtual const Type *GetAsVaryingType() const = 0;
/** Get an instance of the type with unbound variability. */
virtual const Type *GetAsUnboundVariabilityType() const = 0;
/** If this is a signed integer type, return the unsigned version of
the type. Otherwise, return the original type. */
virtual const Type *GetAsUnsignedType() const;
@@ -185,7 +209,8 @@ public:
*/
class AtomicType : public Type {
public:
bool IsUniformType() const;
Variability GetVariability() const;
bool IsBoolType() const;
bool IsFloatType() const;
bool IsIntType() const;
@@ -195,8 +220,10 @@ public:
/** For AtomicTypes, the base type is just the same as the AtomicType
itself. */
const AtomicType *GetBaseType() const;
const AtomicType *GetAsVaryingType() const;
const AtomicType *GetAsUniformType() const;
const AtomicType *GetAsVaryingType() const;
const AtomicType *GetAsUnboundVariabilityType() const;
const AtomicType *ResolveUnboundVariability(Variability v) const;
const AtomicType *GetAsUnsignedType() const;
const Type *GetSOAType(int width) const;
const AtomicType *GetAsConstType() const;
@@ -224,38 +251,45 @@ public:
TYPE_INT64,
TYPE_UINT64,
TYPE_DOUBLE,
NUM_BASIC_TYPES
};
const BasicType basicType;
static const AtomicType *UniformBool, *VaryingBool;
static const AtomicType *UniformInt8, *VaryingInt8;
static const AtomicType *UniformInt16, *VaryingInt16;
static const AtomicType *UniformInt32, *VaryingInt32;
static const AtomicType *UniformUInt8, *VaryingUInt8;
static const AtomicType *UniformUInt16, *VaryingUInt16;
static const AtomicType *UniformUInt32, *VaryingUInt32;
static const AtomicType *UniformFloat, *VaryingFloat;
static const AtomicType *UniformInt64, *VaryingInt64;
static const AtomicType *UniformUInt64, *VaryingUInt64;
static const AtomicType *UniformDouble, *VaryingDouble;
static const AtomicType *UniformConstBool, *VaryingConstBool;
static const AtomicType *UniformConstInt8, *VaryingConstInt8;
static const AtomicType *UniformConstInt16, *VaryingConstInt16;
static const AtomicType *UniformConstInt32, *VaryingConstInt32;
static const AtomicType *UniformConstUInt8, *VaryingConstUInt8;
static const AtomicType *UniformConstUInt16, *VaryingConstUInt16;
static const AtomicType *UniformConstUInt32, *VaryingConstUInt32;
static const AtomicType *UniformConstFloat, *VaryingConstFloat;
static const AtomicType *UniformConstInt64, *VaryingConstInt64;
static const AtomicType *UniformConstUInt64, *VaryingConstUInt64;
static const AtomicType *UniformConstDouble, *VaryingConstDouble;
static const AtomicType *UniformBool, *VaryingBool, *UnboundBool;
static const AtomicType *UniformInt8, *VaryingInt8, *UnboundInt8;
static const AtomicType *UniformInt16, *VaryingInt16, *UnboundInt16;
static const AtomicType *UniformInt32, *VaryingInt32, *UnboundInt32;
static const AtomicType *UniformUInt8, *VaryingUInt8, *UnboundUInt8;
static const AtomicType *UniformUInt16, *VaryingUInt16, *UnboundUInt16;
static const AtomicType *UniformUInt32, *VaryingUInt32, *UnboundUInt32;
static const AtomicType *UniformFloat, *VaryingFloat, *UnboundFloat;
static const AtomicType *UniformInt64, *VaryingInt64, *UnboundInt64;
static const AtomicType *UniformUInt64, *VaryingUInt64, *UnboundUInt64;
static const AtomicType *UniformDouble, *VaryingDouble, *UnboundDouble;
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;
/** 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:
const bool isUniform;
static const AtomicType *typeTable[NUM_BASIC_TYPES][3][2];
const Variability variability;
const bool isConst;
AtomicType(BasicType basicType, bool isUniform, bool isConst);
AtomicType(BasicType basicType, Variability v, bool isConst);
};
@@ -268,7 +302,8 @@ public:
/** Constructor for named enumerated types */
EnumType(const char *name, SourcePos pos);
bool IsUniformType() const;
Variability GetVariability() const;
bool IsBoolType() const;
bool IsFloatType() const;
bool IsIntType() const;
@@ -278,6 +313,8 @@ public:
const EnumType *GetBaseType() const;
const EnumType *GetAsVaryingType() const;
const EnumType *GetAsUniformType() const;
const EnumType *GetAsUnboundVariabilityType() const;
const EnumType *ResolveUnboundVariability(Variability v) const;
const Type *GetSOAType(int width) const;
const EnumType *GetAsConstType() const;
const EnumType *GetAsNonConstType() const;
@@ -300,15 +337,17 @@ public:
private:
const std::string name;
bool isUniform, isConst;
Variability variability;
bool isConst;
std::vector<Symbol *> enumerators;
};
/** @brief Type implementation for pointers to other types
*/
class PointerType : public Type {
public:
PointerType(const Type *t, bool isUniform, bool isConst);
PointerType(const Type *t, Variability v, bool isConst);
/** Helper method to return a uniform pointer to the given type. */
static PointerType *GetUniform(const Type *t);
@@ -318,7 +357,8 @@ public:
/** Returns true if the given type is a void * type. */
static bool IsVoidPointer(const Type *t);
bool IsUniformType() const;
Variability GetVariability() const;
bool IsBoolType() const;
bool IsFloatType() const;
bool IsIntType() const;
@@ -328,6 +368,8 @@ public:
const Type *GetBaseType() const;
const PointerType *GetAsVaryingType() const;
const PointerType *GetAsUniformType() const;
const PointerType *GetAsUnboundVariabilityType() const;
const PointerType *ResolveUnboundVariability(Variability v) const;
const Type *GetSOAType(int width) const;
const PointerType *GetAsConstType() const;
const PointerType *GetAsNonConstType() const;
@@ -342,7 +384,8 @@ public:
static PointerType *Void;
private:
const bool isUniform, isConst;
const Variability variability;
const bool isConst;
const Type *baseType;
};
@@ -408,7 +451,8 @@ public:
*/
ArrayType(const Type *elementType, int numElements);
bool IsUniformType() const;
Variability GetVariability() const;
bool IsBoolType() const;
bool IsFloatType() const;
bool IsIntType() const;
@@ -418,6 +462,9 @@ public:
const Type *GetBaseType() const;
const ArrayType *GetAsVaryingType() const;
const ArrayType *GetAsUniformType() const;
const ArrayType *GetAsUnboundVariabilityType() const;
const ArrayType *ResolveUnboundVariability(Variability v) const;
const ArrayType *GetAsUnsignedType() const;
const Type *GetSOAType(int width) const;
const ArrayType *GetAsConstType() const;
@@ -495,6 +542,9 @@ public:
const SOAArrayType *GetAsVaryingType() const;
const SOAArrayType *GetAsUniformType() const;
const SOAArrayType *GetAsUnboundVariabilityType() const;
const SOAArrayType *ResolveUnboundVariability(Variability v) const;
const Type *GetSOAType(int width) const;
const SOAArrayType *GetAsConstType() const;
const SOAArrayType *GetAsNonConstType() const;
@@ -536,7 +586,8 @@ class VectorType : public SequentialType {
public:
VectorType(const AtomicType *base, int size);
bool IsUniformType() const;
Variability GetVariability() const;
bool IsBoolType() const;
bool IsFloatType() const;
bool IsIntType() const;
@@ -546,6 +597,9 @@ public:
const Type *GetBaseType() const;
const VectorType *GetAsVaryingType() const;
const VectorType *GetAsUniformType() const;
const VectorType *GetAsUnboundVariabilityType() const;
const VectorType *ResolveUnboundVariability(Variability v) const;
const Type *GetSOAType(int width) const;
const VectorType *GetAsConstType() const;
const VectorType *GetAsNonConstType() const;
@@ -580,9 +634,10 @@ public:
StructType(const std::string &name, const std::vector<const Type *> &elts,
const std::vector<std::string> &eltNames,
const std::vector<SourcePos> &eltPositions, bool isConst,
bool isUniform, SourcePos pos);
Variability variability, SourcePos pos);
Variability GetVariability() const;
bool IsUniformType() const;
bool IsBoolType() const;
bool IsFloatType() const;
bool IsIntType() const;
@@ -592,6 +647,9 @@ public:
const Type *GetBaseType() const;
const StructType *GetAsVaryingType() const;
const StructType *GetAsUniformType() const;
const StructType *GetAsUnboundVariabilityType() const;
const StructType *ResolveUnboundVariability(Variability v) const;
const Type *GetSOAType(int width) const;
const StructType *GetAsConstType() const;
const StructType *GetAsNonConstType() const;
@@ -641,7 +699,7 @@ private:
/** Source file position at which each structure element declaration
appeared. */
const std::vector<SourcePos> elementPositions;
const bool isUniform;
const Variability variability;
const bool isConst;
const SourcePos pos;
};
@@ -653,7 +711,8 @@ class ReferenceType : public Type {
public:
ReferenceType(const Type *targetType);
bool IsUniformType() const;
Variability GetVariability() const;
bool IsBoolType() const;
bool IsFloatType() const;
bool IsIntType() const;
@@ -664,6 +723,9 @@ public:
const Type *GetReferenceTarget() const;
const ReferenceType *GetAsVaryingType() const;
const ReferenceType *GetAsUniformType() const;
const ReferenceType *GetAsUnboundVariabilityType() const;
const ReferenceType *ResolveUnboundVariability(Variability v) const;
const Type *GetSOAType(int width) const;
const ReferenceType *GetAsConstType() const;
const ReferenceType *GetAsNonConstType() const;
@@ -696,13 +758,14 @@ public:
FunctionType(const Type *returnType,
const std::vector<const Type *> &argTypes, SourcePos pos);
FunctionType(const Type *returnType,
const std::vector<const Type *> &argTypes, SourcePos pos,
const std::vector<const Type *> &argTypes,
const std::vector<std::string> &argNames,
const std::vector<ConstExpr *> &argDefaults,
const std::vector<SourcePos> &argPos,
bool isTask, bool isExported, bool isExternC);
bool IsUniformType() const;
Variability GetVariability() const;
bool IsBoolType() const;
bool IsFloatType() const;
bool IsIntType() const;
@@ -712,6 +775,9 @@ public:
const Type *GetBaseType() const;
const Type *GetAsVaryingType() const;
const Type *GetAsUniformType() const;
const Type *GetAsUnboundVariabilityType() const;
const FunctionType *ResolveUnboundVariability(Variability v) const;
const Type *GetSOAType(int width) const;
const Type *GetAsConstType() const;
const Type *GetAsNonConstType() const;
@@ -752,6 +818,7 @@ public:
private:
const Type * const returnType;
// The following four vectors should all have the same length (which is
// in turn the length returned by GetNumParameters()).
const std::vector<const Type *> paramTypes;