Merge branch 'master' of git://github.com/ispc/ispc

This commit is contained in:
Jean-Luc Duprat
2012-03-21 17:07:18 -07:00
11 changed files with 446 additions and 139 deletions

24
ast.cpp
View File

@@ -323,14 +323,22 @@ static bool
lCheckAllOffSafety(ASTNode *node, void *data) { lCheckAllOffSafety(ASTNode *node, void *data) {
bool *okPtr = (bool *)data; bool *okPtr = (bool *)data;
if (dynamic_cast<FunctionCallExpr *>(node) != NULL) { FunctionCallExpr *fce;
// FIXME: If we could somehow determine that the function being if ((fce = dynamic_cast<FunctionCallExpr *>(node)) != NULL) {
// called was safe (and all of the args Exprs were safe, then it'd if (fce->func == NULL)
// be nice to be able to return true here. (Consider a call to return false;
// e.g. floatbits() in the stdlib.) Unfortunately for now we just
// have to be conservative. const Type *type = fce->func->GetType();
*okPtr = false; const PointerType *pt = dynamic_cast<const PointerType *>(type);
return false; if (pt != NULL)
type = pt->GetBaseType();
const FunctionType *ftype = dynamic_cast<const FunctionType *>(type);
Assert(ftype != NULL);
if (ftype->isSafe == false) {
*okPtr = false;
return false;
}
} }
if (dynamic_cast<AssertStmt *>(node) != NULL) { if (dynamic_cast<AssertStmt *>(node) != NULL) {

View File

@@ -538,10 +538,31 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const {
return NULL; return NULL;
} }
const Type *functionType = const FunctionType *functionType =
new FunctionType(returnType, args, argNames, argDefaults, new FunctionType(returnType, args, argNames, argDefaults,
argPos, isTask, isExported, isExternC); argPos, isTask, isExported, isExternC);
functionType = functionType->ResolveUnboundVariability(Variability::Varying); functionType = functionType->ResolveUnboundVariability(Variability::Varying);
// handle any explicit __declspecs on the function
if (ds != NULL) {
for (int i = 0; i < (int)ds->declSpecList.size(); ++i) {
std::string str = ds->declSpecList[i].first;
SourcePos pos = ds->declSpecList[i].second;
if (str == "safe")
(const_cast<FunctionType *>(functionType))->isSafe = true;
else if (!strncmp(str.c_str(), "cost", 4)) {
int cost = atoi(str.c_str() + 4);
if (cost < 0)
Error(pos, "Negative function cost %d is illegal.",
cost);
(const_cast<FunctionType *>(functionType))->costOverride = cost;
}
else
Error(pos, "__declspec parameter \"%s\" unknown.", str.c_str());
}
}
return child->GetType(functionType, ds); return child->GetType(functionType, ds);
} }
default: default:
@@ -555,6 +576,14 @@ const Type *
Declarator::GetType(DeclSpecs *ds) const { Declarator::GetType(DeclSpecs *ds) const {
const Type *baseType = ds->GetBaseType(pos); const Type *baseType = ds->GetBaseType(pos);
const Type *type = GetType(baseType, ds); const Type *type = GetType(baseType, ds);
if (ds->declSpecList.size() > 0 &&
type != NULL &
dynamic_cast<const FunctionType *>(type) == NULL) {
Error(pos, "__declspec specifiers for non-function type \"%s\" are "
"not used.", type->GetString().c_str());
}
return type; return type;
} }

5
decl.h
View File

