diff --git a/decl.cpp b/decl.cpp index f5c0eb88..ada96eca 100644 --- a/decl.cpp +++ b/decl.cpp @@ -408,7 +408,11 @@ Declarator::GetType(const Type *base, DeclSpecs *ds) const { return NULL; } - sym->type = PointerType::GetUniform(at->GetElementType()); + const Type *targetType = at->GetElementType(); + targetType = + targetType->ResolveUnboundVariability(Type::Varying); + sym->type = PointerType::GetUniform(targetType); + // Make sure there are no unsized arrays (other than the // first dimension) in function parameter lists. at = dynamic_cast(at->GetElementType()); diff --git a/docs/ispc.rst b/docs/ispc.rst index aa15158d..c131497c 100644 --- a/docs/ispc.rst +++ b/docs/ispc.rst @@ -1499,38 +1499,46 @@ Pointer Types It is possible to have pointers to data in memory; pointer arithmetic, changing values in memory with pointers, and so forth is supported as in C. - -:: - - float a = 0; - float *pa = &a; - *pa = 1; // now a == 1 - -Also as in C, arrays are silently converted into pointers: - -:: - - float a[10] = { ... }; - float *pa = a; // pointer to first element of a - float *pb = a + 5; // pointer to 5th element of a - As with other basic types, pointers can be both ``uniform`` and -``varying``. By default, they are varying. The placement of the -``uniform`` qualifier to declare a ``uniform`` pointer may be initially -surprising, but it matches the form of how for example a pointer that is -itself ``const`` (as opposed to pointing to a ``const`` type) is declared -in C. +``varying``. + +** Like other types in ``ispc``, pointers are ``varying`` by default, if an +explicit ``uniform`` qualifier isn't provided. However, the default +variability of the pointed-to type (``uniform`` or ``varying``) is the +opposite of the pointer variability. ** This rule will be illustrated and +explained in examples below. + +For example, the ``ptr`` variable in the code below is a varying pointer to +``uniform float`` values. Each program instance has a separate pointer +value and the assignment to ``*ptr`` generally represents a scatter to +memory. :: - uniform float f = 0; - uniform float * uniform pf = &f; + uniform float a[] = ...; + int index = ...; + float * ptr = &a[index]; + *ptr = 1; + +A ``uniform`` pointer can be declared with an appropriately-placed +qualifier: + +:: + + float f = 0; + float * uniform pf = &f; // uniform pointer to a varying float *pf = 1; -A subtlety comes in when a uniform pointer points to a varying datatype. -In this case, each program instance accesses a distinct location in memory -(because the underlying varying datatype is itself laid out with a separate -location in memory for each program instance.) +The placement of the ``uniform`` qualifier to declare a ``uniform`` pointer +may be initially surprising, but it matches the form of how, for example, a +pointer that is itself ``const`` (as opposed to pointing to a ``const`` +type) is declared in C. (Reading the declaration from right to left gives +its meaning: a uniform pointer to a float that is varying.) + +A subtlety comes in in cases like the where a uniform pointer points to a +varying datatype. In this case, each program instance accesses a distinct +location in memory (because the underlying varying datatype is itself laid +out with a separate location in memory for each program instance.) :: @@ -1538,17 +1546,26 @@ location in memory for each program instance.) float * uniform pa = &a; *pa = programIndex; // same as (a = programIndex) +Also as in C, arrays are silently converted into pointers: + +:: + + float a[10] = { ... }; + float * uniform pa = a; // pointer to first element of a + float * uniform pb = a + 5; // pointer to 5th element of a Any pointer type can be explicitly typecast to another pointer type, as long as the source type isn't a ``varying`` pointer when the destination -type is a ``uniform`` pointer. Like other types, ``uniform`` pointers can -be typecast to be ``varying`` pointers, however. +type is a ``uniform`` pointer. :: float *pa = ...; int *pb = (int *)pa; // legal, but beware +Like other types, ``uniform`` pointers can be typecast to be ``varying`` +pointers, however. + Any pointer type can be assigned to a ``void`` pointer without a type cast: :: @@ -1992,7 +2009,7 @@ based on C++'s ``new`` and ``delete`` operators: :: int count = ...; - int *ptr = new uniform int[count]; + int *ptr = new int[count]; // use ptr... delete[] ptr; @@ -2002,13 +2019,22 @@ that memory. Uses of ``new`` and ``delete`` in ``ispc`` programs are serviced by corresponding calls the system C library's ``malloc()`` and ``free()`` functions. +Note that the rules for ``uniform`` and ``varying`` for ``new`` are +analogous to the corresponding rules are for pointers (as described in +`Pointer Types`_.) Specifically, if a specific rate qualifier isn't +provided with the ``new`` expression, then the default is that a "varying" +``new`` is performed, where each program instance performs a unique +allocation. The allocated type, in turn, is by default ``uniform`` for +``varying`` ``new`` expressions, and ``varying`` for ``uniform`` new +expressions. + After a pointer has been deleted, it is illegal to access the memory it -points to. However, note that deletion happens on a per-program-instance -basis. In other words, consider the following code: +points to. However, that deletion happens on a per-program-instance basis. +In other words, consider the following code: :: - int *ptr = new uniform int[count]; + int *ptr = new int[count]; // use ptr if (count > 1000) delete[] ptr; @@ -2033,7 +2059,9 @@ gang of program instances. A ``new`` statement can be qualified with While a regular call to ``new`` returns a ``varying`` pointer (i.e. a distinct pointer to separately-allocated memory for each program instance), a ``uniform new`` performs a single allocation and returns a ``uniform`` -pointer. +pointer. Recall that with a ``uniform`` ``new``, the default variability +of the allocated type is ``varying``, so the above code is allocating an +array of ten ``varying float`` values. When using ``uniform new``, it's important to be aware of a subtlety; if the returned pointer is stored in a varying pointer variable (as may be @@ -2043,7 +2071,7 @@ statement, which is an error: effectively :: - float *ptr = uniform new float[10]; + varying float * ptr = uniform new float[10]; // use ptr... delete ptr; // ERROR: varying pointer is deleted @@ -2052,28 +2080,31 @@ executing program instance, which is an error (unless it happens that only a single program instance is active in the above code.) When using ``new`` statements, it's important to make an appropriate choice -of ``uniform`` or ``varying`` (as always, the default), for both the -``new`` operator itself as well as the type of data being allocated, based -on the program's needs. Consider the following four memory allocations: +of ``uniform`` or ``varying``, for both the ``new`` operator itself as well +as the type of data being allocated, based on the program's needs. +Consider the following four memory allocations: :: uniform float * uniform p1 = uniform new uniform float[10]; float * uniform p2 = uniform new float[10]; - uniform float * p3 = new uniform float[10]; - float * p4 = new float[10]; + float * p3 = new float[10]; + varying float * p4 = new varying float[10]; Assuming that a ``float`` is 4 bytes in memory and if the gang size is 8 program instances, then the first allocation represents a single allocation -of 40 bytes, the second is a single allocation of 8*4*10 = 320 bytes, the -third is 8 allocations of 40 bytes, and the last performs 8 allocations of -80 bytes each. +of 10 ``uniform float`` values (40 bytes), the second is a single +allocation of 10 ``varying float`` values (8*4*10 = 320 bytes), the third +is 8 allocations of 10 ``uniform float`` values (8 allocations of 40 bytes +each), and the last performs 8 allocations of 320 bytes each. Note in particular that varying allocations of varying data types are rarely desirable in practice. In that case, each program instance is performing a separate allocation of ``varying float`` memory. In this case, it's likely that the program instances will only access a single element of each -``varying float``, which is wasteful. +``varying float``, which is wasteful. (This in turn is partially why the +allocated type is uniform by default with both pointers and ``new`` +statements.) Although ``ispc`` doesn't support constructors or destructors like C++, it is possible to provide initializer values with ``new`` statements: diff --git a/expr.cpp b/expr.cpp index e7432fb4..be69fd9b 100644 --- a/expr.cpp +++ b/expr.cpp @@ -264,9 +264,9 @@ lDoTypeConv(const Type *fromType, const Type *toType, Expr **expr, if (toType->IsUniformType() && fromType->IsVaryingType()) { if (!failureOk) - Error(pos, "Can't convert from varying type \"%s\" to uniform " - "type \"%s\" for %s.", fromType->GetString().c_str(), - toType->GetString().c_str(), errorMsgBase); + Error(pos, "Can't convert from type \"%s\" to type \"%s\" for %s.", + fromType->GetString().c_str(), toType->GetString().c_str(), + errorMsgBase); return false; } @@ -5238,7 +5238,10 @@ ConstExpr::GetConstant(const Type *type) const { int64_t iv[ISPC_MAX_NVEC]; AsInt64(iv, type->IsVaryingType()); for (int i = 0; i < Count(); ++i) - Assert(iv[i] == 0); + if (iv[i] != 0) + // We'll issue an error about this later--trying to assign + // a constant int to a pointer, without a typecast. + return NULL; return llvm::Constant::getNullValue(llvmType); } @@ -6152,9 +6155,8 @@ TypeCastExpr::TypeCheck() { toType = lDeconstifyType(toType); if (fromType->IsVaryingType() && toType->IsUniformType()) { - Error(pos, "Can't type cast from varying type \"%s\" to uniform " - "type \"%s\"", fromType->GetString().c_str(), - toType->GetString().c_str()); + Error(pos, "Can't type cast from type \"%s\" to type \"%s\"", + fromType->GetString().c_str(), toType->GetString().c_str()); return NULL; } @@ -7310,8 +7312,6 @@ NewExpr::NewExpr(int typeQual, const Type *t, Expr *init, Expr *count, SourcePos tqPos, SourcePos p) : Expr(p) { allocType = t; - if (allocType != NULL && allocType->HasUnboundVariability()) - allocType = allocType->ResolveUnboundVariability(Type::Varying); initExpr = init; countExpr = count; @@ -7333,6 +7333,18 @@ NewExpr::NewExpr(int typeQual, const Type *t, Expr *init, Expr *count, // If no type qualifier is given before the 'new', treat it as a // varying new. isVarying = (typeQual == 0) || (typeQual & TYPEQUAL_VARYING); + + if (allocType != NULL && allocType->HasUnboundVariability()) { + Type::Variability childVariability = isVarying ? + Type::Uniform : Type::Varying; + if (dynamic_cast(allocType) != NULL) + // FIXME: yet another place where the "structs are varying" + // wart pops up.. + childVariability = Type::Varying; + + allocType = allocType->ResolveUnboundVariability(childVariability); + } + } diff --git a/stdlib.ispc b/stdlib.ispc index e8af3790..82993e32 100644 --- a/stdlib.ispc +++ b/stdlib.ispc @@ -484,7 +484,8 @@ static inline void aos_to_soa4(uniform int32 a[], int32 * uniform v0, int32 * uniform v1, int32 * uniform v2, int32 * uniform v3) { aos_to_soa4((uniform float * uniform)a, (float * uniform )v0, - (float * uniform)v1, (float * uniform)v2, (float * uniform)v3); + (float * uniform)v1, (float * uniform)v2, + (float * uniform)v3); } static inline void @@ -763,24 +764,24 @@ static unsigned int64 exclusive_scan_or(unsigned int64 v) { // packed load, store static inline uniform int -packed_load_active(uniform unsigned int * uniform a, +packed_load_active(uniform unsigned int a[], unsigned int * uniform vals) { return __packed_load_active(a, vals, (UIntMaskType)__mask); } static inline uniform int -packed_store_active(uniform unsigned int * uniform a, +packed_store_active(uniform unsigned int a[], unsigned int vals) { return __packed_store_active(a, vals, (UIntMaskType)__mask); } static inline uniform int -packed_load_active(uniform int * uniform a, int * uniform vals) { +packed_load_active(uniform int a[], int * uniform vals) { return __packed_load_active(a, vals, (IntMaskType)__mask); } static inline uniform int -packed_store_active(uniform int * uniform a, int vals) { +packed_store_active(uniform int a[], int vals) { return __packed_store_active(a, vals, (IntMaskType)__mask); } @@ -1630,7 +1631,7 @@ static inline uniform float ldexp(uniform float x, uniform int n) { return floatbits(ix); } -static inline float frexp(float x, int * uniform pw2) { +static inline float frexp(float x, varying int * uniform pw2) { unsigned int ex = 0x7F800000u; // exponent mask unsigned int ix = intbits(x); ex &= ix; @@ -1909,8 +1910,8 @@ static inline uniform float cos(uniform float x_full) { } -static inline void sincos(float x_full, float * uniform sin_result, - float * uniform cos_result) { +static inline void sincos(float x_full, varying float * uniform sin_result, + varying float * uniform cos_result) { if (__math_lib == __math_lib_svml) { __svml_sincos(x_full, sin_result, cos_result); } @@ -2507,8 +2508,8 @@ static inline uniform float exp(uniform float x_full) { // Range reduction for logarithms takes log(x) -> log(2^n * y) -> n // * log(2) + log(y) where y is the reduced range (usually in [1/2, // 1)). -static inline void __range_reduce_log(float input, float * uniform reduced, - int * uniform exponent) { +static inline void __range_reduce_log(float input, varying float * uniform reduced, + varying int * uniform exponent) { int int_version = intbits(input); // single precision = SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM // exponent mask = 0111 1111 1000 0000 0000 0000 0000 0000 @@ -2785,7 +2786,7 @@ static inline uniform double ldexp(uniform double x, uniform int n) { return doublebits(ix); } -static inline double frexp(double x, int * uniform pw2) { +static inline double frexp(double x, varying int * uniform pw2) { unsigned int64 ex = 0x7ff0000000000000; // exponent mask unsigned int64 ix = intbits(x); ex &= ix; @@ -2851,8 +2852,8 @@ static inline uniform double cos(uniform double x) { return __stdlib_cos(x); } -static inline void sincos(double x, double * uniform sin_result, - double * uniform cos_result) { +static inline void sincos(double x, varying double * uniform sin_result, + varying double * uniform cos_result) { if (__math_lib == __math_lib_ispc_fast) { float sr, cr; sincos((float)x, &sr, &cr); @@ -3391,7 +3392,7 @@ struct RNGState { unsigned int z1, z2, z3, z4; }; -static inline unsigned int random(RNGState * uniform state) +static inline unsigned int random(varying RNGState * uniform state) { unsigned int b; @@ -3406,14 +3407,14 @@ static inline unsigned int random(RNGState * uniform state) return (state->z1 ^ state->z2 ^ state->z3 ^ state->z4); } -static inline float frandom(RNGState * uniform state) +static inline float frandom(varying RNGState * uniform state) { unsigned int irand = random(state); irand &= (1<<23)-1; return floatbits(0x3F800000 | irand)-1.0f; } -static inline uniform unsigned int __seed4(RNGState * uniform state, +static inline uniform unsigned int __seed4(varying RNGState * uniform state, uniform int start, uniform unsigned int seed) { uniform unsigned int c1 = 0xf0f0f0f0; @@ -3447,7 +3448,7 @@ static inline uniform unsigned int __seed4(RNGState * uniform state, return seed; } -static inline void seed_rng(uniform RNGState * uniform state, uniform unsigned int seed) { +static inline void seed_rng(varying RNGState * uniform state, uniform unsigned int seed) { if (programCount == 1) { state->z1 = seed; state->z2 = seed ^ 0xbeeff00d; diff --git a/tests/cfor-ref-5.ispc b/tests/cfor-ref-5.ispc index 39e0f817..ef6ebb6e 100644 --- a/tests/cfor-ref-5.ispc +++ b/tests/cfor-ref-5.ispc @@ -3,7 +3,7 @@ export uniform int width() { return programCount; } -void foo(float * uniform a) { +void foo(varying float * uniform a) { *a = 0; } diff --git a/tests/new-delete-3.ispc b/tests/new-delete-3.ispc index 676f9886..d37fe1b3 100644 --- a/tests/new-delete-3.ispc +++ b/tests/new-delete-3.ispc @@ -4,7 +4,7 @@ export uniform int width() { return programCount; } export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { float a = aFOO[programIndex]; - float * uniform buf = uniform new float[programCount+1]; + varying float * uniform buf = uniform new varying float[programCount+1]; for (uniform int i = 0; i < programCount+1; ++i) { buf[i] = i+a; } diff --git a/tests/new-delete-6.ispc b/tests/new-delete-6.ispc index 90018b93..bad82aee 100644 --- a/tests/new-delete-6.ispc +++ b/tests/new-delete-6.ispc @@ -7,7 +7,7 @@ struct Point { export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { float a = aFOO[programIndex]; - Point * varying buf = new Point(0., b, a); + uniform Point * buf = new Point(0., b, a); RET[programIndex] = buf->z; delete buf; } diff --git a/tests/ptr-14.ispc b/tests/ptr-14.ispc index f1331123..746dd539 100644 --- a/tests/ptr-14.ispc +++ b/tests/ptr-14.ispc @@ -3,9 +3,9 @@ export uniform int width() { return programCount; } export void f_f(uniform float RET[], uniform float aFOO[]) { float a = aFOO[programIndex]; - float * uniform pa = &a; - int * uniform pb = (int *)pa; - float *uniform pc = (float *)pb; + varying float * uniform pa = &a; + varying int * uniform pb = (varying int *)pa; + varying float *uniform pc = (varying float *)pb; *pc = programIndex; RET[programIndex] = *pc; } diff --git a/tests/ptr-2.ispc b/tests/ptr-2.ispc index 8fc7c3b1..85db5547 100644 --- a/tests/ptr-2.ispc +++ b/tests/ptr-2.ispc @@ -4,7 +4,7 @@ export uniform int width() { return programCount; } export void f_f(uniform float RET[], uniform float aFOO[]) { int a = aFOO[programIndex]; - int * uniform b = &a; + varying int * uniform b = &a; RET[programIndex] = *b; } diff --git a/tests/ptr-22.ispc b/tests/ptr-22.ispc index b3e203a6..0f00abec 100644 --- a/tests/ptr-22.ispc +++ b/tests/ptr-22.ispc @@ -6,14 +6,14 @@ struct Foo { uniform float b; }; -void update(Foo * varying fp) { +void update(uniform Foo * varying fp) { ++fp; fp->a -= 1; fp->b = 1; } export void f_f(uniform float RET[], uniform float aFOO[]) { - Foo f[2] = { { 1234, 4321 }, { aFOO[programIndex], 5 } }; + uniform Foo f[2] = { { 1234, 4321 }, { aFOO[programIndex], 5 } }; update(f); RET[programIndex] = f[1].a; } diff --git a/tests/ptr-23.ispc b/tests/ptr-23.ispc index a967de47..9e55ecf2 100644 --- a/tests/ptr-23.ispc +++ b/tests/ptr-23.ispc @@ -6,7 +6,7 @@ struct Foo { uniform float b; }; -void update(float<3> * uniform vp) { +void update(varying float<3> * uniform vp) { vp->x = 0; } diff --git a/tests/ptr-25.ispc b/tests/ptr-25.ispc index e471435e..19c8d00d 100644 --- a/tests/ptr-25.ispc +++ b/tests/ptr-25.ispc @@ -1,7 +1,7 @@ export uniform int width() { return programCount; } -void update(float<2> * varying vp) { +void update(varying float<2> * vp) { vp->y = 0; } diff --git a/tests/ptr-3.ispc b/tests/ptr-3.ispc index b84abeb1..3adc57a8 100644 --- a/tests/ptr-3.ispc +++ b/tests/ptr-3.ispc @@ -4,7 +4,7 @@ export uniform int width() { return programCount; } export void f_f(uniform float RET[], uniform float aFOO[]) { int a = aFOO[programIndex]; - int * uniform b = &a; + varying int * uniform b = &a; *b = 2; RET[programIndex] = *b; } diff --git a/tests/ptr-4.ispc b/tests/ptr-4.ispc index 65038dbe..dea857ee 100644 --- a/tests/ptr-4.ispc +++ b/tests/ptr-4.ispc @@ -4,7 +4,7 @@ export uniform int width() { return programCount; } export void f_f(uniform float RET[], uniform float aFOO[]) { int a = aFOO[programIndex]; - int * uniform b = &a; + varying int * uniform b = &a; ++*b; RET[programIndex] = *b; } diff --git a/tests/ptr-5.ispc b/tests/ptr-5.ispc index a0cd0fdc..25f9b76b 100644 --- a/tests/ptr-5.ispc +++ b/tests/ptr-5.ispc @@ -4,7 +4,7 @@ export uniform int width() { return programCount; } export void f_f(uniform float RET[], uniform float aFOO[]) { int a = aFOO[programIndex]; - int * uniform b = &a; + varying int * uniform b = &a; (*b)++; RET[programIndex] = *b; } diff --git a/tests/ptr-8.ispc b/tests/ptr-8.ispc index 4444212d..230564c1 100644 --- a/tests/ptr-8.ispc +++ b/tests/ptr-8.ispc @@ -1,13 +1,13 @@ export uniform int width() { return programCount; } -void inc(int * uniform v) { +void inc(varying int * uniform v) { ++*v; } export void f_f(uniform float RET[], uniform float aFOO[]) { int a = aFOO[programIndex]; - int * uniform b = &a; + varying int * uniform b = &a; if (a <= 2) inc(b); RET[programIndex] = a; diff --git a/tests/ptr-9.ispc b/tests/ptr-9.ispc index ba44bf34..c489ca5b 100644 --- a/tests/ptr-9.ispc +++ b/tests/ptr-9.ispc @@ -1,15 +1,15 @@ export uniform int width() { return programCount; } -void inc(int * uniform v) { +void inc(varying int * uniform v) { ++*v; } export void f_f(uniform float RET[], uniform float aFOO[]) { int a = aFOO[programIndex]; - int * uniform b = &a; + varying int * uniform b = &a; void * uniform vp = b; - int * uniform c = (int * uniform)vp; + varying int * uniform c = (varying int * uniform)vp; RET[programIndex] = *c; } diff --git a/tests/ptr-r--0.ispc b/tests/ptr-r--0.ispc index 2977c6cf..d6fe8f29 100644 --- a/tests/ptr-r--0.ispc +++ b/tests/ptr-r--0.ispc @@ -3,7 +3,7 @@ export uniform int width() { return programCount; } -float foo(float * uniform a) { +float foo(varying float * uniform a) { *a = 0; } diff --git a/tests/ptr-r--2.ispc b/tests/ptr-r--2.ispc index 10d6c2cd..4bd772ee 100644 --- a/tests/ptr-r--2.ispc +++ b/tests/ptr-r--2.ispc @@ -3,7 +3,7 @@ export uniform int width() { return programCount; } -float foo(float * uniform a) { +float foo(varying float * uniform a) { *a = 0; } diff --git a/tests/ptr-r--3.ispc b/tests/ptr-r--3.ispc index fe9bb0fe..a62123f2 100644 --- a/tests/ptr-r--3.ispc +++ b/tests/ptr-r--3.ispc @@ -3,7 +3,7 @@ export uniform int width() { return programCount; } -void foo(float * uniform a) { +void foo(varying float * uniform a) { *a = 0; } diff --git a/tests/ptr-r--4.ispc b/tests/ptr-r--4.ispc index 88593dcf..0c4a4806 100644 --- a/tests/ptr-r--4.ispc +++ b/tests/ptr-r--4.ispc @@ -3,7 +3,7 @@ export uniform int width() { return programCount; } -void foo(float * uniform a) { +void foo(varying float * uniform a) { *a = 0; } diff --git a/tests/ptr-r--5.ispc b/tests/ptr-r--5.ispc index 84f48f6d..4fea07d0 100644 --- a/tests/ptr-r--5.ispc +++ b/tests/ptr-r--5.ispc @@ -3,7 +3,7 @@ export uniform int width() { return programCount; } -void foo(float * uniform a) { +void foo(varying float * uniform a) { *a = 0; } diff --git a/tests/ptr-r-erence-assignment-typeconv.ispc b/tests/ptr-r-erence-assignment-typeconv.ispc index 4ce6ee8e..88e18940 100644 --- a/tests/ptr-r-erence-assignment-typeconv.ispc +++ b/tests/ptr-r-erence-assignment-typeconv.ispc @@ -3,7 +3,7 @@ export uniform int width() { return programCount; } -void foo(float * uniform x, int y) { +void foo(varying float * uniform x, int y) { *x = y; } diff --git a/tests/ptr-r-erence-assignment.ispc b/tests/ptr-r-erence-assignment.ispc index 96e2bc95..84c1b451 100644 --- a/tests/ptr-r-erence-assignment.ispc +++ b/tests/ptr-r-erence-assignment.ispc @@ -3,7 +3,7 @@ export uniform int width() { return programCount; } -void foo(float * uniform x, float y) { +void foo(varying float * uniform x, float y) { *x = y; } diff --git a/tests/ptr-r-erence-prepost-increment.ispc b/tests/ptr-r-erence-prepost-increment.ispc index 02a6fcb4..b54b5115 100644 --- a/tests/ptr-r-erence-prepost-increment.ispc +++ b/tests/ptr-r-erence-prepost-increment.ispc @@ -3,7 +3,7 @@ export uniform int width() { return programCount; } -void foo(float * uniform x) { +void foo(varying float * uniform x) { if ((*x) <= 2) ++(*x); } diff --git a/tests/ref-0.ispc b/tests/ref-0.ispc index 2977c6cf..d6fe8f29 100644 --- a/tests/ref-0.ispc +++ b/tests/ref-0.ispc @@ -3,7 +3,7 @@ export uniform int width() { return programCount; } -float foo(float * uniform a) { +float foo(varying float * uniform a) { *a = 0; } diff --git a/tests/short-vec-6.ispc b/tests/short-vec-6.ispc index 95d22b34..b7693c08 100644 --- a/tests/short-vec-6.ispc +++ b/tests/short-vec-6.ispc @@ -3,7 +3,7 @@ typedef int<4> int4; export uniform int width() { return programCount; } -void inc(int4 * uniform v) { +void inc(varying int4 * uniform v) { int4 delta = { 1, 1, 1, 1 }; (*v) += delta; } diff --git a/tests/short-vec-7.ispc b/tests/short-vec-7.ispc index abfb96cd..9ad015d5 100644 --- a/tests/short-vec-7.ispc +++ b/tests/short-vec-7.ispc @@ -3,7 +3,7 @@ typedef int<4> int4; export uniform int width() { return programCount; } -void incXY(int4 * uniform v) { +void incXY(varying int4 * uniform v) { ++(*v).x; ++(*v).y; } diff --git a/tests_errors/array-plus-equals.ispc b/tests_errors/array-plus-equals.ispc index 9d6f7d3f..0e0ba744 100644 --- a/tests_errors/array-plus-equals.ispc +++ b/tests_errors/array-plus-equals.ispc @@ -1,4 +1,4 @@ -// Illegal to assign to array type "float[5]" +// Illegal to assign to array type "varying float[5]" void foo(float *x) { float a[5] = { 1,2,3,4,5}; diff --git a/tests_errors/array-pointer-assign.ispc b/tests_errors/array-pointer-assign.ispc index a179c332..d709dbd3 100644 --- a/tests_errors/array-pointer-assign.ispc +++ b/tests_errors/array-pointer-assign.ispc @@ -1,4 +1,4 @@ -// Illegal to assign to array type "float[5]" +// Illegal to assign to array type "varying float[5]" void foo(float *x) { float a[5] = { 1,2,3,4,5}; diff --git a/tests_errors/assign-struct-with-const-member-2.ispc b/tests_errors/assign-struct-with-const-member-2.ispc index b2d80de1..7a8bae94 100644 --- a/tests_errors/assign-struct-with-const-member-2.ispc +++ b/tests_errors/assign-struct-with-const-member-2.ispc @@ -1,4 +1,4 @@ -// Illegal to assign to type "uniform struct Bar" in type "uniform struct Foo" due to element "a" with type "const int32" +// Illegal to assign to type "uniform struct Bar" in type "uniform struct Foo" due to element "a" with type "const varying int32" struct Bar { const int a; diff --git a/tests_errors/assign-struct-with-const-member.ispc b/tests_errors/assign-struct-with-const-member.ispc index 320a768b..af85e7f3 100644 --- a/tests_errors/assign-struct-with-const-member.ispc +++ b/tests_errors/assign-struct-with-const-member.ispc @@ -1,4 +1,4 @@ -// Illegal to assign to type "uniform struct Foo" due to element "a" with type "const int32" +// Illegal to assign to type "uniform struct Foo" due to element "a" with type "const varying int32" struct Foo { const int a; diff --git a/tests_errors/const-1.ispc b/tests_errors/const-1.ispc index f36276b5..088302d1 100644 --- a/tests_errors/const-1.ispc +++ b/tests_errors/const-1.ispc @@ -1,4 +1,4 @@ -// Can't assign to type "const int32" on left-hand +// Can't assign to type "const varying int32" on left-hand int func() { const int x = 2; diff --git a/tests_errors/const-global.ispc b/tests_errors/const-global.ispc index 8a814a29..20ef463e 100644 --- a/tests_errors/const-global.ispc +++ b/tests_errors/const-global.ispc @@ -1,4 +1,4 @@ -// Can't assign to type "const int32" on left-hand side +// Can't assign to type "const varying int32" on left-hand side const int x = 0; diff --git a/tests_errors/deref-1.ispc b/tests_errors/deref-1.ispc index 256eff87..109a35b6 100644 --- a/tests_errors/deref-1.ispc +++ b/tests_errors/deref-1.ispc @@ -1,4 +1,4 @@ -// operator "." can't be used with expression of "int32" type +// operator "." can't be used with expression of "uniform int32" type int func(int *a) { a.x = 0; diff --git a/tests_errors/deref-4.ispc b/tests_errors/deref-4.ispc index 33877f72..79c277a8 100644 --- a/tests_errors/deref-4.ispc +++ b/tests_errors/deref-4.ispc @@ -1,4 +1,4 @@ -// Illegal to dereference non-pointer or reference type "float" +// Illegal to dereference non-pointer or reference type "varying float" float func(float a) { *a = 0; diff --git a/tests_errors/deref.ispc b/tests_errors/deref.ispc index f5d571c9..a14a76b5 100644 --- a/tests_errors/deref.ispc +++ b/tests_errors/deref.ispc @@ -1,4 +1,4 @@ -// Member operator "->" can't be used with expression of "int32" type +// Member operator "->" can't be used with expression of "uniform int32" type int func(int *a) { a->x = 0; diff --git a/tests_errors/foreach-assign.ispc b/tests_errors/foreach-assign.ispc index 4eb8a406..f978761c 100644 --- a/tests_errors/foreach-assign.ispc +++ b/tests_errors/foreach-assign.ispc @@ -1,4 +1,4 @@ -// Can't assign to type "const int32" +// Can't assign to type "const varying int32" int foo() { foreach (i = 0 ... 10) { diff --git a/tests_errors/fptr-typecheck-2.ispc b/tests_errors/fptr-typecheck-2.ispc index 3769b301..ea59fa54 100644 --- a/tests_errors/fptr-typecheck-2.ispc +++ b/tests_errors/fptr-typecheck-2.ispc @@ -1,4 +1,4 @@ -// Can't convert argument of type "void * uniform" to type "float" for function call argument. +// Can't convert argument of type "void * uniform" to type "varying float" for function call argument. float bar(float a, float b); diff --git a/tests_errors/initexpr-2.ispc b/tests_errors/initexpr-2.ispc index 66b4a438..681fe6fc 100644 --- a/tests_errors/initexpr-2.ispc +++ b/tests_errors/initexpr-2.ispc @@ -1,3 +1,3 @@ -// Initializer list for array "int32[2][4]" must have no more than 2 elements (has 3) +// Initializer list for array "varying int32[2][4]" must have no more than 2 elements (has 3) int a[2][4] = { { 1, 2, 3 }, { 1, 2, 3, 4 }, 1 }; diff --git a/tests_errors/new-delete-6.ispc b/tests_errors/new-delete-6.ispc index a148298b..250441c2 100644 --- a/tests_errors/new-delete-6.ispc +++ b/tests_errors/new-delete-6.ispc @@ -1,4 +1,4 @@ -// Can't convert from varying type "int32 *" to uniform type "int32 * uniform" for return +// Can't convert from type "uniform int32 * varying" to type "uniform int32 * uniform" for return int * uniform func(int x) { return new int[x]; diff --git a/tests_errors/new-delete-7.ispc b/tests_errors/new-delete-7.ispc index 12a3b79a..e86bd089 100644 --- a/tests_errors/new-delete-7.ispc +++ b/tests_errors/new-delete-7.ispc @@ -1,4 +1,4 @@ -// Can't convert from varying type "float" to uniform type "uniform float" for initializer +// Can't convert from type "varying float" to type "uniform float" for initializer struct Point { uniform float x, y, z; diff --git a/tests_errors/ptr-const-1.ispc b/tests_errors/ptr-const-1.ispc index b334fbe8..4dcfaa75 100644 --- a/tests_errors/ptr-const-1.ispc +++ b/tests_errors/ptr-const-1.ispc @@ -1,4 +1,4 @@ -// Can't assign to type "const int32 * const" +// Can't assign to type "const uniform int32 * const varying" void foo(const int * const p) { ++p; diff --git a/tests_errors/ptr-const.ispc b/tests_errors/ptr-const.ispc index 72f9aba2..7cdd5e30 100644 --- a/tests_errors/ptr-const.ispc +++ b/tests_errors/ptr-const.ispc @@ -1,4 +1,4 @@ -// Can't assign to type "const int32" on left-hand side +// Can't assign to type "const varying int32" on left-hand side void foo(const int * p) { *p = 0; diff --git a/tests_errors/ptrcast-lose-info.ispc b/tests_errors/ptrcast-lose-info.ispc index fdaac83b..eb564482 100644 --- a/tests_errors/ptrcast-lose-info.ispc +++ b/tests_errors/ptrcast-lose-info.ispc @@ -1,4 +1,4 @@ -// Pointer type cast of type "int32 * uniform" to integer type "uniform int32" may lose information. +// Pointer type cast of type "varying int32 * uniform" to integer type "uniform int32" may lose information. int32 foo(int * uniform x) { return (int32) x; diff --git a/tests_errors/ref-const-array.ispc b/tests_errors/ref-const-array.ispc index a6c2c4bc..39453a30 100644 --- a/tests_errors/ref-const-array.ispc +++ b/tests_errors/ref-const-array.ispc @@ -1,4 +1,4 @@ -// Can't assign to type "const int32" on left-hand side of expression +// Can't assign to type "const varying int32" on left-hand side of expression const int x[20]; diff --git a/tests_errors/ref-const-struct-1.ispc b/tests_errors/ref-const-struct-1.ispc index a1789fd6..35c236e5 100644 --- a/tests_errors/ref-const-struct-1.ispc +++ b/tests_errors/ref-const-struct-1.ispc @@ -1,4 +1,4 @@ -// Can't assign to type "const int32" on left-hand side of expression +// Can't assign to type "const varying int32" on left-hand side of expression struct Foo { int x; diff --git a/tests_errors/ref-const-struct.ispc b/tests_errors/ref-const-struct.ispc index 078afc12..12282fa4 100644 --- a/tests_errors/ref-const-struct.ispc +++ b/tests_errors/ref-const-struct.ispc @@ -1,4 +1,4 @@ -// Can't assign to type "const int32" on left-hand side of expression +// Can't assign to type "const varying int32" on left-hand side of expression struct Foo { int x; diff --git a/tests_errors/signed-float-1.ispc b/tests_errors/signed-float-1.ispc index ec2a7220..d98f88b5 100644 --- a/tests_errors/signed-float-1.ispc +++ b/tests_errors/signed-float-1.ispc @@ -1,4 +1,4 @@ -// Can't apply "signed" qualifier to "float" type +// Can't apply "signed" qualifier to "varying float" type struct Foo { signed float x; diff --git a/tests_errors/signed-float.ispc b/tests_errors/signed-float.ispc index 418cd8db..8d72c0ff 100644 --- a/tests_errors/signed-float.ispc +++ b/tests_errors/signed-float.ispc @@ -1,4 +1,4 @@ -// "signed" qualifier is illegal with non-integer type "float" +// "signed" qualifier is illegal with non-integer type "varying float" int foo() { signed float x; diff --git a/tests_errors/unsigned-float-1.ispc b/tests_errors/unsigned-float-1.ispc index 2975c800..6d450201 100644 --- a/tests_errors/unsigned-float-1.ispc +++ b/tests_errors/unsigned-float-1.ispc @@ -1,4 +1,4 @@ -// Can't apply "unsigned" qualifier to "float" type +// Can't apply "unsigned" qualifier to "varying float" type struct Foo { unsigned float x; diff --git a/tests_errors/unsigned-float.ispc b/tests_errors/unsigned-float.ispc index f97dc6dd..9b1f1883 100644 --- a/tests_errors/unsigned-float.ispc +++ b/tests_errors/unsigned-float.ispc @@ -1,3 +1,3 @@ -// "unsigned" qualifier is illegal with "float" type +// "unsigned" qualifier is illegal with "varying float" type unsigned float foo = 1; diff --git a/tests_errors/vary-to-unif-typecast.ispc b/tests_errors/vary-to-unif-typecast.ispc index ca60749a..8042e54e 100644 --- a/tests_errors/vary-to-unif-typecast.ispc +++ b/tests_errors/vary-to-unif-typecast.ispc @@ -1,4 +1,4 @@ -// Can't type cast from varying type "int32" to uniform type "uniform int32" +// Can't type cast from type "varying int32" to type "uniform int32" uniform int foo(int x) { return (uniform int) x; diff --git a/type.cpp b/type.cpp index 01fb1c71..a9988f4e 100644 --- a/type.cpp +++ b/type.cpp @@ -427,7 +427,7 @@ AtomicType::GetString() const { if (isConst) ret += "const "; switch (variability) { case Uniform: ret += "uniform "; break; - case Varying: /*ret += "varying ";*/ break; + case Varying: ret += "varying "; break; case Unbound: ret += "/*unbound*/ "; break; } } @@ -986,9 +986,17 @@ PointerType::ResolveUnboundVariability(Variability v) const { Assert(m->errorCount > 0); return NULL; } - return new PointerType(baseType->ResolveUnboundVariability(v), - (variability == Unbound) ? v : variability, - isConst); + + Assert(v != Unbound); + Variability ptrVariability = (variability == Unbound) ? v : variability; + Variability childVariability = (ptrVariability == Varying) ? + Uniform : Varying; + if (dynamic_cast(baseType)) + // struct members are varying by default.. (FIXME!!!) + childVariability = Varying; + + return new PointerType(baseType->ResolveUnboundVariability(childVariability), + ptrVariability, isConst); } @@ -1030,7 +1038,7 @@ PointerType::GetString() const { if (isConst) ret += " const"; switch (variability) { case Uniform: ret += " uniform"; break; - case Varying: /*ret += " varying";*/ break; + case Varying: ret += " varying"; break; case Unbound: ret += " /*unbound*/"; break; } @@ -1964,7 +1972,7 @@ StructType::GetString() const { switch (variability) { case Uniform: ret += "uniform "; break; - case Varying: /*ret += "varying ";*/ break; + case Varying: ret += "varying "; break; case Unbound: ret += "/*unbound*/ "; break; }