OSDN Git Service

* emit-rtl.c (gen_reg_rtx): Also reallocate reg_decl array.
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index 40524c3..a65bfb5 100644 (file)
@@ -2,22 +2,22 @@
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001 Free Software Foundation, Inc.
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
 
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
 
 /* This file contains the low level primitives for operating on tree nodes,
    including allocation, list operations, interning of identifiers,
@@ -99,7 +99,6 @@ typedef enum
   e_kind,
   c_kind,
   id_kind,
-  op_id_kind,
   perm_list_kind,
   temp_list_kind,
   vec_kind,
@@ -122,7 +121,6 @@ static const char * const tree_node_kind_names[] = {
   "exprs",
   "constants",
   "identifiers",
-  "op_identifiers",
   "perm_tree_lists",
   "temp_tree_lists",
   "vecs",
@@ -136,10 +134,6 @@ static int next_decl_uid;
 /* Unique id for next type created.  */
 static int next_type_uid = 1;
 
-/* Here is how primitive or already-canonicalized types' hash
-   codes are made.  */
-#define TYPE_HASH(TYPE) ((unsigned long) (TYPE) & 0777777)
-
 /* Since we cannot rehash a type after it is in the table, we have to
    keep the hash code.  */
 
@@ -164,12 +158,12 @@ htab_t type_hash_table;
 static void build_real_from_int_cst_1 PARAMS ((PTR));
 static void set_type_quals PARAMS ((tree, int));
 static void append_random_chars PARAMS ((char *));
-static void mark_type_hash PARAMS ((void *));
 static int type_hash_eq PARAMS ((const void*, const void*));
 static unsigned int type_hash_hash PARAMS ((const void*));
 static void print_type_hash_statistics PARAMS((void));
-static int mark_hash_entry PARAMS((void **, void *));
 static void finish_vector_type PARAMS((tree));
+static int type_hash_marked_p PARAMS ((const void *));
+static void type_hash_mark PARAMS ((const void *));
 static int mark_tree_hashtable_entry PARAMS((void **, void *));
 
 /* If non-null, these are language-specific helper functions for
@@ -231,7 +225,8 @@ init_obstacks ()
   /* Initialize the hash table of types.  */
   type_hash_table = htab_create (TYPE_HASH_INITIAL_SIZE, type_hash_hash,
                                 type_hash_eq, 0);
-  ggc_add_root (&type_hash_table, 1, sizeof type_hash_table, mark_type_hash);
+  ggc_add_deletable_htab (type_hash_table, type_hash_marked_p,
+                         type_hash_mark);
   ggc_add_tree_root (global_trees, TI_MAX);
   ggc_add_tree_root (integer_types, itk_none);
 
