Commit e600c0aa by Olli Etuaho Committed by Commit Bot

Use non-human-readable mangled names for types

The new mangled name format is as follows: The first character is a hex digit from 0 to F that encodes vector or matrix size. For scalars, structs etc. the character is 0. Then, if it's a struct, the mangled name continues with "{s", followed by mangled names of fields, and ends with "}". If it's an interface block, the mangled name continues with "{i", followed by mangled names of fields, and ends with "}". If it's anything else, the second alphabetic character encodes the basic type. Characters are assigned to basic types in the enumeration order. If it's an array, the mangled name has a suffix [array_size]. This saves a few kilobytes from the binary size. The effect on symbol lookup speed seems mostly marginal. BUG=angleproject:2267 TEST=angle_unittests Change-Id: I26e65dcb48c3478df9a719ffff9c15f2fd12e293 Reviewed-on: https://chromium-review.googlesource.com/945910 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 64e5ed2a
...@@ -57,10 +57,12 @@ enum TBasicType ...@@ -57,10 +57,12 @@ enum TBasicType
EbtInt, EbtInt,
EbtUInt, EbtUInt,
EbtBool, EbtBool,
EbtAtomicCounter,
EbtYuvCscStandardEXT, // Only valid if EXT_YUV_target exists. EbtYuvCscStandardEXT, // Only valid if EXT_YUV_target exists.
EbtGuardSamplerBegin, // non type: see implementation of IsSampler() EbtGuardSamplerBegin, // non type: see implementation of IsSampler()
EbtSampler2D, EbtSampler2D = EbtGuardSamplerBegin,
EbtSampler3D, EbtSampler3D,
EbtSamplerCube, EbtSamplerCube,
EbtSampler2DArray, EbtSampler2DArray,
...@@ -81,11 +83,11 @@ enum TBasicType ...@@ -81,11 +83,11 @@ enum TBasicType
EbtSampler2DShadow, EbtSampler2DShadow,
EbtSamplerCubeShadow, EbtSamplerCubeShadow,
EbtSampler2DArrayShadow, EbtSampler2DArrayShadow,
EbtGuardSamplerEnd, // non type: see implementation of IsSampler() EbtGuardSamplerEnd = EbtSampler2DArrayShadow, // non type: see implementation of IsSampler()
// images // images
EbtGuardImageBegin, EbtGuardImageBegin,
EbtImage2D, EbtImage2D = EbtGuardImageBegin,
EbtIImage2D, EbtIImage2D,
EbtUImage2D, EbtUImage2D,
EbtImage3D, EbtImage3D,
...@@ -97,119 +99,41 @@ enum TBasicType ...@@ -97,119 +99,41 @@ enum TBasicType
EbtImageCube, EbtImageCube,
EbtIImageCube, EbtIImageCube,
EbtUImageCube, EbtUImageCube,
EbtGuardImageEnd, EbtGuardImageEnd = EbtUImageCube,
EbtLastSimpleType = EbtGuardImageEnd,
EbtStruct, EbtStruct,
EbtInterfaceBlock, EbtInterfaceBlock,
EbtAddress, // should be deprecated??
EbtAtomicCounter,
// end of list // end of list
EbtLast EbtLast = EbtInterfaceBlock
}; };
constexpr const char *GetBasicMangledName(TBasicType t) constexpr char GetBasicMangledName(TBasicType t)
{ {
switch (t) if (t > EbtLastSimpleType)
{ {
case EbtFloat: return '{';
return "f"; }
case EbtInt: static_assert(EbtLastSimpleType < 52, "We only use alphabetic characters for mangled names");
return "i"; if (t < 26)
case EbtUInt: {
return "u"; return static_cast<char>('A' + t);
case EbtBool:
return "b";
case EbtYuvCscStandardEXT:
return "y";
case EbtSampler2D:
return "s2";
case EbtSampler3D:
return "s3";
case EbtSamplerCube:
return "sC";
case EbtSampler2DArray:
return "sA";
case EbtSamplerExternalOES:
return "sX";
case EbtSamplerExternal2DY2YEXT:
return "sY";
case EbtSampler2DRect:
return "sR";
case EbtSampler2DMS:
return "sM";
case EbtISampler2D:
return "is2";
case EbtISampler3D:
return "is3";
case EbtISamplerCube:
return "isC";
case EbtISampler2DArray:
return "isA";
case EbtISampler2DMS:
return "isM";
case EbtUSampler2D:
return "us2";
case EbtUSampler3D:
return "us3";
case EbtUSamplerCube:
return "usC";
case EbtUSampler2DArray:
return "usA";
case EbtUSampler2DMS:
return "usM";
case EbtSampler2DShadow:
return "s2s";
case EbtSamplerCubeShadow:
return "sCs";
case EbtSampler2DArrayShadow:
return "sAs";
case EbtImage2D:
return "I2";
case EbtIImage2D:
return "iI2";
case EbtUImage2D:
return "uI2";
case EbtImage3D:
return "I3";
case EbtIImage3D:
return "iI3";
case EbtUImage3D:
return "uI3";
case EbtImage2DArray:
return "IA";
case EbtIImage2DArray:
return "iIA";
case EbtUImage2DArray:
return "uIA";
case EbtImageCube:
return "Ic";
case EbtIImageCube:
return "iIc";
case EbtUImageCube:
return "uIc";
case EbtAtomicCounter:
return "a";
case EbtStruct:
case EbtInterfaceBlock:
return nullptr;
default:
// EbtVoid, EbtAddress and non types
return "";
} }
return static_cast<char>('a' - 26 + t);
} }
const char *getBasicString(TBasicType t); const char *getBasicString(TBasicType t);
inline bool IsSampler(TBasicType type) inline bool IsSampler(TBasicType type)
{ {
return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd; return type >= EbtGuardSamplerBegin && type <= EbtGuardSamplerEnd;
} }
inline bool IsImage(TBasicType type) inline bool IsImage(TBasicType type)
{ {
return type > EbtGuardImageBegin && type < EbtGuardImageEnd; return type >= EbtGuardImageBegin && type <= EbtGuardImageEnd;
} }
inline bool IsAtomicCounter(TBasicType type) inline bool IsAtomicCounter(TBasicType type)
......
...@@ -25,16 +25,16 @@ namespace Helpers ...@@ -25,16 +25,16 @@ namespace Helpers
// Generation and static allocation of type mangled name values. // Generation and static allocation of type mangled name values.
// //
// Size of the maximum possible constexpr-generated mangled name. // Size of the constexpr-generated mangled name.
// If this value is too small, the compiler will produce errors. // If this value is too small, the compiler will produce errors.
static constexpr size_t kStaticMangledNameMaxLength = 5; static constexpr size_t kStaticMangledNameLength = 2;
// Type which holds the mangled names for constexpr-generated TTypes. // Type which holds the mangled names for constexpr-generated TTypes.
// This simple struct is needed so that a char array can be returned by value. // This simple struct is needed so that a char array can be returned by value.
struct StaticMangledName struct StaticMangledName
{ {
// If this array is too small, the compiler will produce errors. // If this array is too small, the compiler will produce errors.
char name[kStaticMangledNameMaxLength + 1] = {}; char name[kStaticMangledNameLength + 1] = {};
}; };
// Generates a mangled name for a TType given its parameters. // Generates a mangled name for a TType given its parameters.
...@@ -45,31 +45,9 @@ constexpr StaticMangledName BuildStaticMangledName(TBasicType basicType, ...@@ -45,31 +45,9 @@ constexpr StaticMangledName BuildStaticMangledName(TBasicType basicType,
unsigned char secondarySize) unsigned char secondarySize)
{ {
StaticMangledName name = {}; StaticMangledName name = {};
// When this function is executed constexpr (should be always), name.name[0] = TType::GetSizeMangledName(primarySize, secondarySize);
// name.name[at] is guaranteed by the compiler to never go out of bounds. name.name[1] = GetBasicMangledName(basicType);
size_t at = 0; name.name[2] = '\0';
bool isMatrix = primarySize > 1 && secondarySize > 1;
if (primarySize > 1)
{
name.name[at++] = '0' + primarySize;
}
if (isMatrix)
{
name.name[at++] = '0' + secondarySize;
}
{
const char *basicMangledName = GetBasicMangledName(basicType);
for (size_t i = 0; basicMangledName[i] != '\0'; ++i)
{
name.name[at++] = basicMangledName[i];
}
}
name.name[at++] = ';';
name.name[at] = '\0';
return name; return name;
} }
......
...@@ -375,7 +375,7 @@ void TSymbolTable::initializeBuiltIns(sh::GLenum type, ...@@ -375,7 +375,7 @@ void TSymbolTable::initializeBuiltIns(sh::GLenum type,
void TSymbolTable::initSamplerDefaultPrecision(TBasicType samplerType) void TSymbolTable::initSamplerDefaultPrecision(TBasicType samplerType)
{ {
ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd); ASSERT(samplerType >= EbtGuardSamplerBegin && samplerType <= EbtGuardSamplerEnd);
setDefaultPrecision(samplerType, EbpLow); setDefaultPrecision(samplerType, EbpLow);
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -479,20 +479,10 @@ bool TType::canReplaceWithConstantUnion() const ...@@ -479,20 +479,10 @@ bool TType::canReplaceWithConstantUnion() const
// //
const char *TType::buildMangledName() const const char *TType::buildMangledName() const
{ {
TString mangledName; TString mangledName(1, GetSizeMangledName(primarySize, secondarySize));
if (isMatrix())
{
mangledName += static_cast<char>('0' + getCols());
mangledName += static_cast<char>('0' + getRows());
}
else if (getNominalSize() > 1)
{
mangledName += static_cast<char>('0' + getNominalSize());
}
const char *basicMangledName = GetBasicMangledName(type); char basicMangledName = GetBasicMangledName(type);
if (basicMangledName != nullptr) if (basicMangledName != '{')
{ {
mangledName += basicMangledName; mangledName += basicMangledName;
} }
...@@ -502,17 +492,19 @@ const char *TType::buildMangledName() const ...@@ -502,17 +492,19 @@ const char *TType::buildMangledName() const
switch (type) switch (type)
{ {
case EbtStruct: case EbtStruct:
mangledName += "struct-"; mangledName += "{s";
if (mStructure->symbolType() != SymbolType::Empty) if (mStructure->symbolType() != SymbolType::Empty)
{ {
mangledName += mStructure->name().data(); mangledName += mStructure->name().data();
} }
mangledName += mStructure->mangledFieldList(); mangledName += mStructure->mangledFieldList();
mangledName += '}';
break; break;
case EbtInterfaceBlock: case EbtInterfaceBlock:
mangledName += "iblock-"; mangledName += "{i";
mangledName += mInterfaceBlock->name().data(); mangledName += mInterfaceBlock->name().data();
mangledName += mInterfaceBlock->mangledFieldList(); mangledName += mInterfaceBlock->mangledFieldList();
mangledName += '}';
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -532,8 +524,6 @@ const char *TType::buildMangledName() const ...@@ -532,8 +524,6 @@ const char *TType::buildMangledName() const
} }
} }
mangledName += ';';
// Copy string contents into a pool-allocated buffer, so we never need to call delete. // Copy string contents into a pool-allocated buffer, so we never need to call delete.
return AllocatePoolCharArray(mangledName.c_str(), mangledName.size()); return AllocatePoolCharArray(mangledName.c_str(), mangledName.size());
} }
...@@ -874,7 +864,6 @@ TString TFieldListCollection::buildMangledFieldList() const ...@@ -874,7 +864,6 @@ TString TFieldListCollection::buildMangledFieldList() const
TString mangledName; TString mangledName;
for (const auto *field : *mFields) for (const auto *field : *mFields)
{ {
mangledName += '-';
mangledName += field->type()->getMangledName(); mangledName += field->type()->getMangledName();
} }
return mangledName; return mangledName;
......
...@@ -229,6 +229,15 @@ class TType ...@@ -229,6 +229,15 @@ class TType
const TStructure *getStruct() const { return mStructure; } const TStructure *getStruct() const { return mStructure; }
static constexpr char GetSizeMangledName(unsigned char primarySize, unsigned char secondarySize)
{
unsigned int sizeKey = (secondarySize - 1u) * 4u + primarySize - 1u;
if (sizeKey < 10u)
{
return static_cast<char>('0' + sizeKey);
}
return static_cast<char>('A' + sizeKey - 10);
}
const char *getMangledName() const; const char *getMangledName() const;
bool sameNonArrayType(const TType &right) const; bool sameNonArrayType(const TType &right) const;
......
...@@ -188,47 +188,54 @@ parsed_variables = None ...@@ -188,47 +188,54 @@ parsed_variables = None
variables_json_filename = 'builtin_variables.json' variables_json_filename = 'builtin_variables.json'
functions_txt_filename = 'builtin_function_declarations.txt' functions_txt_filename = 'builtin_function_declarations.txt'
basic_mangled_names = { basic_types_enumeration = [
'Float': 'f', 'Void',
'Int': 'i', 'Float',
'UInt': 'u', 'Int',
'Bool': 'b', 'UInt',
'YuvCscStandardEXT': 'y', 'Bool',
'Sampler2D': 's2', 'AtomicCounter',
'Sampler3D': 's3', 'YuvCscStandardEXT',
'SamplerCube': 'sC', 'Sampler2D',
'Sampler2DArray': 'sA', 'Sampler3D',
'SamplerExternalOES': 'sX', 'SamplerCube',
'SamplerExternal2DY2YEXT': 'sY', 'Sampler2DArray',
'Sampler2DRect': 'sR', 'SamplerExternalOES',
'Sampler2DMS': 'sM', 'SamplerExternal2DY2YEXT',
'ISampler2D': 'is2', 'Sampler2DRect',
'ISampler3D': 'is3', 'Sampler2DMS',
'ISamplerCube': 'isC', 'ISampler2D',
'ISampler2DArray': 'isA', 'ISampler3D',
'ISampler2DMS': 'isM', 'ISamplerCube',
'USampler2D': 'us2', 'ISampler2DArray',
'USampler3D': 'us3', 'ISampler2DMS',
'USamplerCube': 'usC', 'USampler2D',
'USampler2DArray': 'usA', 'USampler3D',
'USampler2DMS': 'usM', 'USamplerCube',
'Sampler2DShadow': 's2s', 'USampler2DArray',
'SamplerCubeShadow': 'sCs', 'USampler2DMS',
'Sampler2DArrayShadow': 'sAs', 'Sampler2DShadow',
'Image2D': 'I2', 'SamplerCubeShadow',
'IImage2D': 'iI2', 'Sampler2DArrayShadow',
'UImage2D': 'uI2', 'Image2D',
'Image3D': 'I3', 'IImage2D',
'IImage3D': 'iI3', 'UImage2D',
'UImage3D': 'uI3', 'Image3D',
'Image2DArray': 'IA', 'IImage3D',
'IImage2DArray': 'iIA', 'UImage3D',
'UImage2DArray': 'uIA', 'Image2DArray',
'ImageCube': 'Ic', 'IImage2DArray',
'IImageCube': 'iIc', 'UImage2DArray',
'UImageCube': 'uIc', 'ImageCube',
'AtomicCounter': 'a' 'IImageCube',
} 'UImageCube'
]
def get_basic_mangled_name(basic):
index = basic_types_enumeration.index(basic)
if index < 26:
return chr(ord('A') + index)
return chr(ord('a') + index - 26)
levels = ['ESSL3_1_BUILTINS', 'ESSL3_BUILTINS', 'ESSL1_BUILTINS', 'COMMON_BUILTINS'] levels = ['ESSL3_1_BUILTINS', 'ESSL3_BUILTINS', 'ESSL1_BUILTINS', 'COMMON_BUILTINS']
...@@ -293,18 +300,16 @@ class TType: ...@@ -293,18 +300,16 @@ class TType:
template_type = 'new TType(Ebt{basic}, Ebp{precision}, Evq{qualifier}, {primarySize}, {secondarySize})' template_type = 'new TType(Ebt{basic}, Ebp{precision}, Evq{qualifier}, {primarySize}, {secondarySize})'
return template_type.format(**self.data) return template_type.format(**self.data)
def get_mangled_name(self, separator = ';'): def get_mangled_name(self):
mangled_name = '' mangled_name = ''
if self.is_matrix(): size_key = (self.data['secondarySize'] - 1) * 4 + self.data['primarySize'] - 1
mangled_name += str(self.data['primarySize']) if size_key < 10:
mangled_name += str(self.data['secondarySize']) mangled_name += chr(ord('0') + size_key)
elif self.data['primarySize'] > 1: else:
mangled_name += str(self.data['primarySize']) mangled_name += chr(ord('A') + size_key - 10)
mangled_name += basic_mangled_names[self.data['basic']]
mangled_name += separator mangled_name += get_basic_mangled_name(self.data['basic'])
return mangled_name return mangled_name
def is_vector(self): def is_vector(self):
...@@ -589,20 +594,20 @@ def get_function_mangled_name(function_name, parameters): ...@@ -589,20 +594,20 @@ def get_function_mangled_name(function_name, parameters):
def get_unique_identifier_name(function_name, parameters): def get_unique_identifier_name(function_name, parameters):
unique_name = function_name + '_' unique_name = function_name + '_'
for param in parameters: for param in parameters:
unique_name += param.get_mangled_name('_') unique_name += param.get_mangled_name()
return unique_name return unique_name
def get_variable_name_to_store_parameters(parameters): def get_variable_name_to_store_parameters(parameters):
if len(parameters) == 0: if len(parameters) == 0:
return 'empty' return 'empty'
unique_name = 'p_' unique_name = 'p'
for param in parameters: for param in parameters:
if 'qualifier' in param.data: if 'qualifier' in param.data:
if param.data['qualifier'] == 'Out': if param.data['qualifier'] == 'Out':
unique_name += 'o_' unique_name += '_o_'
if param.data['qualifier'] == 'InOut': if param.data['qualifier'] == 'InOut':
unique_name += 'io_' unique_name += '_io_'
unique_name += param.get_mangled_name('_') unique_name += param.get_mangled_name()
return unique_name return unique_name
def gen_function_variants(function_name, function_props): def gen_function_variants(function_name, function_props):
......
...@@ -7,11 +7,12 @@ ...@@ -7,11 +7,12 @@
// Tests for images // Tests for images
// //
#include "GLSLANG/ShaderLang.h"
#include "angle_gl.h" #include "angle_gl.h"
#include "compiler/translator/StaticType.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "GLSLANG/ShaderLang.h"
#include "tests/test_utils/compiler_test.h"
#include "tests/test_utils/ShaderCompileTreeTest.h" #include "tests/test_utils/ShaderCompileTreeTest.h"
#include "tests/test_utils/compiler_test.h"
using namespace sh; using namespace sh;
...@@ -188,10 +189,16 @@ TEST_F(ShaderImageTest, ImageLoad) ...@@ -188,10 +189,16 @@ TEST_F(ShaderImageTest, ImageLoad)
} }
// imageLoad call with image2D passed // imageLoad call with image2D passed
CheckImageLoadCall(mASTRoot, "imageLoad(I2;2i;", EbtImage2D, 2); std::string mangledName2D = "imageLoad(";
mangledName2D += StaticType::GetBasic<EbtImage2D>()->getMangledName();
mangledName2D += StaticType::GetBasic<EbtInt, 2>()->getMangledName();
CheckImageLoadCall(mASTRoot, mangledName2D.c_str(), EbtImage2D, 2);
// imageLoad call with image3D passed // imageLoad call with image3D passed
CheckImageLoadCall(mASTRoot, "imageLoad(iI3;3i;", EbtIImage3D, 3); std::string mangledName3D = "imageLoad(";
mangledName3D += StaticType::GetBasic<EbtIImage3D>()->getMangledName();
mangledName3D += StaticType::GetBasic<EbtInt, 3>()->getMangledName();
CheckImageLoadCall(mASTRoot, mangledName3D.c_str(), EbtIImage3D, 3);
} }
// Check that imageStore calls get correctly parsed. // Check that imageStore calls get correctly parsed.
...@@ -212,10 +219,18 @@ TEST_F(ShaderImageTest, ImageStore) ...@@ -212,10 +219,18 @@ TEST_F(ShaderImageTest, ImageStore)
} }
// imageStore call with image2D // imageStore call with image2D
CheckImageStoreCall(mASTRoot, "imageStore(I2;2i;4f;", EbtImage2D, 2, EbtFloat, 4); std::string mangledName2D = "imageStore(";
mangledName2D += StaticType::GetBasic<EbtImage2D>()->getMangledName();
mangledName2D += StaticType::GetBasic<EbtInt, 2>()->getMangledName();
mangledName2D += StaticType::GetBasic<EbtFloat, 4>()->getMangledName();
CheckImageStoreCall(mASTRoot, mangledName2D.c_str(), EbtImage2D, 2, EbtFloat, 4);
// imageStore call with image2DArray // imageStore call with image2DArray
CheckImageStoreCall(mASTRoot, "imageStore(uIA;3i;4u;", EbtUImage2DArray, 3, EbtUInt, 4); std::string mangledName2DArray = "imageStore(";
mangledName2DArray += StaticType::GetBasic<EbtUImage2DArray>()->getMangledName();
mangledName2DArray += StaticType::GetBasic<EbtInt, 3>()->getMangledName();
mangledName2DArray += StaticType::GetBasic<EbtUInt, 4>()->getMangledName();
CheckImageStoreCall(mASTRoot, mangledName2DArray.c_str(), EbtUImage2DArray, 3, EbtUInt, 4);
} }
// Check that memory qualifiers are correctly parsed. // Check that memory qualifiers are correctly parsed.
......
...@@ -43,15 +43,15 @@ TEST(Type, VectorAndMatrixMangledNameConsistent) ...@@ -43,15 +43,15 @@ TEST(Type, VectorAndMatrixMangledNameConsistent)
// Verify that basic type mangled names are unique. // Verify that basic type mangled names are unique.
TEST(Type, BaseTypeMangledNamesUnique) TEST(Type, BaseTypeMangledNamesUnique)
{ {
std::set<std::string> uniqueNames; std::set<char> uniqueNames;
for (int i = static_cast<int>(EbtVoid); i < static_cast<int>(EbtLast); ++i) for (int i = static_cast<int>(EbtVoid); i < static_cast<int>(EbtLast); ++i)
{ {
if (i == static_cast<int>(EbtStruct) || i == static_cast<int>(EbtInterfaceBlock)) if (i == static_cast<int>(EbtStruct) || i == static_cast<int>(EbtInterfaceBlock))
{ {
continue; continue;
} }
const std::string &mangledName = GetBasicMangledName(static_cast<TBasicType>(i)); char mangledName = GetBasicMangledName(static_cast<TBasicType>(i));
if (mangledName != "") if (mangledName != '{')
{ {
ASSERT_TRUE(uniqueNames.insert(mangledName).second); ASSERT_TRUE(uniqueNames.insert(mangledName).second);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment