Commit Graph

82 Commits

Author SHA1 Message Date
John Stiles
7bd7ea2c8e Prevent no-op statements in GLSL code generator.
This eliminates a handful of useless statements. They were harmless, but
presumably this saves optimization work for the GLSL compiler.

(Patterned after http://review.skia.org/496377 )

Change-Id: Ibe135750488a9917b982dcac67f22b3765412ee1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/496599
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2022-01-19 17:36:54 +00:00
John Stiles
05c41162fb Allow inlining of functions with unassigned out-params.
Our inliner would ignore any functions with `inout` parameters, because
inlining them properly was more complex than just leaving the function
call. However, real-world code can sometimes contain helper functions
that have `inout` params that are never used at all (e.g. an uber-shader
with some features turned off).

We now read the ProgramUsage and check to see whether or not the
`inout`-qualified parameter is actually modified. If it's never changed,
the function now remains a candidate for inlining.

Change-Id: I92e494f94cc070801cb9aa28bd13faa689b806b6
Bug: skia:12636
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/470299
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-11-11 19:33:06 +00:00
John Stiles
74410023ac Add tests for inlining functions with out/inout params.
Functions which don't write to their out params should be safe to
inline, but we currently don't recognize this.

Change-Id: I753e48067c7be4473675ef6c95e61af17dc5ae41
Bug: skia:12636
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/470298
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-11-11 18:46:21 +00:00
John Stiles
3ff77f4862 Fix inliner bug discovered by fuzzer.
Intrinsic-call optimization can be triggered during inlining. In this
case, inlining turned `normalize(x)` into `normalize(constant-value)`.

DSL is used to implement optimizations for a handful of intrinsic calls,
including `normalize`, which internally relies on `length`.

The DSL expects that it can use the IRGenerator to handle function
calls. This was not working because we were finished with the initial
compilation pass, and the IRGenerator's symbol table is removed when
finish() was called.

We now temporarily give a symbol table back to the IRGenerator while
the inliner runs. We remove it again as soon as inlining is complete.

Change-Id: I6da98788d93749ffeb008c1f4c3f72b436e8ceeb
Bug: oss-fuzz:37994
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/445956
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2021-09-07 13:29:37 +00:00
Brian Osman
c9145f3402 Remove enum support from SkSL
Bug: skia:11296
Change-Id: I7d41614957d6fa535faadebbeca890b54b6977ac
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/425996
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2021-07-09 14:03:15 +00:00
John Stiles
25be58e24b Reland "Eliminate unreachable code during optimization."
This is a reland of c6260f9742

Problematic DeadReturn.sksl test cases have been moved to DeadReturnES3.

Original change's description:
> Eliminate unreachable code during optimization.
>
> The Adreno 5xx and 6xx previously failed the SkSLStaticSwitchInline
> test; the driver struggled to interpret code with multiple return
> statements in a row. We now detect unreachable statements and eliminate
> them.
>
> Change-Id: I344d632f2488ca65b0635b37bebffe6e4fb607c5
> Bug: skia:12012
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/410256
> Auto-Submit: John Stiles <johnstiles@google.com>
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Brian Osman <brianosman@google.com>

Bug: skia:12012
Change-Id: I748e8761cbc71c811b5ad8fe49186f980261d8b9
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/410793
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-05-20 20:02:15 +00:00
Brian Salomon
e72fd09ce1 Revert "Eliminate unreachable code during optimization."
This reverts commit c6260f9742.

Reason for revert: Nexus 7 is grumpy, fails SkSLDeadReturn_GPU
https://ci.chromium.org/raw/build/logs.chromium.org/skia/539fff50ff093c11/+/annotations


Original change's description:
> Eliminate unreachable code during optimization.
>
> The Adreno 5xx and 6xx previously failed the SkSLStaticSwitchInline
> test; the driver struggled to interpret code with multiple return
> statements in a row. We now detect unreachable statements and eliminate
> them.
>
> Change-Id: I344d632f2488ca65b0635b37bebffe6e4fb607c5
> Bug: skia:12012
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/410256
> Auto-Submit: John Stiles <johnstiles@google.com>
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Brian Osman <brianosman@google.com>

TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com

Change-Id: Ia3db1f1b28417e479e2d71a4a6ed94a007e47cf9
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:12012
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/410780
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
2021-05-20 13:00:36 +00:00
John Stiles
c6260f9742 Eliminate unreachable code during optimization.
The Adreno 5xx and 6xx previously failed the SkSLStaticSwitchInline
test; the driver struggled to interpret code with multiple return
statements in a row. We now detect unreachable statements and eliminate
them.

Change-Id: I344d632f2488ca65b0635b37bebffe6e4fb607c5
Bug: skia:12012
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/410256
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-05-19 23:03:23 +00:00
John Stiles
edac7716aa Evaluate single-argument generic intrinsics at compile time.
In particular, this optimizes abs() and sign() when all inputs are known
at compile time. This resolves a TODO on a test case in
`IllegalIndexing.rts`.

Change-Id: Ica310522a85b42dc7ae255bd25004a6629d04176
Bug: skia:10835
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/405676
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
2021-05-10 14:50:50 +00:00
John Stiles
65d7ab2c07 Loosen ES3 restrictions in Runtime Effects for debugging.
This CL adds a RuntimeEffect option flag which skips over the various
`strictES2Mode` checks sprinkled throughout IR generation.

Runtime Effects still won't allow a lot of ES3 things (the Pipeline
stage will reject unsupported statement types, SkVM doesn't support most
non-ES2 constructs, etc). However, this change will give us the ability
to test many more features involving arrays and structs that previously
were off-limits due to ES2 restrictions, and will shore up some
legitimate gaps in our testing. This is a useful starting point to allow
for improved test coverage.

