Implement user-defined name hashing.
ANGLEBUG=315
Review URL: https://codereview.appspot.com/6818109
git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1469 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/Compiler.cpp b/src/compiler/Compiler.cpp
index b067fed..ab12ac9 100644
--- a/src/compiler/Compiler.cpp
+++ b/src/compiler/Compiler.cpp
@@ -195,7 +195,8 @@
// Call mapLongVariableNames() before collectAttribsUniforms() so in
// collectAttribsUniforms() we already have the mapped symbol names and
// we could composite mapped and original variable names.
- if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES))
+ // Also, if we hash all the names, then no need to do this for long names.
+ if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES) && hashFunction == NULL)
mapLongVariableNames(root);
if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS)) {
@@ -244,6 +245,8 @@
uniforms.clear();
builtInFunctionEmulator.Cleanup();
+
+ nameMap.clear();
}
bool TCompiler::detectRecursion(TIntermNode* root)
@@ -319,7 +322,7 @@
void TCompiler::collectAttribsUniforms(TIntermNode* root)
{
- CollectAttribsUniforms collect(attribs, uniforms);
+ CollectAttribsUniforms collect(attribs, uniforms, hashFunction);
root->traverse(&collect);
}
diff --git a/src/compiler/Intermediate.cpp b/src/compiler/Intermediate.cpp
index 92c4505..9032b3a 100644
--- a/src/compiler/Intermediate.cpp
+++ b/src/compiler/Intermediate.cpp
@@ -12,6 +12,7 @@
#include <limits.h>
#include <algorithm>
+#include "compiler/HashNames.h"
#include "compiler/localintermediate.h"
#include "compiler/QualifierAlive.h"
#include "compiler/RemoveTree.h"
@@ -1445,3 +1446,14 @@
return addConstantUnion(leftUnionArray, TType(promoteTo, t.getPrecision(), t.getQualifier(), t.getNominalSize(), t.isMatrix(), t.isArray()), node->getLine());
}
+// static
+TString TIntermTraverser::hash(const TString& name, ShHashFunction64 hashFunction)
+{
+ if (hashFunction == NULL || name.empty())
+ return name;
+ khronos_uint64_t number = (*hashFunction)(name.c_str(), name.length());
+ TStringStream stream;
+ stream << HASHED_NAME_PREFIX << std::hex << number;
+ TString hashedName = stream.str();
+ return hashedName;
+}
diff --git a/src/compiler/OutputESSL.cpp b/src/compiler/OutputESSL.cpp
index 64ee92d..0331752 100644
--- a/src/compiler/OutputESSL.cpp
+++ b/src/compiler/OutputESSL.cpp
@@ -6,8 +6,11 @@
#include "compiler/OutputESSL.h"
-TOutputESSL::TOutputESSL(TInfoSinkBase& objSink)
- : TOutputGLSLBase(objSink)
+TOutputESSL::TOutputESSL(TInfoSinkBase& objSink,
+ ShHashFunction64 hashFunction,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable)
+ : TOutputGLSLBase(objSink, hashFunction, nameMap, symbolTable)
{
}
diff --git a/src/compiler/OutputESSL.h b/src/compiler/OutputESSL.h
index 4fa73c8..dd8c5ab 100644
--- a/src/compiler/OutputESSL.h
+++ b/src/compiler/OutputESSL.h
@@ -12,7 +12,10 @@
class TOutputESSL : public TOutputGLSLBase
{
public:
- TOutputESSL(TInfoSinkBase& objSink);
+ TOutputESSL(TInfoSinkBase& objSink,
+ ShHashFunction64 hashFunction,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable);
protected:
virtual bool writeVariablePrecision(TPrecision precision);
diff --git a/src/compiler/OutputGLSL.cpp b/src/compiler/OutputGLSL.cpp
index dd31b4b..5873042 100644
--- a/src/compiler/OutputGLSL.cpp
+++ b/src/compiler/OutputGLSL.cpp
@@ -6,8 +6,11 @@
#include "compiler/OutputGLSL.h"
-TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink)
- : TOutputGLSLBase(objSink)
+TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink,
+ ShHashFunction64 hashFunction,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable)
+ : TOutputGLSLBase(objSink, hashFunction, nameMap, symbolTable)
{
}
diff --git a/src/compiler/OutputGLSL.h b/src/compiler/OutputGLSL.h
index 0fe2356..9030212 100644
--- a/src/compiler/OutputGLSL.h
+++ b/src/compiler/OutputGLSL.h
@@ -12,7 +12,10 @@
class TOutputGLSL : public TOutputGLSLBase
{
public:
- TOutputGLSL(TInfoSinkBase& objSink);
+ TOutputGLSL(TInfoSinkBase& objSink,
+ ShHashFunction64 hashFunction,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable);
protected:
virtual bool writeVariablePrecision(TPrecision);
diff --git a/src/compiler/OutputGLSLBase.cpp b/src/compiler/OutputGLSLBase.cpp
index 552fa50..ed86c68 100644
--- a/src/compiler/OutputGLSLBase.cpp
+++ b/src/compiler/OutputGLSLBase.cpp
@@ -9,35 +9,6 @@
namespace
{
-TString getTypeName(const TType& type)
-{
- TInfoSinkBase out;
- if (type.isMatrix())
- {
- out << "mat";
- out << type.getNominalSize();
- }
- else if (type.isVector())
- {
- switch (type.getBasicType())
- {
- case EbtFloat: out << "vec"; break;
- case EbtInt: out << "ivec"; break;
- case EbtBool: out << "bvec"; break;
- default: UNREACHABLE(); break;
- }
- out << type.getNominalSize();
- }
- else
- {
- if (type.getBasicType() == EbtStruct)
- out << type.getTypeName();
- else
- out << type.getBasicString();
- }
- return TString(out.c_str());
-}
-
TString arrayBrackets(const TType& type)
{
ASSERT(type.isArray());
@@ -66,10 +37,16 @@
}
} // namespace
-TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink)
+TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink,
+ ShHashFunction64 hashFunction,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable)
: TIntermTraverser(true, true, true),
mObjSink(objSink),
- mDeclaringVariables(false)
+ mDeclaringVariables(false),
+ mHashFunction(hashFunction),
+ mNameMap(nameMap),
+ mSymbolTable(symbolTable)
{
}
@@ -101,7 +78,7 @@
if ((type.getBasicType() == EbtStruct) &&
(mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end()))
{
- out << "struct " << type.getTypeName() << "{\n";
+ out << "struct " << hashName(type.getTypeName()) << "{\n";
const TTypeList* structure = type.getStruct();
ASSERT(structure != NULL);
for (size_t i = 0; i < structure->size(); ++i)
@@ -110,7 +87,7 @@
ASSERT(fieldType != NULL);
if (writeVariablePrecision(fieldType->getPrecision()))
out << " ";
- out << getTypeName(*fieldType) << " " << fieldType->getFieldName();
+ out << getTypeName(*fieldType) << " " << hashName(fieldType->getFieldName());
if (fieldType->isArray())
out << arrayBrackets(*fieldType);
out << ";\n";
@@ -140,7 +117,7 @@
const TString& name = arg->getSymbol();
if (!name.empty())
- out << " " << name;
+ out << " " << hashName(name);
if (type.isArray())
out << arrayBrackets(type);
@@ -157,7 +134,7 @@
if (type.getBasicType() == EbtStruct)
{
- out << type.getTypeName() << "(";
+ out << hashName(type.getTypeName()) << "(";
const TTypeList* structure = type.getStruct();
ASSERT(structure != NULL);
for (size_t i = 0; i < structure->size(); ++i)
@@ -196,7 +173,7 @@
if (mLoopUnroll.NeedsToReplaceSymbolWithValue(node))
out << mLoopUnroll.GetLoopIndexValue(node);
else
- out << node->getSymbol();
+ out << hashVariableName(node->getSymbol());
if (mDeclaringVariables && node->getType().isArray())
out << arrayBrackets(node->getType());
@@ -243,7 +220,7 @@
{
out << ".";
// TODO(alokp): ASSERT
- out << node->getType().getFieldName();
+ out << hashName(node->getType().getFieldName());
visitChildren = false;
}
break;
@@ -467,7 +444,7 @@
// Function declaration.
ASSERT(visit == PreVisit);
writeVariableType(node->getType());
- out << " " << node->getName();
+ out << " " << hashName(node->getName());
out << "(";
writeFunctionParameters(node->getSequence());
@@ -480,7 +457,7 @@
// Function definition.
ASSERT(visit == PreVisit);
writeVariableType(node->getType());
- out << " " << TFunction::unmangleName(node->getName());
+ out << " " << hashFunctionName(node->getName());
incrementDepth();
// Function definition node contains one or two children nodes
@@ -510,8 +487,7 @@
// Function call.
if (visit == PreVisit)
{
- TString functionName = TFunction::unmangleName(node->getName());
- out << functionName << "(";
+ out << hashFunctionName(node->getName()) << "(";
}
else if (visit == InVisit)
{
@@ -572,7 +548,7 @@
{
const TType& type = node->getType();
ASSERT(type.getBasicType() == EbtStruct);
- out << type.getTypeName() << "(";
+ out << hashName(type.getTypeName()) << "(";
}
else if (visit == InVisit)
{
@@ -718,3 +694,59 @@
out << "{\n}\n"; // Empty code block.
}
}
+
+TString TOutputGLSLBase::getTypeName(const TType& type)
+{
+ TInfoSinkBase out;
+ if (type.isMatrix())
+ {
+ out << "mat";
+ out << type.getNominalSize();
+ }
+ else if (type.isVector())
+ {
+ switch (type.getBasicType())
+ {
+ case EbtFloat: out << "vec"; break;
+ case EbtInt: out << "ivec"; break;
+ case EbtBool: out << "bvec"; break;
+ default: UNREACHABLE(); break;
+ }
+ out << type.getNominalSize();
+ }
+ else
+ {
+ if (type.getBasicType() == EbtStruct)
+ out << hashName(type.getTypeName());
+ else
+ out << type.getBasicString();
+ }
+ return TString(out.c_str());
+}
+
+TString TOutputGLSLBase::hashName(const TString& name)
+{
+ if (mHashFunction == NULL || name.empty())
+ return name;
+ NameMap::const_iterator it = mNameMap.find(name.c_str());
+ if (it != mNameMap.end())
+ return it->second.c_str();
+ TString hashedName = TIntermTraverser::hash(name, mHashFunction);
+ mNameMap[name.c_str()] = hashedName.c_str();
+ return hashedName;
+}
+
+TString TOutputGLSLBase::hashVariableName(const TString& name)
+{
+ if (mSymbolTable.findBuiltIn(name) != NULL)
+ return name;
+ return hashName(name);
+}
+
+TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name)
+{
+ TString name = TFunction::unmangleName(mangled_name);
+ if (mSymbolTable.findBuiltIn(mangled_name) != NULL || name == "main")
+ return name;
+ return hashName(name);
+}
diff --git a/src/compiler/OutputGLSLBase.h b/src/compiler/OutputGLSLBase.h
index efd0b5f..01e9d4a 100644
--- a/src/compiler/OutputGLSLBase.h
+++ b/src/compiler/OutputGLSLBase.h
@@ -16,7 +16,10 @@
class TOutputGLSLBase : public TIntermTraverser
{
public:
- TOutputGLSLBase(TInfoSinkBase& objSink);
+ TOutputGLSLBase(TInfoSinkBase& objSink,
+ ShHashFunction64 hashFunction,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable);
protected:
TInfoSinkBase& objSink() { return mObjSink; }
@@ -25,6 +28,7 @@
virtual bool writeVariablePrecision(TPrecision precision) = 0;
void writeFunctionParameters(const TIntermSequence& args);
const ConstantUnion* writeConstantUnion(const TType& type, const ConstantUnion* pConstUnion);
+ TString getTypeName(const TType& type);
virtual void visitSymbol(TIntermSymbol* node);
virtual void visitConstantUnion(TIntermConstantUnion* node);
@@ -37,6 +41,15 @@
void visitCodeBlock(TIntermNode* node);
+
+ // Return the original name if hash function pointer is NULL;
+ // otherwise return the hashed name.
+ TString hashName(const TString& name);
+ // Same as hashName(), but without hashing built-in variables.
+ TString hashVariableName(const TString& name);
+ // Same as hashName(), but without hashing built-in functions.
+ TString hashFunctionName(const TString& mangled_name);
+
private:
TInfoSinkBase& mObjSink;
bool mDeclaringVariables;
@@ -48,6 +61,12 @@
DeclaredStructs mDeclaredStructs;
ForLoopUnroll mLoopUnroll;
+
+ // name hashing.
+ ShHashFunction64 mHashFunction;
+ NameMap& mNameMap;
+
+ TSymbolTable& mSymbolTable;
};
#endif // CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
diff --git a/src/compiler/ShHandle.h b/src/compiler/ShHandle.h
index 0c77bb0..23f0cf3 100644
--- a/src/compiler/ShHandle.h
+++ b/src/compiler/ShHandle.h
@@ -70,7 +70,8 @@
int getMappedNameMaxLength() const;
ShHashFunction64 getHashFunction() const { return hashFunction; }
- const NameMap& getNameMap() const { return nameMap; }
+ NameMap& getNameMap() { return nameMap; }
+ TSymbolTable& getSymbolTable() { return symbolTable; }
protected:
ShShaderType getShaderType() const { return shaderType; }
diff --git a/src/compiler/TranslatorESSL.cpp b/src/compiler/TranslatorESSL.cpp
index e3a2c2a..f718f1e 100644
--- a/src/compiler/TranslatorESSL.cpp
+++ b/src/compiler/TranslatorESSL.cpp
@@ -23,7 +23,7 @@
sink, getShaderType() == SH_FRAGMENT_SHADER);
// Write translated shader.
- TOutputESSL outputESSL(sink);
+ TOutputESSL outputESSL(sink, getHashFunction(), getNameMap(), getSymbolTable());
root->traverse(&outputESSL);
}
diff --git a/src/compiler/TranslatorGLSL.cpp b/src/compiler/TranslatorGLSL.cpp
index bb07a1e..1e3ff38 100644
--- a/src/compiler/TranslatorGLSL.cpp
+++ b/src/compiler/TranslatorGLSL.cpp
@@ -36,6 +36,6 @@
sink, false);
// Write translated shader.
- TOutputGLSL outputGLSL(sink);
+ TOutputGLSL outputGLSL(sink, getHashFunction(), getNameMap(), getSymbolTable());
root->traverse(&outputGLSL);
}
diff --git a/src/compiler/VariableInfo.cpp b/src/compiler/VariableInfo.cpp
index 3ff2836..eb6bea9 100644
--- a/src/compiler/VariableInfo.cpp
+++ b/src/compiler/VariableInfo.cpp
@@ -77,23 +77,25 @@
static void getUserDefinedVariableInfo(const TType& type,
const TString& name,
const TString& mappedName,
- TVariableInfoList& infoList);
+ TVariableInfoList& infoList,
+ ShHashFunction64 hashFunction);
// Returns info for an attribute or uniform.
static void getVariableInfo(const TType& type,
const TString& name,
const TString& mappedName,
- TVariableInfoList& infoList)
+ TVariableInfoList& infoList,
+ ShHashFunction64 hashFunction)
{
if (type.getBasicType() == EbtStruct) {
if (type.isArray()) {
for (int i = 0; i < type.getArraySize(); ++i) {
TString lname = name + arrayBrackets(i);
TString lmappedName = mappedName + arrayBrackets(i);
- getUserDefinedVariableInfo(type, lname, lmappedName, infoList);
+ getUserDefinedVariableInfo(type, lname, lmappedName, infoList, hashFunction);
}
} else {
- getUserDefinedVariableInfo(type, name, mappedName, infoList);
+ getUserDefinedVariableInfo(type, name, mappedName, infoList, hashFunction);
}
} else {
getBuiltInVariableInfo(type, name, mappedName, infoList);
@@ -124,7 +126,8 @@
void getUserDefinedVariableInfo(const TType& type,
const TString& name,
const TString& mappedName,
- TVariableInfoList& infoList)
+ TVariableInfoList& infoList,
+ ShHashFunction64 hashFunction)
{
ASSERT(type.getBasicType() == EbtStruct);
@@ -133,8 +136,9 @@
const TType* fieldType = (*structure)[i].type;
getVariableInfo(*fieldType,
name + "." + fieldType->getFieldName(),
- mappedName + "." + fieldType->getFieldName(),
- infoList);
+ mappedName + "." + TIntermTraverser::hash(fieldType->getFieldName(), hashFunction),
+ infoList,
+ hashFunction);
}
}
@@ -149,9 +153,11 @@
}
CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
- TVariableInfoList& uniforms)
+ TVariableInfoList& uniforms,
+ ShHashFunction64 hashFunction)
: mAttribs(attribs),
- mUniforms(uniforms)
+ mUniforms(uniforms),
+ mHashFunction(hashFunction)
{
}
@@ -206,10 +212,16 @@
// cannot be initialized in a shader, we must have only
// TIntermSymbol nodes in the sequence.
ASSERT(variable != NULL);
+ TString processedSymbol;
+ if (mHashFunction == NULL)
+ processedSymbol = variable->getSymbol();
+ else
+ processedSymbol = TIntermTraverser::hash(variable->getOriginalSymbol(), mHashFunction);
getVariableInfo(variable->getType(),
variable->getOriginalSymbol(),
- variable->getSymbol(),
- infoList);
+ processedSymbol,
+ infoList,
+ mHashFunction);
}
}
break;
diff --git a/src/compiler/VariableInfo.h b/src/compiler/VariableInfo.h
index fdcc08f..4130a58 100644
--- a/src/compiler/VariableInfo.h
+++ b/src/compiler/VariableInfo.h
@@ -27,7 +27,8 @@
class CollectAttribsUniforms : public TIntermTraverser {
public:
CollectAttribsUniforms(TVariableInfoList& attribs,
- TVariableInfoList& uniforms);
+ TVariableInfoList& uniforms,
+ ShHashFunction64 hashFunction);
virtual void visitSymbol(TIntermSymbol*);
virtual void visitConstantUnion(TIntermConstantUnion*);
@@ -41,6 +42,8 @@
private:
TVariableInfoList& mAttribs;
TVariableInfoList& mUniforms;
+
+ ShHashFunction64 mHashFunction;
};
#endif // COMPILER_VARIABLE_INFO_H_
diff --git a/src/compiler/intermediate.h b/src/compiler/intermediate.h
index af78fa0..293db94 100644
--- a/src/compiler/intermediate.h
+++ b/src/compiler/intermediate.h
@@ -16,6 +16,8 @@
#ifndef __INTERMEDIATE_H
#define __INTERMEDIATE_H
+#include "GLSLANG/ShaderLang.h"
+
#include "compiler/Common.h"
#include "compiler/Types.h"
#include "compiler/ConstantUnion.h"
@@ -545,6 +547,10 @@
void incrementDepth() {depth++;}
void decrementDepth() {depth--;}
+ // Return the original name if hash function pointer is NULL;
+ // otherwise return the hashed name.
+ static TString hash(const TString& name, ShHashFunction64 hashFunction);
+
const bool preVisit;
const bool inVisit;
const bool postVisit;