@@ -90,7 +90,8 @@ enum StorageClass {
*/ */
class DeclSpecs { class DeclSpecs {
public: public:
DeclSpecs(const Type *t = NULL, StorageClass sc = SC_NONE, int tq = TYPEQUAL_NONE); DeclSpecs(const Type *t = NULL, StorageClass sc = SC_NONE,
int tq = TYPEQUAL_NONE);
void Print() const; void Print() const;
@@ -117,6 +118,8 @@ public:
SOA width specified. Otherwise this is zero. SOA width specified. Otherwise this is zero.
*/ */
int soaWidth; int soaWidth;
std::vector<std::pair<std::string, SourcePos> > declSpecList;
}; };

View File

@@ -327,8 +327,8 @@ ShadeTile(
// Reconstruct normal from G-buffer // Reconstruct normal from G-buffer
float surface_normal_x, surface_normal_y, surface_normal_z; float surface_normal_x, surface_normal_y, surface_normal_z;
float normal_x = half_to_float_fast(inputData.normalEncoded_x[gBufferOffset]); float normal_x = half_to_float(inputData.normalEncoded_x[gBufferOffset]);
float normal_y = half_to_float_fast(inputData.normalEncoded_y[gBufferOffset]); float normal_y = half_to_float(inputData.normalEncoded_y[gBufferOffset]);
float f = (normal_x - normal_x * normal_x) + (normal_y - normal_y * normal_y); float f = (normal_x - normal_x * normal_x) + (normal_y - normal_y * normal_y);
float m = sqrt(4.0f * f - 1.0f); float m = sqrt(4.0f * f - 1.0f);
@@ -339,9 +339,9 @@ ShadeTile(
// Load other G-buffer parameters // Load other G-buffer parameters
float surface_specularAmount = float surface_specularAmount =
half_to_float_fast(inputData.specularAmount[gBufferOffset]); half_to_float(inputData.specularAmount[gBufferOffset]);
float surface_specularPower = float surface_specularPower =
half_to_float_fast(inputData.specularPower[gBufferOffset]); half_to_float(inputData.specularPower[gBufferOffset]);
float surface_albedo_x = Unorm8ToFloat32(inputData.albedo_x[gBufferOffset]); float surface_albedo_x = Unorm8ToFloat32(inputData.albedo_x[gBufferOffset]);
float surface_albedo_y = Unorm8ToFloat32(inputData.albedo_y[gBufferOffset]); float surface_albedo_y = Unorm8ToFloat32(inputData.albedo_y[gBufferOffset]);
float surface_albedo_z = Unorm8ToFloat32(inputData.albedo_z[gBufferOffset]); float surface_albedo_z = Unorm8ToFloat32(inputData.albedo_z[gBufferOffset]);

View File

@@ -1269,6 +1269,9 @@ UnaryExpr::TypeCheck() {
int int
UnaryExpr::EstimateCost() const { UnaryExpr::EstimateCost() const {
if (dynamic_cast<ConstExpr *>(expr) != NULL)
return 0;
return COST_SIMPLE_ARITH_LOGIC_OP; return COST_SIMPLE_ARITH_LOGIC_OP;
} }
@@ -2501,6 +2504,10 @@ BinaryExpr::TypeCheck() {
int int
BinaryExpr::EstimateCost() const { BinaryExpr::EstimateCost() const {
if (dynamic_cast<ConstExpr *>(arg0) != NULL &&
dynamic_cast<ConstExpr *>(arg1) != NULL)
return 0;
return (op == Div || op == Mod) ? COST_COMPLEX_ARITH_OP : return (op == Div || op == Mod) ? COST_COMPLEX_ARITH_OP :
COST_SIMPLE_ARITH_LOGIC_OP; COST_SIMPLE_ARITH_LOGIC_OP;
} }
@@ -3518,18 +3525,23 @@ int
FunctionCallExpr::EstimateCost() const { FunctionCallExpr::EstimateCost() const {
if (isLaunch) if (isLaunch)
return COST_TASK_LAUNCH; return COST_TASK_LAUNCH;
else if (dynamic_cast<FunctionSymbolExpr *>(func) == NULL) {
// it's going through a function pointer const Type *type = func->GetType();
const Type *fpType = func->GetType(); if (type == NULL)
if (fpType != NULL) { return 0;
Assert(dynamic_cast<const PointerType *>(fpType) != NULL);
if (fpType->IsUniformType()) const PointerType *pt = dynamic_cast<const PointerType *>(type);
return COST_FUNPTR_UNIFORM; if (pt != NULL)
else type = type->GetBaseType();
return COST_FUNPTR_VARYING; const FunctionType *ftype = dynamic_cast<const FunctionType *>(type);
}
} if (ftype->costOverride > -1)
return COST_FUNCALL; return ftype->costOverride;
if (pt != NULL)
return pt->IsUniformType() ? COST_FUNPTR_UNIFORM : COST_FUNPTR_VARYING;
else
return COST_FUNCALL;
} }
@@ -6714,6 +6726,9 @@ TypeCastExpr::Optimize() {
int int
TypeCastExpr::EstimateCost() const { TypeCastExpr::EstimateCost() const {
if (dynamic_cast<ConstExpr *>(expr) != NULL)
return 0;
// FIXME: return COST_TYPECAST_COMPLEX when appropriate // FIXME: return COST_TYPECAST_COMPLEX when appropriate
return COST_TYPECAST_SIMPLE; return COST_TYPECAST_SIMPLE;
} }

1
lex.ll
View File

@@ -346,6 +346,7 @@ cwhile { RT; return TOKEN_CWHILE; }
const { RT; return TOKEN_CONST; } const { RT; return TOKEN_CONST; }
continue { RT; return TOKEN_CONTINUE; } continue { RT; return TOKEN_CONTINUE; }
creturn { RT; return TOKEN_CRETURN; } creturn { RT; return TOKEN_CRETURN; }
__declspec { RT; return TOKEN_DECLSPEC; }
default { RT; return TOKEN_DEFAULT; } default { RT; return TOKEN_DEFAULT; }
do { RT; return TOKEN_DO; } do { RT; return TOKEN_DO; }
delete { RT; return TOKEN_DELETE; } delete { RT; return TOKEN_DELETE; }

View File

@@ -356,8 +356,11 @@ lRecursiveCheckValidParamType(const Type *t) {
return lRecursiveCheckValidParamType(seqt->GetElementType()); return lRecursiveCheckValidParamType(seqt->GetElementType());
const PointerType *pt = dynamic_cast<const PointerType *>(t); const PointerType *pt = dynamic_cast<const PointerType *>(t);
if (pt != NULL) if (pt != NULL) {
return (pt->IsSlice() || pt->IsVaryingType()); if (pt->IsSlice() || pt->IsVaryingType())
return true;
return lRecursiveCheckValidParamType(pt->GetBaseType());
}
return t->IsVaryingType(); return t->IsVaryingType();
} }

View File

@@ -168,6 +168,8 @@ struct ForeachDimension {
std::vector<Symbol *> *symbolList; std::vector<Symbol *> *symbolList;
ForeachDimension *foreachDimension; ForeachDimension *foreachDimension;
std::vector<ForeachDimension *> *foreachDimensionList; std::vector<ForeachDimension *> *foreachDimensionList;
std::pair<std::string, SourcePos> *declspecPair;
std::vector<std::pair<std::string, SourcePos> > *declspecList;
} }
@@ -181,7 +183,7 @@ struct ForeachDimension {
%token TOKEN_AND_ASSIGN TOKEN_OR_ASSIGN TOKEN_XOR_ASSIGN %token TOKEN_AND_ASSIGN TOKEN_OR_ASSIGN TOKEN_XOR_ASSIGN
%token TOKEN_SIZEOF TOKEN_NEW TOKEN_DELETE %token TOKEN_SIZEOF TOKEN_NEW TOKEN_DELETE
%token TOKEN_EXTERN TOKEN_EXPORT TOKEN_STATIC TOKEN_INLINE TOKEN_TASK %token TOKEN_EXTERN TOKEN_EXPORT TOKEN_STATIC TOKEN_INLINE TOKEN_TASK TOKEN_DECLSPEC
%token TOKEN_UNIFORM TOKEN_VARYING TOKEN_TYPEDEF TOKEN_SOA %token TOKEN_UNIFORM TOKEN_VARYING TOKEN_TYPEDEF TOKEN_SOA
%token TOKEN_CHAR TOKEN_INT TOKEN_SIGNED TOKEN_UNSIGNED TOKEN_FLOAT TOKEN_DOUBLE %token TOKEN_CHAR TOKEN_INT TOKEN_SIGNED TOKEN_UNSIGNED TOKEN_FLOAT TOKEN_DOUBLE
%token TOKEN_INT8 TOKEN_INT16 TOKEN_INT64 TOKEN_CONST TOKEN_VOID TOKEN_BOOL %token TOKEN_INT8 TOKEN_INT16 TOKEN_INT64 TOKEN_CONST TOKEN_VOID TOKEN_BOOL
@@ -233,13 +235,16 @@ struct ForeachDimension {
%type <storageClass> storage_class_specifier %type <storageClass> storage_class_specifier
%type <declSpecs> declaration_specifiers %type <declSpecs> declaration_specifiers
%type <stringVal> string_constant %type <stringVal> string_constant
%type <constCharPtr> struct_or_union_name enum_identifier goto_identifier %type <constCharPtr> struct_or_union_name enum_identifier goto_identifier
%type <intVal> int_constant soa_width_specifier rate_qualified_new %type <intVal> int_constant soa_width_specifier rate_qualified_new
%type <foreachDimension> foreach_dimension_specifier %type <foreachDimension> foreach_dimension_specifier
%type <foreachDimensionList> foreach_dimension_list %type <foreachDimensionList> foreach_dimension_list
%type <declspecPair> declspec_item
%type <declspecList> declspec_specifier declspec_list
%start translation_unit %start translation_unit
%% %%
@@ -645,6 +650,37 @@ soa_width_specifier
{ $$ = $3; } { $$ = $3; }
; ;
declspec_item
: TOKEN_IDENTIFIER
{
std::pair<std::string, SourcePos> *p = new std::pair<std::string, SourcePos>;
p->first = *(yylval.stringVal);
p->second = @1;
$$ = p;
}
;
declspec_list
: declspec_item
{
$$ = new std::vector<std::pair<std::string, SourcePos> >;
$$->push_back(*$1);
}
| declspec_list ',' declspec_item
{
if ($1 != NULL)
$1->push_back(*$3);
$$ = $1;
}
;
declspec_specifier
: TOKEN_DECLSPEC '(' declspec_list ')'
{
$$ = $3;
}
;
declaration_specifiers declaration_specifiers
: storage_class_specifier : storage_class_specifier
{ {
@@ -664,6 +700,22 @@ declaration_specifiers
} }
$$ = ds; $$ = ds;
} }
| declspec_specifier
{
$$ = new DeclSpecs;
if ($1 != NULL)
$$->declSpecList = *$1;
}
| declspec_specifier declaration_specifiers
{
DeclSpecs *ds = (DeclSpecs *)$2;
std::vector<std::pair<std::string, SourcePos> > *declSpecList = $1;
if (ds != NULL && declSpecList != NULL) {
for (int i = 0; i < (int)declSpecList->size(); ++i)
ds->declSpecList.push_back((*declSpecList)[i]);
}
$$ = ds;
}
| soa_width_specifier | soa_width_specifier
{ {
DeclSpecs *ds = new DeclSpecs; DeclSpecs *ds = new DeclSpecs;

File diff suppressed because it is too large Load Diff

View File

@@ -2329,6 +2329,8 @@ FunctionType::FunctionType(const Type *r, const std::vector<const Type *> &a,
paramDefaults(std::vector<ConstExpr *>(a.size(), NULL)), paramDefaults(std::vector<ConstExpr *>(a.size(), NULL)),
paramPositions(std::vector<SourcePos>(a.size(), p)) { paramPositions(std::vector<SourcePos>(a.size(), p)) {
Assert(returnType != NULL); Assert(returnType != NULL);
isSafe = false;
costOverride = -1;
} }
@@ -2343,6 +2345,8 @@ FunctionType::FunctionType(const Type *r, const std::vector<const Type *> &a,
paramNames.size() == paramDefaults.size() && paramNames.size() == paramDefaults.size() &&
paramDefaults.size() == paramPositions.size()); paramDefaults.size() == paramPositions.size());
Assert(returnType != NULL); Assert(returnType != NULL);
isSafe = false;
costOverride = -1;
} }
@@ -2434,8 +2438,13 @@ FunctionType::ResolveUnboundVariability(Variability v) const {
pt.push_back(paramTypes[i]->ResolveUnboundVariability(v)); pt.push_back(paramTypes[i]->ResolveUnboundVariability(v));
} }
return new FunctionType(rt, pt, paramNames, paramDefaults, FunctionType *ret = new FunctionType(rt, pt, paramNames, paramDefaults,
paramPositions, isTask, isExported, isExternC); paramPositions, isTask, isExported,
isExternC);
ret->isSafe = isSafe;
ret->costOverride = costOverride;
return ret;
} }
@@ -2457,6 +2466,12 @@ std::string
FunctionType::GetString() const { FunctionType::GetString() const {
std::string ret; std::string ret;
if (isTask) ret += "task "; if (isTask) ret += "task ";
if (isSafe) ret += "/*safe*/ ";
if (costOverride > 0) {
char buf[32];
sprintf(buf, "/*cost=%d*/ ", costOverride);
ret += buf;
}
if (returnType != NULL) if (returnType != NULL)
ret += returnType->GetString(); ret += returnType->GetString();
else else

8
type.h
View File

@@ -801,6 +801,14 @@ public:
function in the source program. */ function in the source program. */
const bool isExternC; const bool isExternC;
/** Indicates whether this function has been declared to be safe to run
with an all-off mask. */
bool isSafe;
/** If non-negative, this provides a user-supplied override to the cost
function estimate for the function. */
int costOverride;
private: private:
const Type * const returnType; const Type * const returnType;