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
EbtInt,
EbtUInt,
EbtBool,
EbtAtomicCounter,
EbtYuvCscStandardEXT, // Only valid if EXT_YUV_target exists.
EbtGuardSamplerBegin, // non type: see implementation of IsSampler()
EbtSampler2D,
EbtSampler2D = EbtGuardSamplerBegin,
EbtSampler3D,
EbtSamplerCube,
EbtSampler2DArray,
......@@ -81,11 +83,11 @@ enum TBasicType
EbtSampler2DShadow,
EbtSamplerCubeShadow,
EbtSampler2DArrayShadow,
EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
EbtGuardSamplerEnd = EbtSampler2DArrayShadow, // non type: see implementation of IsSampler()
// images
EbtGuardImageBegin,
EbtImage2D,
EbtImage2D = EbtGuardImageBegin,
EbtIImage2D,
EbtUImage2D,
EbtImage3D,
......@@ -97,119 +99,41 @@ enum TBasicType
EbtImageCube,
EbtIImageCube,
EbtUImageCube,
EbtGuardImageEnd,
EbtGuardImageEnd = EbtUImageCube,
EbtLastSimpleType = EbtGuardImageEnd,
EbtStruct,
EbtInterfaceBlock,
EbtAddress, // should be deprecated??
EbtAtomicCounter,
// 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 "f";
case EbtInt:
return "i";
case EbtUInt:
return "u";
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_assert(EbtLastSimpleType < 52, "We only use alphabetic characters for mangled names");
if (t < 26)
{
return static_cast<char>('A' + t);
}
return static_cast<char>('a' - 26 + t);
}
const char *getBasicString(TBasicType t);
inline bool IsSampler(TBasicType type)
{
return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
return type >= EbtGuardSamplerBegin && type <= EbtGuardSamplerEnd;
}
inline bool IsImage(TBasicType type)
{
return type > EbtGuardImageBegin && type < EbtGuardImageEnd;
return type >= EbtGuardImageBegin && type <= EbtGuardImageEnd;
}
inline bool IsAtomicCounter(TBasicType type)
......
......@@ -25,16 +25,16 @@ namespace Helpers
// 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.
static constexpr size_t kStaticMangledNameMaxLength = 5;
static constexpr size_t kStaticMangledNameLength = 2;
// 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.
struct StaticMangledName
{
// 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.
......@@ -45,31 +45,9 @@ constexpr StaticMangledName BuildStaticMangledName(TBasicType basicType,
unsigned char secondarySize)
{
StaticMangledName name = {};
// When this function is executed constexpr (should be always),
// name.name[at] is guaranteed by the compiler to never go out of bounds.
size_t at = 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';
name.name[0] = TType::GetSizeMangledName(primarySize, secondarySize);
name.name[1] = GetBasicMangledName(basicType);
name.name[2] = '\0';
return name;
}
......
......@@ -375,7 +375,7 @@ void TSymbolTable::initializeBuiltIns(sh::GLenum type,
void TSymbolTable::initSamplerDefaultPrecision(TBasicType samplerType)
{
ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd);
ASSERT(samplerType >= EbtGuardSamplerBegin && samplerType <= EbtGuardSamplerEnd);
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
//
const char *TType::buildMangledName() const
{
TString mangledName;
if (isMatrix())
{
mangledName += static_cast<char>('0' + getCols());
mangledName += static_cast<char>('0' + getRows());
}
else if (getNominalSize() > 1)
{
mangledName += static_cast<char>('0' + getNominalSize());
}
TString mangledName(1, GetSizeMangledName(primarySize, secondarySize));
const char *basicMangledName = GetBasicMangledName(type);
if (basicMangledName != nullptr)
char basicMangledName = GetBasicMangledName(type);
if (basicMangledName != '{')
{
mangledName += basicMangledName;
}
......@@ -502,17 +492,19 @@ const char *TType::buildMangledName() const
switch (type)
{
case EbtStruct:
mangledName += "struct-";
mangledName += "{s";
if (mStructure->symbolType() != SymbolType::Empty)
{
mangledName += mStructure->name().data();
}
mangledName += mStructure->mangledFieldList();
mangledName += '}';
break;
case EbtInterfaceBlock:
mangledName += "iblock-";
mangledName += "{i";
mangledName += mInterfaceBlock->name().data();
mangledName += mInterfaceBlock->mangledFieldList();
mangledName += '}';
break;
default:
UNREACHABLE();
......@@ -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.
return AllocatePoolCharArray(mangledName.c_str(), mangledName.size());
}
......@@ -874,7 +864,6 @@ TString TFieldListCollection::buildMangledFieldList() const
TString mangledName;
for (const auto *field : *mFields)
{
mangledName += '-';
mangledName += field->type()->getMangledName();
}
return mangledName;
......
......@@ -229,6 +229,15 @@ class TType
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;
bool sameNonArrayType(const TType &right) const;
......
......@@ -188,47 +188,54 @@ parsed_variables = None
variables_json_filename = 'builtin_variables.json'
functions_txt_filename = 'builtin_function_declarations.txt'
basic_mangled_names = {
'Float': 'f',
'Int': 'i',
'UInt': 'u',
'Bool': 'b',
'YuvCscStandardEXT': 'y',
'Sampler2D': 's2',
'Sampler3D': 's3',
'SamplerCube': 'sC',
'Sampler2DArray': 'sA',
'SamplerExternalOES': 'sX',
'SamplerExternal2DY2YEXT': 'sY',
'Sampler2DRect': 'sR',
'Sampler2DMS': 'sM',
'ISampler2D': 'is2',
'ISampler3D': 'is3',
'ISamplerCube': 'isC',
'ISampler2DArray': 'isA',
'ISampler2DMS': 'isM',
'USampler2D': 'us2',
'USampler3D': 'us3',
'USamplerCube': 'usC',
'USampler2DArray': 'usA',
'USampler2DMS': 'usM',
'Sampler2DShadow': 's2s',
'SamplerCubeShadow': 'sCs',
'Sampler2DArrayShadow': 'sAs',
'Image2D': 'I2',
'IImage2D': 'iI2',
'UImage2D': 'uI2',
'Image3D': 'I3',
'IImage3D': 'iI3',
'UImage3D': 'uI3',
'Image2DArray': 'IA',
'IImage2DArray': 'iIA',
'UImage2DArray': 'uIA',
'ImageCube': 'Ic',
'IImageCube': 'iIc',
'UImageCube': 'uIc',
'AtomicCounter': 'a'
}
basic_types_enumeration = [
'Void',
'Float',
'Int',
'UInt',
'Bool',
'AtomicCounter',
'YuvCscStandardEXT',
'Sampler2D',
'Sampler3D',
'SamplerCube',
'Sampler2DArray',
'SamplerExternalOES',
'SamplerExternal2DY2YEXT',
'Sampler2DRect',
'Sampler2DMS',
'ISampler2D',
'ISampler3D',
'ISamplerCube',
'ISampler2DArray',
'ISampler2DMS',
'USampler2D',
'USampler3D',
'USamplerCube',
'USampler2DArray',
'USampler2DMS',
'Sampler2DShadow',
'SamplerCubeShadow',
'Sampler2DArrayShadow',
'Image2D',
'IImage2D',
'UImage2D',
'Image3D',
'IImage3D',
'UImage3D',
'Image2DArray',
'IImage2DArray',
'UImage2DArray',
'ImageCube',
'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']
......@@ -293,18 +300,16 @@ class TType:
template_type = 'new TType(Ebt{basic}, Ebp{precision}, Evq{qualifier}, {primarySize}, {secondarySize})'
return template_type.format(**self.data)
def get_mangled_name(self, separator = ';'):
def get_mangled_name(self):
mangled_name = ''
if self.is_matrix():
mangled_name += str(self.data['primarySize'])
mangled_name += str(self.data['secondarySize'])
elif self.data['primarySize'] > 1:
mangled_name += str(self.data['primarySize'])
mangled_name += basic_mangled_names[self.data['basic']]
size_key = (self.data['secondarySize'] - 1) * 4 + self.data['primarySize'] - 1
if size_key < 10:
mangled_name += chr(ord('0') + size_key)
else:
mangled_name += chr(ord('A') + size_key - 10)
mangled_name += separator
mangled_name += get_basic_mangled_name(self.data['basic'])
return mangled_name
def is_vector(self):
......@@ -589,20 +594,20 @@ def get_function_mangled_name(function_name, parameters):
def get_unique_identifier_name(function_name, parameters):
unique_name = function_name + '_'
for param in parameters:
unique_name += param.get_mangled_name('_')
unique_name += param.get_mangled_name()
return unique_name
def get_variable_name_to_store_parameters(parameters):
if len(parameters) == 0:
return 'empty'
unique_name = 'p_'
unique_name = 'p'
for param in parameters:
if 'qualifier' in param.data:
if param.data['qualifier'] == 'Out':
unique_name += 'o_'
unique_name += '_o_'
if param.data['qualifier'] == 'InOut':
unique_name += 'io_'
unique_name += param.get_mangled_name('_')
unique_name += '_io_'
unique_name += param.get_mangled_name()
return unique_name
def gen_function_variants(function_name, function_props):
......
......@@ -7,11 +7,12 @@
// Tests for images
//
#include "GLSLANG/ShaderLang.h"
#include "angle_gl.h"
#include "compiler/translator/StaticType.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/compiler_test.h"
using namespace sh;
......@@ -188,10 +189,16 @@ TEST_F(ShaderImageTest, ImageLoad)
}
// 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
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.
......@@ -212,10 +219,18 @@ TEST_F(ShaderImageTest, ImageStore)
}
// 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
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.
......
......@@ -43,15 +43,15 @@ TEST(Type, VectorAndMatrixMangledNameConsistent)
// Verify that basic type mangled names are unique.
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)
{
if (i == static_cast<int>(EbtStruct) || i == static_cast<int>(EbtInterfaceBlock))
{
continue;
}
const std::string &mangledName = GetBasicMangledName(static_cast<TBasicType>(i));
if (mangledName != "")
char mangledName = GetBasicMangledName(static_cast<TBasicType>(i));
if (mangledName != '{')
{
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