Migrate EliminateDeadLocalVariables into Transform.

Change-Id: Idc0c51c0d293121fd306e7153b2e47f7e7dec222
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/456646
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/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index ed96215..a3f9ede 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -522,86 +522,6 @@
     return madeChanges;
 }
 
-bool Compiler::removeDeadLocalVariables(Program& program, ProgramUsage* usage) {
-    class DeadLocalVariableEliminator : public ProgramWriter {
-    public:
-        DeadLocalVariableEliminator(const Context& context, ProgramUsage* usage)
-                : fContext(context)
-                , fUsage(usage) {}
-
-        using ProgramWriter::visitProgramElement;
-
-        bool visitExpressionPtr(std::unique_ptr<Expression>& expr) override {
-            // We don't need to look inside expressions at all.
-            return false;
-        }
-
-        bool visitStatementPtr(std::unique_ptr<Statement>& stmt) override {
-            if (stmt->is<VarDeclaration>()) {
-                VarDeclaration& varDecl = stmt->as<VarDeclaration>();
-                const Variable* var = &varDecl.var();
-                ProgramUsage::VariableCounts* counts = fUsage->fVariableCounts.find(var);
-                SkASSERT(counts);
-                SkASSERT(counts->fDeclared);
-                if (CanEliminate(var, *counts)) {
-                    if (var->initialValue()) {
-                        // The variable has an initial-value expression, which might have side
-                        // effects. ExpressionStatement::Make will preserve side effects, but
-                        // replaces pure expressions with Nop.
-                        fUsage->remove(stmt.get());
-                        stmt = ExpressionStatement::Make(fContext, std::move(varDecl.value()));
-                        fUsage->add(stmt.get());
-                    } else {
-                        // The variable has no initial-value and can be cleanly eliminated.
-                        fUsage->remove(stmt.get());
-                        stmt = std::make_unique<Nop>();
-                    }
-                    fMadeChanges = true;
-                }
-                return false;
-            }
-            return INHERITED::visitStatementPtr(stmt);
-        }
-
-        static bool CanEliminate(const Variable* var, const ProgramUsage::VariableCounts& counts) {
-            if (!counts.fDeclared || counts.fRead || var->storage() != VariableStorage::kLocal) {
-                return false;
-            }
-            if (var->initialValue()) {
-                SkASSERT(counts.fWrite >= 1);
-                return counts.fWrite == 1;
-            } else {
-                return counts.fWrite == 0;
-            }
-        }
-
-        bool fMadeChanges = false;
-        const Context& fContext;
-        ProgramUsage* fUsage;
-
-        using INHERITED = ProgramWriter;
-    };
-
-    DeadLocalVariableEliminator visitor{*fContext, usage};
-
-    if (program.fConfig->fSettings.fRemoveDeadVariables) {
-        for (auto& [var, counts] : usage->fVariableCounts) {
-            if (DeadLocalVariableEliminator::CanEliminate(var, counts)) {
-                // This program contains at least one dead local variable.
-                // Scan the program for any dead local variables and eliminate them all.
-                for (std::unique_ptr<ProgramElement>& pe : program.ownedElements()) {
-                    if (pe->is<FunctionDefinition>()) {
-                        visitor.visitProgramElement(*pe);
-                    }
-                }
-                break;
-            }
-        }
-    }
-
-    return visitor.fMadeChanges;
-}
-
 void Compiler::removeUnreachableCode(Program& program, ProgramUsage* usage) {
     for (std::unique_ptr<ProgramElement>& pe : program.ownedElements()) {
         if (pe->is<FunctionDefinition>()) {
@@ -630,7 +550,7 @@
         while (this->removeDeadFunctions(program, usage)) {
             // Removing dead functions may cause more functions to become unreferenced. Try again.
         }
-        while (this->removeDeadLocalVariables(program, usage)) {
+        while (Transform::EliminateDeadLocalVariables(program, usage)) {
             // Removing dead variables may cause more variables to become unreferenced. Try again.
         }