Optimize early-return detection.

Previously, `has_early_return` would count all of the return statements
in the program, and then compare that against the number of return
statements detected at the end of the program's control flow.

However, that's overkill; we don't actually need to know the full number
of returns. We only need to know if there are more returns than what we
found at the end of control flow. i.e. if a program has 1 return at the
end of its control flow, we can stop as soon as we find 2 returns and
say "yes, there's an early return somewhere."

Change-Id: I332810a7fd411d08acd6f8488ce128b5ee9eff09
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/318199
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index 097504f..023c1a0 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -57,10 +57,10 @@
 namespace SkSL {
 namespace {
 
-static int count_all_returns(const FunctionDefinition& funcDef) {
-    class CountAllReturns : public ProgramVisitor {
+static bool contains_returns_above_limit(const FunctionDefinition& funcDef, int limit) {
+    class CountReturnsWithLimit : public ProgramVisitor {
     public:
-        CountAllReturns(const FunctionDefinition& funcDef) {
+        CountReturnsWithLimit(const FunctionDefinition& funcDef, int limit) : fLimit(limit) {
             this->visitProgramElement(funcDef);
         }
 
@@ -68,7 +68,7 @@
             switch (stmt.kind()) {
                 case Statement::Kind::kReturn:
                     ++fNumReturns;
-                    [[fallthrough]];
+                    return (fNumReturns > fLimit) || INHERITED::visitStatement(stmt);
 
                 default:
                     return INHERITED::visitStatement(stmt);
@@ -76,10 +76,11 @@
         }
 
         int fNumReturns = 0;
+        int fLimit = 0;
         using INHERITED = ProgramVisitor;
     };
 
-    return CountAllReturns{funcDef}.fNumReturns;
+    return CountReturnsWithLimit{funcDef, limit}.fNumReturns > limit;
 }
 
 static int count_returns_at_end_of_control_flow(const FunctionDefinition& funcDef) {
@@ -157,13 +158,8 @@
 }
 
 static bool has_early_return(const FunctionDefinition& funcDef) {
-    int returnCount = count_all_returns(funcDef);
-    if (returnCount == 0) {
-        return false;
-    }
-
     int returnsAtEndOfControlFlow = count_returns_at_end_of_control_flow(funcDef);
-    return returnCount > returnsAtEndOfControlFlow;
+    return contains_returns_above_limit(funcDef, returnsAtEndOfControlFlow);
 }
 
 static bool contains_recursive_call(const FunctionDeclaration& funcDecl) {