Merge branch 'master' of git://github.com/ispc/ispc
This commit is contained in:
24
ast.cpp
24
ast.cpp
@@ -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) {
|
||||||
|
|||||||
31
decl.cpp
31
decl.cpp
@@ -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
5
decl.h
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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]);
|
||||||
|
|||||||
39
expr.cpp
39
expr.cpp
@@ -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
1
lex.ll
@@ -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; }
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
56
parse.yy
56
parse.yy
@@ -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;
|
||||||
|
|||||||
387
stdlib.ispc
387
stdlib.ispc
File diff suppressed because it is too large
Load Diff
19
type.cpp
19
type.cpp
@@ -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
8
type.h
@@ -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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user