]> git.draconx.ca Git - cdecl99.git/commitdiff
libcdecl: Further optimize symbol name lookup.
authorNick Bowler <nbowler@draconx.ca>
Wed, 21 Feb 2024 03:36:08 +0000 (22:36 -0500)
committerNick Bowler <nbowler@draconx.ca>
Wed, 21 Feb 2024 03:54:30 +0000 (22:54 -0500)
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.

src/fix-yytname.awk

index 4f46871c19c93ccd7f99dd5690dee1ea081fa370..f1c0307faabe4e592acc08d11f7bd13aa4bdc2c9 100755 (executable)
@@ -99,63 +99,66 @@ in_table && $0 ~ /^};/ {
   print "#endif";
   print "#ifndef assert";
   print "#  include <assert.h>";
-  print "#endif\n";
+  print "#endif";
+  print "#ifndef offsetof";
+  print "#  include <stddef.h>";
+  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)