Change-Id: I4a5bc43914e65fc7e59f1cecb76a0ec5a7f05f2f
Bug: skia:11209
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/402157
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-04-28 19:59:36 +00:00
John Stiles
0c9d888748 Run SkSL inliner tests as part of dm.
Previously, these tests were never actually executed, only read during
code review. They are now properly tested for correctness whenever dm
is run. Non-ES2 compliant statements (do/while/switch) are unfortunately
excluded here, as they are not compatible with Runtime Effects yet.

Change-Id: I965c782baad6f8dd3961a400ae791fb2c1f844d3
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/389296
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
2021-03-25 22:58:54 +00:00
John Stiles
ece1d794b9 Mangle function names in GLSL.
This will be implemented in Metal and SPIR-V in followup CLs.

Change-Id: I397b4db40b15dd54cf1d8a17f414c3fe184b48d2
Bug: skia:10851
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/387638
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-03-22 17:18:26 +00:00
John Stiles
708faba16b Allow multiple expressions on the same statement to be inlined.
This will allow the inliner to successfully do more work in a single
pass.

Change-Id: I26e8831737c10bdf9a35eebd94ea8b74f6487077
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/386916
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-03-19 15:14:24 +00:00
John Stiles
049f0dfaba Reduce unnecessary scratch variables in Inliner.
Arguments without side-effects that aren't read from more than once can
be moved directly into the inlined function, and don't need a scratch
variable. This can allow functions like `guarded_divide` to inline
completely in more cases.

Change-Id: I0bfce35635cf9779f4af1bc0790da966ccfe4230
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/386678
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-03-19 14:10:29 +00:00
John Stiles
bff24abab8 Disallow inlining a function with out-parameters.
It is difficult to do this both efficiently and correctly while honoring
GLSL semantics (which require the lvalues to be kept distinct, even when
they point to the same variable). We could make it work by making copies
of every out parameter in each direction (going in for inouts, and
coming out for outs and inouts).

However, this could be self-defeating if it makes it harder for the
driver to track variable lifetimes. Simply opting out of inlining these
functions entirely seems like the best tradeoff; let the driver optimize
them if it can, and we can enjoy reduced complexity in the SkSL inliner.

Change-Id: I62f7b4550cc181cfe789e4f2ff4e408ba1baf9cb
Bug: skia:11326
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/370257
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2021-03-17 18:04:00 +00:00
John Stiles
dc20847579 Disallow inlining functions containing early returns.
This allows us to remove 100 LOC from the inliner and is very unlikely
to affect any existing benchmark. We don't have any evidence to support
the idea that a one-iteration `for` loop with `continue`-based exits
will be any faster than a standard function call on any existing GPU.
Our fragment processors are generally written to avoid early returns,
in large part to avoid hitting this path.

