6ee5d9e3c9
Yesterday's implementation was close but I realized later that it wasn't quite ideal. - Array index-folding was gated on `isCompileTimeConstant`, which is too strict. The real limitation is `hasSideEffects`. If an array contains a side-effecting expression, we should leave it alone. Otherwise it is safe to pluck out an element from the array and toss the rest. - Matrix index-folding was gated on `getConstantSubexpression` for the extracted elements, but did not check the other elements at all. This was too lenient; we now only proceed to the folding step if `hasSideEffects` returns false. I added some tests to verify the final behavior and also discovered a small related issue. Diagonal matrices were not substituting literals in for constant-values, which inhibited folding as well and would break constant-expression evaluation. This is now fixed. Change-Id: Idda32fd8643c1f32ba21475251cd4d4dd7cea94c Reviewed-on: https://skia-review.googlesource.com/c/skia/+/470396 Auto-Submit: John Stiles <johnstiles@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: John Stiles <johnstiles@google.com>
40 lines
1.2 KiB
Plaintext
40 lines
1.2 KiB
Plaintext
uniform half4 colorRed, colorGreen;
|
|
|
|
int globalValue = 0;
|
|
|
|
noinline int side_effecting(int value) {
|
|
globalValue++;
|
|
return value;
|
|
}
|
|
|
|
bool test() {
|
|
const int x [3] = int[3](1, 2, 3);
|
|
const int xx[3] = int[3](1, 2, 3);
|
|
const int y [3] = int[3](1, 2, 4);
|
|
|
|
const int z = x[0] - y[0];
|
|
const int a [x[z]] = int[1](1);
|
|
const int b [x[x[z]]] = int[2](1, 2);
|
|
const int c [x[x[x[z]]]] = int[3](1, 2, 3);
|
|
|
|
// Arrays with elements lacking side-effects can be optimized.
|
|
int two = 2;
|
|
int flatten0 = (int[3](x[0], two, 3))[0];
|
|
int flatten1 = (int[3](x[0], two, 3))[1];
|
|
int flatten2 = (int[3](x[0], two, 3))[2];
|
|
|
|
// Arrays with elements that have side-effects are not eligible for optimization.
|
|
int noFlatten0 = (int[3](--two, side_effecting(2), 3))[0];
|
|
int noFlatten1 = (int[3](side_effecting(1), 2, 3))[1];
|
|
int noFlatten2 = (int[3](1, ++two, 3))[2];
|
|
|
|
return (x == xx) && !(x != xx) && (x != y) && !(x == y) &&
|
|
(x[0] == y[0]) && (c == x) &&
|
|
(flatten0 == noFlatten0) && (flatten1 == noFlatten1) && (flatten2 == noFlatten2);
|
|
}
|
|
|
|
half4 main(float2 coords) {
|
|
return test() ? colorGreen : colorRed;
|
|
}
|
|
|