From: Nick Bowler Date: Wed, 21 Feb 2024 03:36:08 +0000 (-0500) Subject: libcdecl: Further optimize symbol name lookup. X-Git-Tag: v1.3~14 X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/commitdiff_plain/847964f010e5f56bcd13a6dde2d0a73e7cc67273 libcdecl: Further optimize symbol name lookup. We can combine the mapping and string tables into a single static allocation, which allows everything to be offset from a single base address which is slightly more efficient. Since we are not fitting these offsets in 8 bits, and are nowhere near exceeding 16 bits, just use uint_least16_t for the mapping table unconditionally instead of trying to come up with a new preprocessor conditional string that works with the new calculation. --- diff --git a/src/fix-yytname.awk b/src/fix-yytname.awk index 4f46871..f1c0307 100755 --- a/src/fix-yytname.awk +++ b/src/fix-yytname.awk @@ -99,63 +99,66 @@ in_table && $0 ~ /^};/ { print "#endif"; print "#ifndef assert"; print "# include "; - print "#endif\n"; + print "#endif"; + print "#ifndef offsetof"; + print "# include "; + print "#endif\n" print "static const char *tname(unsigned x)"; print "{"; count = bucketsort(sorted_tokens, tokens); - table = build_strtab(sorted_tokens, count, token_offsets); - token_offset_max = TMAX; - nterm_offset = TLEN; - - sub("\1$", "", table); - gsub("\1", "\"\n\t\t\"\\0\" \"", table); - gsub("\2", "\\", table); - - print "\tstatic const char tname_strings[] ="; - print "\t\t \"" table "\""; + token_table = build_strtab(sorted_tokens, count, token_offsets); + token_size = TLEN; + offset_max = TMAX; if ((count = bucketsort(sorted_nterms, nterms))) { - table = build_strtab(sorted_nterms, count, nterm_offsets); - offset_max = nterm_offset + TMAX; - offset_chk = "(YYDEBUG ? " offset_max " : " token_offset_max ")"; + nterm_table = build_strtab(sorted_nterms, count, nterm_offsets); + offset_max = token_size + TMAX; + nterm_size = TLEN; + } else { + nterm_table = ""; + nterm_size = 0; + } - sub("\1$", "", table); - gsub("\1", "\"\n\t\t\"\\0\" \"", table); - gsub("\2", "\\", table); + print "\tstruct tname_data {"; + print "#if YYDEBUG"; + print "\t\tuint_least16_t map[" num_tokens + num_nterms "];"; + print "\t\tchar tab[" token_size + nterm_size "];"; + print "#else" + print "\t\tuint_least16_t map[" num_tokens "];"; + print "\t\tchar tab[" token_size "];"; + print "#endif"; + print "\t};"; + print "\n\tenum { O = offsetof(struct tname_data, tab) };"; + print "\tstatic const struct tname_data data = {"; + print "\t\t{"; + print_offsets(token_offsets, tokens, num_tokens, log10(offset_max)); + if (num_nterms) { print "#if YYDEBUG"; - if (nterm_offset) - print "\t\t\"\\0\" \"" table "\""; - else - print "\t\t \"" table "\""; + print_offsets(nterm_offsets, nterms, num_nterms, log10(offset_max), token_size); print "#endif"; - } else { - offset_chk = offset_max = token_offset_max; } - print "\t\t;\n"; - - print "\tstatic const"; - print "#if UINT_LEAST8_MAX >= " offset_chk; - print "\tuint_least8_t"; - print "#elif UINT_LEAST16_MAX >= " offset_chk; - print "\tuint_least16_t"; - print "#else"; - print "\tuint_least32_t"; - print "#endif"; - print "\ttname_offsets[] = {"; - print_offsets(token_offsets, tokens, num_tokens, log10(offset_max)); + sub("\1$", "\"", token_table); + gsub("\1", "\"\n\t\t\"\\0\" \"", token_table); + gsub("\2", "\\", token_table); + print "\t\t}, \"" token_table; + if (num_nterms) { print "#if YYDEBUG"; - print_offsets(nterm_offsets, nterms, num_nterms, log10(offset_max), nterm_offset); + sub("\1$", "\"", nterm_table); + gsub("\1", "\"\n\t\t\"\\0\" \"", nterm_table); + gsub("\2", "\\", nterm_table); + print "\t\t\"\\0\" \"" nterm_table; print "#endif"; } - print "\t};\n"; - print "\tassert(x < sizeof tname_offsets / sizeof tname_offsets[0]);"; - print "\treturn tname_strings + tname_offsets[x];"; + print "\t};"; + + print "\n\tassert(x < sizeof data.map / sizeof data.map[0]);" + print "\treturn (char *)&data + data.map[x];"; print "}"; in_table = 0; @@ -227,7 +230,7 @@ function print_offsets(in_offsets, in_strings, in_count, in_w, in_adj, i, t, s) s = ""; for (i = 0; i < in_count; i++) { - s = s sprintf("%" (in_w+1) "d,", (in_offsets[in_strings[i]] + in_adj)); + s = s sprintf("%" (in_w+1) "d+O,", (in_offsets[in_strings[i]] + in_adj)); if (i+1 == in_count) sub(/,$/, "", s); @@ -238,7 +241,8 @@ function print_offsets(in_offsets, in_strings, in_count, in_w, in_adj, i, t, s) } } - print t s; + if (i%8 != 0) + print t s; } # bucketsort(dst, src)