skia2/tests/sksl/runtime/SampleWithConstantMatrix.skvm

38 lines
954 B
Plaintext
Raw Normal View History

Stop calling schedule() The new unit test demonstrates load/store reordering is error-prone. At head we're allowing loads from a given pointer to reorder later than a store to that same pointer, and boy, that's just not sound. In the scenario constructed by the test we reorder this swap, x = load32 X y = load32 Y store32 X y store32 Y x using schedule() (following Op argument data dependencies) into y = load32 Y store32 X y x = load32 X store32 Y x which moves `x = load32 X` illegally past `store X y`. We write `y` twice instead of swapping `x` and `y`. It's not impossible to implement that extra reordering constraint: I think it's easiest to think about by adding implicit use edges in schedule() from stores to prior loads of the same pointer. But that'd be a little complicated to implement, and doesn't handle aliasing at all, so I decided to ponder on other approaches that handle a wider range of programs or would have a simpler implementation to reason about. I ended up walking through this rough chain of ideas: 0) reorder using only Op argument data dependencies (HEAD) 1) don't let load(ptr) pass store(ptr) (above) 2) don't let any load pass any store (allows aliasing) 3) don't reorder any Op that touches memory 4) don't reorder any Op, period. This CL is 4). It's certainly the easiest and cheapest implementation. It's not clear to me that we need this scheduling, and should we find we really want it I'll come back and work back through the list until we find something that meets our needs. (Hoisting of uniforms is unaffected here.) Change-Id: I7765b1d16202e0645b11295f7e30c5e09f2b7339 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/350256 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Mike Klein <mtklein@google.com>
2021-01-05 19:31:15 +00:00
13 registers, 35 instructions:
0 r0 = uniform32 ptr0 0
1 r1 = uniform32 ptr0 C
Stop calling schedule() The new unit test demonstrates load/store reordering is error-prone. At head we're allowing loads from a given pointer to reorder later than a store to that same pointer, and boy, that's just not sound. In the scenario constructed by the test we reorder this swap, x = load32 X y = load32 Y store32 X y store32 Y x using schedule() (following Op argument data dependencies) into y = load32 Y store32 X y x = load32 X store32 Y x which moves `x = load32 X` illegally past `store X y`. We write `y` twice instead of swapping `x` and `y`. It's not impossible to implement that extra reordering constraint: I think it's easiest to think about by adding implicit use edges in schedule() from stores to prior loads of the same pointer. But that'd be a little complicated to implement, and doesn't handle aliasing at all, so I decided to ponder on other approaches that handle a wider range of programs or would have a simpler implementation to reason about. I ended up walking through this rough chain of ideas: 0) reorder using only Op argument data dependencies (HEAD) 1) don't let load(ptr) pass store(ptr) (above) 2) don't let any load pass any store (allows aliasing) 3) don't reorder any Op that touches memory 4) don't reorder any Op, period. This CL is 4). It's certainly the easiest and cheapest implementation. It's not clear to me that we need this scheduling, and should we find we really want it I'll come back and work back through the list until we find something that meets our needs. (Hoisting of uniforms is unaffected here.) Change-Id: I7765b1d16202e0645b11295f7e30c5e09f2b7339 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/350256 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Mike Klein <mtklein@google.com>
2021-01-05 19:31:15 +00:00
2 r2 = splat 0 (0)
3 r3 = splat 40000000 (2)
4 r4 = splat 3F800000 (1)
5 r5 = mul_f32 r2 r0
6 r6 = splat 1 (1.4012985e-45)
7 r7 = splat 2 (2.8025969e-45)
Stop calling schedule() The new unit test demonstrates load/store reordering is error-prone. At head we're allowing loads from a given pointer to reorder later than a store to that same pointer, and boy, that's just not sound. In the scenario constructed by the test we reorder this swap, x = load32 X y = load32 Y store32 X y store32 Y x using schedule() (following Op argument data dependencies) into y = load32 Y store32 X y x = load32 X store32 Y x which moves `x = load32 X` illegally past `store X y`. We write `y` twice instead of swapping `x` and `y`. It's not impossible to implement that extra reordering constraint: I think it's easiest to think about by adding implicit use edges in schedule() from stores to prior loads of the same pointer. But that'd be a little complicated to implement, and doesn't handle aliasing at all, so I decided to ponder on other approaches that handle a wider range of programs or would have a simpler implementation to reason about. I ended up walking through this rough chain of ideas: 0) reorder using only Op argument data dependencies (HEAD) 1) don't let load(ptr) pass store(ptr) (above) 2) don't let any load pass any store (allows aliasing) 3) don't reorder any Op that touches memory 4) don't reorder any Op, period. This CL is 4). It's certainly the easiest and cheapest implementation. It's not clear to me that we need this scheduling, and should we find we really want it I'll come back and work back through the list until we find something that meets our needs. (Hoisting of uniforms is unaffected here.) Change-Id: I7765b1d16202e0645b11295f7e30c5e09f2b7339 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/350256 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Mike Klein <mtklein@google.com>
2021-01-05 19:31:15 +00:00
8 r8 = splat 3 (4.2038954e-45)
loop:
9 r9 = index
Stop calling schedule() The new unit test demonstrates load/store reordering is error-prone. At head we're allowing loads from a given pointer to reorder later than a store to that same pointer, and boy, that's just not sound. In the scenario constructed by the test we reorder this swap, x = load32 X y = load32 Y store32 X y store32 Y x using schedule() (following Op argument data dependencies) into y = load32 Y store32 X y x = load32 X store32 Y x which moves `x = load32 X` illegally past `store X y`. We write `y` twice instead of swapping `x` and `y`. It's not impossible to implement that extra reordering constraint: I think it's easiest to think about by adding implicit use edges in schedule() from stores to prior loads of the same pointer. But that'd be a little complicated to implement, and doesn't handle aliasing at all, so I decided to ponder on other approaches that handle a wider range of programs or would have a simpler implementation to reason about. I ended up walking through this rough chain of ideas: 0) reorder using only Op argument data dependencies (HEAD) 1) don't let load(ptr) pass store(ptr) (above) 2) don't let any load pass any store (allows aliasing) 3) don't reorder any Op that touches memory 4) don't reorder any Op, period. This CL is 4). It's certainly the easiest and cheapest implementation. It's not clear to me that we need this scheduling, and should we find we really want it I'll come back and work back through the list until we find something that meets our needs. (Hoisting of uniforms is unaffected here.) Change-Id: I7765b1d16202e0645b11295f7e30c5e09f2b7339 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/350256 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Mike Klein <mtklein@google.com>
2021-01-05 19:31:15 +00:00
10 r10 = mul_f32 r3 r9
11 r10 = add_f32 r10 r5
12 r9 = mul_f32 r2 r9
13 r11 = add_f32 r9 r0
14 r9 = add_f32 r9 r5
15 r9 = add_f32 r9 r4
16 r9 = div_f32 r4 r9
17 r10 = mul_f32 r10 r9
18 r9 = mul_f32 r11 r9
19 r10 = trunc r10
20 r9 = trunc r9
21 r9 = mul_i32 r9 r1
22 r9 = add_i32 r10 r9
23 r9 = shl_i32 r9 2
24 r10 = gather32 ptr0 4 r9
Stop calling schedule() The new unit test demonstrates load/store reordering is error-prone. At head we're allowing loads from a given pointer to reorder later than a store to that same pointer, and boy, that's just not sound. In the scenario constructed by the test we reorder this swap, x = load32 X y = load32 Y store32 X y store32 Y x using schedule() (following Op argument data dependencies) into y = load32 Y store32 X y x = load32 X store32 Y x which moves `x = load32 X` illegally past `store X y`. We write `y` twice instead of swapping `x` and `y`. It's not impossible to implement that extra reordering constraint: I think it's easiest to think about by adding implicit use edges in schedule() from stores to prior loads of the same pointer. But that'd be a little complicated to implement, and doesn't handle aliasing at all, so I decided to ponder on other approaches that handle a wider range of programs or would have a simpler implementation to reason about. I ended up walking through this rough chain of ideas: 0) reorder using only Op argument data dependencies (HEAD) 1) don't let load(ptr) pass store(ptr) (above) 2) don't let any load pass any store (allows aliasing) 3) don't reorder any Op that touches memory 4) don't reorder any Op, period. This CL is 4). It's certainly the easiest and cheapest implementation. It's not clear to me that we need this scheduling, and should we find we really want it I'll come back and work back through the list until we find something that meets our needs. (Hoisting of uniforms is unaffected here.) Change-Id: I7765b1d16202e0645b11295f7e30c5e09f2b7339 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/350256 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Mike Klein <mtklein@google.com>
2021-01-05 19:31:15 +00:00
25 r11 = add_i32 r9 r6
26 r11 = gather32 ptr0 4 r11
Stop calling schedule() The new unit test demonstrates load/store reordering is error-prone. At head we're allowing loads from a given pointer to reorder later than a store to that same pointer, and boy, that's just not sound. In the scenario constructed by the test we reorder this swap, x = load32 X y = load32 Y store32 X y store32 Y x using schedule() (following Op argument data dependencies) into y = load32 Y store32 X y x = load32 X store32 Y x which moves `x = load32 X` illegally past `store X y`. We write `y` twice instead of swapping `x` and `y`. It's not impossible to implement that extra reordering constraint: I think it's easiest to think about by adding implicit use edges in schedule() from stores to prior loads of the same pointer. But that'd be a little complicated to implement, and doesn't handle aliasing at all, so I decided to ponder on other approaches that handle a wider range of programs or would have a simpler implementation to reason about. I ended up walking through this rough chain of ideas: 0) reorder using only Op argument data dependencies (HEAD) 1) don't let load(ptr) pass store(ptr) (above) 2) don't let any load pass any store (allows aliasing) 3) don't reorder any Op that touches memory 4) don't reorder any Op, period. This CL is 4). It's certainly the easiest and cheapest implementation. It's not clear to me that we need this scheduling, and should we find we really want it I'll come back and work back through the list until we find something that meets our needs. (Hoisting of uniforms is unaffected here.) Change-Id: I7765b1d16202e0645b11295f7e30c5e09f2b7339 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/350256 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Mike Klein <mtklein@google.com>
2021-01-05 19:31:15 +00:00
27 r12 = add_i32 r9 r7
28 r12 = gather32 ptr0 4 r12
Stop calling schedule() The new unit test demonstrates load/store reordering is error-prone. At head we're allowing loads from a given pointer to reorder later than a store to that same pointer, and boy, that's just not sound. In the scenario constructed by the test we reorder this swap, x = load32 X y = load32 Y store32 X y store32 Y x using schedule() (following Op argument data dependencies) into y = load32 Y store32 X y x = load32 X store32 Y x which moves `x = load32 X` illegally past `store X y`. We write `y` twice instead of swapping `x` and `y`. It's not impossible to implement that extra reordering constraint: I think it's easiest to think about by adding implicit use edges in schedule() from stores to prior loads of the same pointer. But that'd be a little complicated to implement, and doesn't handle aliasing at all, so I decided to ponder on other approaches that handle a wider range of programs or would have a simpler implementation to reason about. I ended up walking through this rough chain of ideas: 0) reorder using only Op argument data dependencies (HEAD) 1) don't let load(ptr) pass store(ptr) (above) 2) don't let any load pass any store (allows aliasing) 3) don't reorder any Op that touches memory 4) don't reorder any Op, period. This CL is 4). It's certainly the easiest and cheapest implementation. It's not clear to me that we need this scheduling, and should we find we really want it I'll come back and work back through the list until we find something that meets our needs. (Hoisting of uniforms is unaffected here.) Change-Id: I7765b1d16202e0645b11295f7e30c5e09f2b7339 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/350256 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Mike Klein <mtklein@google.com>
2021-01-05 19:31:15 +00:00
29 r9 = add_i32 r9 r8
30 r9 = gather32 ptr0 4 r9
31 store32 ptr1 r10
32 store32 ptr2 r11
33 store32 ptr3 r12
34 store32 ptr4 r9