OSDN Git Service

* attribs.c: Include hashtab.h
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Jul 2007 20:27:17 +0000 (20:27 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 27 Jul 2007 20:27:17 +0000 (20:27 +0000)
(attribute_hash): New.
(substring): New structure.
(extract_attribute_substring, substring_hash, hash_attr, eq_attr):
New function.
(init_attributes): Initialize attribute hash.
(decl_attributes): Use attribute hash.
* Makefile.in (attribs.c): Depend on hashtab.h.

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

gcc/ChangeLog
gcc/attribs.c

index 9d6dcdc..62ba07d 100644 (file)
@@ -1,3 +1,14 @@
+2007-07-27  Jan Hubicka  <jh@suse.cz>
+
+       * attribs.c: Include hashtab.h
+       (attribute_hash): New.
+       (substring): New structure.
+       (extract_attribute_substring, substring_hash, hash_attr, eq_attr):
+       New function.
+       (init_attributes): Initialize attribute hash.
+       (decl_attributes): Use attribute hash.
+       * Makefile.in (attribs.c): Depend on hashtab.h.
+
 2007-07-27  Steve Ellcey  <sje@cup.hp.com>
 
        * config/ia64/vect.md (vec_initv2si): Remove bad BIG_ENDIAN test.
index cbc6056..5ac72f7 100644 (file)
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cpplib.h"
 #include "target.h"
 #include "langhooks.h"
+#include "hashtab.h"
 
 static void init_attributes (void);
 
@@ -39,14 +40,70 @@ static void init_attributes (void);
    searched.  */
 static const struct attribute_spec *attribute_tables[4];
 
+/* Hashtable mapping names (represented as substrings) to attribute specs. */
+static htab_t attribute_hash;
+
+/* Substring representation.  */
+
+struct substring
+{
+  const char *str;
+  int length;
+};
+
 static bool attributes_initialized = false;
 
 /* Default empty table of attributes.  */
+
 static const struct attribute_spec empty_attribute_table[] =
 {
   { NULL, 0, 0, false, false, false, NULL }
 };
 
+/* Return base name of the attribute.  Ie '__attr__' is turned into 'attr'.
+   To avoid need for copying, we simply return length of the string.  */
+
+static void
+extract_attribute_substring (struct substring *str)
+{
+  if (str->length > 4 && str->str[0] == '_' && str->str[1] == '_'
+      && str->str[str->length - 1] == '_' && str->str[str->length - 2] == '_')
+    {
+      str->length -= 4;
+      str->str += 2;
+    }
+}
+
+/* Simple hash function to avoid need to scan whole string.  */
+
+static inline hashval_t
+substring_hash (const char *str, int l)
+{
+  return str[0] + str[l - 1] * 256 + l * 65536;
+}
+
+/* Used for attribute_hash.  */
+
+static hashval_t
+hash_attr (const void *p)
+{
+  struct attribute_spec *spec = (struct attribute_spec *) p;
+  int l = strlen (spec->name);
+
+  return substring_hash (spec->name, l);
+}
+
+/* Used for attribute_hash.  */
+
+static int
+eq_attr (const void *p, const void *q)
+{
+  const struct attribute_spec *spec = (struct attribute_spec *) p;
+  const struct substring *str = (struct substring *) q;
+
+  return (!strncmp (spec->name, str->str, str->length) && !spec->name[str->length]);
+}
+
 /* Initialize attribute tables, and make some sanity checks
    if --enable-checking.  */
 
@@ -54,6 +111,7 @@ static void
 init_attributes (void)
 {
   size_t i;
+  int k;
 
   attribute_tables[0] = lang_hooks.common_attribute_table;
   attribute_tables[1] = lang_hooks.attribute_table;
@@ -120,6 +178,21 @@ init_attributes (void)
     }
 #endif
 
+  attribute_hash = htab_create (200, hash_attr, eq_attr, NULL);
+  for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
+    for (k = 0; attribute_tables[i][k].name != NULL; k++)
+      {
+       struct substring str;
+       void **slot;
+
+       str.str = attribute_tables[i][k].name;
+       str.length = strlen (attribute_tables[i][k].name);
+       slot = htab_find_slot_with_hash (attribute_hash, &str,
+                                        substring_hash (str.str, str.length),
+                                        INSERT);
+       gcc_assert (!*slot);
+       *slot = (void *)&attribute_tables[i][k];
+      }
   attributes_initialized = true;
 }
 \f
@@ -151,23 +224,13 @@ decl_attributes (tree *node, tree attributes, int flags)
       const struct attribute_spec *spec = NULL;
       bool no_add_attrs = 0;
       tree fn_ptr_tmp = NULL_TREE;
-      size_t i;
-
-      for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
-       {
-         int j;
+      struct substring attr;
 
-         for (j = 0; attribute_tables[i][j].name != NULL; j++)
-           {
-             if (is_attribute_p (attribute_tables[i][j].name, name))
-               {
-                 spec = &attribute_tables[i][j];
-                 break;
-               }
-           }
-         if (spec != NULL)
-           break;
-       }
+      attr.str = IDENTIFIER_POINTER (name);
+      attr.length = IDENTIFIER_LENGTH (name);
+      extract_attribute_substring (&attr);
+      spec = htab_find_with_hash (attribute_hash, &attr,
+                                 substring_hash (attr.str, attr.length));
 
       if (spec == NULL)
        {
@@ -183,6 +246,7 @@ decl_attributes (tree *node, tree attributes, int flags)
                 IDENTIFIER_POINTER (name));
          continue;
        }
+      gcc_assert (is_attribute_p (spec->name, name));
 
       if (spec->decl_required && !DECL_P (*anode))
        {