This drastically impacts BlendEnum.sksl (which can no longer flatten out
a switch over every blend function in SkSL) but is otherwise a wash.

See: http://go/optimization-in-sksl-inliner suggestion 4(a)

Change-Id: I1f9c27bcd7a8de46cc4e8d0b9768d75957cf1c50
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/385377
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-03-17 16:29:00 +00:00
John Stiles
2654187396 Eliminate unused local variables during SkSL optimization.
This can eliminate const variables which have been completely folded
away, unnecessary synthetic variables created during codegen/inlining,
or code that simply didn't need to exist at all.

Change-Id: I37a65e455e6527a6a6c2f4dde918f48d84dc2638
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/383496
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
2021-03-16 17:22:53 +00:00
John Stiles
132cfdd49d Revert "Inline functions of the form 'return (expr)' only."
This reverts commit 92748af1a5.

Reason for revert: SkSLCommaSideEffects_GPU crashing on Android

Original change's description:
> Inline functions of the form 'return (expr)' only.
>
> This drastically reduces the number of functions which we allow to be
> inlined. If this change does not hurt our performance, it will allow us
> to trivially remove hundreds of LOC. All current data leads us to
> believe that it may affect the Mali 400 but is highly unlikely to change
> results on any other device in the tree.
>
> More info: http://go/optimization-in-sksl-inliner
>
> Change-Id: Ia6b706742ce5407453e0e697b6c1f9201084c0e8
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/384858
> Auto-Submit: John Stiles <johnstiles@google.com>
> Commit-Queue: John Stiles <johnstiles@google.com>
> Reviewed-by: Brian Osman <brianosman@google.com>
> Reviewed-by: Ethan Nicholas <ethannicholas@google.com>

TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com

Change-Id: I6a670dacaa58fe3386ff50375ac6d1cac4fd7f2c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/385161
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2021-03-15 22:08:48 +00:00
John Stiles
92748af1a5 Inline functions of the form 'return (expr)' only.
This drastically reduces the number of functions which we allow to be
inlined. If this change does not hurt our performance, it will allow us
to trivially remove hundreds of LOC. All current data leads us to
believe that it may affect the Mali 400 but is highly unlikely to change
results on any other device in the tree.

More info: http://go/optimization-in-sksl-inliner

Change-Id: Ia6b706742ce5407453e0e697b6c1f9201084c0e8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/384858
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
2021-03-15 19:46:46 +00:00
John Stiles
e8b5a73b56 Remove extraneous line-breaks in generated GLSL/Metal code.
I ran into an issue in an upcoming CL which generated a particularly
ugly switch statement:

    switch (x) {
        default:
             discard;}

So I cleaned this up, and while resolving this issue, managed to improve
a bunch of existing codegen as well. The formatting change has been
split out to a separate CL since it impacts so many golden outputs.

Change-Id: I7a6be29903c47560dcc7f6acd3ef15fd0c5c3c50
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/384179
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
2021-03-12 18:39:57 +00:00
John Stiles
0dd1a77e12 Add noinline keyword to SkSL.
As you might expect, a function tagged with `noinline` will never be
considered as a candidate for inlining.

Change-Id: Ia098f8974e6de251d78bb2a76cd71db8a86bc19c
Bug: skia:11362
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/382337
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-03-10 15:39:48 +00:00
John Stiles
c3ce43be8e Replace the vector<Statement> in SwitchCase with a Block.
Change-Id: Ic2d1240ab785101365b0fd934562505fb5a3e599
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/381816
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-03-09 20:46:10 +00:00
John Stiles
7a3f5506b6 Performance experiment: disable control-flow analysis.
This CL will be used to test for potential performance regressions (or
improvements) that we might cause by disabling this optimization pass.

It will be reverted in ~1 day.

Change-Id: I26b7687c341eb6d81231406381c39869cfccf6d6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/381259
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-03-08 19:41:19 +00:00
John Stiles
03467a53e6 Revert "Disable control-flow analysis in SkSL. (Performance experiment)"
This reverts commit 50b1b2b90d.

Reason for revert: ending experiment

