Store invariant declarations in variable metadata

This is simpler than storing the information in symbol table levels.
Invariant declarations can only be present at the global scope, so
storing the information per level is not required.

BUG=angleproject:2267
TEST=angle_unittests

Change-Id: Idb07d734950c8a0a8bda5b2380e181902f9eb633
Reviewed-on: https://chromium-review.googlesource.com/1007060
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/SymbolTable.cpp b/src/compiler/translator/SymbolTable.cpp
index 3d479fb..782045a 100644
--- a/src/compiler/translator/SymbolTable.cpp
+++ b/src/compiler/translator/SymbolTable.cpp
@@ -13,9 +13,6 @@
 
 #include "compiler/translator/SymbolTable.h"
 
-#include <algorithm>
-#include <set>
-
 #include "angle_gl.h"
 #include "compiler/translator/ImmutableString.h"
 #include "compiler/translator/IntermNode.h"
@@ -27,7 +24,7 @@
 class TSymbolTable::TSymbolTableLevel
 {
   public:
-    TSymbolTableLevel() : mGlobalInvariant(false) {}
+    TSymbolTableLevel() {}
 
     bool insert(TSymbol *symbol);
 
@@ -36,15 +33,6 @@
 
     TSymbol *find(const ImmutableString &name) const;
 
-    void addInvariantVarying(const ImmutableString &name) { mInvariantVaryings.insert(name); }
-
-    bool isVaryingInvariant(const ImmutableString &name)
-    {
-        return (mGlobalInvariant || mInvariantVaryings.count(name) > 0);
-    }
-
-    void setGlobalInvariant(bool invariant) { mGlobalInvariant = invariant; }
-
   private:
     using tLevel        = TUnorderedMap<ImmutableString,
                                  TSymbol *,
@@ -53,9 +41,6 @@
     using tInsertResult = std::pair<tLevel::iterator, bool>;
 
     tLevel level;
-
-    std::set<ImmutableString> mInvariantVaryings;
-    bool mGlobalInvariant;
 };
 
 bool TSymbolTable::TSymbolTableLevel::insert(TSymbol *symbol)
@@ -80,7 +65,10 @@
 }
 
 TSymbolTable::TSymbolTable()
-    : mUniqueIdCounter(0), mShaderType(GL_FRAGMENT_SHADER), mGlInVariableWithArraySize(nullptr)
+    : mGlobalInvariant(false),
+      mUniqueIdCounter(0),
+      mShaderType(GL_FRAGMENT_SHADER),
+      mGlInVariableWithArraySize(nullptr)
 {
 }
 
@@ -168,26 +156,26 @@
     return mVar_gl_SecondaryFragDataEXT;
 }
 
-void TSymbolTable::markStaticWrite(const TVariable &variable)
-{
-    int id    = variable.uniqueId().get();
+TSymbolTable::VariableMetadata *TSymbolTable::getOrCreateVariableMetadata(const TVariable &variable) {
+    int id = variable.uniqueId().get();
     auto iter = mVariableMetadata.find(id);
     if (iter == mVariableMetadata.end())
     {
         iter = mVariableMetadata.insert(std::make_pair(id, VariableMetadata())).first;
     }
-    iter->second.staticWrite = true;
+    return &iter->second;
+}
+
+void TSymbolTable::markStaticWrite(const TVariable &variable)
+{
+    auto metadata = getOrCreateVariableMetadata(variable);
+    metadata->staticWrite = true;
 }
 
 void TSymbolTable::markStaticRead(const TVariable &variable)
 {
-    int id    = variable.uniqueId().get();
-    auto iter = mVariableMetadata.find(id);
-    if (iter == mVariableMetadata.end())
-    {
-        iter = mVariableMetadata.insert(std::make_pair(id, VariableMetadata())).first;
-    }
-    iter->second.staticRead = true;
+    auto metadata = getOrCreateVariableMetadata(variable);
+    metadata->staticRead = true;
 }
 
 bool TSymbolTable::isStaticallyUsed(const TVariable &variable) const
@@ -195,7 +183,32 @@
     ASSERT(!variable.getConstPointer());
     int id    = variable.uniqueId().get();
     auto iter = mVariableMetadata.find(id);
-    return iter != mVariableMetadata.end();
+    return iter != mVariableMetadata.end() && (iter->second.staticRead || iter->second.staticWrite);
+}
+
+void TSymbolTable::addInvariantVarying(const TVariable &variable)
+{
+    ASSERT(atGlobalLevel());
+    auto metadata = getOrCreateVariableMetadata(variable);
+    metadata->invariant = true;
+}
+
+bool TSymbolTable::isVaryingInvariant(const TVariable &variable) const
+{
+    ASSERT(atGlobalLevel());
+    if (mGlobalInvariant)
+    {
+        return true;
+    }
+    int id = variable.uniqueId().get();
+    auto iter = mVariableMetadata.find(id);
+    return iter != mVariableMetadata.end() && iter->second.invariant;
+}
+
+void TSymbolTable::setGlobalInvariant(bool invariant)
+{
+    ASSERT(atGlobalLevel());
+    mGlobalInvariant = invariant;
 }
 
 const TSymbol *TSymbolTable::find(const ImmutableString &name, int shaderVersion) const
@@ -278,26 +291,9 @@
     return prec;
 }
 
-void TSymbolTable::addInvariantVarying(const ImmutableString &originalName)
-{
-    ASSERT(atGlobalLevel());
-    mTable.back()->addInvariantVarying(originalName);
-}
-
-bool TSymbolTable::isVaryingInvariant(const ImmutableString &originalName) const
-{
-    ASSERT(atGlobalLevel());
-    return mTable.back()->isVaryingInvariant(originalName);
-}
-
-void TSymbolTable::setGlobalInvariant(bool invariant)
-{
-    ASSERT(atGlobalLevel());
-    mTable.back()->setGlobalInvariant(invariant);
-}
-
 void TSymbolTable::clearCompilationResults()
 {
+    mGlobalInvariant = false;
     mUniqueIdCounter = kLastBuiltInId + 1;
     mVariableMetadata.clear();
     mGlInVariableWithArraySize = nullptr;
@@ -360,7 +356,7 @@
     setDefaultPrecision(samplerType, EbpLow);
 }
 
-TSymbolTable::VariableMetadata::VariableMetadata() : staticRead(false), staticWrite(false)
+TSymbolTable::VariableMetadata::VariableMetadata() : staticRead(false), staticWrite(false), invariant(false)
 {
 }