Store TVariable* in TIntermSymbol instead of storing id

This is an intermediate step to only storing a TVariable * in
TIntermSymbol instead of copying the name.

This makes it possible to get a constant value out of a TIntermSymbol
without doing a symbol table lookup.

BUG=angleproject:2267
TEST=angle_unittests

Change-Id: Ibff588241a4ad4ac330063296273288b20a072c9
Reviewed-on: https://chromium-review.googlesource.com/829142
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index 6f63f0e..18127bf 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -281,7 +281,7 @@
 }
 
 TIntermSymbol::TIntermSymbol(const TVariable *variable)
-    : TIntermTyped(variable->getType()), mId(variable->uniqueId()), mSymbol(variable->name())
+    : TIntermTyped(variable->getType()), mVariable(variable), mSymbol(variable->name())
 {
     if (variable->symbolType() == SymbolType::AngleInternal)
     {
@@ -289,6 +289,11 @@
     }
 }
 
+const TSymbolUniqueId &TIntermSymbol::uniqueId() const
+{
+    return mVariable->uniqueId();
+}
+
 TIntermAggregate *TIntermAggregate::CreateFunctionCall(const TFunction &func,
                                                        TIntermSequence *arguments)
 {
diff --git a/src/compiler/translator/IntermNode.h b/src/compiler/translator/IntermNode.h
index ab3df07..31e71b9 100644
--- a/src/compiler/translator/IntermNode.h
+++ b/src/compiler/translator/IntermNode.h
@@ -263,20 +263,20 @@
 
     bool hasSideEffects() const override { return false; }
 
-    int getId() const { return mId.get(); }
+    const TSymbolUniqueId &uniqueId() const;
     const TString &getSymbol() const { return mSymbol.getString(); }
     const TName &getName() const { return mSymbol; }
+    const TVariable &variable() const { return *mVariable; }
 
     void traverse(TIntermTraverser *it) override;
     TIntermSymbol *getAsSymbolNode() override { return this; }
     bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; }
 
-  protected:
-    const TSymbolUniqueId mId;
-    TName mSymbol;
-
   private:
     TIntermSymbol(const TIntermSymbol &) = default;  // Note: not deleted, just private!