Original change's description:
> Disable control-flow analysis in SkSL. (Performance experiment)
>
> This CL will be used to test for potential performance regressions (or
> improvements?) that we might incur by disabling this optimization pass.
>
> It will be reverted in ~1 day.
>
> Change-Id: I775cdb0c95df81fa25ebbd66e4ff01f64c660f68
> Bug: skia:11319
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/378456
> Commit-Queue: John Stiles <johnstiles@google.com>
> Reviewed-by: Brian Osman <brianosman@google.com>
> Reviewed-by: Ethan Nicholas <ethannicholas@google.com>

TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com

Change-Id: Ie385a82db237ff5651348d82b9651f8ba09375b9
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:11319
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/379581
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2021-03-04 15:20:09 +00:00
John Stiles
4633c9149b # Enter a description of the change.
Reland "Migrate if-statement simplifyStatement logic to IfStatement::Make."

This reverts commit 7e685f0377.

Reason for revert: fixed SkSLBench perf test

Original change's description:
> Revert "Migrate if-statement simplifyStatement logic to IfStatement::Make."
>
> This reverts commit e4da7b672f.
>
> Reason for revert: breaks SkSLBench perf test
>
> Original change's description:
> > Migrate if-statement simplifyStatement logic to IfStatement::Make.
> >
> > This performs essentially the same simplifications as before, just at
> > a different phase of compilation.
> >
> > Change-Id: Ia88df6857d4089962505cd1281798fda74fd0b02
> > Bug: skia:11343, skia:11319
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/376177
> > Commit-Queue: John Stiles <johnstiles@google.com>
> > Auto-Submit: John Stiles <johnstiles@google.com>
> > Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
>
> TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com
>
> Change-Id: I0051188ffe69426904066eb60a932435efdc2af8
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:11343
> Bug: skia:11319
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/379062
> Reviewed-by: John Stiles <johnstiles@google.com>
> Commit-Queue: John Stiles <johnstiles@google.com>

Bug: skia:11343
Bug: skia:11319
Change-Id: I74cc3295004133e9fdcf16e388106eb83603f526
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/379063
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2021-03-03 22:21:36 +00:00
John Stiles
50b1b2b90d Disable control-flow analysis in SkSL. (Performance experiment)
This CL will be used to test for potential performance regressions (or
improvements?) that we might incur by disabling this optimization pass.

It will be reverted in ~1 day.

Change-Id: I775cdb0c95df81fa25ebbd66e4ff01f64c660f68
Bug: skia:11319
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/378456
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
2021-03-03 22:08:56 +00:00
John Stiles
7e685f0377 Revert "Migrate if-statement simplifyStatement logic to IfStatement::Make."
This reverts commit e4da7b672f.

Reason for revert: breaks SkSLBench perf test

Original change's description:
> Migrate if-statement simplifyStatement logic to IfStatement::Make.
>
> This performs essentially the same simplifications as before, just at
> a different phase of compilation.
>
> Change-Id: Ia88df6857d4089962505cd1281798fda74fd0b02
> Bug: skia:11343, skia:11319
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/376177
> Commit-Queue: John Stiles <johnstiles@google.com>
> Auto-Submit: John Stiles <johnstiles@google.com>
> Reviewed-by: Ethan Nicholas <ethannicholas@google.com>

TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com

Change-Id: I0051188ffe69426904066eb60a932435efdc2af8
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:11343
Bug: skia:11319
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/379062
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2021-03-03 20:50:37 +00:00
John Stiles
e4da7b672f Migrate if-statement simplifyStatement logic to IfStatement::Make.
This performs essentially the same simplifications as before, just at
a different phase of compilation.

Change-Id: Ia88df6857d4089962505cd1281798fda74fd0b02
Bug: skia:11343, skia:11319
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/376177
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
2021-03-03 18:12:35 +00:00
John Stiles
511c500ad4 Avoid generating unused variables in the Inliner.
These variables were later being eliminated by the dead-code-elimination
pass, so you can't see them directly in the final output, but removing
them affects the name mangling off all future symbols, so it causes an
enormous ripple effect in the diff. And of course, it's a waste of time
and memory to synthesize IRNodes just to destroy them later.

If we disable control-flow analysis, we lose the dead-code-elimination
pass entirely; this change is also beneficial for emitting better code
when optimizations are turned off.

Change-Id: I882b3be4f3fd99b77d99b6abe128f26bb9252c89
Bug: skia:11319
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/375776
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
2021-02-25 19:18:19 +00:00
John Stiles
04ca41acf3 Fix switch optimization pass.
The optimizer now properly recognizes all types of exits from a switch
statement. Break, continue and return are all potential exits and need
to be considered when determining the exit path from the switch.

Previously, dead code elimination was hiding the effects of this bug
from us, but it meant that an optimized switch had the potential to
generate lots of worthless IR nodes which then needed to be detected and
eliminated by the CFG. In particular, this affected the enum form of
blend, causing a catastrophic amount of extra work to be done.

Change-Id: If857e38cadfc016884624ea4db25a273ad3dce5b
Bug: skia:11352
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/372958
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-02-23 15:38:24 +00:00
John Stiles
66c53b9428 Demonstrate a bug with inlined static switches.
When we detect a static switch, the optimizer finds the matching switch-
case and eliminates all the other switch-cases. It handles case
fall-through by scanning forward and looking for an unconditional break.

However, the inliner has an interesting quirk--it can replace `return`
statements inside of a switch with `continue` statements, since the body
of the inlined function has been wrapped with a for-loop to allow for
early exits. The optimizer does not recognize these continue statements
as exits from the switch (although they certainly qualify), so it
treats continues as fallen-through and keeps emitting switch-cases.

The dead-code elimination pass was actually doing us a favor here and
eliminating the excess code later. A flag was added to disable DCE in
order to reveal the problem in a test.

Change-Id: I8ff19fde5e32d0ab73d7c5411da40cb953a446f5
Bug: skia:11352
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/372956
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
2021-02-22 15:05:58 +00:00
John Stiles
92d83b7b9d Add test to demonstrate out-param semantics violation.
GLSL ES2 documentation on out parameters: "Evaluation of an out
parameter results in an l-value that is used to copy out a value when
the function returns."

The inliner does not do any alias checking when inlining an `out` param.
That is, passing the same variable to two separate `out` parameters
would not generate two distinct lvalues in the inlined code; it reuses
the same variable for each out-params in the inlined code.

(Amusingly, our CFG can fully optimize away this test code so it just
returns "red".)

Change-Id: Ib781d2cfdac54f01b6abe159af0c84ff24ff6976
Bug: skia:11326
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/370256
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-02-16 14:28:49 +00:00
Brian Osman
8e756f379c Support structs in runtime effects
Uses the pipeline-stage callback mechanism. It mangles the type name
(with a test to verify that this works), and then calls defineStruct
with the entire SkSL struct definition string.

Bug: skia:10939
Change-Id: If14cf1b11faaa80ad8d4086cdacf68532bac43fc
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/368809
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2021-02-11 21:09:15 +00:00
Brian Osman
73122aa45f Use guarded_divide in more blend functions
Fixes another instance of anglebug.com/2098 with advanced blend
functions.

Change-Id: I91863723d8b4c33ab2f5a527fe0374e8947bba16
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/368813
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2021-02-10 21:59:26 +00:00
John Stiles
4d6310ab20 Support half4 return values from main() in the SPIR-V code generator.
This creates a helper function, _entrypoint, which invokes main() and
assigns its result into sk_FragColor. We also make sure to prevent
sk_FragColor from being dead-stripped from the code during IR
generation.

At present this is useful for allowing our SkSL test shaders to compile.

Change-Id: I2d7fab0e1959a77778ffdb18ca569e869bcaeece
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/358525
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-01-27 02:46:03 +00:00
John Stiles
bfc9be0f77 Migrate SkSL test inputs to the resources/ directory.
This will allow us to load these inputs for unit testing in `dm`.

Change-Id: Id256ba7c30d3ec94b98048e47af44cf9efe580d5
Bug: skia:11009
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/357282
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-01-22 18:57:29 +00:00
John Stiles
9d7aa41081 Reorder GLSL output so that functions are emitted last.
The Inliner likes to move function bodies around; after inlining, code
can inadvertently move upwards, above ProgramElements that the code
relies on. We work around this by always emitting functions last.

