Directly compute call counts, rather than mutating state

This causes a ~4% regression on sksl_large, but some of that
can be bought back in two ways:

1) Removing (now unnecessary) cloning of program elements
2) Hoisting the new analysis passes, with (nontrivial)
   logic to update/maintain the call counts as we edit IR.

Also, this fixes bugs where we were emitting functions that
had "calls" from no-longer called functions.

Bug: skia:10776
Change-Id: I4f8c29957be2e4233a883c9a1125f363b82ee40c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/327198
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index f0ef4d5..ce4e61e 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -1131,6 +1131,30 @@
     }
 }
 
+static bool multiple_calls_to(const Program& program, const FunctionDeclaration* fn) {
+    class MulitpleCallVisitor : public ProgramVisitor {
+    public:
+        MulitpleCallVisitor(const FunctionDeclaration* function) : fFunction(function) {}
+
+        bool visitExpression(const Expression& e) override {
+            if (e.is<FunctionCall>() && &e.as<FunctionCall>().function() == fFunction) {
+                if (fCalled) {
+                    return true;
+                }
+                fCalled = true;
+            }
+            return INHERITED::visitExpression(e);
+        }
+
+        const FunctionDeclaration* fFunction;
+        bool fCalled = false;
+        using INHERITED = ProgramVisitor;
+    };
+
+    MulitpleCallVisitor visitor(fn);
+    return visitor.visit(program);
+}
+
 bool Inliner::analyze(Program& program) {
     // A threshold of zero indicates that the inliner is completely disabled, so we can just return.
     if (fSettings->fInlineThreshold <= 0) {
@@ -1151,7 +1175,7 @@
         // idea to inline it.
         if (candidate.fIsLargeFunction &&
             !(funcDecl->modifiers().fFlags & Modifiers::kInline_Flag) &&
-            funcDecl->callCount() > 1) {
+            multiple_calls_to(program, funcDecl)) {
             continue;
         }