tokhash: Speed up the rejection of unhashed values
authorH. Peter Anvin <hpa@zytor.com>
Fri, 31 Aug 2007 07:23:31 +0000 (07:23 +0000)
committerH. Peter Anvin <hpa@zytor.com>
Fri, 31 Aug 2007 07:23:31 +0000 (07:23 +0000)
Speed up the rejection of unhashed values (typically identifiers) by
filling unused hash slots with a large value (but not so large that
it is likely to overflow.)  This means those values will be rejected
already by the range check, not needing strcmp().

perllib/phash.ph
tokhash.pl

index 017155d..e17874a 100644 (file)
@@ -156,10 +156,16 @@ sub gen_hash_n($$$) {
     # for the edge (which is our hash index.)  Since the graph is
     # acyclic, this is always doable.
     for ($i = 0; $i < $gsize; $i++) {
-       if (!$gr->has_vertex_attribute($i, "val")) {
-           walk_graph($gr,$i,0); # First vertex in a cluster
+       if ($gr->degree($i)) {
+           # This vertex has neighbors (is used)
+           if (!$gr->has_vertex_attribute($i, "val")) {
+               walk_graph($gr,$i,0); # First vertex in a cluster
+           }
+           push(@g, $gr->get_vertex_attribute($i, "val"));
+       } else {
+           # Unused vertex
+           push(@g, undef);
        }
-       push(@g, $gr->get_vertex_attribute($i, "val"));
     }
 
     # for ($i = 0; $i < $n; $i++) {
index 4730a8b..9afe61d 100755 (executable)
@@ -148,17 +148,24 @@ print "\n";
 print "int nasm_token_hash(const char *token, struct tokenval *tv)\n";
 print "{\n";
 
+# Put a large value in unused slots.  This makes it extremely unlikely
+# that any combination that involves unused slot will pass the range test.
+# This speeds up rejection of unrecognized tokens, i.e. identifiers.
+$unused = 16383;
+
 print "\tstatic const int16_t hash1[$n] =\n";
 print "\t{\n";
 for ($i = 0; $i < $n; $i++) {
-    print "\t\t", ${$g}[${$f1}[$i]], ",\n";
+    my $h = ${$g}[${$f1}[$i]];
+    printf "\t\t%d,\n", defined($h) ? $h : $unused;
 }
 print "\t};\n\n";
 
 print "\tstatic const int16_t hash2[$n] =\n";
 print "\t{\n";
 for ($i = 0; $i < $n; $i++) {
-    print "\t\t", ${$g}[${$f2}[$i]], ",\n";
+    my $h = ${$g}[${$f2}[$i]];
+    printf "\t\t%d,\n", defined($h) ? $h : $unused;
 }
 print "\t};\n\n";