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>
diff --git a/src/sksl/SkSLProgramSettings.h b/src/sksl/SkSLProgramSettings.h
index bc13775..219624a 100644
--- a/src/sksl/SkSLProgramSettings.h
+++ b/src/sksl/SkSLProgramSettings.h
@@ -51,14 +51,17 @@
// At present, zero is always used by our backends.
int fDefaultUniformSet = 0;
int fDefaultUniformBinding = 0;
- // If true, remove any uncalled functions other than main(). Note that a function which
- // starts out being used may end up being uncalled after optimization.
- bool fRemoveDeadFunctions = true;
- // Sets an upper limit on the acceptable amount of code growth from inlining.
- // A value of zero will disable the inliner entirely.
- int fInlineThreshold = SkSL::kDefaultInlineThreshold;
- // true to enable optimization passes
+ // Enables the SkSL optimizer.
bool fOptimize = true;
+ // (Requires fOptimize = true) Remove any uncalled functions other than main(). Note that a
+ // function which starts out being used may end up being uncalled after optimization.
+ bool fRemoveDeadFunctions = true;
+ // (Requires fOptimize = true) Uses the control-flow graph to detect and eliminate code within
+ // a function that has become unreachable due to optimization.
+ bool fDeadCodeElimination = true;
+ // (Requires fOptimize = true) When greater than zero, enables the inliner. The threshold value
+ // sets an upper limit on the acceptable amount of code growth from inlining.
+ int fInlineThreshold = SkSL::kDefaultInlineThreshold;
// If true, implicit conversions to lower precision numeric types are allowed
// (eg, float to half)
bool fAllowNarrowingConversions = false;