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/CollectVariables.cpp b/src/compiler/translator/CollectVariables.cpp
index 635f364..f7fbd60 100644
--- a/src/compiler/translator/CollectVariables.cpp
+++ b/src/compiler/translator/CollectVariables.cpp
@@ -284,7 +284,7 @@
setBuiltInInfoFromSymbol(variable, &info);
info.staticUse = true;
info.active = true;
- info.isInvariant = mSymbolTable->isVaryingInvariant(variable.name());
+ info.isInvariant = mSymbolTable->isVaryingInvariant(variable);
varyings->push_back(info);
(*addedFlag) = true;
}
@@ -668,7 +668,7 @@
case EvqFlatOut:
case EvqCentroidOut:
case EvqGeometryOut:
- if (mSymbolTable->isVaryingInvariant(variable.getName()) || type.isInvariant())
+ if (mSymbolTable->isVaryingInvariant(variable.variable()) || type.isInvariant())
{
varying.isInvariant = true;
}
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 6cf0eb9..5f3c928 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -2632,7 +2632,7 @@
typeQualifier.line);
checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
- symbolTable.addInvariantVarying(identifier);
+ symbolTable.addInvariantVarying(*variable);
TIntermSymbol *intermSymbol = new TIntermSymbol(variable);
intermSymbol->setLine(identifierLoc);
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)
{
}
diff --git a/src/compiler/translator/SymbolTable.h b/src/compiler/translator/SymbolTable.h
index e3667c6..ae0456f 100644
--- a/src/compiler/translator/SymbolTable.h
+++ b/src/compiler/translator/SymbolTable.h
@@ -31,6 +31,7 @@
//
#include <memory>
+#include <set>
#include "common/angleutils.h"
#include "compiler/translator/ExtensionBehavior.h"
@@ -117,15 +118,11 @@
// for the specified TBasicType
TPrecision getDefaultPrecision(TBasicType type) const;
- // This records invariant varyings declared through
- // "invariant varying_name;".
- void addInvariantVarying(const ImmutableString &originalName);
+ // This records invariant varyings declared through "invariant varying_name;".
+ void addInvariantVarying(const TVariable &variable);
- // If this returns false, the varying could still be invariant
- // if it is set as invariant during the varying variable
- // declaration - this piece of information is stored in the
- // variable's type, not here.
- bool isVaryingInvariant(const ImmutableString &originalName) const;
+ // If this returns false, the varying could still be invariant if it is set as invariant during the varying variable declaration - this piece of information is stored in the variable's type, not here.
+ bool isVaryingInvariant(const TVariable &variable) const;
void setGlobalInvariant(bool invariant);
@@ -142,6 +139,15 @@
private:
friend class TSymbolUniqueId;
+
+ struct VariableMetadata
+ {
+ VariableMetadata();
+ bool staticRead;
+ bool staticWrite;
+ bool invariant;
+ };
+
int nextUniqueIdValue();
class TSymbolTableLevel;
@@ -154,6 +160,8 @@
ShShaderSpec spec,
const ShBuiltInResources &resources);
+ VariableMetadata *getOrCreateVariableMetadata(const TVariable &variable);
+
std::vector<std::unique_ptr<TSymbolTableLevel>> mTable;
// There's one precision stack level for predefined precisions and then one level for each scope
@@ -161,6 +169,8 @@
typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
std::vector<std::unique_ptr<PrecisionStackLevel>> mPrecisionStack;
+ bool mGlobalInvariant;
+
int mUniqueIdCounter;
static const int kLastBuiltInId;
@@ -168,13 +178,6 @@
sh::GLenum mShaderType;
ShBuiltInResources mResources;
- struct VariableMetadata
- {
- VariableMetadata();
- bool staticRead;
- bool staticWrite;
- };
-
// Indexed by unique id. Map instead of vector since the variables are fairly sparse.
std::map<int, VariableMetadata> mVariableMetadata;