Commit 9031bdd9 by Clemen Deng Committed by Commit Bot

Use perfect-hash module in gen_builtin_symbols.py

The script currently takes ~4 minutes to run Using this module instead of manually hashing will improve runtime significantly Bug: angleproject:3747 Change-Id: I7e2d2ef5bbfd136b0299d571e0acc11f334c80b5 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1724667 Commit-Queue: Clemen Deng <clemendeng@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent b8a27c5e
{ {
"src/compiler/translator/ImmutableString_autogen.cpp":
"325dc410635436401990388b73531c11",
"src/compiler/translator/ParseContext_autogen.h": "src/compiler/translator/ParseContext_autogen.h":
"58786d2f352ee1a58d529fb7572c86a4", "58786d2f352ee1a58d529fb7572c86a4",
"src/compiler/translator/SymbolTable_autogen.cpp": "src/compiler/translator/SymbolTable_autogen.cpp":
"9a0b524e9254116e1a38e3ef1b57b669", "040a451ff0ad57612d5614d853cebd5a",
"src/compiler/translator/SymbolTable_autogen.h": "src/compiler/translator/SymbolTable_autogen.h":
"bdb3c8eab0d48267a2f264e3af635e1a", "bdb3c8eab0d48267a2f264e3af635e1a",
"src/compiler/translator/builtin_function_declarations.txt": "src/compiler/translator/builtin_function_declarations.txt":
"d0c15cb9f2ef6c0ba5cd6612470db000", "d0c15cb9f2ef6c0ba5cd6612470db000",
"src/compiler/translator/builtin_symbols_hash_autogen.txt":
"e2fb536afe6669e60e45f6b5d0730631",
"src/compiler/translator/builtin_variables.json": "src/compiler/translator/builtin_variables.json":
"04f763459cfbd47831bec22299287e82", "04f763459cfbd47831bec22299287e82",
"src/compiler/translator/gen_builtin_symbols.py": "src/compiler/translator/gen_builtin_symbols.py":
"5d5467e17ca5ed5bf9938df9a3391e6f", "5fca8cb433dcbbd956ec27dc583ccee8",
"src/compiler/translator/tree_util/BuiltIn_autogen.h": "src/compiler/translator/tree_util/BuiltIn_autogen.h":
"69268b2f3bda048ba8aaabe60c9b9912", "69268b2f3bda048ba8aaabe60c9b9912",
"src/tests/compiler_tests/ImmutableString_test_autogen.cpp": "src/tests/compiler_tests/ImmutableString_test_autogen.cpp":
"e23f23bbd011ab29c4bb37ea69cfb3bd" "aafd90302c36e2a848711576aa3a1aee"
} }
\ No newline at end of file
...@@ -12,6 +12,7 @@ import json ...@@ -12,6 +12,7 @@ import json
import os import os
import subprocess import subprocess
import sys import sys
import platform
script_dir = sys.path[0] script_dir = sys.path[0]
root_dir = os.path.abspath(os.path.join(script_dir, '..')) root_dir = os.path.abspath(os.path.join(script_dir, '..'))
...@@ -37,8 +38,12 @@ def rebase_script_path(script_path, relative_path): ...@@ -37,8 +38,12 @@ def rebase_script_path(script_path, relative_path):
return os.path.relpath(os.path.join(os.path.dirname(script_path), relative_path), root_dir) return os.path.relpath(os.path.join(os.path.dirname(script_path), relative_path), root_dir)
def get_executable_name():
return 'vpython.bat' if platform.system() == 'Windows' else 'vpython'
def grab_from_script(script, param): def grab_from_script(script, param):
res = subprocess.check_output(['python', script, param]).strip() res = subprocess.check_output([get_executable_name(), script, param]).strip()
if res == '': if res == '':
return [] return []
return [clean_path_slashes(rebase_script_path(script, name)) for name in res.split(',')] return [clean_path_slashes(rebase_script_path(script, name)) for name in res.split(',')]
...@@ -183,7 +188,7 @@ def main(): ...@@ -183,7 +188,7 @@ def main():
os.chdir(get_child_script_dirname(script)) os.chdir(get_child_script_dirname(script))
print('Running ' + name + ' code generator') print('Running ' + name + ' code generator')
if subprocess.call(['python', os.path.basename(script)]) != 0: if subprocess.call([get_executable_name(), os.path.basename(script)]) != 0:
sys.exit(1) sys.exit(1)
# Update the hash dictionary. # Update the hash dictionary.
......
...@@ -44,7 +44,7 @@ angle_translator_sources = [ ...@@ -44,7 +44,7 @@ angle_translator_sources = [
"src/compiler/translator/FunctionLookup.h", "src/compiler/translator/FunctionLookup.h",
"src/compiler/translator/HashNames.cpp", "src/compiler/translator/HashNames.cpp",
"src/compiler/translator/HashNames.h", "src/compiler/translator/HashNames.h",
"src/compiler/translator/ImmutableString.cpp", "src/compiler/translator/ImmutableString_autogen.cpp",
"src/compiler/translator/ImmutableString.h", "src/compiler/translator/ImmutableString.h",
"src/compiler/translator/ImmutableStringBuilder.cpp", "src/compiler/translator/ImmutableStringBuilder.cpp",
"src/compiler/translator/ImmutableStringBuilder.h", "src/compiler/translator/ImmutableStringBuilder.h",
......
//
// Copyright (c) 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ImmutableString.cpp: Wrapper for static or pool allocated char arrays, that are guaranteed to be
// valid and unchanged for the duration of the compilation.
//
#include "compiler/translator/ImmutableString.h"
std::ostream &operator<<(std::ostream &os, const sh::ImmutableString &str)
{
return os.write(str.data(), str.length());
}
#if defined(_MSC_VER)
# pragma warning(disable : 4309) // truncation of constant value
#endif
namespace sh
{
template <>
const size_t ImmutableString::FowlerNollVoHash<4>::kFnvPrime = 16777619u;
template <>
const size_t ImmutableString::FowlerNollVoHash<4>::kFnvOffsetBasis = 0x811c9dc5u;
template <>
const size_t ImmutableString::FowlerNollVoHash<8>::kFnvPrime =
static_cast<size_t>(1099511628211ull);
template <>
const size_t ImmutableString::FowlerNollVoHash<8>::kFnvOffsetBasis =
static_cast<size_t>(0xcbf29ce484222325ull);
uint32_t ImmutableString::mangledNameHash() const
{
const char *dataPtr = data();
uint32_t hash = static_cast<uint32_t>(FowlerNollVoHash<4>::kFnvOffsetBasis);
const uint32_t kMaxSixBitValue = (1u << 6) - 1u;
uint32_t parenLocation = kMaxSixBitValue;
uint32_t hasArrayOrBlockParamBit = 0u;
uint32_t index = 0;
while (dataPtr[index] != '\0')
{
hash = hash ^ dataPtr[index];
hash = hash * static_cast<uint32_t>(FowlerNollVoHash<4>::kFnvPrime);
if (dataPtr[index] == '(')
{
// We should only reach here once, since this function should not be called with invalid
// mangled names.
ASSERT(parenLocation == kMaxSixBitValue);
parenLocation = index;
}
else if (dataPtr[index] == '{' || dataPtr[index] == '[')
{
hasArrayOrBlockParamBit = 1u;
}
++index;
}
// Should not be called with strings longer than 63 characters.
ASSERT(index <= kMaxSixBitValue);
return ((hash >> 13) ^ (hash & 0x1fff)) | (index << 19) | (parenLocation << 25) |
(hasArrayOrBlockParamBit << 31);
}
} // namespace sh
// GENERATED FILE - DO NOT EDIT.
// Generated by gen_builtin_symbols.py using data from builtin_variables.json and
// builtin_function_declarations.txt.
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ImmutableString_autogen.cpp: Wrapper for static or pool allocated char arrays, that are
// guaranteed to be valid and unchanged for the duration of the compilation. Implements
// mangledNameHash using perfect hash function from gen_builtin_symbols.py
#include "compiler/translator/ImmutableString.h"
std::ostream &operator<<(std::ostream &os, const sh::ImmutableString &str)
{
return os.write(str.data(), str.length());
}
#if defined(_MSC_VER)
# pragma warning(disable : 4309) // truncation of constant value
#endif
namespace
{
constexpr int kT1[] = {1449, 850, 687, 94, 1160, 2137, 389, 55, 2314, 1465, 1942, 1342,
1619, 2259, 2238, 725, 2029, 881, 2320, 1229, 684, 853, 1921, 239,
413, 1657, 236, 654, 237, 1663, 2284, 2208, 952, 1152, 691};
constexpr int kT2[] = {1352, 2323, 1943, 1117, 1361, 512, 1103, 2213, 1371, 523, 1964, 995,
1843, 714, 179, 1093, 1916, 1705, 1050, 1026, 1497, 2043, 438, 1129,
1461, 2114, 344, 618, 1274, 1858, 1343, 1528, 1923, 1407, 838};
constexpr int kG[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2303, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 380, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 169, 1553, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 619, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 186, 702, 0, 0, 2256, 0, 0, 630, 0, 0,
0, 0, 0, 0, 2032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 654, 2017, 963, 2266, 0, 0, 0, 0, 0, 0, 0, 0,
1496, 0, 0, 0, 0, 0, 0, 0, 610, 0, 0, 0, 2309, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 356, 0, 2071, 0, 1778, 0, 0,
48, 0, 0, 0, 0, 0, 0, 0, 689, 1754, 30, 494, 0, 0, 590, 0,
0, 0, 455, 1392, 0, 0, 0, 0, 0, 103, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 2098, 0, 0, 0, 0, 1983, 629, 0, 0, 0, 106,
0, 0, 1403, 0, 1644, 0, 0, 0, 0, 0, 0, 0, 2272, 197, 1880, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1093, 0, 0, 0, 0, 749, 437, 560, 918, 0, 0, 0, 0,
1871, 0, 0, 0, 787, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1035, 0, 0, 501, 0, 2246, 0, 0, 939, 0, 0, 81, 0,
0, 0, 0, 355, 943, 0, 0, 0, 0, 858, 0, 1029, 0, 939, 870, 0,
0, 0, 0, 0, 0, 0, 0, 0, 321, 367, 0, 0, 0, 585, 0, 1685,
0, 0, 0, 0, 0, 379, 0, 0, 0, 0, 0, 0, 0, 372, 0, 0,
0, 11, 0, 0, 0, 0, 0, 2035, 0, 0, 2194, 0, 0, 323, 0, 2291,
1876, 0, 447, 0, 417, 0, 0, 0, 0, 0, 0, 0, 221, 0, 927, 0,
0, 0, 2268, 0, 0, 0, 0, 0, 1738, 738, 32, 367, 0, 0, 0, 0,
150, 0, 0, 1724, 0, 1169, 0, 0, 392, 0, 2156, 2042, 0, 0, 0, 2333,
894, 234, 0, 437, 0, 2072, 0, 561, 0, 1005, 165, 775, 0, 0, 0, 0,
0, 814, 0, 0, 682, 0, 0, 73, 1035, 0, 0, 0, 47, 0, 541, 0,
0, 0, 0, 396, 0, 0, 0, 0, 0, 2315, 223, 786, 379, 0, 872, 0,
2121, 62, 0, 0, 0, 907, 0, 0, 0, 335, 0, 0, 0, 2210, 406, 0,
0, 339, 0, 0, 0, 1047, 0, 0, 2026, 2304, 0, 0, 582, 1909, 0, 0,
0, 0, 0, 661, 0, 0, 0, 0, 711, 0, 0, 0, 0, 0, 0, 0,
0, 438, 0, 0, 725, 0, 701, 1019, 0, 4, 264, 0, 0, 822, 0, 1021,
641, 0, 0, 0, 617, 0, 999, 1863, 0, 189, 83, 319, 0, 0, 1893, 239,
1026, 0, 916, 0, 846, 0, 0, 0, 0, 2171, 0, 260, 0, 0, 1310, 0,
470, 0, 255, 0, 601, 0, 1885, 0, 0, 0, 0, 530, 0, 0, 527, 0,
0, 460, 782, 0, 1981, 0, 0, 0, 965, 333, 0, 0, 954, 0, 2313, 0,
0, 303, 1234, 0, 0, 51, 0, 75, 0, 0, 112, 0, 0, 0, 1008, 0,
0, 0, 0, 1602, 0, 0, 0, 0, 2132, 1056, 1020, 1726, 2236, 1057, 992, 0,
0, 0, 767, 0, 0, 853, 0, 0, 879, 81, 0, 0, 0, 483, 299, 0,
0, 645, 0, 0, 2045, 0, 0, 0, 431, 0, 2126, 0, 0, 432, 0, 987,
0, 1075, 1152, 0, 326, 1902, 0, 0, 723, 0, 0, 607, 0, 2190, 406, 0,
964, 321, 600, 0, 0, 0, 0, 0, 1977, 0, 0, 0, 0, 1255, 0, 1681,
0, 0, 1091, 0, 0, 1551, 885, 0, 532, 0, 0, 362, 0, 0, 1478, 0,
0, 0, 418, 0, 1003, 0, 0, 274, 544, 0, 0, 147, 821, 0, 828, 327,
0, 0, 0, 0, 0, 2198, 0, 139, 222, 0, 345, 0, 1473, 145, 1013, 0,
2307, 2166, 0, 1844, 0, 321, 0, 0, 2010, 0, 0, 0, 0, 0, 0, 0,
0, 1189, 386, 0, 0, 0, 0, 0, 0, 1463, 1159, 908, 0, 0, 0, 0,
0, 1284, 2129, 0, 838, 0, 0, 0, 0, 2149, 342, 67, 924, 0, 0, 2161,
878, 0, 0, 1870, 520, 0, 724, 622, 822, 676, 0, 0, 2145, 0, 52, 0,
0, 0, 0, 0, 0, 0, 222, 0, 0, 0, 1901, 8, 0, 0, 0, 311,
0, 2202, 509, 667, 0, 642, 199, 0, 268, 1717, 0, 0, 0, 0, 1389, 2325,
0, 1202, 0, 766, 496, 0, 559, 95, 0, 277, 0, 0, 0, 1827, 2182, 0,
79, 879, 0, 289, 0, 0, 0, 0, 260, 982, 541, 689, 0, 1725, 0, 0,
0, 0, 246, 1589, 576, 0, 2201, 0, 238, 967, 0, 0, 683, 0, 0, 270,
0, 0, 0, 375, 1, 465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 595,
152, 0, 996, 560, 603, 297, 0, 2175, 330, 284, 0, 178, 0, 0, 0, 757,
0, 859, 0, 641, 0, 479, 1020, 0, 676, 697, 0, 0, 0, 2165, 2044, 2140,
470, 0, 2250, 0, 2048, 0, 2313, 0, 0, 0, 96, 1840, 0, 1328, 0, 0,
1990, 0, 338, 1977, 0, 781, 0, 206, 293, 991, 383, 467, 1961, 269, 0, 714,
0, 0, 0, 845, 0, 0, 531, 0, 0, 1841, 0, 1740, 0, 163, 372, 644,
0, 1055, 0, 410, 568, 439, 1611, 0, 0, 0, 0, 0, 581, 470, 1052, 0,
1583, 0, 0, 659, 0, 245, 0, 175, 0, 195, 0, 880, 0, 0, 381, 0,
0, 1030, 0, 126, 0, 0, 0, 344, 0, 0, 32, 98, 0, 1792, 0, 2117,
176, 0, 0, 0, 268, 0, 0, 0, 0, 2261, 0, 0, 0, 97, 0, 702,
0, 25, 0, 194, 0, 0, 439, 1868, 350, 829, 1784, 754, 0, 0, 0, 0,
582, 313, 0, 268, 0, 0, 250, 0, 0, 463, 1567, 2308, 0, 100, 0, 1743,
428, 149, 0, 492, 587, 0, 0, 301, 0, 808, 217, 0, 0, 0, 1518, 1799,
0, 0, 485, 0, 362, 2212, 0, 0, 0, 518, 42, 0, 0, 1462, 1016, 730,
0, 0, 0, 2261, 382, 0, 94, 0, 0, 580, 0, 0, 0, 153, 0, 0,
0, 0, 719, 210, 382, 0, 0, 1191, 2078, 0, 228, 1014, 385, 0, 0, 397,
0, 0, 0, 692, 0, 105, 0, 500, 0, 0, 500, 0, 686, 0, 1268, 0,
565, 892, 0, 0, 436, 0, 0, 566, 62, 0, 351, 0, 0, 1670, 0, 696,
685, 0, 934, 243, 379, 593, 332, 0, 0, 0, 0, 0, 2258, 1512, 2033, 0,
948, 0, 2343, 2233, 308, 224, 1802, 0, 0, 512, 0, 0, 0, 0, 0, 2029,
1038, 0, 0, 210, 0, 0, 0, 0, 1428, 542, 0, 1753, 171, 266, 1787, 405,
1408, 0, 0, 0, 1424, 0, 518, 0, 547, 728, 530, 0, 0, 619, 0, 0,
647, 0, 379, 814, 312, 2081, 1700, 92, 0, 0, 1331, 698, 0, 87, 0, 0,
0, 2174, 0, 460, 1074, 1215, 1849, 13, 9, 0, 0, 0, 729, 955, 784, 399,
993, 0, 167, 0, 0, 647, 186, 0, 0, 0, 0, 1075, 0, 984, 125, 1917,
1429, 0, 306, 705, 0, 0, 0, 0, 0, 1405, 0, 1000, 0, 0, 0, 1480,
0, 0, 334, 1776, 800, 1497, 1938, 0, 7, 67, 0, 662, 656, 181, 489, 0,
655, 263, 0, 0, 961, 0, 653, 920, 1416, 232, 0, 733, 0, 2, 2192, 2322,
0, 0, 387, 1850, 547, 639, 2292, 2197, 2083, 445, 0, 0, 474, 0, 357, 465,
1124, 1479, 476, 0, 0, 0, 340, 0, 1743, 1317, 170, 0, 0, 989, 0, 1837,
290, 811, 0, 38, 0, 1198, 0, 61, 0, 772, 543, 0, 0, 0, 905, 707,
138, 2225, 176, 2284, 0, 0, 2344, 0, 0, 0, 1218, 0, 0, 0, 1503, 1015,
0, 251, 442, 0, 0, 0, 1631, 0, 210, 1257, 179, 1903, 0, 0, 0, 59,
0, 0, 0, 0, 371, 558, 359, 188, 588, 0, 0, 670, 103, 1580, 942, 963,
0, 55, 1935, 510, 2236, 589, 1834, 2340, 0, 721, 0, 1067, 0, 0, 110, 1764,
49, 402, 0, 0, 0, 0, 1990, 430, 0, 0, 243, 282, 0, 978, 408, 226,
0, 0, 0, 517, 0, 2103, 2331, 0, 0, 0, 0, 0, 0, 736, 0, 0,
685, 0, 291, 14, 0, 0, 618, 231, 0, 0, 744, 0, 0, 442, 1084, 0,
857, 1857, 0, 463, 2262, 0, 908, 507, 99, 1547, 379, 0, 629, 0, 0, 273,
2184, 0, 0, 0, 0, 0, 0, 814, 1301, 1283, 1060, 761, 1767, 5, 0, 0,
780, 0, 2280, 0, 908, 0, 319, 0, 996, 2331, 1575, 618, 2334, 0, 0, 0,
0, 0, 0, 240, 0, 0, 796, 1006, 0, 55, 0, 0, 603, 0, 0, 0,
0, 0, 0, 0, 0, 0, 2038, 907, 1081, 0, 0, 0, 2117, 0, 440, 0,
2343, 0, 712, 0, 365, 162, 1116, 296, 407, 0, 0, 930, 0, 0, 616, 568,
1308, 0, 0, 1054, 819, 0, 2204, 0, 0, 1391, 865, 0, 0, 2197, 869, 185,
551, 456, 0, 681, 0, 0, 582, 112, 0, 2298, 580, 0, 0, 0, 810, 0,
867, 900, 990, 0, 2335, 320, 0, 485, 723, 0, 553, 866, 0, 1556, 0, 0,
0, 0, 0, 0, 0, 2172, 157, 2049, 0, 10, 2301, 0, 851, 1913, 2269, 439,
0, 0, 0, 0, 0, 1377, 0, 0, 0, 0, 0, 148, 0, 425, 1929, 212,
2083, 668, 826, 0, 190, 0, 0, 0, 0, 310, 28, 0, 0, 0, 2310, 856,
2210, 0, 1813, 556, 0, 383, 0, 184, 481, 0, 0, 121, 0, 0, 156, 61,
0, 1854, 0, 856, 740, 0, 986, 584, 932, 977, 805, 0, 258, 0, 0, 1685,
495, 0, 2250, 1524, 107, 0, 0, 0, 0, 1159, 0, 107, 433, 37, 0, 0,
1105, 0, 0, 342, 1687, 1448, 836, 5, 1971, 2219, 0, 0, 448, 465, 0, 1619,
0, 0, 577, 0, 0, 0, 76, 0, 0, 142, 0, 0, 0, 0, 0, 1037,
879, 171, 291, 0, 700, 2228, 0, 0, 0, 2270, 0, 896, 77, 0, 0, 796,
235, 0, 0, 0, 269, 112, 1039, 1560, 0, 0, 2262, 0, 0, 861, 113, 0,
904, 0, 0, 0, 0, 0, 568, 2022, 110, 1027, 648, 374, 0, 759, 0, 356,
0, 0, 2111, 456, 0, 285, 0, 0, 203, 0, 657, 53, 643, 0, 74, 335,
1939, 103, 2165, 30, 192, 2072, 97, 562, 454, 316, 2061, 172, 0, 0, 926, 0,
0, 750, 1934, 0, 0, 0, 0, 0, 816, 0, 941, 0, 897, 0, 690, 615,
0, 853, 0, 662, 1910, 0, 350, 0, 0, 0, 0, 759, 0, 988, 0, 281,
0, 0, 0, 447, 420, 58, 0, 124, 51, 2228, 0, 0, 0, 138, 0, 0,
127, 0, 0, 0, 185, 970, 0, 2205, 230, 468, 0, 448, 287, 0, 66, 1665,
302, 1430, 2080, 0, 1109, 1863, 0, 180, 0, 467, 771, 2147, 0, 2129, 0, 441,
89, 498, 448, 1076, 0, 1966, 0, 2263, 2293, 0, 0, 3, 0, 1053, 0, 1065,
2059, 240, 261, 1134, 644, 0, 197, 342, 0, 0, 631, 0, 19, 1053, 0, 214,
0, 0, 0, 0, 0, 336, 16, 0, 0, 809, 0, 0, 214, 193, 0, 449,
0, 139, 0, 0, 0, 355, 580, 123, 478, 187, 550, 0, 0, 0, 0, 704,
791, 812, 0, 0, 0, 0, 302, 721, 829, 414, 0, 204, 163, 0, 331, 2233,
18, 9, 687, 0, 0, 974, 82, 959, 0, 0, 938, 570, 475, 650, 833, 0,
347, 0, 115, 0, 1415, 623, 227, 0, 804, 0, 2347, 2242, 0, 258, 0, 1808,
0, 0, 602, 0, 501, 893, 0, 0, 155, 928, 15, 0, 190, 1271, 1076, 1028,
155, 0, 679, 1043, 0, 738, 287, 711, 0, 0, 0, 0, 0, 0, 1809, 0,
0, 1043, 0, 370, 0, 0, 0, 768, 0, 0, 994, 0, 0, 0, 2324, 618,
1924, 0, 64, 0, 0, 0, 0, 7, 1816, 418, 1083, 0, 0, 54, 85, 0,
216, 0, 0, 2048, 0, 0, 0, 807, 187, 0, 131, 524, 973, 670, 0, 1860,
0, 0, 0, 986, 0, 317, 202, 0, 0, 0, 608, 618, 2262, 0, 0, 0,
92, 150, 699, 0, 68, 844, 0, 0, 567, 158, 921, 868, 0, 0, 937, 0,
2202, 846, 0, 111, 352, 958, 0, 435, 434, 301, 847, 0, 0, 953, 2216, 134,
0, 0, 0, 358, 916, 515, 2284, 0, 0, 0, 522, 0, 0, 214, 0, 890,
188, 169, 0, 0, 0, 837, 2128, 0, 636, 691, 0, 712, 685, 0, 221, 0,
1031, 0, 0, 0, 273, 583, 571, 0, 1487, 0, 239, 93, 0, 33, 0, 1861,
624, 1357, 2214, 641, 1493, 65, 0, 36, 0, 634, 883, 0, 0, 517, 574, 373,
380, 624, 987, 0, 303, 698, 1287, 33, 0, 0, 490, 1025, 645, 219, 1058, 719,
378, 524, 508, 338, 627, 341, 753, 0, 253, 0, 713, 0, 0, 0, 295, 0,
852, 2244, 141, 0, 0, 466, 578, 0, 0, 121, 0, 169, 890, 0, 0, 0,
0, 0, 0, 361, 841, 0, 351, 1005, 0, 0, 0, 0, 0, 311, 0, 0,
246, 5, 849, 182, 2142, 2198, 0, 391, 1259, 0, 0, 709, 116, 114, 364, 1986,
204, 0, 398, 321, 816, 777, 0, 0, 894, 0, 1046, 0, 319, 0, 590, 240,
0, 0, 1866, 0, 0, 0, 629, 0, 763, 1826, 452, 28, 872, 0, 451, 891,
696, 1055, 2199, 0, 0, 2135, 499, 0, 792, 200, 0, 0, 1068, 750, 2124, 2257,
542, 835, 0, 57, 0, 2, 718, 0, 0, 2163, 322, 1799};
int HashG(const char *key, const int *T)
{
int sum = 0;
for (int i = 0; key[i] != '\0'; i++)
{
sum += T[i] * key[i];
sum %= 2348;
}
return kG[sum];
}
int PerfectHash(const char *key)
{
if (strlen(key) > 35)
return 0;
return (HashG(key, kT1) + HashG(key, kT2)) % 2348;
}
} // namespace
namespace sh
{
template <>
const size_t ImmutableString::FowlerNollVoHash<4>::kFnvPrime = 16777619u;
template <>
const size_t ImmutableString::FowlerNollVoHash<4>::kFnvOffsetBasis = 0x811c9dc5u;
template <>
const size_t ImmutableString::FowlerNollVoHash<8>::kFnvPrime =
static_cast<size_t>(1099511628211ull);
template <>
const size_t ImmutableString::FowlerNollVoHash<8>::kFnvOffsetBasis =
static_cast<size_t>(0xcbf29ce484222325ull);
uint32_t ImmutableString::mangledNameHash() const
{
return PerfectHash(data());
}
} // namespace sh
This source diff could not be displayed because it is too large. You can view the blob instead.
571dbbc401f64a7bd3d3dca5d9002ba1
\ No newline at end of file
#!/usr/bin/python #!/usr/bin/env vpython
#
# [VPYTHON:BEGIN]
# wheel: <
# name: "infra/python/wheels/perfect-hash-py2_py3"
# version: "version:0.2.1"
# >
# [VPYTHON:END]
#
# Copyright 2018 The ANGLE Project Authors. All rights reserved. # Copyright 2018 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
...@@ -8,6 +16,7 @@ ...@@ -8,6 +16,7 @@
from collections import OrderedDict from collections import OrderedDict
from datetime import date from datetime import date
from perfect_hash import generate_hash, Hash2
import argparse import argparse
import hashlib import hashlib
import json import json
...@@ -15,6 +24,84 @@ import re ...@@ -15,6 +24,84 @@ import re
import os import os
import sys import sys
template_immutablestring_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {variable_data_source_name} and
// {function_data_source_name}.
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ImmutableString_autogen.cpp: Wrapper for static or pool allocated char arrays, that are guaranteed to be
// valid and unchanged for the duration of the compilation.
// Implements mangledNameHash using perfect hash function from gen_builtin_symbols.py
#include "compiler/translator/ImmutableString.h"
std::ostream &operator<<(std::ostream &os, const sh::ImmutableString &str)
{{
return os.write(str.data(), str.length());
}}
#if defined(_MSC_VER)
# pragma warning(disable : 4309) // truncation of constant value
#endif
namespace
{{
constexpr int kT1[] = {{{S1}}};
constexpr int kT2[] = {{{S2}}};
constexpr int kG[] = {{{G}}};
int HashG(const char *key, const int *T)
{{
int sum = 0;
for (int i = 0; key[i] != '\\0'; i++)
{{
sum += T[i] * key[i];
sum %= {NG};
}}
return kG[sum];
}}
int PerfectHash(const char *key)
{{
if (strlen(key) > {NS})
return 0;
return (HashG(key, kT1) + HashG(key, kT2)) % {NG};
}}
}}
namespace sh
{{
template <>
const size_t ImmutableString::FowlerNollVoHash<4>::kFnvPrime = 16777619u;
template <>
const size_t ImmutableString::FowlerNollVoHash<4>::kFnvOffsetBasis = 0x811c9dc5u;
template <>
const size_t ImmutableString::FowlerNollVoHash<8>::kFnvPrime =
static_cast<size_t>(1099511628211ull);
template <>
const size_t ImmutableString::FowlerNollVoHash<8>::kFnvOffsetBasis =
static_cast<size_t>(0xcbf29ce484222325ull);
uint32_t ImmutableString::mangledNameHash() const
{{
return PerfectHash(data());
}}
}} // namespace sh
"""
template_immutablestringtest_cpp = """// GENERATED FILE - DO NOT EDIT. template_immutablestringtest_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {function_data_source_name}. // Generated by {script_name} using data from {function_data_source_name}.
// //
...@@ -201,11 +288,6 @@ const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name, ...@@ -201,11 +288,6 @@ const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name,
return nullptr; return nullptr;
}} }}
uint32_t nameHash = name.mangledNameHash(); uint32_t nameHash = name.mangledNameHash();
if ((nameHash >> 31) != 0)
{{
// The name contains [ or {{.
return nullptr;
}}
{get_builtin} {get_builtin}
}} }}
...@@ -330,7 +412,7 @@ class GroupedList: ...@@ -330,7 +412,7 @@ class GroupedList:
def get_max_name_length(self): def get_max_name_length(self):
return self.max_name_length return self.max_name_length
def get_switch_code(self, script_generated_hash_tests): def get_switch_code(self, hashfn, script_generated_hash_tests):
code = [] code = []
for level in levels: for level in levels:
if len(self.objs[level]) == 0: if len(self.objs[level]) == 0:
...@@ -347,7 +429,7 @@ class GroupedList: ...@@ -347,7 +429,7 @@ class GroupedList:
switch = {} switch = {}
for name, obj in objs.iteritems(): for name, obj in objs.iteritems():
name_hash = mangledNameHash(name, script_generated_hash_tests) name_hash = mangledNameHash(name, hashfn, script_generated_hash_tests)
if name_hash not in switch: if name_hash not in switch:
switch[name_hash] = [] switch[name_hash] = []
switch[name_hash].append(obj['hash_matched_code']) switch[name_hash].append(obj['hash_matched_code'])
...@@ -528,6 +610,17 @@ class TType: ...@@ -528,6 +610,17 @@ class TType:
raise Exception('Unrecognized type: ' + str(glsl_header_type)) raise Exception('Unrecognized type: ' + str(glsl_header_type))
class HashFunction:
def __init__(self, f1, f2, G):
self.f1 = f1
self.f2 = f2
self.G = G
def hash(self, key):
return (self.G[self.f1(key)] + self.G[self.f2(key)]) % len(self.G)
def get_parsed_functions(functions_txt_filename): def get_parsed_functions(functions_txt_filename):
def parse_function_parameters(parameters): def parse_function_parameters(parameters):
...@@ -596,32 +689,8 @@ def get_parsed_functions(functions_txt_filename): ...@@ -596,32 +689,8 @@ def get_parsed_functions(functions_txt_filename):
return parsed_functions return parsed_functions
fnvPrime = 16777619 def mangledNameHash(str, hashfn, script_generated_hash_tests, save_test=True):
hash = hashfn.hash(str)
def hash32(str):
fnvOffsetBasis = 0x811c9dc5
hash = fnvOffsetBasis
for c in str:
hash = hash ^ ord(c)
hash = (hash * fnvPrime) & 0xffffffff
return hash
def mangledNameHash(str, script_generated_hash_tests, save_test=True):
hash = hash32(str)
index = 0
max_six_bit_value = (1 << 6) - 1
paren_location = max_six_bit_value
has_array_or_block_param_bit = 0
for c in str:
if c == '(':
paren_location = index
elif c == '{' or c == '[':
has_array_or_block_param_bit = 1
index += 1
hash = ((hash >> 13) ^ (hash & 0x1fff)) | (index << 19) | (paren_location << 25) | (
has_array_or_block_param_bit << 31)
if save_test: if save_test:
sanity_check = ' ASSERT_EQ(0x{hash}u, ImmutableString("{str}").mangledNameHash());'.format( sanity_check = ' ASSERT_EQ(0x{hash}u, ImmutableString("{str}").mangledNameHash());'.format(
hash=('%08x' % hash), str=str) hash=('%08x' % hash), str=str)
...@@ -629,6 +698,29 @@ def mangledNameHash(str, script_generated_hash_tests, save_test=True): ...@@ -629,6 +698,29 @@ def mangledNameHash(str, script_generated_hash_tests, save_test=True):
return hash return hash
def get_function_names(group, mangled_names):
if 'functions' in group:
for function_props in group['functions']:
function_name = function_props['name']
mangled_names.append(function_name)
function_variants = gen_function_variants(function_name, function_props)
for function_props in function_variants:
parameters = get_parameters(function_props)
mangled_names.append(get_function_mangled_name(function_name, parameters))
if 'subgroups' in group:
for subgroup_name, subgroup in group['subgroups'].iteritems():
get_function_names(subgroup, mangled_names)
def get_variable_names(group, mangled_names):
if 'variables' in group:
for variable_name, props in group['variables'].iteritems():
mangled_names.append(variable_name)
if 'subgroups' in group:
for subgroup_name, subgroup in group['subgroups'].iteritems():
get_variable_names(subgroup, mangled_names)
def get_suffix(props): def get_suffix(props):
if 'suffix' in props: if 'suffix' in props:
return props['suffix'] return props['suffix']
...@@ -682,77 +774,6 @@ def get_function_human_readable_name(function_name, parameters): ...@@ -682,77 +774,6 @@ def get_function_human_readable_name(function_name, parameters):
return name return name
def gen_parameters_variant_ids(str_len, ttype_mangled_name_variants):
# Note that this doesn't generate variants with array parameters or struct / interface block parameters. They are assumed to have been filtered out separately.
if str_len % 2 != 0:
raise Exception('Expecting parameters mangled name length to be divisible by two')
num_variants = pow(len(ttype_mangled_name_variants), str_len / 2)
return xrange(num_variants)
def get_parameters_mangled_name_variant(variant_id, paren_location, total_length,
ttype_mangled_name_variants):
str_len = total_length - paren_location - 1
if str_len % 2 != 0:
raise Exception('Expecting parameters mangled name length to be divisible by two')
variant = ''
while (len(variant)) < str_len:
parameter_index = len(variant) / 2
parameter_variant_index = variant_id
for i in xrange(parameter_index):
parameter_variant_index = parameter_variant_index / len(ttype_mangled_name_variants)
parameter_variant_index = parameter_variant_index % len(ttype_mangled_name_variants)
variant += ttype_mangled_name_variants[parameter_variant_index]
return variant
# Calculate the mangled name hash of a common prefix string that's been pre-hashed with hash32()
# plus a variant of the parameters. This is faster than constructing the whole string and then
# calculating the hash for that.
def get_mangled_name_variant_hash(prefix_hash32, variant_id, paren_location, total_length,
num_type_variants, ttype_mangled_name_variants):
hash = prefix_hash32
parameter_count = (total_length - paren_location) >> 1
parameter_variant_id_base = variant_id
for parameter_index in xrange(parameter_count):
parameter_variant_index = parameter_variant_id_base % num_type_variants
param_str = ttype_mangled_name_variants[parameter_variant_index]
hash = hash ^ ord(param_str[0])
hash = (hash * fnvPrime) & 0xffffffff
hash = hash ^ ord(param_str[1])
hash = (hash * fnvPrime) & 0xffffffff
parameter_variant_id_base = parameter_variant_id_base / num_type_variants
return ((hash >> 13) ^ (hash & 0x1fff)) | (total_length << 19) | (paren_location << 25)
def mangled_name_hash_can_collide_with_different_parameters(
function_variant_props, num_type_variants, ttype_mangled_name_variants,
script_generated_hash_tests):
# We exhaustively search through all possible lists of parameters and see if any other mangled
# name has the same hash.
mangled_name = function_variant_props['mangled_name']
mangled_name_len = len(mangled_name)
hash = mangledNameHash(mangled_name, script_generated_hash_tests)
mangled_name_prefix = function_variant_props['name'] + '('
paren_location = len(mangled_name_prefix) - 1
prefix_hash32 = hash32(mangled_name_prefix)
parameters_mangled_name_len = len(mangled_name) - len(mangled_name_prefix)
parameters_mangled_name = mangled_name[len(mangled_name_prefix):]
if (parameters_mangled_name_len > 6):
# This increases the complexity of searching for hash collisions considerably, so rather than doing it we just conservatively assume that a hash collision may be possible.
return True
for variant_id in gen_parameters_variant_ids(parameters_mangled_name_len,
ttype_mangled_name_variants):
variant_hash = get_mangled_name_variant_hash(prefix_hash32, variant_id, paren_location,
mangled_name_len, num_type_variants,
ttype_mangled_name_variants)
manged_name_variant = get_parameters_mangled_name_variant(
variant_id, paren_location, mangled_name_len, ttype_mangled_name_variants)
if variant_hash == hash and manged_name_variant != parameters_mangled_name:
return True
return False
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:
...@@ -839,11 +860,11 @@ def gen_function_variants(function_name, function_props): ...@@ -839,11 +860,11 @@ def gen_function_variants(function_name, function_props):
def process_single_function_group( def process_single_function_group(
condition, group_name, group, num_type_variants, parameter_declarations, condition, group_name, group, parameter_declarations, name_declarations,
ttype_mangled_name_variants, name_declarations, unmangled_function_if_statements, unmangled_function_if_statements, unmangled_builtin_declarations,
unmangled_builtin_declarations, defined_function_variants, builtin_id_declarations, defined_function_variants, builtin_id_declarations, builtin_id_definitions,
builtin_id_definitions, defined_parameter_names, variable_declarations, defined_parameter_names, variable_declarations, function_declarations,
function_declarations, script_generated_hash_tests, get_builtin_if_statements): script_generated_hash_tests, get_builtin_if_statements):
global id_counter global id_counter
if 'functions' not in group: if 'functions' not in group:
...@@ -932,8 +953,8 @@ def process_single_function_group( ...@@ -932,8 +953,8 @@ def process_single_function_group(
template_builtin_id_declaration.format(**param_template_args)) template_builtin_id_declaration.format(**param_template_args))
define_constexpr_variable(param_template_args, variable_declarations) define_constexpr_variable(param_template_args, variable_declarations)
defined_parameter_names.add(unique_param_name) defined_parameter_names.add(unique_param_name)
parameters_list.append('&BuiltInVariable::kVar_{name_with_suffix}'.format( parameters_list.append(
**param_template_args)) '&BuiltInVariable::kVar_{name_with_suffix}'.format(**param_template_args))
template_args['parameters_var_name'] = get_variable_name_to_store_parameters( template_args['parameters_var_name'] = get_variable_name_to_store_parameters(
parameters) parameters)
...@@ -952,25 +973,12 @@ def process_single_function_group( ...@@ -952,25 +973,12 @@ def process_single_function_group(
template_function_declaration = 'constexpr const TFunction kFunction_{unique_name}(BuiltInId::{human_readable_name}, BuiltInName::{name_with_suffix}, TExtension::{extension}, BuiltInParameters::{parameters_var_name}, {param_count}, {return_type}, EOp{op}, {known_to_not_have_side_effects});' template_function_declaration = 'constexpr const TFunction kFunction_{unique_name}(BuiltInId::{human_readable_name}, BuiltInName::{name_with_suffix}, TExtension::{extension}, BuiltInParameters::{parameters_var_name}, {param_count}, {return_type}, EOp{op}, {known_to_not_have_side_effects});'
function_declarations.append(template_function_declaration.format(**template_args)) function_declarations.append(template_function_declaration.format(**template_args))
# If we can make sure that there's no other mangled name with the same length, function template_mangled_name_declaration = 'constexpr const ImmutableString {unique_name}("{mangled_name}");'
# name and hash, then we can only check the mangled name length and the function name name_declarations.add(template_mangled_name_declaration.format(**template_args))
# instead of checking the whole mangled name. template_mangled_if = """if (name == BuiltInName::{unique_name})
template_mangled_if = ''
if mangled_name_hash_can_collide_with_different_parameters(
template_args, num_type_variants, ttype_mangled_name_variants,
script_generated_hash_tests):
template_mangled_name_declaration = 'constexpr const ImmutableString {unique_name}("{mangled_name}");'
name_declarations.add(template_mangled_name_declaration.format(**template_args))
template_mangled_if = """if (name == BuiltInName::{unique_name})
{{ {{
return &BuiltInFunction::kFunction_{unique_name}; return &BuiltInFunction::kFunction_{unique_name};
}}""" }}"""
else:
template_mangled_if = """if (name.beginsWith(BuiltInName::{name_with_suffix}))
{{
ASSERT(name.length() == {mangled_name_length});
return &BuiltInFunction::kFunction_{unique_name};
}}"""
mangled_if = template_mangled_if.format(**template_args) mangled_if = template_mangled_if.format(**template_args)
get_builtin_if_statements.add_obj(level, condition, template_args['mangled_name'], get_builtin_if_statements.add_obj(level, condition, template_args['mangled_name'],
{'hash_matched_code': mangled_if}) {'hash_matched_code': mangled_if})
...@@ -978,12 +986,12 @@ def process_single_function_group( ...@@ -978,12 +986,12 @@ def process_single_function_group(
id_counter += 1 id_counter += 1
def process_function_group( def process_function_group(group_name, group, parameter_declarations, name_declarations,
group_name, group, num_type_variants, parameter_declarations, ttype_mangled_name_variants, unmangled_function_if_statements, unmangled_builtin_declarations,
name_declarations, unmangled_function_if_statements, unmangled_builtin_declarations, defined_function_variants, builtin_id_declarations,
defined_function_variants, builtin_id_declarations, builtin_id_definitions, builtin_id_definitions, defined_parameter_names, variable_declarations,
defined_parameter_names, variable_declarations, function_declarations, function_declarations, script_generated_hash_tests,
script_generated_hash_tests, get_builtin_if_statements, is_in_group_definitions): get_builtin_if_statements, is_in_group_definitions):
global id_counter global id_counter
first_id = id_counter first_id = id_counter
...@@ -992,21 +1000,20 @@ def process_function_group( ...@@ -992,21 +1000,20 @@ def process_function_group(
condition = group['condition'] condition = group['condition']
process_single_function_group( process_single_function_group(
condition, group_name, group, num_type_variants, parameter_declarations, condition, group_name, group, parameter_declarations, name_declarations,
ttype_mangled_name_variants, name_declarations, unmangled_function_if_statements, unmangled_function_if_statements, unmangled_builtin_declarations,
unmangled_builtin_declarations, defined_function_variants, builtin_id_declarations, defined_function_variants, builtin_id_declarations, builtin_id_definitions,
builtin_id_definitions, defined_parameter_names, variable_declarations, defined_parameter_names, variable_declarations, function_declarations,
function_declarations, script_generated_hash_tests, get_builtin_if_statements) script_generated_hash_tests, get_builtin_if_statements)
if 'subgroups' in group: if 'subgroups' in group:
for subgroup_name, subgroup in group['subgroups'].iteritems(): for subgroup_name, subgroup in group['subgroups'].iteritems():
process_function_group( process_function_group(
group_name + subgroup_name, subgroup, num_type_variants, parameter_declarations, group_name + subgroup_name, subgroup, parameter_declarations, name_declarations,
ttype_mangled_name_variants, name_declarations, unmangled_function_if_statements, unmangled_function_if_statements, unmangled_builtin_declarations,
unmangled_builtin_declarations, defined_function_variants, builtin_id_declarations, defined_function_variants, builtin_id_declarations, builtin_id_definitions,
builtin_id_definitions, defined_parameter_names, variable_declarations, defined_parameter_names, variable_declarations, function_declarations,
function_declarations, script_generated_hash_tests, get_builtin_if_statements, script_generated_hash_tests, get_builtin_if_statements, is_in_group_definitions)
is_in_group_definitions)
if 'queryFunction' in group: if 'queryFunction' in group:
template_args = {'first_id': first_id, 'last_id': id_counter - 1, 'group_name': group_name} template_args = {'first_id': first_id, 'last_id': id_counter - 1, 'group_name': group_name}
...@@ -1083,8 +1090,8 @@ def process_single_variable_group(condition, group_name, group, builtin_id_decla ...@@ -1083,8 +1090,8 @@ def process_single_variable_group(condition, group_name, group, builtin_id_decla
# Handle struct and interface block definitions. # Handle struct and interface block definitions.
template_args['class'] = props['class'] template_args['class'] = props['class']
template_args['fields'] = 'fields_{name_with_suffix}'.format(**template_args) template_args['fields'] = 'fields_{name_with_suffix}'.format(**template_args)
init_member_variables.append(' TFieldList *{fields} = new TFieldList();'.format( init_member_variables.append(
**template_args)) ' TFieldList *{fields} = new TFieldList();'.format(**template_args))
for field_name, field_type in props['fields'].iteritems(): for field_name, field_type in props['fields'].iteritems():
template_args['field_name'] = field_name template_args['field_name'] = field_name
template_args['field_type'] = TType(field_type).get_dynamic_type_string() template_args['field_type'] = TType(field_type).get_dynamic_type_string()
...@@ -1255,7 +1262,6 @@ def main(): ...@@ -1255,7 +1262,6 @@ def main():
test_filename = '../../tests/compiler_tests/ImmutableString_test_autogen.cpp' test_filename = '../../tests/compiler_tests/ImmutableString_test_autogen.cpp'
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'
hash_filename = 'builtin_symbols_hash_autogen.txt'
# auto_script parameters. # auto_script parameters.
if args.auto_script_command != '': if args.auto_script_command != '':
...@@ -1264,12 +1270,12 @@ def main(): ...@@ -1264,12 +1270,12 @@ def main():
variables_json_filename, variables_json_filename,
] ]
outputs = [ outputs = [
'ImmutableString_autogen.cpp',
'ParseContext_autogen.h', 'ParseContext_autogen.h',
'SymbolTable_autogen.cpp', 'SymbolTable_autogen.cpp',
'SymbolTable_autogen.h', 'SymbolTable_autogen.h',
'tree_util/BuiltIn_autogen.h', 'tree_util/BuiltIn_autogen.h',
test_filename, test_filename,
hash_filename,
] ]
if args.auto_script_command == 'inputs': if args.auto_script_command == 'inputs':
...@@ -1281,20 +1287,6 @@ def main(): ...@@ -1281,20 +1287,6 @@ def main():
return 1 return 1
return 0 return 0
all_inputs = [os.path.abspath(__file__), variables_json_filename, functions_txt_filename]
# This script takes a while to run since it searches for hash collisions of mangled names. To avoid
# running it unnecessarily, we first check if we've already ran it with the same inputs.
m = hashlib.md5()
for input_path in all_inputs:
with open(input_path, 'rU') as input_file:
m.update(input_file.read())
input_hash = m.hexdigest()
if os.path.exists(hash_filename):
with open(hash_filename) as hash_file:
if input_hash == hash_file.read():
print "Canceling ESSL static builtins code generator - generated hash matches inputs."
sys.exit(0)
# Declarations of symbol unique ids # Declarations of symbol unique ids
builtin_id_declarations = [] builtin_id_declarations = []
...@@ -1340,8 +1332,6 @@ def main(): ...@@ -1340,8 +1332,6 @@ def main():
# declaration. # declaration.
parameter_declarations = {} parameter_declarations = {}
ttype_mangled_name_variants = []
defined_function_variants = set() defined_function_variants = set()
defined_parameter_names = set() defined_parameter_names = set()
...@@ -1362,41 +1352,28 @@ def main(): ...@@ -1362,41 +1352,28 @@ def main():
with open(variables_json_filename) as f: with open(variables_json_filename) as f:
parsed_variables = json.load(f, object_pairs_hook=OrderedDict) parsed_variables = json.load(f, object_pairs_hook=OrderedDict)
for basic_type in basic_types_enumeration: # This script uses a perfect hash function to avoid dealing with collisions
primary_sizes = [1] names = []
secondary_sizes = [1] for group_name, group in parsed_functions.iteritems():
if basic_type in ['Float', 'Int', 'UInt', 'Bool']: get_function_names(group, names)
primary_sizes = [1, 2, 3, 4] for group_name, group in parsed_variables.iteritems():
if basic_type == 'Float': get_variable_names(group, names)
secondary_sizes = [1, 2, 3, 4] # Remove duplicates
for primary_size in primary_sizes: names = list(dict.fromkeys(names))
for secondary_size in secondary_sizes: names_dict = dict(zip(names, range(1, len(names) + 1)))
type = TType({ # Generate the perfect hash function
'basic': basic_type, f1, f2, G = generate_hash(names_dict, Hash2)
'primarySize': primary_size, hashfn = HashFunction(f1, f2, G)
'secondarySize': secondary_size S1 = f1.salt
}) S2 = f2.salt
ttype_mangled_name_variants.append(type.get_mangled_name())
num_type_variants = len(ttype_mangled_name_variants)
# Sanity check for get_mangled_name_variant_hash:
variant_hash = get_mangled_name_variant_hash(
hash32("atan("), 3, 4, len("atan(0123"), num_type_variants, ttype_mangled_name_variants)
mangled_name_hash = mangledNameHash(
"atan(" + get_parameters_mangled_name_variant(
3, 4, len("atan(0123"), ttype_mangled_name_variants), script_generated_hash_tests)
if variant_hash != mangled_name_hash:
raise Exception("get_mangled_name_variant_hash sanity check failed")
for group_name, group in parsed_functions.iteritems(): for group_name, group in parsed_functions.iteritems():
process_function_group( process_function_group(
group_name, group, num_type_variants, parameter_declarations, group_name, group, parameter_declarations, name_declarations,
ttype_mangled_name_variants, name_declarations, unmangled_function_if_statements, unmangled_function_if_statements, unmangled_builtin_declarations,
unmangled_builtin_declarations, defined_function_variants, builtin_id_declarations, defined_function_variants, builtin_id_declarations, builtin_id_definitions,
builtin_id_definitions, defined_parameter_names, variable_declarations, defined_parameter_names, variable_declarations, function_declarations,
function_declarations, script_generated_hash_tests, get_builtin_if_statements, script_generated_hash_tests, get_builtin_if_statements, is_in_group_definitions)
is_in_group_definitions)
parameter_declarations = prune_parameters_arrays(parameter_declarations, function_declarations) parameter_declarations = prune_parameters_arrays(parameter_declarations, function_declarations)
...@@ -1446,17 +1423,31 @@ def main(): ...@@ -1446,17 +1423,31 @@ def main():
'init_member_variables': 'init_member_variables':
'\n'.join(init_member_variables), '\n'.join(init_member_variables),
'get_unmangled_builtin': 'get_unmangled_builtin':
unmangled_function_if_statements.get_switch_code(script_generated_hash_tests), unmangled_function_if_statements.get_switch_code(hashfn, script_generated_hash_tests),
'get_builtin': 'get_builtin':
get_builtin_if_statements.get_switch_code(script_generated_hash_tests), get_builtin_if_statements.get_switch_code(hashfn, script_generated_hash_tests),
'max_unmangled_name_length': 'max_unmangled_name_length':
unmangled_function_if_statements.get_max_name_length(), unmangled_function_if_statements.get_max_name_length(),
'max_mangled_name_length': 'max_mangled_name_length':
get_builtin_if_statements.get_max_name_length(), get_builtin_if_statements.get_max_name_length(),
'script_generated_hash_tests': 'script_generated_hash_tests':
'\n'.join(script_generated_hash_tests.iterkeys()) '\n'.join(script_generated_hash_tests.iterkeys()),
'S1':
str(S1).replace('[', ' ').replace(']', ' '),
'S2':
str(S2).replace('[', ' ').replace(']', ' '),
'G':
str(G).replace('[', ' ').replace(']', ' '),
'NG':
len(G),
'NS':
len(S1)
} }
with open('ImmutableString_autogen.cpp', 'wt') as outfile_cpp:
output_cpp = template_immutablestring_cpp.format(**output_strings)
outfile_cpp.write(output_cpp)
with open(test_filename, 'wt') as outfile_cpp: with open(test_filename, 'wt') as outfile_cpp:
output_cpp = template_immutablestringtest_cpp.format(**output_strings) output_cpp = template_immutablestringtest_cpp.format(**output_strings)
outfile_cpp.write(output_cpp) outfile_cpp.write(output_cpp)
...@@ -1477,9 +1468,6 @@ def main(): ...@@ -1477,9 +1468,6 @@ def main():
output_h = template_symboltable_h.format(**output_strings) output_h = template_symboltable_h.format(**output_strings)
outfile_h.write(output_h) outfile_h.write(output_h)
with open(hash_filename, 'wt') as hash_file:
hash_file.write(input_hash)
return 0 return 0
......
This source diff could not be displayed because it is too large. You can view the blob instead.
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