Remove temporary slot in writeSwitchStatement.

Discussion with brianosman@ inspired some more code simplification.

Change-Id: I1279c55b6ece5397a3e26fe84ed795b539b7c5b1
Bug: skia:12450
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/452322
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/codegen/SkSLVMCodeGenerator.cpp b/src/sksl/codegen/SkSLVMCodeGenerator.cpp
index 5ac28df..2548188 100644
--- a/src/sksl/codegen/SkSLVMCodeGenerator.cpp
+++ b/src/sksl/codegen/SkSLVMCodeGenerator.cpp
@@ -217,7 +217,7 @@
     void writeVarDeclaration(const VarDeclaration& decl);
 
     Value writeStore(const Expression& lhs, const Value& rhs);
-    void  writeStore(SkSpan<size_t> slots, const Value& rhs);
+    skvm::Val writeConditionalStore(skvm::Val lhs, skvm::Val rhs, skvm::I32 mask);
 
     Value writeMatrixInverse2x2(const Value& m);
     Value writeMatrixInverse3x3(const Value& m);
@@ -1464,19 +1464,17 @@
     }
 
     // `slots` are now absolute indices into `fSlots`.
-    this->writeStore(SkMakeSpan(slots), rhs);
+    skvm::I32 mask = this->mask();
+    for (size_t i = rhs.slots(); i --> 0;) {
+        skvm::Val& slotVal = fSlots[slots[i]];
+        slotVal = this->writeConditionalStore(slotVal, rhs[i], mask);
+    }
+
     return rhs;
 }
 
-void SkVMGenerator::writeStore(SkSpan<size_t> slots, const Value& rhs) {
-    SkASSERT(rhs.slots() == slots.size());
-
-    skvm::I32 mask = this->mask();
-    for (size_t i = rhs.slots(); i --> 0;) {
-        skvm::F32 curr = f32(fSlots[slots[i]]),
-                  next = f32(rhs[i]);
-        fSlots[slots[i]] = select(mask, next, curr).id;
-    }
+skvm::Val SkVMGenerator::writeConditionalStore(skvm::Val lhs, skvm::Val rhs, skvm::I32 mask) {
+    return select(mask, f32(rhs), f32(lhs)).id;
 }
 
 void SkVMGenerator::writeBlock(const Block& b) {
@@ -1559,9 +1557,8 @@
     skvm::I32 falseValue = fBuilder->splat( 0);
     skvm::I32 trueValue  = fBuilder->splat(~0);
 
-    // Create a new slot for the "switchFallthough" scratch variable, initialized to false.
-    size_t switchFallthroughSlot = fSlots.size();
-    fSlots.push_back(falseValue.id);
+    // Create a "switchFallthough" scratch variable, initialized to false.
+    skvm::I32 switchFallthrough = falseValue;
 
     // Loop masks behave just like for statements. When a break is encountered, it masks off all
     // lanes for the rest of the body of the switch.
@@ -1577,12 +1574,13 @@
             // if the case value matches.
             ScopedCondition conditionalCaseBlock(
                     this,
-                    i32(fSlots[switchFallthroughSlot]) | (i32(caseValue) == i32(switchValue)));
+                    switchFallthrough | (i32(caseValue) == i32(switchValue)));
             this->writeStatement(*c.statement());
 
-            // We always set the fallthrough flag after a case block (`break` still works to stop
-            // the flow of execution regardless).
-            this->writeStore(SkMakeSpan(&switchFallthroughSlot, 1), trueValue);
+            // If we are inside the case block, we set the fallthrough flag to true (`break` still
+            // works to stop the flow of execution regardless, since it zeroes out the loop-mask).
+            switchFallthrough.id = this->writeConditionalStore(switchFallthrough.id, trueValue.id,
+                                                               this->mask());
         } else {
             // This is the default case. Since it's always last, we can just dump in the code.
             this->writeStatement(*c.statement());
@@ -1591,7 +1589,6 @@
 
     // Restore state.
     fLoopMask = oldLoopMask;
-    fSlots.pop_back();
 }
 
 void SkVMGenerator::writeVarDeclaration(const VarDeclaration& decl) {