Change-Id: Ie5486cc3a79a478920342fb9f578d575486fb4cf
Bug: skia:11186
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/354669
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-01-15 23:15:46 +00:00
John Stiles
4f2bcff08e Implement Type cloning for enums and structs.
As far as I know, there shouldn't be a way to introduce a struct or enum
other than at global scope; the keywords are not accepted inside a
function body. In fact, I wasn't able to find a way to exercise these
code paths in practice. But we now have concrete assurance that any
possible type can be cloned into a symbol table safely; all Types are
either built-in (available everywhere by design) or are clonable.

Change-Id: I4b006b6cab995b3e598b683736ab9689828629c9
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/354664
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2021-01-15 21:45:56 +00:00
John Stiles
bd058477e2 Constant-propagate the ! prefix onto constant boolean expressions.
This will flatten out expressions such as `!false` or `!true`. We
already had a similar fix-up at IR generation time which handled simple
cases, but this will catch more complicated ones like `!sk_Caps.xxxxx`
(since caps bits are only flattened out at constant propagation time).

Change-Id: I04282809d9a784266a64dbcafd097f3b0662806c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/351497
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2021-01-07 20:09:49 +00:00
John Stiles
c5ff48648a Elide return expression temp-var in vardecl-less blocks.
Previously, a return statement inside a scoped Block would always result
in the return expression being assigned to a temporary variable instead
of replacing the function-call-expression directly. This was done
because there might be variables inside the Block; these would have
fallen out of scope when the expression is migrated to the call site,
resulting in an invalid expression.

We aren't actually examining the return expression so we don't know if
it uses variables from an inner scope at all. (Inspecting the return
expression for variable usage is certainly possible! But it's a fair
amount of code and complexity for a small payoff.)

However, we can very easily get most of the benefit here without paying
for the complexity. In this CL we now look for variable declarations
inside of scoped Blocks. If the code doesn't add any vardecls into
scoped Blocks, there's no risk of scope problems, and we don't need to
use a temp-var to store our return expressions. If any vardecls are
added, we go back to using a temp-var as before.

Change-Id: I4c81400dad2f33db06a1c18eb671ba2140232006
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/346499
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-12-22 19:33:12 +00:00
John Stiles
f2ce4e91a2 Test that the inliner uses a temp var for return statements.
We have a handful of tests that demonstrate this behavior indirectly,
but lacked a focused test.

Change-Id: I895cc4e3bebf30721ed649244e42bf170cc6ec06
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/346497
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
2020-12-22 17:52:49 +00:00
John Stiles
74ebd7e6ce Add support for inlining switches with returns inside.
Because we use `continue` for flow control handling now, we can escape
from the middle of a switch statement. This wasn't possible when we used
`break`.

This unlocks some pretty stellar optimization opportunities if the
switch value can be determined at compile time; see BlendEnum for an
example.

Change-Id: Id29be92c343c10fd604683a80c5d5bd2bd070cb0
Bug: skia:11097
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345419
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
2020-12-18 00:14:48 +00:00
John Stiles
77702f1704 Eliminate inliner temporary variables for top-level-exit functions.
When we determine that a function only contains a single return
statement and it is at the top level (i.e. not inside any scopes),
there is no need to create a temporary variable and store the
result expression into a variable. Instead, we can directly replace
the function-call expression with the return-statement's expression.

Unlike my previous solution, this does not require variable
declarations to be rewritten. The no-scopes limitation makes it
slightly less effective in theory, but in practice we still get
almost all of the benefit. The no-scope limitation bites us on
structures like

@if (true) {
    return x;
} else {
    return y;
}

Which will optimize away the if, but leave the scope:

{
    return x;
}

However, this is not a big deal; the biggest wins are single-line
helper functions like `guarded_divide` and `unpremul` which retain
the full benefit.

Change-Id: I7fbb725e65db021b9795c04c816819669815578f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345167
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
2020-12-17 20:37:21 +00:00
John Stiles
fa9a08369e Remove unnecessary Blocks from the inliner.
If we aren't wrapping the inlined function body in a loop, there's no
need to add a scopeless Block; we've already got one. This doesn't
affect the final output meaningfully--it just suppresses a newline--but
it's one fewer IRNode allocation.

