Merge branch 'master' into nvptx
This commit is contained in:
@@ -2938,23 +2938,28 @@ Function Overloading
|
||||
--------------------
|
||||
|
||||
Functions can be overloaded by parameter type. Given multiple definitions
|
||||
of a function, ``ispc`` uses the following methods to try to find a match.
|
||||
If a single match of a given type is found, it is used; if multiple matches
|
||||
of a given type are found, an error is issued.
|
||||
of a function, ``ispc`` uses the following model to choose the best function:
|
||||
each conversion of two types has its cost. ``ispc`` tries to find conversion
|
||||
with the smallest cost. When ``ispc`` can't find any conversion it means that
|
||||
this function is not suitable. Then ``ispc`` sums costs for all arguments and
|
||||
chooses the function with the smallest final cost. If the chosen function
|
||||
has some arguments which costs are bigger than their costs in other function
|
||||
this treats as ambiguous.
|
||||
Costs of type conversions placed from small to big:
|
||||
|
||||
* All parameter types match exactly.
|
||||
* All parameter types match exactly, where any reference-type
|
||||
parameters are considered equivalent to their underlying type.
|
||||
* Parameters match with only type conversions that don't risk losing any
|
||||
information (for example, converting an ``int16`` value to an ``int32``
|
||||
parameter value.)
|
||||
* Parameters match with only promotions from ``uniform`` to ``varying``
|
||||
types.
|
||||
* Parameters match using arbitrary type conversion, without changing
|
||||
variability from ``uniform`` to ``varying`` (e.g., ``int`` to ``float``,
|
||||
``float`` to ``int``.)
|
||||
* Parameters match using arbitrary type conversion, including also changing
|
||||
variability from ``uniform`` to ``varying`` as needed.
|
||||
1. Parameter types match exactly.
|
||||
2. Function parameter type is reference and parameters match when any reference-type parameter are considered equivalent to their underlying type.
|
||||
3. Function parameter type is const-reference and parameters match when any reference-type parameter are considered equivalent to their underlying type ignoring const attributes.
|
||||
4. Parameters match exactly, except constant attributes. [NO CONSTANT ATTRIBUTES LATER]
|
||||
5. Parameters match exactly, except reference attributes. [NO REFERENCES ATTRIBUTES LATER]
|
||||
6. Parameters match with only type conversions that don't risk losing any information (for example, converting an int16 value to an int32 parameter value.)
|
||||
7. Parameters match with only promotions from uniform to varying types.
|
||||
8. Parameters match using arbitrary type conversion, without changing variability from uniform to varying (e.g., int to float, float to int.)
|
||||
9. Parameters match with widening and promotions from uniform to varying types. (combination of "6" and "7")
|
||||
10. Parameters match using arbitrary type conversion, including also changing variability from uniform to varying.
|
||||
|
||||
* If function parameter type is reference and neither "2" nor "3" aren't suitable, function is not suitable
|
||||
* If "10" isn't suitable, function is not suitable
|
||||
|
||||
|
||||
Re-establishing The Execution Mask
|
||||
|
||||
186
expr.cpp
186
expr.cpp
@@ -8097,23 +8097,6 @@ lGetOverloadCandidateMessage(const std::vector<Symbol *> &funcs,
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
lIsMatchToNonConstReference(const Type *callType, const Type *funcArgType) {
|
||||
return (CastType<ReferenceType>(funcArgType) &&
|
||||
(funcArgType->IsConstType() == false) &&
|
||||
Type::Equal(callType, funcArgType->GetReferenceTarget()));
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
lIsMatchToNonConstReferenceUnifToVarying(const Type *callType,
|
||||
const Type *funcArgType) {
|
||||
return (CastType<ReferenceType>(funcArgType) &&
|
||||
(funcArgType->IsConstType() == false) &&
|
||||
Type::Equal(callType->GetAsVaryingType(),
|
||||
funcArgType->GetReferenceTarget()));
|
||||
}
|
||||
|
||||
/** Helper function used for function overload resolution: returns true if
|
||||
converting the argument to the call type only requires a type
|
||||
conversion that won't lose information. Otherwise return false.
|
||||
@@ -8160,31 +8143,6 @@ lIsMatchWithTypeWidening(const Type *callType, const Type *funcArgType) {
|
||||
}
|
||||
|
||||
|
||||
/** Helper function used for function overload resolution: returns true if
|
||||
the call argument type and the function argument type match if we only
|
||||
do a uniform -> varying type conversion but otherwise have exactly the
|
||||
same type.
|
||||
*/
|
||||
static bool
|
||||
lIsMatchWithUniformToVarying(const Type *callType, const Type *funcArgType) {
|
||||
return (callType->IsUniformType() &&
|
||||
funcArgType->IsVaryingType() &&
|
||||
Type::EqualIgnoringConst(callType->GetAsVaryingType(), funcArgType));
|
||||
}
|
||||
|
||||
|
||||
/** Helper function used for function overload resolution: returns true if
|
||||
we can type convert from the call argument type to the function
|
||||
argument type, but without doing a uniform -> varying conversion.
|
||||
*/
|
||||
static bool
|
||||
lIsMatchWithTypeConvSameVariability(const Type *callType,
|
||||
const Type *funcArgType) {
|
||||
return (CanConvertTypes(callType, funcArgType) &&
|
||||
(callType->GetVariability() == funcArgType->GetVariability()));
|
||||
}
|
||||
|
||||
|
||||
/* Returns the set of function overloads that are potential matches, given
|
||||
argCount values being passed as arguments to the function call.
|
||||
*/
|
||||
@@ -8236,13 +8194,15 @@ int
|
||||
FunctionSymbolExpr::computeOverloadCost(const FunctionType *ftype,
|
||||
const std::vector<const Type *> &argTypes,
|
||||
const std::vector<bool> *argCouldBeNULL,
|
||||
const std::vector<bool> *argIsConstant) {
|
||||
const std::vector<bool> *argIsConstant,
|
||||
int * cost) {
|
||||
int costSum = 0;
|
||||
|
||||
// In computing the cost function, we only worry about the actual
|
||||
// argument types--using function default parameter values is free for
|
||||
// the purposes here...
|
||||
for (int i = 0; i < (int)argTypes.size(); ++i) {
|
||||
cost[i] = 0;
|
||||
// The cost imposed by this argument will be a multiple of
|
||||
// costScale, which has a value set so that for each of the cost
|
||||
// buckets, even if all of the function arguments undergo the next
|
||||
@@ -8255,51 +8215,105 @@ FunctionSymbolExpr::computeOverloadCost(const FunctionType *ftype,
|
||||
|
||||
if (Type::Equal(callType, fargType))
|
||||
// Perfect match: no cost
|
||||
costSum += 0;
|
||||
// Step "1" from documentation
|
||||
cost[i] += 0;
|
||||
else if (argCouldBeNULL && (*argCouldBeNULL)[i] &&
|
||||
lArgIsPointerType(fargType))
|
||||
// Passing NULL to a pointer-typed parameter is also a no-cost
|
||||
// operation
|
||||
costSum += 0;
|
||||
// Passing NULL to a pointer-typed parameter is also a no-cost operation
|
||||
// Step "1" from documentation
|
||||
cost[i] += 0;
|
||||
else {
|
||||
// If the argument is a compile-time constant, we'd like to
|
||||
// count the cost of various conversions as much lower than the
|
||||
// cost if it wasn't--so scale up the cost when this isn't the
|
||||
// case..
|
||||
if (argIsConstant == NULL || (*argIsConstant)[i] == false)
|
||||
costScale *= 128;
|
||||
costScale *= 512;
|
||||
|
||||
// For convenience, normalize to non-const types (except for
|
||||
// references, where const-ness matters). For all other types,
|
||||
// we're passing by value anyway, so const doesn't matter.
|
||||
const Type *callTypeNC = callType, *fargTypeNC = fargType;
|
||||
if (CastType<ReferenceType>(callType) == NULL)
|
||||
callTypeNC = callType->GetAsNonConstType();
|
||||
if (CastType<ReferenceType>(fargType) == NULL)
|
||||
fargTypeNC = fargType->GetAsNonConstType();
|
||||
if (CastType<ReferenceType>(fargType)) {
|
||||
// Here we completely handle the case where fargType is reference.
|
||||
if (callType->IsConstType() && !fargType->IsConstType()) {
|
||||
// It is forbidden to pass const object to non-const reference (cvf -> vfr)
|
||||
return -1;
|
||||
}
|
||||
if (!callType->IsConstType() && fargType->IsConstType()) {
|
||||
// It is possible to pass (vf -> cvfr)
|
||||
// but it is worse than (vf -> vfr) or (cvf -> cvfr)
|
||||
// Step "3" from documentation
|
||||
cost[i] += 2 * costScale;
|
||||
}
|
||||
if (!Type::Equal(callType->GetReferenceTarget()->GetAsNonConstType(),
|
||||
fargType->GetReferenceTarget()->GetAsNonConstType())) {
|
||||
// Types under references must be equal completely.
|
||||
// vd -> vfr or vd -> cvfr are forbidden. (Although clang allows vd -> cvfr case.)
|
||||
return -1;
|
||||
}
|
||||
// penalty for equal types under reference (vf -> vfr is worse than vf -> vf)
|
||||
// Step "2" from documentation
|
||||
cost[i] += 2 * costScale;
|
||||
continue;
|
||||
}
|
||||
const Type *callTypeNP = callType;
|
||||
if (CastType<ReferenceType>(callType)) {
|
||||
callTypeNP = callType->GetReferenceTarget();
|
||||
// we can treat vfr as vf for callType with some penalty
|
||||
// Step "5" from documentation
|
||||
cost[i] += 2 * costScale;
|
||||
}
|
||||
|
||||
if (Type::Equal(callTypeNC, fargTypeNC))
|
||||
// Exact match (after dealing with references, above)
|
||||
costSum += 1 * costScale;
|
||||
// note: orig fargType for the next two...
|
||||
else if (lIsMatchToNonConstReference(callTypeNC, fargType))
|
||||
costSum += 2 * costScale;
|
||||
else if (lIsMatchToNonConstReferenceUnifToVarying(callTypeNC, fargType))
|
||||
costSum += 4 * costScale;
|
||||
else if (lIsMatchWithTypeWidening(callTypeNC, fargTypeNC))
|
||||
costSum += 8 * costScale;
|
||||
else if (lIsMatchWithUniformToVarying(callTypeNC, fargTypeNC))
|
||||
costSum += 16 * costScale;
|
||||
else if (lIsMatchWithTypeConvSameVariability(callTypeNC, fargTypeNC))
|
||||
costSum += 32 * costScale;
|
||||
else if (CanConvertTypes(callTypeNC, fargTypeNC))
|
||||
costSum += 64 * costScale;
|
||||
// Now we deal with references, so we can normalize to non-const types
|
||||
// because we're passing by value anyway, so const doesn't matter.
|
||||
const Type *callTypeNC = callTypeNP, *fargTypeNC = fargType;
|
||||
callTypeNC = callTypeNP->GetAsNonConstType();
|
||||
fargTypeNC = fargType->GetAsNonConstType();
|
||||
|
||||
// Now we forget about constants and references!
|
||||
if (Type::Equal(callTypeNC, fargTypeNC)) {
|
||||
// The best case: vf -> vf.
|
||||
// Step "4" from documentation
|
||||
cost[i] += 1 * costScale;
|
||||
continue;
|
||||
}
|
||||
if (lIsMatchWithTypeWidening(callTypeNC, fargTypeNC)) {
|
||||
// A little bit worse case: vf -> vd.
|
||||
// Step "6" from documentation
|
||||
cost[i] += 8 * costScale;
|
||||
continue;
|
||||
}
|
||||
if (fargType->IsVaryingType() && callType->IsUniformType()) {
|
||||
// Here we deal with brodcasting uniform to varying.
|
||||
// callType - varying and fargType - uniform is forbidden.
|
||||
if (Type::Equal(callTypeNC->GetAsVaryingType(), fargTypeNC)) {
|
||||
// uf -> vf is better than uf -> ui or uf -> ud
|
||||
// Step "7" from documentation
|
||||
cost[i] += 16 * costScale;
|
||||
continue;
|
||||
}
|
||||
if (lIsMatchWithTypeWidening(callTypeNC->GetAsVaryingType(), fargTypeNC)) {
|
||||
// uf -> vd is better than uf -> vi (128 < 128 + 64)
|
||||
// but worse than uf -> ui (128 > 64)
|
||||
// Step "9" from documentation
|
||||
cost[i] += 128 * costScale;
|
||||
continue;
|
||||
}
|
||||
// 128 + 64 is the max. uf -> vi is the worst case.
|
||||
// Step "10" from documentation
|
||||
cost[i] += 128 * costScale;
|
||||
}
|
||||
if (CanConvertTypes(callTypeNC, fargTypeNC))
|
||||
// two cases: the worst is 128 + 64: uf -> vi and
|
||||
// the only 64: (64 < 128) uf -> ui worse than uf -> vd
|
||||
// Step "8" from documentation
|
||||
cost[i] += 64 * costScale;
|
||||
else
|
||||
// Failure--no type conversion possible...
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)argTypes.size(); ++i) {
|
||||
costSum = costSum + cost[i];
|
||||
}
|
||||
return costSum;
|
||||
}
|
||||
|
||||
@@ -8334,6 +8348,7 @@ FunctionSymbolExpr::ResolveOverloads(SourcePos argPos,
|
||||
int bestMatchCost = 1<<30;
|
||||
std::vector<Symbol *> matches;
|
||||
std::vector<int> candidateCosts;
|
||||
std::vector<int*> candidateExpandCosts;
|
||||
|
||||
if (actualCandidates.size() == 0)
|
||||
goto failure;
|
||||
@@ -8343,9 +8358,12 @@ FunctionSymbolExpr::ResolveOverloads(SourcePos argPos,
|
||||
const FunctionType *ft =
|
||||
CastType<FunctionType>(actualCandidates[i]->type);
|
||||
AssertPos(pos, ft != NULL);
|
||||
int * cost = new int[argTypes.size()];
|
||||
candidateCosts.push_back(computeOverloadCost(ft, argTypes,
|
||||
argCouldBeNULL,
|
||||
argIsConstant));
|
||||
argIsConstant,
|
||||
cost));
|
||||
candidateExpandCosts.push_back(cost);
|
||||
}
|
||||
|
||||
// Find the best cost, and then the candidate or candidates that have
|
||||
@@ -8358,8 +8376,28 @@ FunctionSymbolExpr::ResolveOverloads(SourcePos argPos,
|
||||
if (bestMatchCost == (1<<30))
|
||||
goto failure;
|
||||
for (int i = 0; i < (int)candidateCosts.size(); ++i) {
|
||||
if (candidateCosts[i] == bestMatchCost)
|
||||
if (candidateCosts[i] == bestMatchCost) {
|
||||
for (int j = 0; j < (int)candidateCosts.size(); ++j) {
|
||||
for (int k = 0; k < argTypes.size(); k++) {
|
||||
if (candidateCosts[j] != -1 &&
|
||||
candidateExpandCosts[j][k] < candidateExpandCosts[i][k]) {
|
||||
std::vector<Symbol *> temp;
|
||||
temp.push_back(actualCandidates[i]);
|
||||
temp.push_back(actualCandidates[j]);
|
||||
std::string candidateMessage =
|
||||
lGetOverloadCandidateMessage(temp, argTypes, argCouldBeNULL);
|
||||
Warning(pos, "call to \"%s\" is ambiguous. "
|
||||
"This warning will be turned into error in the next ispc release.\n"
|
||||
"Please add explicit cast to arguments to have unambiguous match."
|
||||
"\n%s", funName, candidateMessage.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
matches.push_back(actualCandidates[i]);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < (int)candidateExpandCosts.size(); ++i) {
|
||||
delete [] candidateExpandCosts[i];
|
||||
}
|
||||
|
||||
if (matches.size() == 1) {
|
||||
|
||||
3
expr.h
3
expr.h
@@ -635,7 +635,8 @@ private:
|
||||
static int computeOverloadCost(const FunctionType *ftype,
|
||||
const std::vector<const Type *> &argTypes,
|
||||
const std::vector<bool> *argCouldBeNULL,
|
||||
const std::vector<bool> *argIsConstant);
|
||||
const std::vector<bool> *argIsConstant,
|
||||
int * cost);
|
||||
|
||||
/** Name of the function that is being called. */
|
||||
std::string name;
|
||||
|
||||
@@ -840,7 +840,6 @@ Module::AddFunctionDeclaration(const std::string &name,
|
||||
// Set function attributes: we never throw exceptions
|
||||
function->setDoesNotThrow();
|
||||
if (storageClass != SC_EXTERN_C &&
|
||||
!g->generateDebuggingSymbols &&
|
||||
isInline)
|
||||
#ifdef LLVM_3_2
|
||||
function->addFnAttr(llvm::Attributes::AlwaysInline);
|
||||
@@ -1273,7 +1272,12 @@ lEmitStructDecl(const StructType *st, std::vector<const StructType *> *emittedSt
|
||||
for (int i = 0; i < st->GetElementCount(); ++i) {
|
||||
const Type *type = st->GetElementType(i)->GetAsNonConstType();
|
||||
std::string d = type->GetCDeclaration(st->GetElementName(i));
|
||||
fprintf(file, " %s;\n", d.c_str());
|
||||
if (type->IsVaryingType()) {
|
||||
fprintf(file, " %s[%d];\n", d.c_str(), g->target->getVectorWidth());
|
||||
}
|
||||
else {
|
||||
fprintf(file, " %s;\n", d.c_str());
|
||||
}
|
||||
}
|
||||
fprintf(file, "};\n");
|
||||
fprintf(file, "#endif\n\n");
|
||||
|
||||
@@ -16,7 +16,7 @@ export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
|
||||
else
|
||||
x[a][b-1] = 1;
|
||||
|
||||
a = min(a, 46);
|
||||
a = min(a, 46.f);
|
||||
|
||||
RET[programIndex] = x[3][a];
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
|
||||
for (uniform int j = 0; j < 47; ++j)
|
||||
x[i][j] = 2+b-5;
|
||||
|
||||
a = min(a,46);
|
||||
a = min(a,46.f);
|
||||
x[a][b-1] = 0;
|
||||
RET[programIndex] = x[2][a];
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
|
||||
|
||||
uniform int index[4] = { 0, 1, 2, 4 };
|
||||
float v = index[programIndex & 0x3];
|
||||
x[min(a,39)][v] = 0;
|
||||
x[min(a,39.f)][v] = 0;
|
||||
RET[programIndex] = x[v+1][v];
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ export uniform int width() { return programCount; }
|
||||
|
||||
export void f_f(uniform float RET[], uniform float aFOO[]) {
|
||||
float a = 1. / aFOO[programIndex];
|
||||
RET[programIndex] = max(0, a);
|
||||
RET[programIndex] = max(0.f, a);
|
||||
}
|
||||
|
||||
export void result(uniform float RET[]) {
|
||||
|
||||
@@ -16,7 +16,7 @@ export void f_f(uniform float RET[], uniform float aFOO[]) {
|
||||
uniform FuncType func[] = { bar, foo };
|
||||
float a = aFOO[programIndex];
|
||||
float b = aFOO[0]-1; // == 0
|
||||
func[min(a, 0)] = foo;
|
||||
func[min(a, 0.f)] = foo;
|
||||
RET[programIndex] = func[0](a, b);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ export void f_f(uniform float RET[], uniform float aFOO[]) {
|
||||
encore:
|
||||
++RET[programIndex];
|
||||
if (any(a != 0)) {
|
||||
a = max(a-1, 0);
|
||||
a = max(a-1, 0.f);
|
||||
goto encore;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ export uniform int width() { return programCount; }
|
||||
export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
|
||||
float a = aFOO[programIndex];
|
||||
RET[programIndex] = max(3 * a, 10.f);
|
||||
RET[width()-1] = max(b, 100);
|
||||
RET[width()-1] = max(b, 100.f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ export uniform int width() { return programCount; }
|
||||
export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
|
||||
float a = aFOO[programIndex];
|
||||
RET[programIndex] = max(-10 * (a-3), .1f);
|
||||
RET[width() - 1] = max(-10 * b, 2);
|
||||
RET[width() - 1] = max(-10 * b, 2.f);
|
||||
}
|
||||
|
||||
export void result(uniform float RET[]) {
|
||||
|
||||
@@ -6,7 +6,7 @@ export uniform int width() { return programCount; }
|
||||
export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
|
||||
float a = aFOO[programIndex];
|
||||
RET[programIndex] = min(3 * a, 10.f);
|
||||
RET[width()-1] = min(b, 100);
|
||||
RET[width()-1] = min(b, 100.f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ export uniform int width() { return programCount; }
|
||||
export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
|
||||
float a = aFOO[programIndex];
|
||||
RET[programIndex] = min(-10 * (a-3), .1f);
|
||||
RET[width() - 1] = min(-10 * b, 2);
|
||||
RET[width() - 1] = min(-10 * b, 2.f);
|
||||
}
|
||||
|
||||
export void result(uniform float RET[]) {
|
||||
|
||||
93
tests/ref-overloads.ispc
Normal file
93
tests/ref-overloads.ispc
Normal file
@@ -0,0 +1,93 @@
|
||||
/////////////////////////VARYING
|
||||
//int A011(varying float f){return 0;} int A011(varying float& f){return 1;} int A011(varying const float& f){return 2;}
|
||||
//int A011(varying double f){return 3;} int A011(varying int f){return 4;} int A011(uniform float f){return 5;}
|
||||
//int A011(uniform float& f){return 6;} int A011(uniform const float& f){return 7;} int A011(uniform double f){return 8;} int A011(uniform int f){return 9;}
|
||||
|
||||
int A013(varying const float& f){return 2;} int A013(varying double f){return 3;} int A013(varying int f){return 4;}
|
||||
int A013(uniform float f){return 5;} int A013(uniform float& f){return 6;} int A013(uniform const float& f){return 7;}
|
||||
int A013(uniform double f){return 8;} int A013(uniform int f){return 9;}
|
||||
|
||||
int A014(varying double f){return 3;} int A014(varying int f){return 4;}
|
||||
int A014(uniform float f){return 5;} int A014(uniform float& f){return 6;} int A014(uniform const float& f){return 7;}
|
||||
int A014(uniform double f){return 8;} int A014(uniform int f){return 9;}
|
||||
|
||||
int A015(varying int f){return 4;} int A015(uniform float f){return 5;}
|
||||
int A015(uniform float& f){return 6;} int A015(uniform const float& f){return 7;}
|
||||
int A015(uniform double f){return 8;} int A015(uniform int f){return 9;}
|
||||
|
||||
int A032(varying float& f){return 1;} int A032(varying double f){return 3;} int A032(varying int f){return 4;}
|
||||
int A032(uniform float f){return 5;} int A032(uniform float& f){return 6;} int A032(uniform const float& f){return 7;}
|
||||
int A032(uniform double f){return 8;} int A032(uniform int f){return 9;}
|
||||
|
||||
int A033(varying int f){return 4;}
|
||||
int A033(uniform float f){return 5;} int A033(uniform float& f){return 6;} int A033(uniform const float& f){return 7;}
|
||||
int A033(uniform double f){return 8;} int A033(uniform int f){return 9;}
|
||||
|
||||
/////////////////////////UNIFORM
|
||||
|
||||
int A051(varying float f){return 0;} int A051(varying float& f){return 1;} int A051(varying const float& f){return 2;}
|
||||
int A051(varying double f){return 3;} int A051(varying int f){return 4;}
|
||||
int A051(uniform const float& f){return 7;} int A051(uniform double f){return 8;} int A051(uniform int f){return 9;}
|
||||
|
||||
int A052(varying float f){return 0;} int A052(varying float& f){return 1;} int A052(varying const float& f){return 2;}
|
||||
int A052(varying double f){return 3;} int A052(varying int f){return 4;}
|
||||
int A052(uniform double f){return 8;} int A052(uniform int f){return 9;}
|
||||
|
||||
int A053(varying float f){return 0;} int A053(varying float& f){return 1;} int A053(varying const float& f){return 2;}
|
||||
int A053(varying double f){return 3;} int A053(varying int f){return 4;} int A053(uniform int f){return 9;}
|
||||
|
||||
int A054(varying float& f){return 1;} int A054(varying const float& f){return 2;}
|
||||
int A054(varying double f){return 3;} int A054(varying int f){return 4;} int A054(uniform int f){return 9;}
|
||||
|
||||
int A055(varying float& f){return 1;} int A055(varying const float& f){return 2;}
|
||||
int A055(varying double f){return 3;} int A055(varying int f){return 4;}
|
||||
|
||||
int A056(varying float& f){return 1;} int A056(varying const float& f){return 2;} int A056(varying int f){return 4;}
|
||||
|
||||
|
||||
export uniform int width() { return programCount; }
|
||||
|
||||
|
||||
|
||||
export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
|
||||
varying float vf = 5;
|
||||
varying const float vcf = 5;
|
||||
varying float& vfr = vf;
|
||||
varying const float& vcfr = vf;
|
||||
uniform float uf = 5;
|
||||
uniform const float ucf = 5;
|
||||
uniform float& ufr = uf;
|
||||
uniform const float& ucfr = uf;
|
||||
|
||||
if (A013(vf) != 2) {RET[programIndex] = 1; return;}
|
||||
if (A014(vf) != 3) {RET[programIndex] = 2; return;}
|
||||
if (A015(vf) != 4) {RET[programIndex] = 3; return;}
|
||||
|
||||
if (A013(vfr) != 2) {RET[programIndex] = 4; return;}
|
||||
if (A014(vfr) != 3) {RET[programIndex] = 5; return;}
|
||||
if (A015(vfr) != 4) {RET[programIndex] = 6; return;}
|
||||
|
||||
if (A032(vcf) != 3) {RET[programIndex] = 7; return;}
|
||||
if (A033(vcf) != 4) {RET[programIndex] = 8; return;}
|
||||
|
||||
if (A032(vcfr) != 3) {RET[programIndex] = 9; return;}
|
||||
if (A033(vcfr) != 4) {RET[programIndex] = 10; return;}
|
||||
|
||||
if (A051(uf) != 7) {RET[programIndex] = 11; return;}
|
||||
if (A052(uf) != 8) {RET[programIndex] = 12; return;}
|
||||
if (A053(uf) != 0) {RET[programIndex] = 13; return;}
|
||||
if (A054(uf) != 9) {RET[programIndex] = 14; return;}
|
||||
if (A055(uf) != 3) {RET[programIndex] = 15; return;}
|
||||
if (A056(uf) != 4) {RET[programIndex] = 16; return;}
|
||||
|
||||
if (A051(ufr) != 7) {RET[programIndex] = 17; return;}
|
||||
if (A052(ufr) != 8) {RET[programIndex] = 18; return;}
|
||||
if (A053(ufr) != 0) {RET[programIndex] = 19; return;}
|
||||
if (A054(ufr) != 9) {RET[programIndex] = 20; return;}
|
||||
if (A055(ufr) != 3) {RET[programIndex] = 21; return;}
|
||||
if (A056(ufr) != 4) {RET[programIndex] = 22; return;}
|
||||
|
||||
RET[programIndex] = 0;
|
||||
}
|
||||
|
||||
export void result(uniform float RET[]) { RET[programIndex] = 0; }
|
||||
41
tests/ref-overloads1.ispc
Normal file
41
tests/ref-overloads1.ispc
Normal file
@@ -0,0 +1,41 @@
|
||||
void A1(float f) {}
|
||||
void A2(float& f) {}
|
||||
void A3(const float& f) {}
|
||||
void A4(double f) {}
|
||||
void A5(int f) {}
|
||||
void A6(uniform float f) {}
|
||||
void A7(uniform float& f) {}
|
||||
void A8(uniform const float& f){}
|
||||
void A9(uniform double f) {}
|
||||
void A0(uniform int f) {}
|
||||
|
||||
|
||||
|
||||
export uniform int width() { return programCount; }
|
||||
|
||||
|
||||
|
||||
export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
|
||||
varying float vf = 5;
|
||||
varying const float vcf = 5;
|
||||
varying float& vfr = vf;
|
||||
varying const float& vcfr = vf;
|
||||
uniform float uf = 5;
|
||||
uniform const float ucf = 5;
|
||||
uniform float& ufr = uf;
|
||||
uniform const float& ucfr = uf;
|
||||
|
||||
A1(vf); A1(vcf); A1(vfr); A1(vcfr); A1(uf); A1(ucf); A1(ufr); A1(ucfr);
|
||||
A2(vf); A2(vfr);
|
||||
A3(vf); A3(vcf); A3(vfr); A3(vcfr);
|
||||
A4(vf); A4(vcf); A4(vfr); A4(vcfr); A4(uf); A4(ucf); A4(ufr); A4(ucfr);
|
||||
A5(vf); A5(vcf); A5(vfr); A5(vcfr); A5(uf); A5(ucf); A5(ufr); A5(ucfr);
|
||||
A6(uf); A6(ucf); A6(ufr); A6(ucfr);
|
||||
A7(uf); A7(ufr);
|
||||
A8(uf); A8(ucf); A8(ufr); A8(ucfr);
|
||||
A9(uf); A9(ucf); A9(ufr); A9(ucfr);
|
||||
A0(uf); A0(ucf); A0(ufr); A0(ucfr);
|
||||
RET[programIndex] = 1;
|
||||
}
|
||||
|
||||
export void result(uniform float RET[]) { RET[programIndex] = 1; }
|
||||
54
tests/ref-overloads2.ispc
Normal file
54
tests/ref-overloads2.ispc
Normal file
@@ -0,0 +1,54 @@
|
||||
void A01(varying float f){} void A01(varying float& f){} void A01(varying const float& f){} void A01(varying double f){} void A01(varying int f){}
|
||||
void A02(varying float& f){} void A02(varying const float& f){} void A02(varying double f){} void A02(varying int f){}
|
||||
void A03(varying float f){} void A03(varying const float& f){} void A03(varying double f){} void A03(varying int f){}
|
||||
void A04(varying float f){} void A04(varying float& f){} void A04(varying double f){} void A04(varying int f){}
|
||||
void A05(varying float f){} void A05(varying float& f){} void A05(varying const float& f){} void A05(varying int f){}
|
||||
void A06(varying float f){} void A06(varying float& f){} void A06(varying const float& f){} void A06(varying double f){}
|
||||
|
||||
void A07(varying float f){} void A07(varying float& f){} void A07(varying const float& f){} void A07(varying double f){} void A07(varying int f){}
|
||||
void A08(varying float f){} void A08(varying float& f){} void A08(varying const float& f){} void A08(varying double f){} void A08(varying int f){}
|
||||
void A09(varying float f){} void A09(varying float& f){} void A09(varying const float& f){} void A09(varying double f){} void A09(varying int f){}
|
||||
void A10(varying float f){} void A10(varying float& f){} void A10(varying const float& f){} void A10(varying double f){} void A10(varying int f){}
|
||||
void A11(varying float f){} void A11(varying float& f){} void A11(varying const float& f){} void A11(varying double f){} void A11(varying int f){}
|
||||
|
||||
void A01(uniform float f){} void A01(uniform float& f){} void A01(uniform const float& f){} void A01(uniform double f){} void A01(uniform int f){}
|
||||
void A02(uniform float f){} void A02(uniform float& f){} void A02(uniform const float& f){} void A02(uniform double f){} void A02(uniform int f){}
|
||||
void A03(uniform float f){} void A03(uniform float& f){} void A03(uniform const float& f){} void A03(uniform double f){} void A03(uniform int f){}
|
||||
void A04(uniform float f){} void A04(uniform float& f){} void A04(uniform const float& f){} void A04(uniform double f){} void A04(uniform int f){}
|
||||
void A05(uniform float f){} void A05(uniform float& f){} void A05(uniform const float& f){} void A05(uniform double f){} void A05(uniform int f){}
|
||||
void A06(uniform float f){} void A06(uniform float& f){} void A06(uniform const float& f){} void A06(uniform double f){} void A06(uniform int f){}
|
||||
|
||||
void A07(uniform float& f){} void A07(uniform const float& f){} void A07(uniform double f){} void A07(uniform int f){}
|
||||
void A08(uniform float f){} void A08(uniform const float& f){} void A08(uniform double f){} void A08(uniform int f){}
|
||||
void A09(uniform float f){} void A09(uniform float& f){} void A09(uniform double f){} void A09(uniform int f){}
|
||||
void A10(uniform float f){} void A10(uniform float& f){} void A10(uniform const float& f){} void A10(uniform int f){}
|
||||
void A11(uniform float f){} void A11(uniform float& f){} void A11(uniform const float& f){} void A11(uniform double f){}
|
||||
|
||||
export uniform int width() { return programCount; }
|
||||
|
||||
|
||||
|
||||
export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
|
||||
varying float vf = 5;
|
||||
varying const float vcf = 5;
|
||||
varying float& vfr = vf;
|
||||
varying const float& vcfr = vf;
|
||||
uniform float uf = 5;
|
||||
uniform const float ucf = 5;
|
||||
uniform float& ufr = uf;
|
||||
uniform const float& ucfr = uf;
|
||||
|
||||
A01(vf); A01(vcf); A01(vfr); A01(vcfr); A01(uf); A01(ucf); A01(ufr); A01(ucfr);
|
||||
A02(vf); A02(vcf); A02(vfr); A02(vcfr); A02(uf); A02(ucf); A02(ufr); A02(ucfr);
|
||||
A03(vf); A03(vcf); A03(vfr); A03(vcfr); A03(uf); A03(ucf); A03(ufr); A03(ucfr);
|
||||
A04(vf); A04(vcf); A04(vfr); A04(vcfr); A04(uf); A04(ucf); A04(ufr); A04(ucfr);
|
||||
A05(vf); A05(vcf); A05(vfr); A05(vcfr); A05(uf); A05(ucf); A05(ufr); A05(ucfr);
|
||||
A06(vf); A06(vcf); A06(vfr); A06(vcfr); A06(uf); A06(ucf); A06(ufr); A06(ucfr);
|
||||
A07(vf); A07(vcf); A07(vfr); A07(vcfr); A07(uf); A07(ucf); A07(ufr); A07(ucfr);
|
||||
A08(vf); A08(vcf); A08(vfr); A08(vcfr); A08(uf); A08(ucf); A08(ufr); A08(ucfr);
|
||||
A09(vf); A09(vcf); A09(vfr); A09(vcfr); A09(uf); A09(ucf); A09(ufr); A09(ucfr);
|
||||
A10(vf); A10(vcf); A10(vfr); A10(vcfr); A10(uf); A10(ucf); A10(ufr); A10(ucfr);
|
||||
RET[programIndex] = 1;
|
||||
}
|
||||
|
||||
export void result(uniform float RET[]) { RET[programIndex] = 1; }
|
||||
99
tests/ref-overloads3.ispc
Normal file
99
tests/ref-overloads3.ispc
Normal file
@@ -0,0 +1,99 @@
|
||||
int A01(varying float f){return 0;} int A01(varying float& f){return 1;} int A01(varying const float& f){return 2;} int A01(varying double f){return 3;} int A01(varying int f){return 4;}
|
||||
int A02(varying float& f){return 1;} int A02(varying const float& f){return 2;} int A02(varying double f){return 3;} int A02(varying int f){return 4;}
|
||||
int A03(varying float f){return 0;} int A03(varying const float& f){return 2;} int A03(varying double f){return 3;} int A03(varying int f){return 4;}
|
||||
int A04(varying float f){return 0;} int A04(varying float& f){return 1;} int A04(varying double f){return 3;} int A04(varying int f){return 4;}
|
||||
|
||||
int A07(varying float f){return 0;} int A07(varying float& f){return 1;} int A07(varying const float& f){return 2;} int A07(varying double f){return 3;} int A07(varying int f){return 4;}
|
||||
int A08(varying float f){return 0;} int A08(varying float& f){return 1;} int A08(varying const float& f){return 2;} int A08(varying double f){return 3;} int A08(varying int f){return 4;}
|
||||
int A09(varying float f){return 0;} int A09(varying float& f){return 1;} int A09(varying const float& f){return 2;} int A09(varying double f){return 3;} int A09(varying int f){return 4;}
|
||||
|
||||
int A01(uniform float f){return 5;} int A01(uniform float& f){return 6;} int A01(uniform const float& f){return 7;} int A01(uniform double f){return 8;} int A01(uniform int f){return 9;}
|
||||
int A02(uniform float f){return 5;} int A02(uniform float& f){return 6;} int A02(uniform const float& f){return 7;} int A02(uniform double f){return 8;} int A02(uniform int f){return 9;}
|
||||
int A03(uniform float f){return 5;} int A03(uniform float& f){return 6;} int A03(uniform const float& f){return 7;} int A03(uniform double f){return 8;} int A03(uniform int f){return 9;}
|
||||
int A04(uniform float f){return 5;} int A04(uniform float& f){return 6;} int A04(uniform const float& f){return 7;} int A04(uniform double f){return 8;} int A04(uniform int f){return 9;}
|
||||
|
||||
int A07(uniform float& f){return 6;} int A07(uniform const float& f){return 7;} int A07(uniform double f){return 8;} int A07(uniform int f){return 9;}
|
||||
int A08(uniform float f){return 5;} int A08(uniform const float& f){return 7;} int A08(uniform double f){return 8;} int A08(uniform int f){return 9;}
|
||||
int A09(uniform float f){return 5;} int A09(uniform float& f){return 6;} int A09(uniform double f){return 8;} int A09(uniform int f){return 9;}
|
||||
|
||||
export uniform int width() { return programCount; }
|
||||
|
||||
|
||||
|
||||
export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
|
||||
varying float vf = 5;
|
||||
varying const float vcf = 5;
|
||||
varying float& vfr = vf;
|
||||
varying const float& vcfr = vf;
|
||||
uniform float uf = 5;
|
||||
uniform const float ucf = 5;
|
||||
uniform float& ufr = uf;
|
||||
uniform const float& ucfr = uf;
|
||||
|
||||
if (A01(vf) != 0) {RET[programIndex] = 1; return;}
|
||||
if (A01(vcf) != 0) {RET[programIndex] = 2; return;}
|
||||
if (A01(vfr) != 1) {RET[programIndex] = 3; return;}
|
||||
if (A01(vcfr)!= 2) {RET[programIndex] = 4; return;}
|
||||
if (A01(uf) != 5) {RET[programIndex] = 5; return;}
|
||||
if (A01(ucf) != 5) {RET[programIndex] = 6; return;}
|
||||
if (A01(ufr) != 6) {RET[programIndex] = 7; return;}
|
||||
if (A01(ucfr)!= 7) {RET[programIndex] = 8; return;}
|
||||
|
||||
if (A02(vf) != 1) {RET[programIndex] = 9; return;}
|
||||
if (A02(vcf) != 2) {RET[programIndex] = 10; return;}
|
||||
if (A02(vfr) != 1) {RET[programIndex] = 11; return;}
|
||||
if (A02(vcfr)!= 2) {RET[programIndex] = 12; return;}
|
||||
if (A02(uf) != 5) {RET[programIndex] = 13; return;}
|
||||
if (A02(ucf) != 5) {RET[programIndex] = 14; return;}
|
||||
if (A02(ufr) != 6) {RET[programIndex] = 15; return;}
|
||||
if (A02(ucfr)!= 7) {RET[programIndex] = 16; return;}
|
||||
|
||||
if (A03(vf) != 0) {RET[programIndex] = 17; return;}
|
||||
if (A03(vcf) != 0) {RET[programIndex] = 18; return;}
|
||||
if (A03(vfr) != 0) {RET[programIndex] = 19; return;}
|
||||
if (A03(vcfr)!= 2) {RET[programIndex] = 20; return;}
|
||||
if (A03(uf) != 5) {RET[programIndex] = 21; return;}
|
||||
if (A03(ucf) != 5) {RET[programIndex] = 22; return;}
|
||||
if (A03(ufr) != 6) {RET[programIndex] = 23; return;}
|
||||
if (A03(ucfr)!= 7) {RET[programIndex] = 24; return;}
|
||||
|
||||
if (A04(vf) != 0) {RET[programIndex] = 25; return;}
|
||||
if (A04(vcf) != 0) {RET[programIndex] = 26; return;}
|
||||
if (A04(vfr) != 1) {RET[programIndex] = 27; return;}
|
||||
if (A04(vcfr)!= 0) {RET[programIndex] = 28; return;}
|
||||
if (A04(uf) != 5) {RET[programIndex] = 29; return;}
|
||||
if (A04(ucf) != 5) {RET[programIndex] = 30; return;}
|
||||
if (A04(ufr) != 6) {RET[programIndex] = 31; return;}
|
||||
if (A04(ucfr)!= 7) {RET[programIndex] = 32; return;}
|
||||
|
||||
if (A07(vf) != 0) {RET[programIndex] = 33; return;}
|
||||
if (A07(vcf) != 0) {RET[programIndex] = 34; return;}
|
||||
if (A07(vfr) != 1) {RET[programIndex] = 35; return;}
|
||||
if (A07(vcfr)!= 2) {RET[programIndex] = 36; return;}
|
||||
if (A07(uf) != 6) {RET[programIndex] = 37; return;}
|
||||
if (A07(ucf) != 7) {RET[programIndex] = 38; return;}
|
||||
if (A07(ufr) != 6) {RET[programIndex] = 39; return;}
|
||||
if (A07(ucfr)!= 7) {RET[programIndex] = 40; return;}
|
||||
|
||||
if (A08(vf) != 0) {RET[programIndex] = 41; return;}
|
||||
if (A08(vcf) != 0) {RET[programIndex] = 42; return;}
|
||||
if (A08(vfr) != 1) {RET[programIndex] = 43; return;}
|
||||
if (A08(vcfr)!= 2) {RET[programIndex] = 44; return;}
|
||||
if (A08(uf) != 5) {RET[programIndex] = 45; return;}
|
||||
if (A08(ucf) != 5) {RET[programIndex] = 46; return;}
|
||||
if (A08(ufr) != 5) {RET[programIndex] = 47; return;}
|
||||
if (A08(ucfr)!= 7) {RET[programIndex] = 48; return;}
|
||||
|
||||
if (A09(vf) != 0) {RET[programIndex] = 49; return;}
|
||||
if (A09(vcf) != 0) {RET[programIndex] = 50; return;}
|
||||
if (A09(vfr) != 1) {RET[programIndex] = 51; return;}
|
||||
if (A09(vcfr)!= 2) {RET[programIndex] = 52; return;}
|
||||
if (A09(uf) != 5) {RET[programIndex] = 53; return;}
|
||||
if (A09(ucf) != 5) {RET[programIndex] = 54; return;}
|
||||
if (A09(ufr) != 6) {RET[programIndex] = 55; return;}
|
||||
if (A09(ucfr)!= 5) {RET[programIndex] = 56; return;}
|
||||
|
||||
RET[programIndex] = 0;
|
||||
}
|
||||
|
||||
export void result(uniform float RET[]) { RET[programIndex] = 0; }
|
||||
@@ -19,7 +19,7 @@ export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
|
||||
for (uniform int i = 0; i < 16; ++i)
|
||||
for (uniform int j = 0; j < 16; ++j)
|
||||
bar.foo[i].x[j] = b;
|
||||
RET[programIndex] = bar.foo[min(15, a-1)].x[min(15, a-1)];
|
||||
RET[programIndex] = bar.foo[min(15.f, a-1)].x[min(15.f, a-1)];
|
||||
}
|
||||
|
||||
export void result(uniform float RET[]) { RET[programIndex] = 5; }
|
||||
|
||||
10
type.cpp
10
type.cpp
@@ -1909,7 +1909,15 @@ StructType::StructType(const std::string &n, const llvm::SmallVector<const Type
|
||||
|
||||
const std::string
|
||||
StructType::GetCStructName() const {
|
||||
return lMangleStructName(name, variability);
|
||||
// only return mangled name for varying structs for backwards
|
||||
// compatibility...
|
||||
|
||||
if (variability == Variability::Varying) {
|
||||
return lMangleStructName(name, variability);
|
||||
}
|
||||
else {
|
||||
return GetStructName();
|
||||
}
|
||||
}
|
||||
|
||||
Variability
|
||||
|
||||
Reference in New Issue
Block a user