+
+    const TVariable *const mVariable;  // Guaranteed to be non-null
+    TName mSymbol;
 };
 
 // A Raw node stores raw code, that the translator will insert verbatim
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 739f686..65270ff 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -2408,7 +2408,7 @@
     {
         TIntermBinary *test = node->getCondition()->getAsBinaryNode();
 
-        if (test && test->getLeft()->getAsSymbolNode()->getId() == index->getId())
+        if (test && test->getLeft()->getAsSymbolNode()->uniqueId() == index->uniqueId())
         {
             TIntermConstantUnion *constant = test->getRight()->getAsConstantUnion();
 
diff --git a/src/compiler/translator/OutputTree.cpp b/src/compiler/translator/OutputTree.cpp
index 67efc0f..4afff03 100644
--- a/src/compiler/translator/OutputTree.cpp
+++ b/src/compiler/translator/OutputTree.cpp
@@ -82,7 +82,7 @@
     OutputTreeText(mOut, node, mDepth);
 
     mOut << "'" << node->getSymbol() << "' ";
-    mOut << "(symbol id " << node->getId() << ") ";
+    mOut << "(symbol id " << node->uniqueId().get() << ") ";
     mOut << "(" << node->getCompleteString() << ")";
     mOut << "\n";
 }
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index b502fe2..c118cee 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1996,11 +1996,8 @@
         }
         else if (initializer->getAsSymbolNode())
         {
-            const TSymbol *symbol =
-                symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0);
-            const TVariable *tVar = static_cast<const TVariable *>(symbol);
-
-            const TConstantUnion *constArray = tVar->getConstPointer();
+            const TVariable &var             = initializer->getAsSymbolNode()->variable();
+            const TConstantUnion *constArray = var.getConstPointer();
             if (constArray)
             {
                 variable->shareConstPointer(constArray);
diff --git a/src/compiler/translator/RemoveUnreferencedVariables.cpp b/src/compiler/translator/RemoveUnreferencedVariables.cpp
index 0f845cd..9b5339e 100644
--- a/src/compiler/translator/RemoveUnreferencedVariables.cpp
+++ b/src/compiler/translator/RemoveUnreferencedVariables.cpp
@@ -92,10 +92,10 @@
 {
     incrementStructTypeRefCount(node->getType());
 
-    auto iter = mSymbolIdRefCounts.find(node->getId());
+    auto iter = mSymbolIdRefCounts.find(node->uniqueId().get());
     if (iter == mSymbolIdRefCounts.end())
     {
-        mSymbolIdRefCounts[node->getId()] = 1u;
+        mSymbolIdRefCounts[node->uniqueId().get()] = 1u;
         return;
     }
     ++(iter->second);
@@ -234,14 +234,14 @@
         TIntermSymbol *symbolNode = declarator->getAsSymbolNode();
         if (symbolNode != nullptr)
         {
-            canRemoveVariable =
-                (*mSymbolIdRefCounts)[symbolNode->getId()] == 1u || symbolNode->getSymbol().empty();
+            canRemoveVariable = (*mSymbolIdRefCounts)[symbolNode->uniqueId().get()] == 1u ||
+                                symbolNode->getSymbol().empty();
         }
         TIntermBinary *initNode = declarator->getAsBinaryNode();
         if (initNode != nullptr)
         {
             ASSERT(initNode->getLeft()->getAsSymbolNode());
-            int symbolId = initNode->getLeft()->getAsSymbolNode()->getId();
+            int symbolId = initNode->getLeft()->getAsSymbolNode()->uniqueId().get();
             canRemoveVariable =
                 (*mSymbolIdRefCounts)[symbolId] == 1u && !initNode->getRight()->hasSideEffects();
         }
@@ -262,8 +262,8 @@
 {
     if (mRemoveReferences)
     {
-        ASSERT(mSymbolIdRefCounts->find(node->getId()) != mSymbolIdRefCounts->end());
-        --(*mSymbolIdRefCounts)[node->getId()];
+        ASSERT(mSymbolIdRefCounts->find(node->uniqueId().get()) != mSymbolIdRefCounts->end());
+        --(*mSymbolIdRefCounts)[node->uniqueId().get()];
 
         decrementStructTypeRefCount(node->getType());
     }
diff --git a/src/compiler/translator/SymbolUniqueId.cpp b/src/compiler/translator/SymbolUniqueId.cpp
index 7f09d22..e5dc15c 100644
--- a/src/compiler/translator/SymbolUniqueId.cpp
+++ b/src/compiler/translator/SymbolUniqueId.cpp
@@ -20,9 +20,17 @@
 {
 }
 
+TSymbolUniqueId::TSymbolUniqueId(const TSymbolUniqueId &) = default;
+TSymbolUniqueId &TSymbolUniqueId::operator=(const TSymbolUniqueId &) = default;
+
 int TSymbolUniqueId::get() const
 {
     return mId;
 }
 
+bool TSymbolUniqueId::operator==(const TSymbolUniqueId &other) const
+{
+    return mId == other.mId;
+}
+
 }  // namespace sh
diff --git a/src/compiler/translator/SymbolUniqueId.h b/src/compiler/translator/SymbolUniqueId.h
index 4bd5604..b00728c 100644
--- a/src/compiler/translator/SymbolUniqueId.h
+++ b/src/compiler/translator/SymbolUniqueId.h
@@ -22,8 +22,9 @@
     POOL_ALLOCATOR_NEW_DELETE();
     explicit TSymbolUniqueId(TSymbolTable *symbolTable);
     explicit TSymbolUniqueId(const TSymbol &symbol);
-    TSymbolUniqueId(const TSymbolUniqueId &) = default;
-    TSymbolUniqueId &operator=(const TSymbolUniqueId &) = default;
+    TSymbolUniqueId(const TSymbolUniqueId &);
+    TSymbolUniqueId &operator=(const TSymbolUniqueId &);
+    bool operator==(const TSymbolUniqueId &) const;
 
     int get() const;
 
diff --git a/src/compiler/translator/ValidateLimitations.cpp b/src/compiler/translator/ValidateLimitations.cpp
index 828f958..e43ff37 100644
--- a/src/compiler/translator/ValidateLimitations.cpp
+++ b/src/compiler/translator/ValidateLimitations.cpp
@@ -25,7 +25,7 @@
     TIntermBinary *declInit  = (*declSeq)[0]->getAsBinaryNode();
     TIntermSymbol *symbol    = declInit->getLeft()->getAsSymbolNode();
 
-    return symbol->getId();
+    return symbol->uniqueId().get();
 }
 
 // Traverses a node to check if it represents a constant index expression.
@@ -55,7 +55,7 @@
         if (mValid)
         {
             bool isLoopSymbol = std::find(mLoopSymbolIds.begin(), mLoopSymbolIds.end(),
-                                          symbol->getId()) != mLoopSymbolIds.end();
+                                          symbol->uniqueId().get()) != mLoopSymbolIds.end();
             mValid = (symbol->getQualifier() == EvqConst) || isLoopSymbol;
         }
     }
@@ -165,7 +165,7 @@
 
 bool ValidateLimitationsTraverser::isLoopIndex(TIntermSymbol *symbol)
 {
-    return std::find(mLoopSymbolIds.begin(), mLoopSymbolIds.end(), symbol->getId()) !=
+    return std::find(mLoopSymbolIds.begin(), mLoopSymbolIds.end(), symbol->uniqueId().get()) !=
            mLoopSymbolIds.end();
 }
 
@@ -252,7 +252,7 @@
         return -1;
     }
 
-    return symbol->getId();
+    return symbol->uniqueId().get();
 }
 
 bool ValidateLimitationsTraverser::validateForLoopCond(TIntermLoop *node, int indexSymbolId)
@@ -280,7 +280,7 @@
         error(binOp->getLine(), "Invalid condition", "for");
         return false;
     }
-    if (symbol->getId() != indexSymbolId)
+    if (symbol->uniqueId().get() != indexSymbolId)
     {
         error(symbol->getLine(), "Expected loop index", symbol->getSymbol().c_str());
         return false;
@@ -351,7 +351,7 @@
         error(expr->getLine(), "Invalid expression", "for");
         return false;
     }
-    if (symbol->getId() != indexSymbolId)
+    if (symbol->uniqueId().get() != indexSymbolId)
     {
         error(symbol->getLine(), "Expected loop index", symbol->getSymbol().c_str());
         return false;