* g++.dg/compat/struct-layout-1.exp: Do not link with libiberty.
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Dec 2005 07:59:01 +0000 (07:59 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Dec 2005 07:59:01 +0000 (07:59 +0000)
* g++.dg/compat/struct-layout-1_generate.c (config.h): Do not include.
(limits.h): Include unconditionally.
(stdlib.h): Likewise.
(hashtab.h): Do not include.
(getopt.h): Likewise.
(stddef.h): Include.
(hashval_t): Define.
(struct entry): Add "next" field.
(HASH_SIZE): New macro.
(hash_table): New variable.
(switchfiles): Do not use xmalloc.
(mix): New macro.
(iterative_hash): New function.
(hasht): Remove.
(e_exists): New function.
(e_insert): Likewise.
(output): Use, instead of libiberty hashtable functions.
(main): Do not use getopt.  Do not call htab_create.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@108461 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/compat/struct-layout-1.exp
gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c

index e71e05e..9bde74d 100644 (file)
@@ -1,4 +1,25 @@
-2005-12-13  Jakub Jelinek  <jakub@redhat.com>
+2005-12-13  Mark Mitchell  <mark@codesourcery.com>
+           Jakub Jelinek  <jakub@redhat.com>
+
+       * g++.dg/compat/struct-layout-1.exp: Do not link with libiberty.
+       * g++.dg/compat/struct-layout-1_generate.c (config.h): Do not include.
+       (limits.h): Include unconditionally.
+       (stdlib.h): Likewise.
+       (hashtab.h): Do not include.
+       (getopt.h): Likewise.
+       (stddef.h): Include.
+       (hashval_t): Define.
+       (struct entry): Add "next" field.
+       (HASH_SIZE): New macro.
+       (hash_table): New variable.
+       (switchfiles): Do not use xmalloc.
+       (mix): New macro.
+       (iterative_hash): New function.
+       (hasht): Remove.
+       (e_exists): New function.
+       (e_insert): Likewise.
+       (output): Use, instead of libiberty hashtable functions.
+       (main): Do not use getopt.  Do not call htab_create.
 
        PR c++/25331
        * gcc.dg/compat/struct-layout-1_generate.c (subfield): Don't
index d2e1de9..e0a13f7 100644 (file)
@@ -127,10 +127,7 @@ set generator "$tmpdir/g++.dg-struct-layout-1_generate"
 set generator_src "$srcdir/$subdir/struct-layout-1_generate.c"
 set generator_src "$generator_src $srcdir/$subdir/../../gcc.dg/compat/generate-random.c"
 set generator_src "$generator_src $srcdir/$subdir/../../gcc.dg/compat/generate-random_r.c"
-set generator_inc "-I$srcdir/$subdir -I$srcdir/../../include"
-set generator_inc "$generator_inc -I$rootme/../libiberty"
-set generator_lib "-L$rootme/../libiberty -liberty"
-set generator_cmd "-o $generator $generator_src $generator_inc $generator_lib"
+set generator_cmd "-o $generator $generator_src"
 
 set status [remote_exec host "$HOSTCC $HOSTCFLAGS $generator_cmd"]
 set status [lindex $status 0]
index da915c7..a2aba71 100644 (file)
@@ -19,23 +19,15 @@ along with GCC; see the file COPYING.  If not, write to the Free
 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 02110-1301, USA.  */
 
-/* Compile with gcc -I$(srcdir)/../include -{I,L}$(objdir)/../libiberty/ \
-   -o struct-layout-1_generate{,.c} generate_random{,_r}.c -liberty */
+/* Compile with gcc -o struct-layout-1_generate{,.c} generate_random{,_r}.c */
 
-#include "config.h"
-#ifdef HAVE_LIMITS_H
+/* N.B. -- This program cannot use libiberty as that will not work
+   when testing an installed compiler.  */
 #include <limits.h>
-#endif
-#include "libiberty.h"
 #include <stdio.h>
-#ifdef HAVE_STDLIB_H
 #include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
 #include <string.h>
-#endif
-#include "hashtab.h"
-#include "getopt.h"
+#include <stddef.h>
 /* We use our own pseudo-random number generator, so that it gives the same
    values on all hosts.  */
 #include "../../gcc.dg/compat/generate-random.h"
@@ -44,6 +36,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 # error Need 64-bit long long
 #endif
 
+typedef unsigned int hashval_t;
+
 enum TYPE
 {
   TYPE_INT,
@@ -390,6 +384,8 @@ struct entry
   unsigned char arr_len;
   struct types *type;
   const char *attrib;
+  /* Used to chain together entries in the hash table.  */
+  struct entry *next;
 };
 struct types attrib_array_types[] = {
 { "Talx1char", TYPE_UINT, 127, 'C' },
@@ -478,6 +474,10 @@ struct types attrib_array_types[] = {
 #define NAATYPES2 (sizeof (attrib_array_types) / sizeof (attrib_array_types[0]))
 };
 
+/* A prime number giving the number of slots in the hash table.  */
+#define HASH_SIZE 32749
+static struct entry *hash_table[HASH_SIZE];
+
 static int idx, limidx, output_one;
 static const char *destdir;
 static const char *srcdir;
@@ -499,7 +499,9 @@ switchfiles (int fields)
   if (destbuf == NULL)
     {
       size_t len = strlen (destdir);
-      destbuf = xmalloc (len + 20);
+      destbuf = malloc (len + 20);
+      if (!destbuf)
+       abort ();
       memcpy (destbuf, destdir, len);
       if (!len || destbuf[len - 1] != '/')
        destbuf[len++] = '/';
@@ -916,6 +918,130 @@ subvalues (struct entry *e, char *p, char *letter)
     }
 }
 
+/* DERIVED FROM:
+--------------------------------------------------------------------
+lookup2.c, by Bob Jenkins, December 1996, Public Domain.
+hash(), hash2(), hash3, and mix() are externally useful functions.
+Routines to test the hash are included if SELF_TEST is defined.
+You can use this free for any purpose.  It has no warranty.
+--------------------------------------------------------------------
+*/
+
+/*
+--------------------------------------------------------------------
+mix -- mix 3 32-bit values reversibly.
+For every delta with one or two bit set, and the deltas of all three
+  high bits or all three low bits, whether the original value of a,b,c
+  is almost all zero or is uniformly distributed,
+* If mix() is run forward or backward, at least 32 bits in a,b,c
+  have at least 1/4 probability of changing.
+* If mix() is run forward, every bit of c will change between 1/3 and
+  2/3 of the time.  (Well, 22/100 and 78/100 for some 2-bit deltas.)
+mix() was built out of 36 single-cycle latency instructions in a 
+  structure that could supported 2x parallelism, like so:
+      a -= b; 
+      a -= c; x = (c>>13);
+      b -= c; a ^= x;
+      b -= a; x = (a<<8);
+      c -= a; b ^= x;
+      c -= b; x = (b>>13);
+      ...
+  Unfortunately, superscalar Pentiums and Sparcs can't take advantage 
+  of that parallelism.  They've also turned some of those single-cycle
+  latency instructions into multi-cycle latency instructions.  Still,
+  this is the fastest good hash I could find.  There were about 2^^68
+  to choose from.  I only looked at a billion or so.
+--------------------------------------------------------------------
+*/
+/* same, but slower, works on systems that might have 8 byte hashval_t's */
+#define mix(a,b,c) \
+{ \
+  a -= b; a -= c; a ^= (c>>13); \
+  b -= c; b -= a; b ^= (a<< 8); \
+  c -= a; c -= b; c ^= ((b&0xffffffff)>>13); \
+  a -= b; a -= c; a ^= ((c&0xffffffff)>>12); \
+  b -= c; b -= a; b = (b ^ (a<<16)) & 0xffffffff; \
+  c -= a; c -= b; c = (c ^ (b>> 5)) & 0xffffffff; \
+  a -= b; a -= c; a = (a ^ (c>> 3)) & 0xffffffff; \
+  b -= c; b -= a; b = (b ^ (a<<10)) & 0xffffffff; \
+  c -= a; c -= b; c = (c ^ (b>>15)) & 0xffffffff; \
+}
+
+/*
+--------------------------------------------------------------------
+hash() -- hash a variable-length key into a 32-bit value
+  k     : the key (the unaligned variable-length array of bytes)
+  len   : the length of the key, counting by bytes
+  level : can be any 4-byte value
+Returns a 32-bit value.  Every bit of the key affects every bit of
+the return value.  Every 1-bit and 2-bit delta achieves avalanche.
+About 36+6len instructions.
+
+The best hash table sizes are powers of 2.  There is no need to do
+mod a prime (mod is sooo slow!).  If you need less than 32 bits,
+use a bitmask.  For example, if you need only 10 bits, do
+  h = (h & hashmask(10));
+In which case, the hash table should have hashsize(10) elements.
+
+If you are hashing n strings (ub1 **)k, do it like this:
+  for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
+
+By Bob Jenkins, 1996.  bob_jenkins@burtleburtle.net.  You may use this
+code any way you wish, private, educational, or commercial.  It's free.
+
+See http://burtleburtle.net/bob/hash/evahash.html
+Use for hash table lookup, or anything where one collision in 2^32 is
+acceptable.  Do NOT use for cryptographic purposes.
+--------------------------------------------------------------------
+*/
+
+static hashval_t
+iterative_hash (const void *k_in /* the key */,
+               register size_t  length /* the length of the key */,
+               register hashval_t initval /* the previous hash, or
+                                             an arbitrary value */)
+{
+  register const unsigned char *k = (const unsigned char *)k_in;
+  register hashval_t a,b,c,len;
+
+  /* Set up the internal state */
+  len = length;
+  a = b = 0x9e3779b9;  /* the golden ratio; an arbitrary value */
+  c = initval;    /* the previous hash value */
+
+  /*---------------------------------------- handle most of the key */
+    while (len >= 12)
+      {
+       a += (k[0] +((hashval_t)k[1]<<8) +((hashval_t)k[2]<<16) +((hashval_t)k[3]<<24));
+       b += (k[4] +((hashval_t)k[5]<<8) +((hashval_t)k[6]<<16) +((hashval_t)k[7]<<24));
+       c += (k[8] +((hashval_t)k[9]<<8) +((hashval_t)k[10]<<16)+((hashval_t)k[11]<<24));
+       mix(a,b,c);
+       k += 12; len -= 12;
+      }
+
+  /*------------------------------------- handle the last 11 bytes */
+  c += length;
+  switch(len)        /* all the case statements fall through */
+    {
+    case 11: c+=((hashval_t)k[10]<<24);
+    case 10: c+=((hashval_t)k[9]<<16);
+    case 9 : c+=((hashval_t)k[8]<<8);
+      /* the first byte of c is reserved for the length */
+    case 8 : b+=((hashval_t)k[7]<<24);
+    case 7 : b+=((hashval_t)k[6]<<16);
+    case 6 : b+=((hashval_t)k[5]<<8);
+    case 5 : b+=k[4];
+    case 4 : a+=((hashval_t)k[3]<<24);
+    case 3 : a+=((hashval_t)k[2]<<16);
+    case 2 : a+=((hashval_t)k[1]<<8);
+    case 1 : a+=k[0];
+      /* case 0: nothing left to add */
+    }
+  mix(a,b,c);
+  /*-------------------------------------------- report the result */
+  return c;
+}
+
 hashval_t
 e_hash (const void *a)
 {
@@ -961,24 +1087,45 @@ e_eq (const void *a, const void *b)
   return 1;
 }
 
-htab_t hasht;
+static int 
+e_exists (const struct entry *e) 
+{
+  struct entry *h;
+  hashval_t hval;
+
+  hval = e_hash (e);
+  for (h = hash_table[hval % HASH_SIZE]; h; h = h->next)
+    if (e_eq (e, h))
+      return 1;
+  return 0;
+}
+
+static void
+e_insert (struct entry *e)
+{
+  hashval_t hval;
+
+  hval = e_hash (e);
+  e->next = hash_table[hval % HASH_SIZE];
+  hash_table[hval % HASH_SIZE] = e;
+}
 
 void
 output (struct entry *e)
 {
   int i;
   char c;
-  void **p;
+  struct entry *n;
 
   if (e[0].etype != ETYPE_STRUCT && e[0].etype != ETYPE_UNION)
     abort ();
 
-  p = htab_find_slot (hasht, e, INSERT);
-  if (*p != NULL)
+  if (e_exists (e))
     return;
 
-  *p = malloc ((e[0].len + 1) * sizeof (struct entry));
-  memcpy (*p, e, (e[0].len + 1) * sizeof (struct entry));
+  n = (struct entry *) malloc ((e[0].len + 1) * sizeof (struct entry));
+  memcpy (n, e, (e[0].len + 1) * sizeof (struct entry));
+  e_insert (n);
 
   if (idx == limidx)
     switchfiles (e[0].len);
@@ -1357,29 +1504,41 @@ int
 main (int argc, char **argv)
 {
   int i, j, count, c, n = 3000;
+  char *optarg;
 
   if (sizeof (int) != 4 || sizeof (long long) != 8)
     return 1;
-
-  while ((c = getopt (argc, argv, "d:i:n:s:")) != -1)
-    switch (c)
-      {
-      case 'n':
-       n = atoi (optarg);
-       break;
-      case 'd':
-       destdir = optarg;
-       break;
-      case 's':
-       srcdir = optarg;
-       break;
-      case 'i':
-       output_one = 1;
-       limidx = atoi (optarg);
-       break;
-      default:
+  
+  i = 1;
+  while (i < argc) 
+    {
+      c = '\0';
+      if (argv[i][0] == '-' && argv[i][2] == '\0')
+       c = argv[i][1];
+      optarg = argv[i + 1];
+      if (!optarg)
        goto usage;
+      switch (c)
+       {
+       case 'n':
+         n = atoi (optarg);
+         break;
+       case 'd':
+         destdir = optarg;
+         break;
+       case 's':
+         srcdir = optarg;
+         break;
+       case 'i':
+         output_one = 1;
+         limidx = atoi (optarg);
+         break;
+       default:
+         fprintf (stderr, "unrecognized option %s\n", argv[i]);
+         goto usage;
       }
+      i += 2;
+    }
 
   if (output_one)
     {
@@ -1404,7 +1563,6 @@ Either -s srcdir -d destdir or -i idx must be used\n", argv[0]);
   if (srcdir == NULL && !output_one)
     goto usage;
 
-  hasht = htab_create (40000, e_hash, e_eq, NULL);
   for (i = 0; i < NTYPES2; ++i)
     if (base_types[i].bitfld)
       bitfld_types[n_bitfld_types++] = base_types[i];