Change-Id: Ib7b0014e908586d8acfcf6c23520873fad31d0b7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345163
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2020-12-17 19:35:35 +00:00
John Stiles
7b920446a8 Replace inliner do-while loops with for loops.
do-while loops aren't compatible with GLSL ES2. For-loops which run
only one time should work exactly the same for our purposes. We expect
such a loop to be unrolled by every driver, so it shouldn't come at any
performance cost.

Change-Id: Ia8de5fcab8128c34da97eaeaf81f91ad1ac36ce4
Bug: skia:11097
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345159
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2020-12-17 19:23:47 +00:00
John Stiles
6f31e27f1e Improve inliner variable name mangling.
Previously, multiple inliner passes in a row would each apply a
separate name mangling to variable names, so names like "_25_14_3_1_pos"
were not uncommon. This change demangles the name before re-mangling it,
so we would have just "_25_pos" instead.

It's not important, but it makes things easier to read.

Change-Id: I1257222dac2a68e337f431af230ce50730cedc9b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345116
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2020-12-16 20:46:43 +00:00
John Stiles
35fee4c079 Revert "Declare all inlined variables at the topmost scope possible."
This reverts commit e8e4aca955.

Reason for revert: can break ES2 for-loop rules

Original change's description:
> Declare all inlined variables at the topmost scope possible.
>
> By itself, this is uninteresting and even perhaps slightly
> counterproductive (as it separates vardecl from its initializer,
> increasing LOC). However, this enables a followup CL
> (http://review.skia.org/344665) which allows single-return functions to
> be inlined without the creation of a temporary variable at all. This
> applies to the majority of fragment processors in a typical Ganesh
> hierarchy. This change will greatly reduce the number of inliner-created
> temporary copies when compiling a typical tree of FPs.
>
> Change-Id: I03423a13cf35050637dabace4a32973a08a4ed0a
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/344764
> Reviewed-by: Brian Osman <brianosman@google.com>
> Commit-Queue: John Stiles <johnstiles@google.com>

TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com

Change-Id: Ica01d6906bcb9cef1f49d22dda714fc9cbfa3885
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345121
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2020-12-16 18:26:21 +00:00
John Stiles
9e94812bef Revert "Eliminate inliner temporary variables for functions with a single exit."
This reverts commit 345d72124d.

Reason for revert: can break ES2 for-loop rules

Original change's description:
> Eliminate inliner temporary variables for functions with a single exit.
>
> When we determine that a function only contains a single return
> statement, there is no need to create a temporary variable and store the
> result expression into a variable. Instead, we can directly replace the
> function-call expression with the return-statement's expression.
>
> This dramatically simplifies the final optimized output from chains of
> very simple inlined functions, which is a very common pattern for trees
> of Skia fragment processors.
>
> Change-Id: I6789064a321daf43db2e1cef4915f25ed74d6131
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/344665
> Commit-Queue: John Stiles <johnstiles@google.com>
> Reviewed-by: Brian Osman <brianosman@google.com>
> Auto-Submit: John Stiles <johnstiles@google.com>

TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com

Change-Id: I60845f22159605a06047b030e2686a769121a35a
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345120
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2020-12-16 18:24:57 +00:00
John Stiles
345d72124d Eliminate inliner temporary variables for functions with a single exit.
When we determine that a function only contains a single return
statement, there is no need to create a temporary variable and store the
result expression into a variable. Instead, we can directly replace the
function-call expression with the return-statement's expression.

This dramatically simplifies the final optimized output from chains of
very simple inlined functions, which is a very common pattern for trees
of Skia fragment processors.

Change-Id: I6789064a321daf43db2e1cef4915f25ed74d6131
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/344665
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
2020-12-16 17:26:06 +00:00
John Stiles
e8e4aca955 Declare all inlined variables at the topmost scope possible.
By itself, this is uninteresting and even perhaps slightly
counterproductive (as it separates vardecl from its initializer,
increasing LOC). However, this enables a followup CL
(http://review.skia.org/344665) which allows single-return functions to
be inlined without the creation of a temporary variable at all. This
applies to the majority of fragment processors in a typical Ganesh
hierarchy. This change will greatly reduce the number of inliner-created
temporary copies when compiling a typical tree of FPs.

Change-Id: I03423a13cf35050637dabace4a32973a08a4ed0a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/344764
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2020-12-16 17:24:56 +00:00