Migrate ModifiersPool into the context.

The IRGenerator no longer owns the pool of modifiers; they are now
available to any function that has a Context.

Change-Id: I4f2f37ae5e06966bed00107b0483b42b07a454d8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/404237
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index 8915821..c2007ef 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -108,6 +108,21 @@
     Context* fContext;
 };
 
+class AutoModifiersPool {
+public:
+    AutoModifiersPool(std::shared_ptr<Context>& context, ModifiersPool* modifiersPool)
+            : fContext(context.get()) {
+        SkASSERT(!fContext->fModifiersPool);
+        fContext->fModifiersPool = modifiersPool;
+    }
+
+    ~AutoModifiersPool() {
+        fContext->fModifiersPool = nullptr;
+    }
+
+    Context* fContext;
+};
+
 Compiler::Compiler(const ShaderCapsClass* caps)
         : fContext(std::make_shared<Context>(/*errors=*/*this, *caps))
         , fInliner(fContext.get())
@@ -181,13 +196,13 @@
 
     // sk_Caps is "builtin", but all references to it are resolved to Settings, so we don't need to
     // treat it as builtin (ie, no need to clone it into the Program).
-    fPrivateSymbolTable->add(
-            std::make_unique<Variable>(/*offset=*/-1,
-                                       fIRGenerator->modifiersPool().add(Modifiers()),
-                                       "sk_Caps",
-                                       fContext->fTypes.fSkCaps.get(),
-                                       /*builtin=*/false,
-                                       Variable::Storage::kGlobal));
+    static const Modifiers kNoModifiers{};
+    fPrivateSymbolTable->add(std::make_unique<Variable>(/*offset=*/-1,
+                                                        &kNoModifiers,
+                                                        "sk_Caps",
+                                                        fContext->fTypes.fSkCaps.get(),
+                                                        /*builtin=*/false,
+                                                        Variable::Storage::kGlobal));
 
     fRootModule = {fRootSymbolTable, /*fIntrinsics=*/nullptr};
     fPrivateModule = {fPrivateSymbolTable, /*fIntrinsics=*/nullptr};
@@ -307,6 +322,10 @@
     }
     SkASSERT(base);
 
+    // Put a fresh modifier pool into the context.
+    auto modifiersPool = std::make_unique<ModifiersPool>();
+    AutoModifiersPool autoPool(fContext, modifiersPool.get());
+
     // Built-in modules always use default program settings.
     ProgramConfig config;
     config.fKind = kind;
@@ -334,13 +353,12 @@
         printf("Unexpected errors: %s\n", this->fErrorText.c_str());
         SkDEBUGFAILF("%s %s\n", data.fPath, this->fErrorText.c_str());
     }
-    fModifiers.push_back(std::move(ir.fModifiers));
+    fModifiers.push_back(std::move(modifiersPool));
 #else
     SkASSERT(data.fData && (data.fSize != 0));
-    Rehydrator rehydrator(fContext.get(), fIRGenerator->fModifiers.get(), base,
-                          data.fData, data.fSize);
+    Rehydrator rehydrator(fContext.get(), base, data.fData, data.fSize);
     LoadedModule module = { kind, rehydrator.symbolTable(), rehydrator.elements() };
-    fModifiers.push_back(fIRGenerator->releaseModifiers());
+    fModifiers.push_back(std::move(modifiersPool));
 #endif
 
     return module;
@@ -353,7 +371,7 @@
     // For modules that just declare (but don't define) intrinsic functions, there will be no new
     // program elements. In that case, we can share our parent's intrinsic map:
     if (module.fElements.empty()) {
-        return {module.fSymbols, base.fIntrinsics};
+        return ParsedModule{module.fSymbols, base.fIntrinsics};
     }
 
     auto intrinsics = std::make_shared<IRIntrinsicMap>(base.fIntrinsics.get());
@@ -398,7 +416,7 @@
         }
     }
 
-    return {module.fSymbols, std::move(intrinsics)};
+    return ParsedModule{module.fSymbols, std::move(intrinsics)};
 }
 
 std::unique_ptr<Program> Compiler::convertProgram(
@@ -414,6 +432,10 @@
     // *then* configure the inliner with the settings for this program.
     const ParsedModule& baseModule = this->moduleForProgramKind(kind);
 
+    // Put a fresh modifier pool into the context.
+    auto modifiersPool = std::make_unique<ModifiersPool>();
+    AutoModifiersPool autoPool(fContext, modifiersPool.get());
+
     // Update our context to point to the program configuration for the duration of compilation.
     auto config = std::make_unique<ProgramConfig>(ProgramConfig{kind, settings});
     AutoProgramConfig autoConfig(fContext, config.get());
@@ -450,10 +472,10 @@
 
     fErrorText = "";
     fErrorCount = 0;
-    fInliner.reset(fIRGenerator->fModifiers.get());
+    fInliner.reset();
 
     // Not using AutoSource, because caller is likely to call errorText() if we fail to compile
-    std::unique_ptr<String> textPtr(new String(std::move(text)));
+    auto textPtr = std::make_unique<String>(std::move(text));
     fSource = textPtr.get();
 
     // Enable node pooling while converting and optimizing the program for a performance boost.
@@ -471,7 +493,7 @@
                                              fContext,
                                              std::move(ir.fElements),
                                              std::move(ir.fSharedElements),
-                                             std::move(ir.fModifiers),
+                                             std::move(modifiersPool),
                                              std::move(ir.fSymbolTable),
                                              std::move(pool),
                                              ir.fInputs);
@@ -551,7 +573,7 @@
     AutoProgramConfig autoConfig(fContext, &config);
 
     // Reset the Inliner.
-    fInliner.reset(fModifiers.back().get());
+    fInliner.reset();
 
     std::unique_ptr<ProgramUsage> usage = Analysis::GetUsage(module);