[WIP] parses polymorphic types
This commit is contained in:
44
lex.ll
44
lex.ll
@@ -63,31 +63,28 @@ inline int isatty(int) { return 0; }
|
||||
#endif // ISPC_IS_WINDOWS
|
||||
|
||||
static int allTokens[] = {
|
||||
TOKEN_ASSERT, TOKEN_BOOL, TOKEN_BREAK, TOKEN_CASE,
|
||||
TOKEN_CDO, TOKEN_CFOR, TOKEN_CIF, TOKEN_CWHILE,
|
||||
TOKEN_CONST, TOKEN_CONTINUE, TOKEN_DEFAULT, TOKEN_DO,
|
||||
TOKEN_DELETE, TOKEN_DOUBLE, TOKEN_ELSE, TOKEN_ENUM,
|
||||
TOKEN_EXPORT, TOKEN_EXTERN, TOKEN_FALSE, TOKEN_FLOAT, TOKEN_FOR,
|
||||
TOKEN_ASSERT, TOKEN_BOOL, TOKEN_BREAK, TOKEN_CASE, TOKEN_CDO, TOKEN_CFOR,
|
||||
TOKEN_CIF, TOKEN_CWHILE, TOKEN_CONST, TOKEN_CONTINUE, TOKEN_DEFAULT, TOKEN_DO,
|
||||
TOKEN_DELETE, TOKEN_DOUBLE, TOKEN_ELSE, TOKEN_ENUM, TOKEN_EXPORT,
|
||||
TOKEN_EXTERN, TOKEN_FALSE, TOKEN_FLOAT, TOKEN_FLOATING, TOKEN_FOR,
|
||||
TOKEN_FOREACH, TOKEN_FOREACH_ACTIVE, TOKEN_FOREACH_TILED,
|
||||
TOKEN_FOREACH_UNIQUE, TOKEN_GOTO, TOKEN_IF, TOKEN_IN, TOKEN_INLINE,
|
||||
TOKEN_INT, TOKEN_INT8, TOKEN_INT16, TOKEN_INT, TOKEN_INT64, TOKEN_LAUNCH,
|
||||
TOKEN_NEW, TOKEN_NULL, TOKEN_PRINT, TOKEN_RETURN, TOKEN_SOA, TOKEN_SIGNED,
|
||||
TOKEN_SIZEOF, TOKEN_STATIC, TOKEN_STRUCT, TOKEN_SWITCH, TOKEN_SYNC,
|
||||
TOKEN_TASK, TOKEN_TRUE, TOKEN_TYPEDEF, TOKEN_UNIFORM, TOKEN_UNMASKED,
|
||||
TOKEN_UNSIGNED, TOKEN_VARYING, TOKEN_VOID, TOKEN_WHILE,
|
||||
TOKEN_STRING_C_LITERAL, TOKEN_DOTDOTDOT,
|
||||
TOKEN_FLOAT_CONSTANT, TOKEN_DOUBLE_CONSTANT,
|
||||
TOKEN_INT8_CONSTANT, TOKEN_UINT8_CONSTANT,
|
||||
TOKEN_INT16_CONSTANT, TOKEN_UINT16_CONSTANT,
|
||||
TOKEN_INT32_CONSTANT, TOKEN_UINT32_CONSTANT,
|
||||
TOKEN_INT64_CONSTANT, TOKEN_UINT64_CONSTANT,
|
||||
TOKEN_FOREACH_UNIQUE, TOKEN_GOTO, TOKEN_IF, TOKEN_IN, TOKEN_INLINE, TOKEN_INT,
|
||||
TOKEN_INT8, TOKEN_INT16, TOKEN_INT, TOKEN_INT64, TOKEN_INTEGER, TOKEN_LAUNCH,
|
||||
TOKEN_NEW, TOKEN_NULL, TOKEN_NUMBER, TOKEN_PRINT, TOKEN_RETURN, TOKEN_SOA,
|
||||
TOKEN_SIGNED, TOKEN_SIZEOF, TOKEN_STATIC, TOKEN_STRUCT, TOKEN_SWITCH,
|
||||
TOKEN_SYNC, TOKEN_TASK, TOKEN_TRUE, TOKEN_TYPEDEF, TOKEN_UNIFORM,
|
||||
TOKEN_UNMASKED, TOKEN_UNSIGNED, TOKEN_VARYING, TOKEN_VOID, TOKEN_WHILE,
|
||||
TOKEN_STRING_C_LITERAL, TOKEN_DOTDOTDOT, TOKEN_FLOAT_CONSTANT,
|
||||
TOKEN_DOUBLE_CONSTANT, TOKEN_INT8_CONSTANT, TOKEN_UINT8_CONSTANT,
|
||||
TOKEN_INT16_CONSTANT, TOKEN_UINT16_CONSTANT, TOKEN_INT32_CONSTANT,
|
||||
TOKEN_UINT32_CONSTANT, TOKEN_INT64_CONSTANT, TOKEN_UINT64_CONSTANT,
|
||||
TOKEN_INC_OP, TOKEN_DEC_OP, TOKEN_LEFT_OP, TOKEN_RIGHT_OP, TOKEN_LE_OP,
|
||||
TOKEN_GE_OP, TOKEN_EQ_OP, TOKEN_NE_OP, TOKEN_AND_OP, TOKEN_OR_OP,
|
||||
TOKEN_MUL_ASSIGN, TOKEN_DIV_ASSIGN, TOKEN_MOD_ASSIGN, TOKEN_ADD_ASSIGN,
|
||||
TOKEN_SUB_ASSIGN, TOKEN_LEFT_ASSIGN, TOKEN_RIGHT_ASSIGN, TOKEN_AND_ASSIGN,
|
||||
TOKEN_XOR_ASSIGN, TOKEN_OR_ASSIGN, TOKEN_PTR_OP,
|
||||
';', '{', '}', ',', ':', '=', '(', ')', '[', ']', '.', '&', '!', '~', '-',
|
||||
'+', '*', '/', '%', '<', '>', '^', '|', '?',
|
||||
'+', '*', '/', '%', '<', '>', '^', '|', '?', '$'
|
||||
};
|
||||
|
||||
std::map<int, std::string> tokenToName;
|
||||
@@ -114,6 +111,7 @@ void ParserInit() {
|
||||
tokenToName[TOKEN_EXTERN] = "extern";
|
||||
tokenToName[TOKEN_FALSE] = "false";
|
||||
tokenToName[TOKEN_FLOAT] = "float";
|
||||
tokenToName[TOKEN_FLOATING] = "floating";
|
||||
tokenToName[TOKEN_FOR] = "for";
|
||||
tokenToName[TOKEN_FOREACH] = "foreach";
|
||||
tokenToName[TOKEN_FOREACH_ACTIVE] = "foreach_active";
|
||||
@@ -127,10 +125,12 @@ void ParserInit() {
|
||||
tokenToName[TOKEN_INT8] = "int8";
|
||||
tokenToName[TOKEN_INT16] = "int16";
|
||||
tokenToName[TOKEN_INT] = "int";
|
||||
tokenToName[TOKEN_INTEGER] = "integer";
|
||||
tokenToName[TOKEN_INT64] = "int64";
|
||||
tokenToName[TOKEN_LAUNCH] = "launch";
|
||||
tokenToName[TOKEN_NEW] = "new";
|
||||
tokenToName[TOKEN_NULL] = "NULL";
|
||||
tokenToName[TOKEN_NUMBER] = "number";
|
||||
tokenToName[TOKEN_PRINT] = "print";
|
||||
tokenToName[TOKEN_RETURN] = "return";
|
||||
tokenToName[TOKEN_SOA] = "soa";
|
||||
@@ -207,6 +207,7 @@ void ParserInit() {
|
||||
tokenToName['|'] = "|";
|
||||
tokenToName['?'] = "?";
|
||||
tokenToName[';'] = ";";
|
||||
tokenToName['$'] = "$";
|
||||
|
||||
tokenNameRemap["TOKEN_ASSERT"] = "\'assert\'";
|
||||
tokenNameRemap["TOKEN_BOOL"] = "\'bool\'";
|
||||
@@ -228,6 +229,7 @@ void ParserInit() {
|
||||
tokenNameRemap["TOKEN_EXTERN"] = "\'extern\'";
|
||||
tokenNameRemap["TOKEN_FALSE"] = "\'false\'";
|
||||
tokenNameRemap["TOKEN_FLOAT"] = "\'float\'";
|
||||
tokenNameRemap["TOKEN_FLOATING"] = "\'floating\'";
|
||||
tokenNameRemap["TOKEN_FOR"] = "\'for\'";
|
||||
tokenNameRemap["TOKEN_FOREACH"] = "\'foreach\'";
|
||||
tokenNameRemap["TOKEN_FOREACH_ACTIVE"] = "\'foreach_active\'";
|
||||
@@ -243,9 +245,11 @@ void ParserInit() {
|
||||
tokenNameRemap["TOKEN_INT16"] = "\'int16\'";
|
||||
tokenNameRemap["TOKEN_INT"] = "\'int\'";
|
||||
tokenNameRemap["TOKEN_INT64"] = "\'int64\'";
|
||||
tokenNameRemap["TOKEN_INTEGER"] = "\'integer\'";
|
||||
tokenNameRemap["TOKEN_LAUNCH"] = "\'launch\'";
|
||||
tokenNameRemap["TOKEN_NEW"] = "\'new\'";
|
||||
tokenNameRemap["TOKEN_NULL"] = "\'NULL\'";
|
||||
tokenNameRemap["TOKEN_NUMBER"] = "\'number\'";
|
||||
tokenNameRemap["TOKEN_PRINT"] = "\'print\'";
|
||||
tokenNameRemap["TOKEN_RETURN"] = "\'return\'";
|
||||
tokenNameRemap["TOKEN_SOA"] = "\'soa\'";
|
||||
@@ -381,6 +385,7 @@ export { RT; return TOKEN_EXPORT; }
|
||||
extern { RT; return TOKEN_EXTERN; }
|
||||
false { RT; return TOKEN_FALSE; }
|
||||
float { RT; return TOKEN_FLOAT; }
|
||||
floating { RT; return TOKEN_FLOATING; }
|
||||
for { RT; return TOKEN_FOR; }
|
||||
foreach { RT; return TOKEN_FOREACH; }
|
||||
foreach_active { RT; return TOKEN_FOREACH_ACTIVE; }
|
||||
@@ -395,9 +400,11 @@ int8 { RT; return TOKEN_INT8; }
|
||||
int16 { RT; return TOKEN_INT16; }
|
||||
int32 { RT; return TOKEN_INT; }
|
||||
int64 { RT; return TOKEN_INT64; }
|
||||
integer { RT; return TOKEN_INTEGER; }
|
||||
launch { RT; return TOKEN_LAUNCH; }
|
||||
new { RT; return TOKEN_NEW; }
|
||||
NULL { RT; return TOKEN_NULL; }
|
||||
number { RT; return TOKEN_NUMBER; }
|
||||
print { RT; return TOKEN_PRINT; }
|
||||
return { RT; return TOKEN_RETURN; }
|
||||
soa { RT; return TOKEN_SOA; }
|
||||
@@ -521,6 +528,7 @@ L?\"(\\.|[^\\"])*\" { lStringConst(&yylval, &yylloc); return TOKEN_STRING_LITERA
|
||||
"^" { RT; return '^'; }
|
||||
"|" { RT; return '|'; }
|
||||
"?" { RT; return '?'; }
|
||||
"$" { RT; return '$'; }
|
||||
|
||||
{WHITESPACE} { }
|
||||
|
||||
|
||||
67
parse.yy
67
parse.yy
@@ -118,21 +118,20 @@ static void lFinalizeEnumeratorSymbols(std::vector<Symbol *> &enums,
|
||||
const EnumType *enumType);
|
||||
|
||||
static const char *lBuiltinTokens[] = {
|
||||
"assert", "bool", "break", "case", "cdo",
|
||||
"cfor", "cif", "cwhile", "const", "continue", "default",
|
||||
"do", "delete", "double", "else", "enum", "export", "extern", "false",
|
||||
"float", "for", "foreach", "foreach_active", "foreach_tiled",
|
||||
"foreach_unique", "goto", "if", "in", "inline",
|
||||
"int", "int8", "int16", "int32", "int64", "launch", "new", "NULL",
|
||||
"print", "return", "signed", "sizeof", "static", "struct", "switch",
|
||||
"sync", "task", "true", "typedef", "uniform", "unmasked", "unsigned",
|
||||
"varying", "void", "while", NULL
|
||||
"assert", "bool", "break", "case", "cdo", "cfor", "cif", "cwhile", "const",
|
||||
"continue", "default", "do", "delete", "double", "else", "enum", "export",
|
||||
"extern", "false", "float", "floating", "for", "foreach", "foreach_active",
|
||||
"foreach_tiled", "foreach_unique", "goto", "if", "in", "inline", "int",
|
||||
"int8", "int16", "int32", "int64", "integer", "launch", "new", "NULL",
|
||||
"number", "print", "return", "signed", "sizeof", "static", "struct",
|
||||
"switch", "sync", "task", "true", "typedef", "uniform", "unmasked",
|
||||
"unsigned", "varying", "void", "while", NULL
|
||||
};
|
||||
|
||||
static const char *lParamListTokens[] = {
|
||||
"bool", "const", "double", "enum", "false", "float", "int",
|
||||
"int8", "int16", "int32", "int64", "signed", "struct", "true",
|
||||
"uniform", "unsigned", "varying", "void", NULL
|
||||
"bool", "const", "double", "enum", "false", "float", "floating", "int",
|
||||
"int8", "int16", "int32", "int64", "integer", "number", "signed", "struct",
|
||||
"true", "uniform", "unsigned", "varying", "void", NULL
|
||||
};
|
||||
|
||||
struct ForeachDimension {
|
||||
@@ -159,6 +158,7 @@ struct ForeachDimension {
|
||||
const Type *type;
|
||||
std::vector<std::pair<const Type *, SourcePos> > *typeList;
|
||||
const AtomicType *atomicType;
|
||||
const PolyType *polyType;
|
||||
int typeQualifier;
|
||||
StorageClass storageClass;
|
||||
Stmt *stmt;
|
||||
@@ -198,6 +198,7 @@ struct ForeachDimension {
|
||||
%token TOKEN_EXTERN TOKEN_EXPORT TOKEN_STATIC TOKEN_INLINE TOKEN_TASK TOKEN_DECLSPEC
|
||||
%token TOKEN_UNIFORM TOKEN_VARYING TOKEN_TYPEDEF TOKEN_SOA TOKEN_UNMASKED
|
||||
%token TOKEN_CHAR TOKEN_INT TOKEN_SIGNED TOKEN_UNSIGNED TOKEN_FLOAT TOKEN_DOUBLE
|
||||
%token TOKEN_INTEGER TOKEN_FLOATING TOKEN_NUMBER
|
||||
%token TOKEN_INT8 TOKEN_INT16 TOKEN_INT64 TOKEN_CONST TOKEN_VOID TOKEN_BOOL
|
||||
%token TOKEN_ENUM TOKEN_STRUCT TOKEN_TRUE TOKEN_FALSE
|
||||
|
||||
@@ -244,6 +245,7 @@ struct ForeachDimension {
|
||||
%type <type> short_vec_specifier
|
||||
%type <typeList> type_specifier_list
|
||||
%type <atomicType> atomic_var_type_specifier
|
||||
%type <polyType> poly_type_specifier poly_quant_type_specifier
|
||||
|
||||
%type <typeQualifier> type_qualifier type_qualifier_list
|
||||
%type <storageClass> storage_class_specifier
|
||||
@@ -364,60 +366,60 @@ launch_expression
|
||||
}
|
||||
|
||||
| TOKEN_LAUNCH '[' assignment_expression ']' postfix_expression '(' argument_expression_list ')'
|
||||
{
|
||||
{
|
||||
ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @5);
|
||||
Expr *launchCount[3] = {$3, oneExpr, oneExpr};
|
||||
$$ = new FunctionCallExpr($5, $7, Union(@5,@8), true, launchCount);
|
||||
}
|
||||
| TOKEN_LAUNCH '[' assignment_expression ']' postfix_expression '(' ')'
|
||||
{
|
||||
{
|
||||
ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @5);
|
||||
Expr *launchCount[3] = {$3, oneExpr, oneExpr};
|
||||
$$ = new FunctionCallExpr($5, new ExprList(Union(@5,@6)), Union(@5,@7), true, launchCount);
|
||||
}
|
||||
|
||||
| TOKEN_LAUNCH '[' assignment_expression ',' assignment_expression ']' postfix_expression '(' argument_expression_list ')'
|
||||
{
|
||||
{
|
||||
ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @7);
|
||||
Expr *launchCount[3] = {$3, $5, oneExpr};
|
||||
$$ = new FunctionCallExpr($7, $9, Union(@7,@10), true, launchCount);
|
||||
}
|
||||
| TOKEN_LAUNCH '[' assignment_expression ',' assignment_expression ']' postfix_expression '(' ')'
|
||||
{
|
||||
{
|
||||
ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @7);
|
||||
Expr *launchCount[3] = {$3, $5, oneExpr};
|
||||
$$ = new FunctionCallExpr($7, new ExprList(Union(@7,@8)), Union(@7,@9), true, launchCount);
|
||||
}
|
||||
| TOKEN_LAUNCH '[' assignment_expression ']' '[' assignment_expression ']' postfix_expression '(' argument_expression_list ')'
|
||||
{
|
||||
{
|
||||
ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @8);
|
||||
Expr *launchCount[3] = {$6, $3, oneExpr};
|
||||
$$ = new FunctionCallExpr($8, $10, Union(@8,@11), true, launchCount);
|
||||
}
|
||||
| TOKEN_LAUNCH '[' assignment_expression ']' '[' assignment_expression ']' postfix_expression '(' ')'
|
||||
{
|
||||
{
|
||||
ConstExpr *oneExpr = new ConstExpr(AtomicType::UniformInt32, (int32_t)1, @8);
|
||||
Expr *launchCount[3] = {$6, $3, oneExpr};
|
||||
$$ = new FunctionCallExpr($8, new ExprList(Union(@8,@9)), Union(@8,@10), true, launchCount);
|
||||
}
|
||||
|
||||
| TOKEN_LAUNCH '[' assignment_expression ',' assignment_expression ',' assignment_expression ']' postfix_expression '(' argument_expression_list ')'
|
||||
{
|
||||
{
|
||||
Expr *launchCount[3] = {$3, $5, $7};
|
||||
$$ = new FunctionCallExpr($9, $11, Union(@9,@12), true, launchCount);
|
||||
}
|
||||
| TOKEN_LAUNCH '[' assignment_expression ',' assignment_expression ',' assignment_expression ']' postfix_expression '(' ')'
|
||||
{
|
||||
{
|
||||
Expr *launchCount[3] = {$3, $5, $7};
|
||||
$$ = new FunctionCallExpr($9, new ExprList(Union(@9,@10)), Union(@9,@11), true, launchCount);
|
||||
}
|
||||
| TOKEN_LAUNCH '[' assignment_expression ']' '[' assignment_expression ']' '[' assignment_expression ']' postfix_expression '(' argument_expression_list ')'
|
||||
{
|
||||
{
|
||||
Expr *launchCount[3] = {$9, $6, $3};
|
||||
$$ = new FunctionCallExpr($11, $13, Union(@11,@14), true, launchCount);
|
||||
}
|
||||
| TOKEN_LAUNCH '[' assignment_expression ']' '[' assignment_expression ']' '[' assignment_expression ']' postfix_expression '(' ')'
|
||||
{
|
||||
{
|
||||
Expr *launchCount[3] = {$9, $6, $3};
|
||||
$$ = new FunctionCallExpr($11, new ExprList(Union(@11,@12)), Union(@11,@13), true, launchCount);
|
||||
}
|
||||
@@ -908,6 +910,7 @@ storage_class_specifier
|
||||
|
||||
type_specifier
|
||||
: atomic_var_type_specifier { $$ = $1; }
|
||||
| poly_quant_type_specifier { $$ = $1; }
|
||||
| TOKEN_TYPE_NAME
|
||||
{
|
||||
const Type *t = m->symbolTable->LookupType(yytext);
|
||||
@@ -950,6 +953,20 @@ atomic_var_type_specifier
|
||||
| TOKEN_INT64 { $$ = AtomicType::UniformInt64->GetAsUnboundVariabilityType(); }
|
||||
;
|
||||
|
||||
poly_type_specifier
|
||||
: TOKEN_FLOATING { $$ = PolyType::UniformFloating->GetAsUnboundVariabilityType(); }
|
||||
| TOKEN_INTEGER { $$ = PolyType::UniformInteger->GetAsUnboundVariabilityType(); }
|
||||
| TOKEN_NUMBER { $$ = PolyType::UniformNumber->GetAsUnboundVariabilityType(); }
|
||||
;
|
||||
|
||||
poly_quant_type_specifier
|
||||
: poly_type_specifier '$' int_constant
|
||||
{
|
||||
$$ = $1->Quantify($3);
|
||||
}
|
||||
| poly_type_specifier { $$ = $1; }
|
||||
;
|
||||
|
||||
short_vec_specifier
|
||||
: atomic_var_type_specifier '<' int_constant '>'
|
||||
{
|
||||
@@ -2272,10 +2289,10 @@ static void lAddThreadIndexCountToSymbolTable(SourcePos pos) {
|
||||
|
||||
Symbol *taskIndexSym = new Symbol("taskIndex", pos, type);
|
||||
m->symbolTable->AddVariable(taskIndexSym);
|
||||
|
||||
|
||||
Symbol *taskCountSym = new Symbol("taskCount", pos, type);
|
||||
m->symbolTable->AddVariable(taskCountSym);
|
||||
|
||||
|
||||
Symbol *taskIndexSym0 = new Symbol("taskIndex0", pos, type);
|
||||
m->symbolTable->AddVariable(taskIndexSym0);
|
||||
Symbol *taskIndexSym1 = new Symbol("taskIndex1", pos, type);
|
||||
@@ -2283,7 +2300,7 @@ static void lAddThreadIndexCountToSymbolTable(SourcePos pos) {
|
||||
Symbol *taskIndexSym2 = new Symbol("taskIndex2", pos, type);
|
||||
m->symbolTable->AddVariable(taskIndexSym2);
|
||||
|
||||
|
||||
|
||||
Symbol *taskCountSym0 = new Symbol("taskCount0", pos, type);
|
||||
m->symbolTable->AddVariable(taskCountSym0);
|
||||
Symbol *taskCountSym1 = new Symbol("taskCount1", pos, type);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//@error
|
||||
//assigning mismatched polymorphic types
|
||||
|
||||
export void foo(floating<0> bar) {
|
||||
floating<1> baz = bar;
|
||||
export void foo(floating$0 bar) {
|
||||
floating$1 baz = bar;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//@error
|
||||
//assigning mismatched polymorphic types
|
||||
|
||||
export void foo(floating<0> bar) {
|
||||
export void foo(floating$0 bar) {
|
||||
floating baz = bar;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//@error
|
||||
//assigning mismatched polymorphic types
|
||||
|
||||
export void foo(number<0> bar) {
|
||||
floating<0> baz = bar;
|
||||
export void foo(number$0 bar) {
|
||||
floating$0 baz = bar;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//@error
|
||||
//assigning mismatched polymorphic types
|
||||
|
||||
export void foo(number<0> bar) {
|
||||
export void foo(number$0 bar) {
|
||||
integer baz = bar;
|
||||
}
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
// cannot determine return type for mult
|
||||
|
||||
|
||||
floating mult(floating<0> x, floating<1>y) {
|
||||
floating mult(floating$0 x, floating$1 y) {
|
||||
return x * y;
|
||||
}
|
||||
|
||||
export void saxpy(uniform int N,
|
||||
uniform floating<0> scale,
|
||||
uniform floating<1> X[],
|
||||
uniform floating<1> Y[],
|
||||
uniform floating<2> result[])
|
||||
uniform floating$0 scale,
|
||||
uniform floating$1 X[],
|
||||
uniform floating$1 Y[],
|
||||
uniform floating$2 result[])
|
||||
{
|
||||
foreach (i = 0 ... N) {
|
||||
floating<2> tmp = mult(scale, X[i]) + Y[i];
|
||||
floating$2 tmp = mult(scale, X[i]) + Y[i];
|
||||
result[i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
export void saxpy(uniform int N,
|
||||
uniform floating<0> scale,
|
||||
uniform floating<1> X[],
|
||||
uniform floating<1> Y[],
|
||||
uniform floating<2> result[])
|
||||
uniform floating$0 scale,
|
||||
uniform floating$1 X[],
|
||||
uniform floating$1 Y[],
|
||||
uniform floating$2 result[])
|
||||
{
|
||||
foreach (i = 0 ... N) {
|
||||
floating<2> tmp = scale * X[i] + Y[i];
|
||||
floating$2 tmp = scale * X[i] + Y[i];
|
||||
result[i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
6
tests_ispcpp/simple.ispc
Normal file
6
tests_ispcpp/simple.ispc
Normal file
@@ -0,0 +1,6 @@
|
||||
export void foo(uniform int N, floating$1 X[])
|
||||
{
|
||||
foreach (i = 0 ... N) {
|
||||
X[i] = X[i] + 1.0;
|
||||
}
|
||||
}
|
||||
320
type.cpp
320
type.cpp
@@ -673,6 +673,326 @@ llvm::DIType *AtomicType::GetDIType(llvm::DIScope *scope) const {
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// PolyType
|
||||
|
||||
const PolyType *PolyType::UniformInteger =
|
||||
new PolyType(PolyType::TYPE_INTEGER, Variability::Uniform, false);
|
||||
const PolyType *PolyType::VaryingInteger =
|
||||
new PolyType(PolyType::TYPE_INTEGER, Variability::Varying, false);
|
||||
const PolyType *PolyType::UniformFloating =
|
||||
new PolyType(PolyType::TYPE_FLOATING, Variability::Uniform, false);
|
||||
const PolyType *PolyType::VaryingFloating =
|
||||
new PolyType(PolyType::TYPE_FLOATING, Variability::Varying, false);
|
||||
const PolyType *PolyType::UniformNumber =
|
||||
new PolyType(PolyType::TYPE_NUMBER, Variability::Uniform, false);
|
||||
const PolyType *PolyType::VaryingNumber =
|
||||
new PolyType(PolyType::TYPE_NUMBER, Variability::Varying, false);
|
||||
|
||||
PolyType::PolyType(PolyRestriction r, Variability v, bool ic)
|
||||
: Type(POLY_TYPE), restriction(r), variability(v), isConst(ic), quant(-1) {
|
||||
asOtherConstType = NULL;
|
||||
asUniformType = asVaryingType = NULL;
|
||||
}
|
||||
|
||||
PolyType::PolyType(PolyRestriction r, Variability v, bool ic, int q)
|
||||
: Type(POLY_TYPE), restriction(r), variability(v), isConst(ic), quant(q) {
|
||||
asOtherConstType = NULL;
|
||||
asUniformType = asVaryingType = NULL;
|
||||
}
|
||||
|
||||
|
||||
Variability
|
||||
PolyType::GetVariability() const {
|
||||
return variability;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PolyType::IsFloatType() const {
|
||||
return (restriction == TYPE_FLOATING);
|
||||
}
|
||||
|
||||
bool
|
||||
PolyType::IsIntType() const {
|
||||
return (restriction == TYPE_INTEGER);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PolyType::IsUnsignedType() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PolyType::IsBoolType() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PolyType::IsConstType() const {
|
||||
return isConst;
|
||||
}
|
||||
|
||||
|
||||
const PolyType *
|
||||
PolyType::GetAsUnsignedType() const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
const PolyType *
|
||||
PolyType::GetAsConstType() const {
|
||||
if (isConst == true)
|
||||
return this;
|
||||
|
||||
if (asOtherConstType == NULL) {
|
||||
asOtherConstType = new PolyType(restriction, variability, true);
|
||||
asOtherConstType->asOtherConstType = this;
|
||||
}
|
||||
return asOtherConstType;
|
||||
}
|
||||
|
||||
|
||||
const PolyType *
|
||||
PolyType::GetAsNonConstType() const {
|
||||
if (isConst == false)
|
||||
return this;
|
||||
|
||||
if (asOtherConstType == NULL) {
|
||||
asOtherConstType = new PolyType(restriction, variability, false);
|
||||
asOtherConstType->asOtherConstType = this;
|
||||
}
|
||||
return asOtherConstType;
|
||||
}
|
||||
|
||||
|
||||
const PolyType *
|
||||
PolyType::GetBaseType() const {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
const PolyType *
|
||||
PolyType::GetAsVaryingType() const {
|
||||
if (variability == Variability::Varying)
|
||||
return this;
|
||||
|
||||
if (asVaryingType == NULL) {
|
||||
asVaryingType = new PolyType(restriction, Variability::Varying, isConst);
|
||||
if (variability == Variability::Uniform)
|
||||
asVaryingType->asUniformType = this;
|
||||
}
|
||||
return asVaryingType;
|
||||
}
|
||||
|
||||
|
||||
const PolyType *
|
||||
PolyType::GetAsUniformType() const {
|
||||
if (variability == Variability::Uniform)
|
||||
return this;
|
||||
|
||||
if (asUniformType == NULL) {
|
||||
asUniformType = new PolyType(restriction, Variability::Uniform, isConst);
|
||||
if (variability == Variability::Varying)
|
||||
asUniformType->asVaryingType = this;
|
||||
}
|
||||
return asUniformType;
|
||||
}
|
||||
|
||||
|
||||
const PolyType *
|
||||
PolyType::GetAsUnboundVariabilityType() const {
|
||||
if (variability == Variability::Unbound)
|
||||
return this;
|
||||
return new PolyType(restriction, Variability::Unbound, isConst);
|
||||
}
|
||||
|
||||
|
||||
const PolyType *
|
||||
PolyType::GetAsSOAType(int width) const {
|
||||
if (variability == Variability(Variability::SOA, width))
|
||||
return this;
|
||||
return new PolyType(restriction, Variability(Variability::SOA, width),
|
||||
isConst);
|
||||
}
|
||||
|
||||
|
||||
const PolyType *
|
||||
PolyType::ResolveUnboundVariability(Variability v) const {
|
||||
Assert(v != Variability::Unbound);
|
||||
if (variability != Variability::Unbound)
|
||||
return this;
|
||||
return new PolyType(restriction, v, isConst);
|
||||
}
|
||||
|
||||
const PolyType *
|
||||
PolyType::Quantify(int quant) const {
|
||||
return new PolyType(restriction, variability, isConst, quant);
|
||||
}
|
||||
|
||||
std::string
|
||||
PolyType::GetString() const {
|
||||
std::string ret;
|
||||
if (isConst) ret += "const ";
|
||||
|
||||
ret += variability.GetString();
|
||||
ret += " ";
|
||||
|
||||
switch (restriction) {
|
||||
case TYPE_INTEGER: ret += "integer"; break;
|
||||
case TYPE_FLOATING: ret += "floating"; break;
|
||||
case TYPE_NUMBER: ret += "number"; break;
|
||||
default: FATAL("Logic error in PolyType::GetString()");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
PolyType::Mangle() const {
|
||||
std::string ret;
|
||||
if (isConst) ret += "C";
|
||||
ret += variability.MangleString();
|
||||
|
||||
switch (restriction) {
|
||||
case TYPE_INTEGER: ret += "Z"; break;
|
||||
case TYPE_FLOATING: ret += "Q"; break;
|
||||
case TYPE_NUMBER: ret += "R"; break;
|
||||
default: FATAL("Logic error in PolyType::Mangle()");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
PolyType::GetCDeclaration(const std::string &name) const {
|
||||
std::string ret;
|
||||
if (variability == Variability::Unbound) {
|
||||
Assert(m->errorCount > 0);
|
||||
return ret;
|
||||
}
|
||||
if (isConst) ret += "const ";
|
||||
|
||||
switch (restriction) {
|
||||
case TYPE_INTEGER: ret += "int32_t"; break;
|
||||
case TYPE_FLOATING: ret += "double"; break;
|
||||
case TYPE_NUMBER: ret += "double"; break;
|
||||
default: FATAL("Logic error in PolyType::GetCDeclaration()");
|
||||
}
|
||||
|
||||
if (lShouldPrintName(name)) {
|
||||
ret += " ";
|
||||
ret += name;
|
||||
}
|
||||
|
||||
if (variability == Variability::SOA) {
|
||||
char buf[32];
|
||||
sprintf(buf, "[%d]", variability.soaWidth);
|
||||
ret += buf;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
llvm::Type *
|
||||
PolyType::LLVMType(llvm::LLVMContext *ctx) const {
|
||||
Assert(variability.type != Variability::Unbound);
|
||||
bool isUniform = (variability == Variability::Uniform);
|
||||
bool isVarying = (variability == Variability::Varying);
|
||||
|
||||
if (isUniform || isVarying) {
|
||||
switch (restriction) {
|
||||
case TYPE_INTEGER:
|
||||
return isUniform ? LLVMTypes::Int32Type : LLVMTypes::Int32VectorType;
|
||||
case TYPE_FLOATING:
|
||||
case TYPE_NUMBER:
|
||||
return isUniform ? LLVMTypes::DoubleType : LLVMTypes::DoubleVectorType;
|
||||
default:
|
||||
FATAL("logic error in PolyType::LLVMType");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ArrayType at(GetAsUniformType(), variability.soaWidth);
|
||||
return at.LLVMType(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
|
||||
llvm::DIType PolyType::GetDIType(llvm::DIDescriptor scope) const {
|
||||
#else //LLVM 3.7++
|
||||
llvm::DIType *PolyType::GetDIType(llvm::DIScope *scope) const {
|
||||
#endif
|
||||
Assert(variability.type != Variability::Unbound);
|
||||
|
||||
if (variability.type == Variability::Uniform) {
|
||||
switch (restriction) {
|
||||
#if ISPC_LLVM_VERSION <= ISPC_LLVM_3_9
|
||||
case TYPE_INTEGER:
|
||||
return m->diBuilder->createBasicType("int32", 32 /* size */, 32 /* align */,
|
||||
llvm::dwarf::DW_ATE_signed);
|
||||
break;
|
||||
case TYPE_FLOATING:
|
||||
case TYPE_NUMBER:
|
||||
return m->diBuilder->createBasicType("double", 64 /* size */, 64 /* align */,
|
||||
llvm::dwarf::DW_ATE_float);
|
||||
break;
|
||||
#else // LLVM 4.0+
|
||||
case TYPE_INTEGER:
|
||||
return m->diBuilder->createBasicType("int32", 32 /* size */,
|
||||
llvm::dwarf::DW_ATE_signed);
|
||||
break;
|
||||
case TYPE_FLOATING:
|
||||
case TYPE_NUMBER:
|
||||
return m->diBuilder->createBasicType("double", 64 /* size */,
|
||||
llvm::dwarf::DW_ATE_float);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
FATAL("unhandled basic type in PolyType::GetDIType()");
|
||||
#if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
|
||||
return llvm::DIType();
|
||||
#else //LLVM 3.7+
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (variability == Variability::Varying) {
|
||||
#if ISPC_LLVM_VERSION == ISPC_LLVM_3_2
|
||||
llvm::Value *sub = m->diBuilder->getOrCreateSubrange(0, g->target->getVectorWidth()-1);
|
||||
#elif ISPC_LLVM_VERSION > ISPC_VERSION_3_2 && ISPC_LLVM_VERSION <= ISPC_LLVM_3_5
|
||||
llvm::Value *sub = m->diBuilder->getOrCreateSubrange(0, g->target->getVectorWidth());
|
||||
#else // LLVM 3.6+
|
||||
llvm::Metadata *sub = m->diBuilder->getOrCreateSubrange(0, g->target->getVectorWidth());
|
||||
#endif
|
||||
#if ISPC_LLVM_VERSION > ISPC_VERSION_3_2 && ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
|
||||
llvm::DIArray subArray = m->diBuilder->getOrCreateArray(sub);
|
||||
llvm::DIType unifType = GetAsUniformType()->GetDIType(scope);
|
||||
uint64_t size = unifType.getSizeInBits() * g->target->getVectorWidth();
|
||||
uint64_t align = unifType.getAlignInBits() * g->target->getVectorWidth();
|
||||
#else // LLVM 3.7+
|
||||
llvm::DINodeArray subArray = m->diBuilder->getOrCreateArray(sub);
|
||||
llvm::DIType *unifType = GetAsUniformType()->GetDIType(scope);
|
||||
//llvm::DebugNodeArray subArray = m->diBuilder->getOrCreateArray(sub);
|
||||
//llvm::MDType *unifType = GetAsUniformType()->GetDIType(scope);
|
||||
uint64_t size = unifType->getSizeInBits() * g->target->getVectorWidth();
|
||||
uint64_t align = unifType->getAlignInBits()* g->target->getVectorWidth();
|
||||
#endif
|
||||
return m->diBuilder->createVectorType(size, align, unifType, subArray);
|
||||
}
|
||||
else {
|
||||
Assert(variability == Variability::SOA);
|
||||
ArrayType at(GetAsUniformType(), variability.soaWidth);
|
||||
return at.GetDIType(scope);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// EnumType
|
||||
|
||||
64
type.h
64
type.h
@@ -89,7 +89,8 @@ enum TypeId {
|
||||
STRUCT_TYPE, // 5
|
||||
UNDEFINED_STRUCT_TYPE, // 6
|
||||
REFERENCE_TYPE, // 7
|
||||
FUNCTION_TYPE // 8
|
||||
FUNCTION_TYPE, // 8
|
||||
POLY_TYPE // 9
|
||||
};
|
||||
|
||||
|
||||
@@ -364,6 +365,67 @@ private:
|
||||
mutable const AtomicType *asOtherConstType, *asUniformType, *asVaryingType;
|
||||
};
|
||||
|
||||
class PolyType : public Type {
|
||||
public:
|
||||
Variability GetVariability() const;
|
||||
|
||||
bool IsBoolType() const;
|
||||
bool IsFloatType() const;
|
||||
bool IsIntType() const;
|
||||
bool IsUnsignedType() const;
|
||||
bool IsConstType() const;
|
||||
|
||||
const PolyType *GetBaseType() const;
|
||||
const PolyType *GetAsUniformType() const;
|
||||
const PolyType *GetAsVaryingType() const;
|
||||
const PolyType *GetAsUnboundVariabilityType() const;
|
||||
const PolyType *GetAsSOAType(int width) const;
|
||||
|
||||
const PolyType *ResolveUnboundVariability(Variability v) const;
|
||||
const PolyType *GetAsUnsignedType() const;
|
||||
const PolyType *GetAsConstType() const;
|
||||
const PolyType *GetAsNonConstType() const;
|
||||
|
||||
const PolyType *Quantify(int quant) const;
|
||||
|
||||
std::string GetString() const;
|
||||
std::string Mangle() const;
|
||||
std::string GetCDeclaration(const std::string &name) const;
|
||||
|
||||
llvm::Type *LLVMType(llvm::LLVMContext *ctx) const;
|
||||
#if ISPC_LLVM_VERSION <= ISPC_LLVM_3_6
|
||||
llvm::DIType GetDIType(llvm::DIDescriptor scope) const;
|
||||
#else // LLVM 3.7++
|
||||
llvm::DIType *GetDIType(llvm::DIScope *scope) const;
|
||||
#endif
|
||||
|
||||
enum PolyRestriction {
|
||||
TYPE_INTEGER,
|
||||
TYPE_FLOATING,
|
||||
TYPE_NUMBER
|
||||
};
|
||||
|
||||
const PolyRestriction restriction;
|
||||
|
||||
|
||||
static const PolyType *UniformInteger, *VaryingInteger;
|
||||
static const PolyType *UniformFloating, *VaryingFloating;
|
||||
static const PolyType *UniformNumber, *VaryingNumber;
|
||||
|
||||
// Returns the list of AtomicTypes that are valid instantiations of the
|
||||
// polymorphic type
|
||||
const std::vector<AtomicType *> GetEnumeratedTypes() const;
|
||||
|
||||
private:
|
||||
const Variability variability;
|
||||
const bool isConst;
|
||||
const int quant;
|
||||
PolyType(PolyRestriction type, Variability v, bool isConst);
|
||||
PolyType(PolyRestriction type, Variability v, bool isConst, int quant);
|
||||
|
||||
mutable const PolyType *asOtherConstType, *asUniformType, *asVaryingType;
|
||||
};
|
||||
|
||||
|
||||
/** @brief Type implementation for enumerated types
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user