Move function intrinsic handling into Finalizer

This continues the process of moving code out of IRGenerator and into
better homes.

Change-Id: I4803d39ecb2f4c0e916e82e907b5dcaa285a35ce
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/456116
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index bcfdd90..c0eeb01 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -371,48 +371,9 @@
     }
 }
 
-void IRGenerator::copyIntrinsicIfNeeded(const FunctionDeclaration& function) {
-    if (const ProgramElement* found =
-            fContext.fIntrinsics->findAndInclude(function.description())) {
-        const FunctionDefinition& original = found->as<FunctionDefinition>();
-
-        // Sort the referenced intrinsics into a consistent order; otherwise our output will become
-        // non-deterministic.
-        std::vector<const FunctionDeclaration*> intrinsics(original.referencedIntrinsics().begin(),
-                                                           original.referencedIntrinsics().end());
-        std::sort(intrinsics.begin(), intrinsics.end(),
-                  [](const FunctionDeclaration* a, const FunctionDeclaration* b) {
-                      if (a->isBuiltin() != b->isBuiltin()) {
-                          return a->isBuiltin() < b->isBuiltin();
-                      }
-                      if (a->fLine != b->fLine) {
-                          return a->fLine < b->fLine;
-                      }
-                      if (a->name() != b->name()) {
-                          return a->name() < b->name();
-                      }
-                      return a->description() < b->description();
-                  });
-        for (const FunctionDeclaration* f : intrinsics) {
-            this->copyIntrinsicIfNeeded(*f);
-        }
-
-        fSharedElements->push_back(found);
-    }
-}
-
 std::unique_ptr<Expression> IRGenerator::call(int line,
                                               const FunctionDeclaration& function,
                                               ExpressionArray arguments) {
-    if (function.isBuiltin()) {
-        if (function.intrinsicKind() == k_dFdy_IntrinsicKind) {
-            fInputs.fUseFlipRTUniform = true;
-        }
-        if (!fContext.fConfig->fIsBuiltinCode && fContext.fIntrinsics) {
-            this->copyIntrinsicIfNeeded(function);
-        }
-    }
-
     return FunctionCall::Convert(fContext, line, function, std::move(arguments));
 }
 
diff --git a/src/sksl/SkSLIRGenerator.h b/src/sksl/SkSLIRGenerator.h
index 0306f59..7816246 100644
--- a/src/sksl/SkSLIRGenerator.h
+++ b/src/sksl/SkSLIRGenerator.h
@@ -135,8 +135,6 @@
     /** Appends sk_Position fixup to the bottom of main() if this is a vertex program. */
     void appendRTAdjustFixupToVertexMain(const FunctionDeclaration& decl, Block* body);
 
-    void copyIntrinsicIfNeeded(const FunctionDeclaration& function);
-
     // Runtime effects (and the interpreter, which uses the same CPU runtime) require adherence to
     // the strict rules from The OpenGL ES Shading Language Version 1.00. (Including Appendix A).
     bool strictES2Mode() const {
diff --git a/src/sksl/dsl/priv/DSLWriter.cpp b/src/sksl/dsl/priv/DSLWriter.cpp
index 7c93d9b..852b1a7 100644
--- a/src/sksl/dsl/priv/DSLWriter.cpp
+++ b/src/sksl/dsl/priv/DSLWriter.cpp
@@ -92,6 +92,10 @@
     return Context().fConfig->fSettings;
 }
 
+SkSL::Program::Inputs& DSLWriter::Inputs() {
+    return IRGenerator().fInputs;
+}
+
 const std::shared_ptr<SkSL::SymbolTable>& DSLWriter::SymbolTable() {
     return IRGenerator().fSymbolTable;
 }
diff --git a/src/sksl/dsl/priv/DSLWriter.h b/src/sksl/dsl/priv/DSLWriter.h
index 15d4a08..9a57576 100644
--- a/src/sksl/dsl/priv/DSLWriter.h
+++ b/src/sksl/dsl/priv/DSLWriter.h
@@ -80,6 +80,11 @@
     static SkSL::ProgramSettings& Settings();
 
     /**
+     * Returns the Program::Inputs used by the current thread.
+     */
+    static SkSL::Program::Inputs& Inputs();
+
+    /**
      * Returns the collection to which DSL program elements in this thread should be appended.
      */
     static std::vector<std::unique_ptr<SkSL::ProgramElement>>& ProgramElements() {
diff --git a/src/sksl/ir/SkSLFunctionDefinition.cpp b/src/sksl/ir/SkSLFunctionDefinition.cpp
index f15bfc9..8c10a89 100644
--- a/src/sksl/ir/SkSLFunctionDefinition.cpp
+++ b/src/sksl/ir/SkSLFunctionDefinition.cpp
@@ -7,7 +7,9 @@
 
 #include "src/sksl/SkSLAnalysis.h"
 #include "src/sksl/SkSLContext.h"
+#include "src/sksl/SkSLIntrinsicMap.h"
 #include "src/sksl/SkSLProgramSettings.h"
+#include "src/sksl/dsl/priv/DSLWriter.h"
 #include "src/sksl/ir/SkSLFunctionCall.h"
 #include "src/sksl/ir/SkSLFunctionDefinition.h"
 #include "src/sksl/ir/SkSLReturnStatement.h"
@@ -35,6 +37,37 @@
             SkASSERT(fContinuableLevel == std::forward_list<int>{0});
         }
 
+        void copyIntrinsicIfNeeded(const FunctionDeclaration& function) {
+            if (const ProgramElement* found =
+                    fContext.fIntrinsics->findAndInclude(function.description())) {
+                const FunctionDefinition& original = found->as<FunctionDefinition>();
+
+                // Sort the referenced intrinsics into a consistent order; otherwise our output will
+                // become non-deterministic.
+                std::vector<const FunctionDeclaration*> intrinsics(
+                        original.referencedIntrinsics().begin(),
+                        original.referencedIntrinsics().end());
+                std::sort(intrinsics.begin(), intrinsics.end(),
+                          [](const FunctionDeclaration* a, const FunctionDeclaration* b) {
+                              if (a->isBuiltin() != b->isBuiltin()) {
+                                  return a->isBuiltin() < b->isBuiltin();
+                              }
+                              if (a->fLine != b->fLine) {
+                                  return a->fLine < b->fLine;
+                              }
+                              if (a->name() != b->name()) {
+                                  return a->name() < b->name();
+                              }
+                              return a->description() < b->description();
+                          });
+                for (const FunctionDeclaration* f : intrinsics) {
+                    this->copyIntrinsicIfNeeded(*f);
+                }
+
+                dsl::DSLWriter::SharedElements().push_back(found);
+            }
+        }
+
         bool functionReturnsValue() const {
             return !fFunction.returnType().isVoid();
         }
@@ -42,9 +75,18 @@
         bool visitExpression(Expression& expr) override {
             if (expr.is<FunctionCall>()) {
                 const FunctionDeclaration& func = expr.as<FunctionCall>().function();
-                if (func.isBuiltin() && func.definition()) {
-                    fReferencedIntrinsics->insert(&func);
+                if (func.isBuiltin()) {
+                    if (func.intrinsicKind() == k_dFdy_IntrinsicKind) {
+                        dsl::DSLWriter::Inputs().fUseFlipRTUniform = true;
+                    }
+                    if (func.definition()) {
+                        fReferencedIntrinsics->insert(&func);
+                    }
+                    if (!fContext.fConfig->fIsBuiltinCode && fContext.fIntrinsics) {
+                        this->copyIntrinsicIfNeeded(func);
+                    }
                 }
+
             }
             return INHERITED::visitExpression(expr);
         }