@@ -331,11 +326,11 @@ tree
 make_node (code)
      enum tree_code code;
 {
-  register tree t;
-  register int type = TREE_CODE_CLASS (code);
-  register size_t length;
+  tree t;
+  int type = TREE_CODE_CLASS (code);
+  size_t length;
 #ifdef GATHER_STATISTICS
-  register tree_node_kind kind;
+  tree_node_kind kind;
 #endif
   struct tree_common ttmp;
   
@@ -384,8 +379,6 @@ make_node (code)
     case 'x':  /* something random, like an identifier.  */
       if (code == IDENTIFIER_NODE)
        kind = id_kind;
-      else if (code == OP_IDENTIFIER)
-       kind = op_id_kind;
       else if (code == TREE_VEC)
        kind = vec_kind;
       else
@@ -422,8 +415,8 @@ make_node (code)
       DECL_SOURCE_FILE (t) =
        (input_filename) ? input_filename : "<built-in>";
       DECL_UID (t) = next_decl_uid++;
-      /* Note that we have not yet computed the alias set for this
-        declaration.  */
+
+      /* We have not yet computed the alias set for this declaration.  */
       DECL_POINTER_ALIAS_SET (t) = -1;
       break;
 
@@ -432,12 +425,12 @@ make_node (code)
       TYPE_ALIGN (t) = char_type_node ? TYPE_ALIGN (char_type_node) : 0;
       TYPE_USER_ALIGN (t) = 0;
       TYPE_MAIN_VARIANT (t) = t;
+
+      /* Default to no attributes for type, but let target change that.  */
       TYPE_ATTRIBUTES (t) = NULL_TREE;
-#ifdef SET_DEFAULT_TYPE_ATTRIBUTES
-      SET_DEFAULT_TYPE_ATTRIBUTES (t);
-#endif
-      /* Note that we have not yet computed the alias set for this
-        type.  */
+      (*targetm.set_default_type_attributes) (t);
+
+      /* We have not yet computed the alias set for this type.  */
       TYPE_ALIAS_SET (t) = -1;
       break;
 
@@ -492,9 +485,9 @@ tree
 copy_node (node)
      tree node;
 {
-  register tree t;
-  register enum tree_code code = TREE_CODE (node);
-  register size_t length;
+  tree t;
+  enum tree_code code = TREE_CODE (node);
+  size_t length;
 
   length = tree_size (node);
   t = ggc_alloc_tree (length);
@@ -528,7 +521,7 @@ copy_list (list)
      tree list;
 {
   tree head;
-  register tree prev, next;
+  tree prev, next;
 
   if (list == 0)
     return 0;
@@ -556,7 +549,7 @@ build_int_2_wide (low, hi)
      unsigned HOST_WIDE_INT low;
      HOST_WIDE_INT hi;
 {
-  register tree t = make_node (INTEGER_CST);
+  tree t = make_node (INTEGER_CST);
 
   TREE_INT_CST_LOW (t) = low;
   TREE_INT_CST_HIGH (t) = hi;
@@ -720,7 +713,7 @@ build_string (len, str)
      int len;
      const char *str;
 {
-  register tree s = make_node (STRING_CST);
+  tree s = make_node (STRING_CST);
 
   TREE_STRING_LENGTH (s) = len;
   TREE_STRING_POINTER (s) = ggc_alloc_string (str, len);
@@ -738,7 +731,7 @@ build_complex (type, real, imag)
      tree type;
      tree real, imag;
 {
-  register tree t = make_node (COMPLEX_CST);
+  tree t = make_node (COMPLEX_CST);
 
   TREE_REALPART (t) = real;
   TREE_IMAGPART (t) = imag;
@@ -755,8 +748,8 @@ tree
 make_tree_vec (len)
      int len;
 {
-  register tree t;
-  register int length = (len-1) * sizeof (tree) + sizeof (struct tree_vec);
+  tree t;
+  int length = (len-1) * sizeof (tree) + sizeof (struct tree_vec);
 
 #ifdef GATHER_STATISTICS
   tree_node_counts[(int)vec_kind]++;
@@ -815,8 +808,8 @@ int
 integer_all_onesp (expr)
      tree expr;
 {
-  register int prec;
-  register int uns;
+  int prec;
+  int uns;
 
   STRIP_NOPS (expr);
 
@@ -1155,8 +1148,8 @@ int
 list_length (t)
      tree t;
 {
-  register tree tail;
-  register int len = 0;
+  tree tail;
+  int len = 0;
 
   for (tail = t; tail; tail = TREE_CHAIN (tail))
     len++;
@@ -1191,9 +1184,9 @@ chainon (op1, op2)
 
   if (op1)
     {
-      register tree t1;
+      tree t1;
 #ifdef ENABLE_TREE_CHECKING
-      register tree t2;
+      tree t2;
 #endif
 
       for (t1 = op1; TREE_CHAIN (t1); t1 = TREE_CHAIN (t1))
@@ -1214,9 +1207,9 @@ chainon (op1, op2)
 
 tree
 tree_last (chain)
-     register tree chain;
+     tree chain;
 {
-  register tree next;
+  tree next;
   if (chain)
     while ((next = TREE_CHAIN (chain)))
       chain = next;
@@ -1230,7 +1223,7 @@ tree
 nreverse (t)
      tree t;
 {
-  register tree prev = 0, decl, next;
+  tree prev = 0, decl, next;
   for (decl = t; decl; decl = next)
     {
       next = TREE_CHAIN (decl);
@@ -1272,7 +1265,7 @@ tree
 build_tree_list (parm, value)
      tree parm, value;
 {
-  register tree t = make_node (TREE_LIST);
+  tree t = make_node (TREE_LIST);
   TREE_PURPOSE (t) = parm;
   TREE_VALUE (t) = value;
   return t;
@@ -1286,7 +1279,7 @@ tree
 tree_cons (purpose, value, chain)
      tree purpose, value, chain;
 {
-  register tree node;
+  tree node;
 
   node = ggc_alloc_tree (sizeof (struct tree_list));
 
@@ -1555,7 +1548,7 @@ tree
 save_expr (expr)
      tree expr;
 {
-  register tree t = fold (expr);
+  tree t = fold (expr);
 
   /* We don't care about whether this can be used as an lvalue in this
      context.  */
@@ -1628,8 +1621,7 @@ first_rtl_op (code)
     case RTL_EXPR:
       return 0;
     case WITH_CLEANUP_EXPR:
-      /* Should be defined to be 2.  */
-      return 1;
+      return 2;
     case METHOD_CALL_EXPR:
       return 3;
     default:
@@ -1841,7 +1833,7 @@ int
 contains_placeholder_p (exp)
      tree exp;
 {
-  register enum tree_code code;
+  enum tree_code code;
   int result;
 
   if (!exp)
@@ -2166,8 +2158,8 @@ tree
 stabilize_reference (ref)
      tree ref;
 {
-  register tree result;
-  register enum tree_code code = TREE_CODE (ref);
+  tree result;
+  enum tree_code code = TREE_CODE (ref);
 
   switch (code)
     {
@@ -2264,8 +2256,8 @@ tree
 stabilize_reference_1 (e)
      tree e;
 {
-  register tree result;
-  register enum tree_code code = TREE_CODE (e);
+  tree result;
+  enum tree_code code = TREE_CODE (e);
 
   /* We cannot ignore const expressions because it might be a reference
      to a const array but whose index contains side-effects.  But we can
@@ -2339,23 +2331,15 @@ stabilize_reference_1 (e)
 tree
 build VPARAMS ((enum tree_code code, tree tt, ...))
 {
-#ifndef ANSI_PROTOTYPES
-  enum tree_code code;
-  tree tt;
-#endif
-  va_list p;
-  register tree t;
-  register int length;
-  register int i;
+  tree t;
+  int length;
+  int i;
   int fro;
   int constant;
 
-  VA_START (p, tt);
-
-#ifndef ANSI_PROTOTYPES
-  code = va_arg (p, enum tree_code);
-  tt = va_arg (p, tree);
-#endif
+  VA_OPEN (p, tt);
+  VA_FIXEDARG (p, enum tree_code, code);
+  VA_FIXEDARG (p, tree, tt);
 
   t = make_node (code);
   length = TREE_CODE_LENGTH (code);
@@ -2377,8 +2361,8 @@ build VPARAMS ((enum tree_code code, tree tt, ...))
   if (length == 2)
     {
       /* This is equivalent to the loop below, but faster.  */
-      register tree arg0 = va_arg (p, tree);
-      register tree arg1 = va_arg (p, tree);
+      tree arg0 = va_arg (p, tree);
+      tree arg1 = va_arg (p, tree);
 
       TREE_OPERAND (t, 0) = arg0;
       TREE_OPERAND (t, 1) = arg1;
@@ -2405,7 +2389,7 @@ build VPARAMS ((enum tree_code code, tree tt, ...))
     }
   else if (length == 1)
     {
-      register tree arg0 = va_arg (p, tree);
+      tree arg0 = va_arg (p, tree);
 
       /* The only one-operand cases we handle here are those with side-effects.
         Others are handled with build1.  So don't bother checked if the
@@ -2420,7 +2404,7 @@ build VPARAMS ((enum tree_code code, tree tt, ...))
     {
       for (i = 0; i < length; i++)
        {
-         register tree operand = va_arg (p, tree);
+         tree operand = va_arg (p, tree);
 
          TREE_OPERAND (t, i) = operand;
          if (operand && fro > i)
@@ -2432,7 +2416,7 @@ build VPARAMS ((enum tree_code code, tree tt, ...))
            }
        }
     }
-  va_end (p);
+  VA_CLOSE (p);
 
   TREE_CONSTANT (t) = constant;
   return t;
@@ -2448,11 +2432,11 @@ build1 (code, type, node)
      tree type;
      tree node;
 {
-  register int length;
+  int length;
 #ifdef GATHER_STATISTICS
-  register tree_node_kind kind;
+  tree_node_kind kind;
 #endif
-  register tree t;
+  tree t;
 
 #ifdef GATHER_STATISTICS
   if (TREE_CODE_CLASS (code) == 'r')
@@ -2523,19 +2507,12 @@ build1 (code, type, node)
 tree
 build_nt VPARAMS ((enum tree_code code, ...))
 {
-#ifndef ANSI_PROTOTYPES
-  enum tree_code code;
-#endif
-  va_list p;
-  register tree t;
-  register int length;
-  register int i;
-
-  VA_START (p, code);
+  tree t;
+  int length;
+  int i;
 
-#ifndef ANSI_PROTOTYPES
-  code = va_arg (p, enum tree_code);
-#endif
+  VA_OPEN (p, code);
+  VA_FIXEDARG (p, enum tree_code, code);
 
   t = make_node (code);
   length = TREE_CODE_LENGTH (code);
@@ -2543,23 +2520,9 @@ build_nt VPARAMS ((enum tree_code code, ...))
   for (i = 0; i < length; i++)
     TREE_OPERAND (t, i) = va_arg (p, tree);
 
-  va_end (p);
+  VA_CLOSE (p);
   return t;
 }
-
-#if 0
-/* Commented out because this wants to be done very
-   differently.  See cp-lex.c.  */
-tree
-build_op_identifier (op1, op2)
-     tree op1, op2;
-{
-  register tree t = make_node (OP_IDENTIFIER);
-  TREE_PURPOSE (t) = op1;
-  TREE_VALUE (t) = op2;
-  return t;
-}
-#endif
 \f
 /* Create a DECL_... node of code CODE, name NAME and data type TYPE.
    We do NOT enter this node in any sort of symbol table.
@@ -2572,7 +2535,7 @@ build_decl (code, name, type)
      enum tree_code code;
      tree name, type;
 {
-  register tree t;
+  tree t;
 
   t = make_node (code);
 
@@ -2600,7 +2563,7 @@ tree
 build_block (vars, tags, subblocks, supercontext, chain)
      tree vars, tags ATTRIBUTE_UNUSED, subblocks, supercontext, chain;
 {
-  register tree block = make_node (BLOCK);
+  tree block = make_node (BLOCK);
 
   BLOCK_VARS (block) = vars;
   BLOCK_SUBBLOCKS (block) = subblocks;
@@ -2622,7 +2585,7 @@ build_expr_wfl (node, file, line, col)
 {
   static const char *last_file = 0;
   static tree last_filenode = NULL_TREE;
-  register tree wfl = make_node (EXPR_WITH_FILE_LOCATION);
+  tree wfl = make_node (EXPR_WITH_FILE_LOCATION);
 
   EXPR_WFL_NODE (wfl) = node;
   EXPR_WFL_SET_LINECOL (wfl, line, col);
@@ -2642,14 +2605,14 @@ build_expr_wfl (node, file, line, col)
   return wfl;
 }
 \f
-/* Return a declaration like DDECL except that its DECL_MACHINE_ATTRIBUTE
+/* Return a declaration like DDECL except that its DECL_ATTRIBUTES
    is ATTRIBUTE.  */
 
 tree
 build_decl_attribute_variant (ddecl, attribute)
      tree ddecl, attribute;
 {
-  DECL_MACHINE_ATTRIBUTES (ddecl) = attribute;
+  DECL_ATTRIBUTES (ddecl) = attribute;
   return ddecl;
 }
 
@@ -2707,119 +2670,47 @@ build_type_attribute_variant (ttype, attribute)
   return ttype;
 }
 
-/* Return 1 if ATTR_NAME and ATTR_ARGS is valid for either declaration
-   DECL or type TYPE and 0 otherwise.  Validity is determined the
-   target functions valid_decl_attribute and valid_machine_attribute.  */
+/* Default value of targetm.comp_type_attributes that always returns 1.  */
 
 int
-valid_machine_attribute (attr_name, attr_args, decl, type)
-     tree attr_name;
-     tree attr_args;
-     tree decl;
-     tree type;
+default_comp_type_attributes (type1, type2)
+     tree type1 ATTRIBUTE_UNUSED;
+     tree type2 ATTRIBUTE_UNUSED;
 {
-  if (TREE_CODE (attr_name) != IDENTIFIER_NODE)
-    abort ();
-
-  if (decl && target.valid_decl_attribute != NULL)
-    {
-      tree decl_attrs = DECL_MACHINE_ATTRIBUTES (decl);
-
-      if ((*target.valid_decl_attribute) (decl, decl_attrs, attr_name,
-                                         attr_args))
-       {
-         tree attr = lookup_attribute (IDENTIFIER_POINTER (attr_name),
-                                       decl_attrs);
-
-         if (attr != NULL_TREE)
-           {
-             /* Override existing arguments.  Declarations are unique
-                so we can modify this in place.  */
-             TREE_VALUE (attr) = attr_args;
-           }
-         else
-           {
-             decl_attrs = tree_cons (attr_name, attr_args, decl_attrs);
-             decl = build_decl_attribute_variant (decl, decl_attrs);
-           }
-
-         /* Don't apply the attribute to both the decl and the type.  */
-         return 1;
-       }
-    }
-
-  if (target.valid_type_attribute != NULL)
-    {
-      tree type_attrs = TYPE_ATTRIBUTES (type);
-
-      if ((*target.valid_type_attribute) (type, type_attrs, attr_name,
-                                         attr_args))
-       {
-         tree attr = lookup_attribute (IDENTIFIER_POINTER (attr_name),
-                                       type_attrs);
-
-         if (attr != NULL_TREE)
-           {
-             /* Override existing arguments.  ??? This currently
-                works since attribute arguments are not included in
-                `attribute_hash_list'.  Something more complicated
-                may be needed in the future.  */
-             TREE_VALUE (attr) = attr_args;
-           }
-         else
-           {
-             /* If this is part of a declaration, create a type variant,
-                otherwise, this is part of a type definition, so add it
-                to the base type.  */
-             type_attrs = tree_cons (attr_name, attr_args, type_attrs);
-             if (decl != 0)
-               type = build_type_attribute_variant (type, type_attrs);
-             else
-               TYPE_ATTRIBUTES (type) = type_attrs;
-           }
-
-         if (decl)
-           TREE_TYPE (decl) = type;
-
-         return 1;
-       }
+  return 1;
+}
 
-      /* Handle putting a type attribute on pointer-to-function-type
-        by putting the attribute on the function type.  */
-      else if (POINTER_TYPE_P (type)
-              && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
-              && (*target.valid_type_attribute) (TREE_TYPE (type), type_attrs,
-                                                 attr_name, attr_args))
-       {
-         tree inner_type = TREE_TYPE (type);
-         tree inner_attrs = TYPE_ATTRIBUTES (inner_type);
-         tree attr = lookup_attribute (IDENTIFIER_POINTER (attr_name),
-                                       type_attrs);
+/* Default version of targetm.set_default_type_attributes that always does
+   nothing.  */
 
-         if (attr != NULL_TREE)
-           TREE_VALUE (attr) = attr_args;
-         else
-           {
-             inner_attrs = tree_cons (attr_name, attr_args, inner_attrs);
-             inner_type = build_type_attribute_variant (inner_type,
-                                                        inner_attrs);
-           }
+void
+default_set_default_type_attributes (type)
+     tree type ATTRIBUTE_UNUSED;
+{
+}
 
-         if (decl)
-           TREE_TYPE (decl) = build_pointer_type (inner_type);
-         else
-           {
-             /* Clear TYPE_POINTER_TO for the old inner type, since
-                `type' won't be pointing to it anymore.  */
-             TYPE_POINTER_TO (TREE_TYPE (type)) = NULL_TREE;
-             TREE_TYPE (type) = inner_type;
-           }
+/* Default version of targetm.insert_attributes that always does nothing.  */
+void
+default_insert_attributes (decl, attr_ptr)
+     tree decl ATTRIBUTE_UNUSED;
+     tree *attr_ptr ATTRIBUTE_UNUSED;
+{
+}
 
-         return 1;
-       }
-    }
+/* Default value of targetm.attribute_table that is empty.  */
+const struct attribute_spec default_target_attribute_table[] =
+{
+  { NULL, 0, 0, false, false, false, NULL }
+};
 
-  return 0;
+/* Default value of targetm.function_attribute_inlinable_p that always
+   returns false.  */
+bool
+default_function_attribute_inlinable_p (fndecl)
+     tree fndecl ATTRIBUTE_UNUSED;
+{
+  /* By default, functions with machine attributes cannot be inlined.  */
+  return false;
 }
 
 /* Return non-zero if IDENT is a valid name for attribute ATTR,
@@ -2873,7 +2764,9 @@ is_attribute_p (attr, ident)
 
 /* Given an attribute name and a list of attributes, return a pointer to the
    attribute's list element if the attribute is part of the list, or NULL_TREE
-   if not found.  */
+   if not found.  If the attribute appears more than once, this only
+   returns the first occurance; the TREE_CHAIN of the return value should
+   be passed back in if further occurances are wanted.  */
 
 tree
 lookup_attribute (attr_name, list)
@@ -2897,7 +2790,7 @@ lookup_attribute (attr_name, list)
 
 tree
 merge_attributes (a1, a2)
-     register tree a1, a2;
+     tree a1, a2;
 {
   tree attributes;
 
@@ -2915,19 +2808,29 @@ merge_attributes (a1, a2)
       else
        {
          /* Pick the longest list, and hang on the other list.  */
-         /* ??? For the moment we punt on the issue of attrs with args.  */
 
          if (list_length (a1) < list_length (a2))
            attributes = a2, a2 = a1;
 
          for (; a2 != 0; a2 = TREE_CHAIN (a2))
-           if (lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),
-                                 attributes) == NULL_TREE)
-             {
-               a1 = copy_node (a2);
-               TREE_CHAIN (a1) = attributes;
-               attributes = a1;
-             }
+           {
+             tree a;
+             for (a = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),
+                                        attributes);
+                  a != NULL_TREE;
+                  a = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),
+                                        TREE_CHAIN (a)))
+               {
+                 if (simple_cst_equal (TREE_VALUE (a), TREE_VALUE (a2)) == 1)
+                   break;
+               }
+             if (a == NULL_TREE)
+               {
+                 a1 = copy_node (a2);
+                 TREE_CHAIN (a1) = attributes;
+                 attributes = a1;
+               }
+           }
        }
     }
   return attributes;
@@ -2951,8 +2854,8 @@ tree
 merge_decl_attributes (olddecl, newdecl)
      tree olddecl, newdecl;
 {
-  return merge_attributes (DECL_MACHINE_ATTRIBUTES (olddecl),
-                          DECL_MACHINE_ATTRIBUTES (newdecl));
+  return merge_attributes (DECL_ATTRIBUTES (olddecl),
+                          DECL_ATTRIBUTES (newdecl));
 }
 
 #ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
@@ -2974,8 +2877,8 @@ merge_dllimport_decl_attributes (old, new)
   tree a;
   int delete_dllimport_p;
 
-  old = DECL_MACHINE_ATTRIBUTES (old);
-  new = DECL_MACHINE_ATTRIBUTES (new);
+  old = DECL_ATTRIBUTES (old);
+  new = DECL_ATTRIBUTES (new);
 
   /* What we need to do here is remove from `old' dllimport if it doesn't
      appear in `new'.  dllimport behaves like extern: if a declaration is
@@ -3076,7 +2979,7 @@ tree
 build_type_copy (type)
      tree type;
 {
-  register tree t, m = TYPE_MAIN_VARIANT (type);
+  tree t, m = TYPE_MAIN_VARIANT (type);
 
   t = copy_node (type);
 
@@ -3102,7 +3005,7 @@ type_hash_list (list)
      tree list;
 {
   unsigned int hashcode;
-  register tree tail;
+  tree tail;
 
   for (hashcode = 0, tail = list; tail; tail = TREE_CHAIN (tail))
     hashcode += TYPE_HASH (TREE_VALUE (tail));
@@ -3187,7 +3090,7 @@ type_hash_add (hashcode, type)
   struct type_hash *h;
   void **loc;
 
-  h = (struct type_hash *) permalloc (sizeof (struct type_hash));
+  h = (struct type_hash *) ggc_alloc (sizeof (struct type_hash));
   h->hash = hashcode;
   h->type = type;
   loc = htab_find_slot_with_hash (type_hash_table, h, hashcode, INSERT);
@@ -3218,6 +3121,8 @@ type_hash_canon (hashcode, type)
   if (debug_no_type_hash)
     return type;
 
+  /* See if the type is in the hash table already.  If so, return it.
+     Otherwise, add the type.  */
   t1 = type_hash_lookup (hashcode, type);
   if (t1 != 0)
     {
@@ -3227,37 +3132,38 @@ type_hash_canon (hashcode, type)
 #endif
       return t1;
     }
-
-  /* If this is a permanent type, record it for later reuse.  */
-  type_hash_add (hashcode, type);
-
-  return type;
+  else
+    {
+      type_hash_add (hashcode, type);
+      return type;
+    }
 }
 
-/* Callback function for htab_traverse.  */
+/* See if the data pointed to by the type hash table is marked.  We consider
+   it marked if the type is marked or if a debug type number or symbol
+   table entry has been made for the type.  This reduces the amount of
+   debugging output and eliminates that dependency of the debug output on
+   the number of garbage collections.  */
 
 static int
-mark_hash_entry (entry, param)
-     void **entry;
-     void *param ATTRIBUTE_UNUSED;
+type_hash_marked_p (p)
+     const void *p;
 {
-  struct type_hash *p = *(struct type_hash **) entry;
-
-  ggc_mark_tree (p->type);
+  tree type = ((struct type_hash *) p)->type;
 
-  /* Continue scan.  */
-  return 1;
+  return ggc_marked_p (type) || TYPE_SYMTAB_POINTER (type);
 }
 
-/* Mark ARG (which is really a htab_t *) for GC.  */
+/* Mark the entry in the type hash table the type it points to is marked.
+   Also mark the type in case we are considering this entry "marked" by
+   virtue of TYPE_SYMTAB_POINTER being set.  */
 
 static void
-mark_type_hash (arg)
-     void *arg;
+type_hash_mark (p)
+     const void *p;
 {
-  htab_t t = *(htab_t *) arg;
-
-  htab_traverse (t, mark_hash_entry, 0);
+  ggc_mark (p);
+  ggc_mark_tree (((struct type_hash *) p)->type);
 }
 
 /* Mark the hashtable slot pointed to by ENTRY (which is really a
@@ -3301,7 +3207,7 @@ attribute_hash_list (list)
      tree list;
 {
   unsigned int hashcode;
-  register tree tail;
+  tree tail;
 
   for (hashcode = 0, tail = list; tail; tail = TREE_CHAIN (tail))
     /* ??? Do we want to add in TREE_VALUE too? */
@@ -3332,7 +3238,7 @@ int
 attribute_list_contained (l1, l2)
      tree l1, l2;
 {
-  register tree t1, t2;
+  tree t1, t2;
 
   /* First check the obvious, maybe the lists are identical.  */
   if (l1 == l2)
@@ -3351,8 +3257,15 @@ attribute_list_contained (l1, l2)
 
   for (; t2 != 0; t2 = TREE_CHAIN (t2))
     {
-      tree attr
-       = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)), l1);
+      tree attr;
+      for (attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)), l1);
+          attr != NULL_TREE;
+          attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
+                                   TREE_CHAIN (attr)))
+       {
+         if (simple_cst_equal (TREE_VALUE (t2), TREE_VALUE (attr)) == 1)
+           break;
+       }
 
       if (attr == 0)
        return 0;
@@ -3373,7 +3286,7 @@ int
 type_list_equal (l1, l2)
      tree l1, l2;
 {
-  register tree t1, t2;
+  tree t1, t2;
 
   for (t1 = l1, t2 = l2; t1 && t2; t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
     if (TREE_VALUE (t1) != TREE_VALUE (t2)
@@ -3500,7 +3413,7 @@ int
 tree_int_cst_msb (t)
      tree t;
 {
-  register int prec;
+  int prec;
   HOST_WIDE_INT h;
   unsigned HOST_WIDE_INT l;
 
@@ -3559,7 +3472,7 @@ int
 simple_cst_equal (t1, t2)
      tree t1, t2;
 {
-  register enum tree_code code1, code2;
+  enum tree_code code1, code2;
   int cmp;
   int i;
 
@@ -3642,7 +3555,7 @@ simple_cst_equal (t1, t2)
       if (cmp <= 0)
        return cmp;
 
-      return simple_cst_equal (TREE_OPERAND (t1, 2), TREE_OPERAND (t1, 2));
+      return simple_cst_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t1, 1));
 
     case COMPONENT_REF:
       if (TREE_OPERAND (t1, 1) == TREE_OPERAND (t2, 1))
@@ -3722,7 +3635,7 @@ tree
 build_pointer_type (to_type)
      tree to_type;
 {
-  register tree t = TYPE_POINTER_TO (to_type);
+  tree t = TYPE_POINTER_TO (to_type);
 
   /* First, if we already have a type for pointers to TO_TYPE, use it.  */
 
@@ -3751,7 +3664,7 @@ tree
 build_reference_type (to_type)
      tree to_type;
 {
-  register tree t = TYPE_REFERENCE_TO (to_type);
+  tree t = TYPE_REFERENCE_TO (to_type);
 
   /* First, if we already have a type for pointers to TO_TYPE, use it.  */
 
@@ -3804,7 +3717,7 @@ tree
 build_index_type (maxval)
      tree maxval;
 {
-  register tree itype = make_node (INTEGER_TYPE);
+  tree itype = make_node (INTEGER_TYPE);
 
   TREE_TYPE (itype) = sizetype;
   TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype);
@@ -3831,7 +3744,7 @@ tree
 build_range_type (type, lowval, highval)
      tree type, lowval, highval;
 {
-  register tree itype = make_node (INTEGER_TYPE);
+  tree itype = make_node (INTEGER_TYPE);
 
   TREE_TYPE (itype) = type;
   if (type == NULL_TREE)
@@ -3903,7 +3816,7 @@ tree
 build_array_type (elt_type, index_type)
      tree elt_type, index_type;
 {
-  register tree t;
+  tree t;
   unsigned int hashcode;
 
   if (TREE_CODE (elt_type) == FUNCTION_TYPE)
@@ -3960,7 +3873,7 @@ tree
 build_function_type (value_type, arg_types)
      tree value_type, arg_types;
 {
-  register tree t;
+  tree t;
   unsigned int hashcode;
 
   if (TREE_CODE (value_type) == FUNCTION_TYPE)
@@ -3992,7 +3905,7 @@ tree
 build_method_type (basetype, type)
      tree basetype, type;
 {
-  register tree t;
+  tree t;
   unsigned int hashcode;
 
   /* Make a node of the sort we want.  */
@@ -4029,7 +3942,7 @@ tree
 build_offset_type (basetype, type)
      tree basetype, type;
 {
-  register tree t;
+  tree t;
   unsigned int hashcode;
 
   /* Make a node of the sort we want.  */
@@ -4054,7 +3967,7 @@ tree
 build_complex_type (component_type)
      tree component_type;
 {
-  register tree t;
+  tree t;
   unsigned int hashcode;
 
   /* Make a node of the sort we want.  */
@@ -4132,22 +4045,22 @@ build_complex_type (component_type)
 
 tree
 get_unwidened (op, for_type)
-     register tree op;
+     tree op;
      tree for_type;
 {
   /* Set UNS initially if converting OP to FOR_TYPE is a zero-extension.  */
-  register tree type = TREE_TYPE (op);
-  register unsigned final_prec
+  tree type = TREE_TYPE (op);
+  unsigned final_prec
     = TYPE_PRECISION (for_type != 0 ? for_type : type);
-  register int uns
+  int uns
     = (for_type != 0 && for_type != type
        && final_prec > TYPE_PRECISION (type)
        && TREE_UNSIGNED (type));
-  register tree win = op;
+  tree win = op;
 
   while (TREE_CODE (op) == NOP_EXPR)
     {
-      register int bitschange
+      int bitschange
        = TYPE_PRECISION (TREE_TYPE (op))
          - TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op, 0)));
 
@@ -4225,16 +4138,16 @@ get_unwidened (op, for_type)
 
 tree
 get_narrower (op, unsignedp_ptr)
-     register tree op;
+     tree op;
      int *unsignedp_ptr;
 {
-  register int uns = 0;
+  int uns = 0;
   int first = 1;
-  register tree win = op;
+  tree win = op;
 
   while (TREE_CODE (op) == NOP_EXPR)
     {
-      register int bitschange
+      int bitschange
        = (TYPE_PRECISION (TREE_TYPE (op))
           - TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op, 0))));
 
@@ -4534,19 +4447,21 @@ append_random_chars (template)
   static unsigned HOST_WIDE_INT value;
   unsigned HOST_WIDE_INT v;
 
-#ifdef HAVE_GETTIMEOFDAY
-  struct timeval tv;
-#endif
+  if (! value)
+    {
+      struct stat st;
 
-  template += strlen (template);
+      /* VALUE should be unique for each file and must
+        not change between compiles since this can cause
+        bootstrap comparison errors.  */
 
-#ifdef HAVE_GETTIMEOFDAY
-  /* Get some more or less random data.  */
-  gettimeofday (&tv, NULL);
-  value += ((unsigned HOST_WIDE_INT) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid ();
-#else
-  value += getpid ();
-#endif
+      if (stat (main_input_filename, &st) < 0)
+       abort ();
+
+      value = st.st_dev ^ st.st_ino ^ st.st_mtime;
+    }
+
+  template += strlen (template);
 
   v = value;
 
@@ -4962,4 +4877,9 @@ build_common_tree_nodes_2 (short_double)
   TREE_TYPE (V8QI_type_node) = intQI_type_node;
   TYPE_MODE (V8QI_type_node) = V8QImode;
   finish_vector_type (V8QI_type_node);
+
+  V2SF_type_node = make_node (VECTOR_TYPE);
+  TREE_TYPE (V2SF_type_node) = float_type_node;
+  TYPE_MODE (V2SF_type_node) = V2SFmode;
+  finish_vector_type (V2SF_type_node);
 }