OSDN Git Service

2012-01-04 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index ef6a812..76488f7 100644 (file)
@@ -41,8 +41,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "toplev.h"
 #include "ggc.h"
 #include "hashtab.h"
+#include "filenames.h"
 #include "output.h"
 #include "target.h"
+#include "common/common-target.h"
 #include "langhooks.h"
 #include "tree-inline.h"
 #include "tree-iterator.h"
@@ -123,6 +125,7 @@ extern int _obstack_allocated_p (struct obstack *h, void *obj);
 #ifdef GATHER_STATISTICS
 /* Statistics-gathering stuff.  */
 
+static int tree_code_counts[MAX_TREE_CODES];
 int tree_node_counts[(int) all_kinds];
 int tree_node_sizes[(int) all_kinds];
 
@@ -200,6 +203,9 @@ static GTY ((if_marked ("tree_decl_map_marked_p"), param_is (struct tree_decl_ma
 static GTY ((if_marked ("tree_decl_map_marked_p"), param_is (struct tree_decl_map)))
      htab_t value_expr_for_decl;
 
+static GTY ((if_marked ("tree_vec_map_marked_p"), param_is (struct tree_vec_map)))
+     htab_t debug_args_for_decl;
+
 static GTY ((if_marked ("tree_priority_map_marked_p"),
             param_is (struct tree_priority_map)))
   htab_t init_priority_for_decl;
@@ -241,7 +247,9 @@ unsigned const char omp_clause_num_ops[] =
   0, /* OMP_CLAUSE_ORDERED  */
   0, /* OMP_CLAUSE_DEFAULT  */
   3, /* OMP_CLAUSE_COLLAPSE  */
-  0  /* OMP_CLAUSE_UNTIED   */
+  0, /* OMP_CLAUSE_UNTIED   */
+  1, /* OMP_CLAUSE_FINAL  */
+  0  /* OMP_CLAUSE_MERGEABLE  */
 };
 
 const char * const omp_clause_code_name[] =
@@ -261,7 +269,9 @@ const char * const omp_clause_code_name[] =
   "ordered",
   "default",
   "collapse",
-  "untied"
+  "untied",
+  "final",
+  "mergeable"
 };
 
 
@@ -301,7 +311,7 @@ tree_node_structure_for_code (enum tree_code code)
          }
       }
     case tcc_type:
-      return TS_TYPE;
+      return TS_TYPE_NON_COMMON;
     case tcc_reference:
     case tcc_comparison:
     case tcc_unary:
@@ -351,47 +361,6 @@ initialize_tree_contains_struct (void)
 {
   unsigned i;
 
-#define MARK_TS_BASE(C)                                        \
-  do {                                                 \
-    tree_contains_struct[C][TS_BASE] = 1;              \
-  } while (0)
-
-#define MARK_TS_COMMON(C)                              \
-  do {                                                 \
-    MARK_TS_BASE (C);                                  \
-    tree_contains_struct[C][TS_COMMON] = 1;            \
-  } while (0)
-
-#define MARK_TS_DECL_MINIMAL(C)                                \
-  do {                                                 \
-    MARK_TS_COMMON (C);                                        \
-    tree_contains_struct[C][TS_DECL_MINIMAL] = 1;      \
-  } while (0)
-
-#define MARK_TS_DECL_COMMON(C)                         \
-  do {                                                 \
-    MARK_TS_DECL_MINIMAL (C);                          \
-    tree_contains_struct[C][TS_DECL_COMMON] = 1;       \
-  } while (0)
-
-#define MARK_TS_DECL_WRTL(C)                           \
-  do {                                                 \
-    MARK_TS_DECL_COMMON (C);                           \
-    tree_contains_struct[C][TS_DECL_WRTL] = 1;         \
-  } while (0)
-
-#define MARK_TS_DECL_WITH_VIS(C)                       \
-  do {                                                 \
-    MARK_TS_DECL_WRTL (C);                             \
-    tree_contains_struct[C][TS_DECL_WITH_VIS] = 1;     \
-  } while (0)
-
-#define MARK_TS_DECL_NON_COMMON(C)                     \
-  do {                                                 \
-    MARK_TS_DECL_WITH_VIS (C);                         \
-    tree_contains_struct[C][TS_DECL_NON_COMMON] = 1;   \
-  } while (0)
-
   for (i = ERROR_MARK; i < LAST_AND_UNUSED_TREE_CODE; i++)
     {
       enum tree_code code;
@@ -406,38 +375,51 @@ initialize_tree_contains_struct (void)
       /* Mark all the structures that TS is derived from.  */
       switch (ts_code)
        {
-       case TS_COMMON:
+       case TS_TYPED:
+       case TS_BLOCK:
          MARK_TS_BASE (code);
          break;
 
+       case TS_COMMON:
        case TS_INT_CST:
        case TS_REAL_CST:
        case TS_FIXED_CST:
        case TS_VECTOR:
        case TS_STRING:
        case TS_COMPLEX:
+       case TS_SSA_NAME:
+       case TS_CONSTRUCTOR:
+       case TS_EXP:
+       case TS_STATEMENT_LIST:
+         MARK_TS_TYPED (code);
+         break;
+
        case TS_IDENTIFIER:
        case TS_DECL_MINIMAL:
-       case TS_TYPE:
+       case TS_TYPE_COMMON:
        case TS_LIST:
        case TS_VEC:
-       case TS_EXP:
-       case TS_SSA_NAME:
-       case TS_BLOCK:
        case TS_BINFO:
-       case TS_STATEMENT_LIST:
-       case TS_CONSTRUCTOR:
        case TS_OMP_CLAUSE:
        case TS_OPTIMIZATION:
        case TS_TARGET_OPTION:
          MARK_TS_COMMON (code);
          break;
 
+       case TS_TYPE_WITH_LANG_SPECIFIC:
+         MARK_TS_TYPE_COMMON (code);
+         break;
+
+       case TS_TYPE_NON_COMMON:
+         MARK_TS_TYPE_WITH_LANG_SPECIFIC (code);
+         break;
+
        case TS_DECL_COMMON:
          MARK_TS_DECL_MINIMAL (code);
          break;
 
        case TS_DECL_WRTL:
+       case TS_CONST_DECL:
          MARK_TS_DECL_COMMON (code);
          break;
 
@@ -449,7 +431,6 @@ initialize_tree_contains_struct (void)
        case TS_PARM_DECL:
        case TS_LABEL_DECL:
        case TS_RESULT_DECL:
-       case TS_CONST_DECL:
          MARK_TS_DECL_WRTL (code);
          break;
 
@@ -487,7 +468,6 @@ initialize_tree_contains_struct (void)
   gcc_assert (tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_COMMON]);
   gcc_assert (tree_contains_struct[LABEL_DECL][TS_DECL_COMMON]);
   gcc_assert (tree_contains_struct[FIELD_DECL][TS_DECL_COMMON]);
-  gcc_assert (tree_contains_struct[CONST_DECL][TS_DECL_WRTL]);
   gcc_assert (tree_contains_struct[VAR_DECL][TS_DECL_WRTL]);
   gcc_assert (tree_contains_struct[PARM_DECL][TS_DECL_WRTL]);
   gcc_assert (tree_contains_struct[RESULT_DECL][TS_DECL_WRTL]);
@@ -515,14 +495,6 @@ initialize_tree_contains_struct (void)
   gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_FUNCTION_DECL]);
   gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_MINIMAL]);
   gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_COMMON]);
-
-#undef MARK_TS_BASE
-#undef MARK_TS_COMMON
-#undef MARK_TS_DECL_MINIMAL
-#undef MARK_TS_DECL_COMMON
-#undef MARK_TS_DECL_WRTL
-#undef MARK_TS_DECL_WITH_VIS
-#undef MARK_TS_DECL_NON_COMMON
 }
 
 
@@ -683,7 +655,7 @@ tree_code_size (enum tree_code code)
       }
 
     case tcc_type:  /* a type node */
-      return sizeof (struct tree_type);
+      return sizeof (struct tree_type_non_common);
 
     case tcc_reference:   /* a reference */
     case tcc_expression:  /* an expression */
@@ -854,11 +826,20 @@ record_node_allocation_statistics (enum tree_code code ATTRIBUTE_UNUSED,
       gcc_unreachable ();
     }
 
+  tree_code_counts[(int) code]++;
   tree_node_counts[(int) kind]++;
   tree_node_sizes[(int) kind] += length;
 #endif
 }
 
+/* Allocate and return a new UID from the DECL_UID namespace.  */
+
+int
+allocate_decl_uid (void)
+{
+  return next_decl_uid++;
+}
+
 /* Return a newly allocated node of code CODE.  For decl and type
    nodes, some other fields are initialized.  The rest of the node is
    initialized to zero.  This function cannot be used for TREE_VEC or
@@ -902,7 +883,7 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
        DECL_UID (t) = --next_debug_decl_uid;
       else
        {
-         DECL_UID (t) = next_decl_uid++;
+         DECL_UID (t) = allocate_decl_uid ();
          SET_DECL_PT_UID (t, -1);
        }
       if (TREE_CODE (t) == LABEL_DECL)
@@ -958,7 +939,7 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
 }
 \f
 /* Return a new node with the same contents as NODE except that its
-   TREE_CHAIN is zero and it has a fresh uid.  */
+   TREE_CHAIN, if it has one, is zero and it has a fresh uid.  */
 
 tree
 copy_node_stat (tree node MEM_STAT_DECL)
@@ -974,7 +955,8 @@ copy_node_stat (tree node MEM_STAT_DECL)
   t = ggc_alloc_zone_tree_node_stat (&tree_zone, length PASS_MEM_STAT);
   memcpy (t, node, length);
 
-  TREE_CHAIN (t) = 0;
+  if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
+    TREE_CHAIN (t) = 0;
   TREE_ASM_WRITTEN (t) = 0;
   TREE_VISITED (t) = 0;
   if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
@@ -986,7 +968,7 @@ copy_node_stat (tree node MEM_STAT_DECL)
        DECL_UID (t) = --next_debug_decl_uid;
       else
        {
-         DECL_UID (t) = next_decl_uid++;
+         DECL_UID (t) = allocate_decl_uid ();
          if (DECL_PT_UID_SET_P (node))
            SET_DECL_PT_UID (t, DECL_PT_UID (node));
        }
@@ -1048,7 +1030,7 @@ copy_list (tree list)
 }
 
 \f
-/* Create an INT_CST node with a LOW value sign extended.  */
+/* Create an INT_CST node with a LOW value sign extended to TYPE.  */
 
 tree
 build_int_cst (tree type, HOST_WIDE_INT low)
@@ -1057,17 +1039,10 @@ build_int_cst (tree type, HOST_WIDE_INT low)
   if (!type)
     type = integer_type_node;
 
-  return build_int_cst_wide (type, low, low < 0 ? -1 : 0);
+  return double_int_to_tree (type, shwi_to_double_int (low));
 }
 
-/* Create an INT_CST node with a LOW value in TYPE.  The value is sign extended
-   if it is negative.  This function is similar to build_int_cst, but
-   the extra bits outside of the type precision are cleared.  Constants
-   with these extra bits may confuse the fold so that it detects overflows
-   even in cases when they do not occur, and in general should be avoided.
-   We cannot however make this a default behavior of build_int_cst without
-   more intrusive changes, since there are parts of gcc that rely on the extra
-   precision of the integer constants.  */
+/* Create an INT_CST node with a LOW value sign extended to TYPE.  */
 
 tree
 build_int_cst_type (tree type, HOST_WIDE_INT low)
@@ -1550,6 +1525,7 @@ build_real_from_int_cst (tree type, const_tree i)
 
 /* Return a newly constructed STRING_CST node whose value is
    the LEN characters at STR.
+   Note that for a C string literal, LEN should include the trailing NUL.
    The TREE_TYPE is not initialized.  */
 
 tree
@@ -1565,7 +1541,7 @@ build_string (int len, const char *str)
 
   s = ggc_alloc_tree_node (length);
 
-  memset (s, 0, sizeof (struct tree_common));
+  memset (s, 0, sizeof (struct tree_typed));
   TREE_SET_CODE (s, STRING_CST);
   TREE_CONSTANT (s) = 1;
   TREE_STRING_LENGTH (s) = len;
@@ -1694,6 +1670,23 @@ make_tree_binfo_stat (unsigned base_binfos MEM_STAT_DECL)
   return t;
 }
 
+/* Create a CASE_LABEL_EXPR tree node and return it.  */
+
+tree
+build_case_label (tree low_value, tree high_value, tree label_decl)
+{
+  tree t = make_node (CASE_LABEL_EXPR);
+
+  TREE_TYPE (t) = void_type_node;
+  SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (label_decl));
+
+  CASE_LOW (t) = low_value;
+  CASE_HIGH (t) = high_value;
+  CASE_LABEL (t) = label_decl;
+  CASE_CHAIN (t) = NULL_TREE;
+
+  return t;
+}
 
 /* Build a newly constructed TREE_VEC node of length LEN.  */
 
@@ -1771,9 +1764,7 @@ integer_all_onesp (const_tree expr)
   if (!uns)
     return 0;
 
-  /* Note that using TYPE_PRECISION here is wrong.  We care about the
-     actual bits, not the (arbitrary) range of the type.  */
-  prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr)));
+  prec = TYPE_PRECISION (TREE_TYPE (expr));
   if (prec >= HOST_BITS_PER_WIDE_INT)
     {
       HOST_WIDE_INT high_value;
@@ -2462,6 +2453,10 @@ array_type_nelts (const_tree type)
   min = TYPE_MIN_VALUE (index_type);
   max = TYPE_MAX_VALUE (index_type);
 
+  /* TYPE_MAX_VALUE may not be set if the array has unknown length.  */
+  if (!max)
+    return error_mark_node;
+
   return (integer_zerop (min)
          ? max
          : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
@@ -3790,8 +3785,7 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
 
   if (code == POINTER_PLUS_EXPR && arg0 && arg1 && tt)
     gcc_assert (POINTER_TYPE_P (tt) && POINTER_TYPE_P (TREE_TYPE (arg0))
-               && INTEGRAL_TYPE_P (TREE_TYPE (arg1))
-               && useless_type_conversion_p (sizetype, TREE_TYPE (arg1)));
+               && ptrofftype_p (TREE_TYPE (arg1)));
 
   t = make_node_stat (code PASS_MEM_STAT);
   TREE_TYPE (t) = tt;
@@ -4404,7 +4398,7 @@ free_lang_data_in_one_sizepos (tree *expr_p)
 
 
 /* Reset all the fields in a binfo node BINFO.  We only keep
-   BINFO_VIRTUALS, which is used by gimple_fold_obj_type_ref.  */
+   BINFO_VTABLE, which is used by gimple_fold_obj_type_ref.  */
 
 static void
 free_lang_data_in_binfo (tree binfo)
@@ -4414,7 +4408,7 @@ free_lang_data_in_binfo (tree binfo)
 
   gcc_assert (TREE_CODE (binfo) == TREE_BINFO);
 
-  BINFO_VTABLE (binfo) = NULL_TREE;
+  BINFO_VIRTUALS (binfo) = NULL_TREE;
   BINFO_BASE_ACCESSES (binfo) = NULL;
   BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE;
   BINFO_SUBVTT_INDEX (binfo) = NULL_TREE;
@@ -4483,7 +4477,8 @@ free_lang_data_in_type (tree type)
       member = TYPE_FIELDS (type);
       while (member)
        {
-         if (TREE_CODE (member) == FIELD_DECL)
+         if (TREE_CODE (member) == FIELD_DECL
+             || TREE_CODE (member) == TYPE_DECL)
            {
              if (prev)
                TREE_CHAIN (prev) = member;
@@ -4527,9 +4522,6 @@ free_lang_data_in_type (tree type)
          && TREE_CODE (TYPE_CONTEXT (type)) != FUNCTION_DECL
          && TREE_CODE (TYPE_CONTEXT (type)) != NAMESPACE_DECL))
     TYPE_CONTEXT (type) = NULL_TREE;
-
-  if (debug_info_level < DINFO_LEVEL_TERSE)
-    TYPE_STUB_DECL (type) = NULL_TREE;
 }
 
 
@@ -4601,20 +4593,11 @@ free_lang_data_in_decl (tree decl)
   TREE_LANG_FLAG_5 (decl) = 0;
   TREE_LANG_FLAG_6 (decl) = 0;
 
-  /* Identifiers need not have a type.  */
-  if (DECL_NAME (decl))
-    TREE_TYPE (DECL_NAME (decl)) = NULL_TREE;
-
   free_lang_data_in_one_sizepos (&DECL_SIZE (decl));
   free_lang_data_in_one_sizepos (&DECL_SIZE_UNIT (decl));
   if (TREE_CODE (decl) == FIELD_DECL)
     free_lang_data_in_one_sizepos (&DECL_FIELD_OFFSET (decl));
 
- /* DECL_FCONTEXT is only used for debug info generation.  */
- if (TREE_CODE (decl) == FIELD_DECL
-     && debug_info_level < DINFO_LEVEL_TERSE)
-   DECL_FCONTEXT (decl) = NULL_TREE;
-
  if (TREE_CODE (decl) == FUNCTION_DECL)
     {
       if (gimple_has_body_p (decl))
@@ -4646,6 +4629,13 @@ free_lang_data_in_decl (tree decl)
          && RECORD_OR_UNION_TYPE_P
               (DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl))))
        DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE;
+
+      /* Sometimes the C++ frontend doesn't manage to transform a temporary
+         DECL_VINDEX referring to itself into a vtable slot number as it
+        should.  Happens with functions that are copied and then forgotten
+        about.  Just clear it, it won't matter anymore.  */
+      if (DECL_VINDEX (decl) && !host_integerp (DECL_VINDEX (decl), 0))
+       DECL_VINDEX (decl) = NULL_TREE;
     }
   else if (TREE_CODE (decl) == VAR_DECL)
     {
@@ -4654,16 +4644,16 @@ free_lang_data_in_decl (tree decl)
          || (decl_function_context (decl) && !TREE_STATIC (decl)))
        DECL_INITIAL (decl) = NULL_TREE;
     }
-  else if (TREE_CODE (decl) == TYPE_DECL)
+  else if (TREE_CODE (decl) == TYPE_DECL
+          || TREE_CODE (decl) == FIELD_DECL)
     DECL_INITIAL (decl) = NULL_TREE;
   else if (TREE_CODE (decl) == TRANSLATION_UNIT_DECL
            && DECL_INITIAL (decl)
            && TREE_CODE (DECL_INITIAL (decl)) == BLOCK)
     {
-      /* Strip builtins from the translation-unit BLOCK.  We still have
-        targets without builtin_decl support and also builtins are
-        shared nodes and thus we can't use TREE_CHAIN in multiple
-        lists.  */
+      /* Strip builtins from the translation-unit BLOCK.  We still have targets
+        without builtin_decl_explicit support and also builtins are shared
+        nodes and thus we can't use TREE_CHAIN in multiple lists.  */
       tree *nextp = &BLOCK_VARS (DECL_INITIAL (decl));
       while (*nextp)
         {
@@ -4804,6 +4794,7 @@ find_decls_types_r (tree *tp, int *ws, void *data)
        {
          fld_worklist_push (DECL_ARGUMENT_FLD (t), fld);
          fld_worklist_push (DECL_VINDEX (t), fld);
+         fld_worklist_push (DECL_ORIGINAL_TYPE (t), fld);
        }
       else if (TREE_CODE (t) == FIELD_DECL)
        {
@@ -4882,13 +4873,14 @@ find_decls_types_r (tree *tp, int *ws, void *data)
          tem = TYPE_FIELDS (t);
          while (tem)
            {
-             if (TREE_CODE (tem) == FIELD_DECL)
+             if (TREE_CODE (tem) == FIELD_DECL
+                 || TREE_CODE (tem) == TYPE_DECL)
                fld_worklist_push (tem, fld);
              tem = TREE_CHAIN (tem);
            }
        }
 
-      fld_worklist_push (TREE_CHAIN (t), fld);
+      fld_worklist_push (TYPE_STUB_DECL (t), fld);
       *ws = 0;
     }
   else if (TREE_CODE (t) == BLOCK)
@@ -4901,7 +4893,8 @@ find_decls_types_r (tree *tp, int *ws, void *data)
       fld_worklist_push (BLOCK_ABSTRACT_ORIGIN (t), fld);
     }
 
-  if (TREE_CODE (t) != IDENTIFIER_NODE)
+  if (TREE_CODE (t) != IDENTIFIER_NODE
+      && CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED))
     fld_worklist_push (TREE_TYPE (t), fld);
 
   return NULL_TREE;
@@ -5184,32 +5177,18 @@ free_lang_data (void)
   /* Create gimple variants for common types.  */
   ptrdiff_type_node = integer_type_node;
   fileptr_type_node = ptr_type_node;
-  if (TREE_CODE (boolean_type_node) != BOOLEAN_TYPE
-      || (TYPE_MODE (boolean_type_node)
-         != mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0))
-      || TYPE_PRECISION (boolean_type_node) != 1
-      || !TYPE_UNSIGNED (boolean_type_node))
-    {
-      boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
-      TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
-      TYPE_MAX_VALUE (boolean_type_node) = build_int_cst (boolean_type_node, 1);
-      TYPE_PRECISION (boolean_type_node) = 1;
-      boolean_false_node = TYPE_MIN_VALUE (boolean_type_node);
-      boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
-    }
-
-  /* Unify char_type_node with its properly signed variant.  */
-  if (TYPE_UNSIGNED (char_type_node))
-    unsigned_char_type_node = char_type_node;
-  else
-    signed_char_type_node = char_type_node;
 
   /* Reset some langhooks.  Do not reset types_compatible_p, it may
      still be used indirectly via the get_alias_set langhook.  */
   lang_hooks.callgraph.analyze_expr = NULL;
   lang_hooks.dwarf_name = lhd_dwarf_name;
   lang_hooks.decl_printable_name = gimple_decl_printable_name;
-  lang_hooks.set_decl_assembler_name = lhd_set_decl_assembler_name;
+  /* We do not want the default decl_assembler_name implementation,
+     rather if we have fixed everything we want a wrapper around it
+     asserting that all non-local symbols already got their assembler
+     name and only produce assembler names for local symbols.  Or rather
+     make sure we never call decl_assembler_name on local symbols and
+     devise a separate, middle-end private scheme for it.  */
 
   /* Reset diagnostic machinery.  */
   diagnostic_starter (global_dc) = default_tree_diagnostic_starter;
@@ -5239,82 +5218,119 @@ struct simple_ipa_opt_pass pass_ipa_free_lang_data =
  }
 };
 
-/* Return nonzero if IDENT is a valid name for attribute ATTR,
-   or zero if not.
-
-   We try both `text' and `__text__', ATTR may be either one.  */
-/* ??? It might be a reasonable simplification to require ATTR to be only
-   `text'.  One might then also require attribute lists to be stored in
-   their canonicalized form.  */
-
-static int
-is_attribute_with_length_p (const char *attr, int attr_len, const_tree ident)
+/* The backbone of is_attribute_p().  ATTR_LEN is the string length of
+   ATTR_NAME.  Also used internally by remove_attribute().  */
+bool
+private_is_attribute_p (const char *attr_name, size_t attr_len, const_tree ident)
 {
-  int ident_len;
-  const char *p;
+  size_t ident_len = IDENTIFIER_LENGTH (ident);
 
-  if (TREE_CODE (ident) != IDENTIFIER_NODE)
-    return 0;
-
-  p = IDENTIFIER_POINTER (ident);
-  ident_len = IDENTIFIER_LENGTH (ident);
-
-  if (ident_len == attr_len
-      && strcmp (attr, p) == 0)
-    return 1;
-
-  /* If ATTR is `__text__', IDENT must be `text'; and vice versa.  */
-  if (attr[0] == '_')
+  if (ident_len == attr_len)
     {
-      gcc_assert (attr[1] == '_');
-      gcc_assert (attr[attr_len - 2] == '_');
-      gcc_assert (attr[attr_len - 1] == '_');
-      if (ident_len == attr_len - 4
-         && strncmp (attr + 2, p, attr_len - 4) == 0)
-       return 1;
+      if (strcmp (attr_name, IDENTIFIER_POINTER (ident)) == 0)
+       return true;
     }
-  else
+  else if (ident_len == attr_len + 4)
     {
-      if (ident_len == attr_len + 4
-         && p[0] == '_' && p[1] == '_'
+      /* There is the possibility that ATTR is 'text' and IDENT is
+        '__text__'.  */
+      const char *p = IDENTIFIER_POINTER (ident);      
+      if (p[0] == '_' && p[1] == '_'
          && p[ident_len - 2] == '_' && p[ident_len - 1] == '_'
-         && strncmp (attr, p + 2, attr_len) == 0)
-       return 1;
+         && strncmp (attr_name, p + 2, attr_len) == 0)
+       return true;
     }
 
-  return 0;
+  return false;
 }
 
-/* Return nonzero if IDENT is a valid name for attribute ATTR,
-   or zero if not.
+/* The backbone of lookup_attribute().  ATTR_LEN is the string length
+   of ATTR_NAME, and LIST is not NULL_TREE.  */
+tree
+private_lookup_attribute (const char *attr_name, size_t attr_len, tree list)
+{
+  while (list)
+    {
+      size_t ident_len = IDENTIFIER_LENGTH (TREE_PURPOSE (list));
 
-   We try both `text' and `__text__', ATTR may be either one.  */
+      if (ident_len == attr_len)
+       {
+         if (strcmp (attr_name, IDENTIFIER_POINTER (TREE_PURPOSE (list))) == 0)
+           break;
+       }
+      /* TODO: If we made sure that attributes were stored in the
+        canonical form without '__...__' (ie, as in 'text' as opposed
+        to '__text__') then we could avoid the following case.  */
+      else if (ident_len == attr_len + 4)
+       {
+         const char *p = IDENTIFIER_POINTER (TREE_PURPOSE (list));
+         if (p[0] == '_' && p[1] == '_'
+             && p[ident_len - 2] == '_' && p[ident_len - 1] == '_'
+             && strncmp (attr_name, p + 2, attr_len) == 0)
+           break;
+       }
+      list = TREE_CHAIN (list);
+    }
 
-int
-is_attribute_p (const char *attr, const_tree ident)
-{
-  return is_attribute_with_length_p (attr, strlen (attr), ident);
+  return list;
 }
 
-/* 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 the attribute appears more than once, this only
-   returns the first occurrence; the TREE_CHAIN of the return value should
-   be passed back in if further occurrences are wanted.  */
+/* A variant of lookup_attribute() that can be used with an identifier
+   as the first argument, and where the identifier can be either
+   'text' or '__text__'.
 
-tree
-lookup_attribute (const char *attr_name, tree list)
+   Given an attribute ATTR_IDENTIFIER, and a list of attributes LIST,
+   return a pointer to the attribute's list element if the attribute
+   is part of the list, or NULL_TREE if not found.  If the attribute
+   appears more than once, this only returns the first occurrence; the
+   TREE_CHAIN of the return value should be passed back in if further
+   occurrences are wanted.  ATTR_IDENTIFIER must be an identifier but
+   can be in the form 'text' or '__text__'.  */
+static tree
+lookup_ident_attribute (tree attr_identifier, tree list)
 {
-  tree l;
-  size_t attr_len = strlen (attr_name);
+  gcc_checking_assert (TREE_CODE (attr_identifier) == IDENTIFIER_NODE);
 
-  for (l = list; l; l = TREE_CHAIN (l))
+  while (list)
     {
-      gcc_assert (TREE_CODE (TREE_PURPOSE (l)) == IDENTIFIER_NODE);
-      if (is_attribute_with_length_p (attr_name, attr_len, TREE_PURPOSE (l)))
-       return l;
+      gcc_checking_assert (TREE_CODE (TREE_PURPOSE (list)) == IDENTIFIER_NODE);
+
+      /* Identifiers can be compared directly for equality.  */
+      if (attr_identifier == TREE_PURPOSE (list))
+       break;
+
+      /* If they are not equal, they may still be one in the form
+        'text' while the other one is in the form '__text__'.  TODO:
+        If we were storing attributes in normalized 'text' form, then
+        this could all go away and we could take full advantage of
+        the fact that we're comparing identifiers. :-)  */
+      {
+       size_t attr_len = IDENTIFIER_LENGTH (attr_identifier);
+       size_t ident_len = IDENTIFIER_LENGTH (TREE_PURPOSE (list));
+
+       if (ident_len == attr_len + 4)
+         {
+           const char *p = IDENTIFIER_POINTER (TREE_PURPOSE (list));
+           const char *q = IDENTIFIER_POINTER (attr_identifier);
+           if (p[0] == '_' && p[1] == '_'
+               && p[ident_len - 2] == '_' && p[ident_len - 1] == '_'
+               && strncmp (q, p + 2, attr_len) == 0)
+             break;
+         }
+       else if (ident_len + 4 == attr_len)
+         {
+           const char *p = IDENTIFIER_POINTER (TREE_PURPOSE (list));
+           const char *q = IDENTIFIER_POINTER (attr_identifier);
+           if (q[0] == '_' && q[1] == '_'
+               && q[attr_len - 2] == '_' && q[attr_len - 1] == '_'
+               && strncmp (q + 2, p, ident_len) == 0)
+             break;
+         }
+      }
+      list = TREE_CHAIN (list);
     }
-  return NULL_TREE;
+
+  return list;
 }
 
 /* Remove any instances of attribute ATTR_NAME in LIST and return the
@@ -5326,11 +5342,14 @@ remove_attribute (const char *attr_name, tree list)
   tree *p;
   size_t attr_len = strlen (attr_name);
 
+  gcc_checking_assert (attr_name[0] != '_');
+
   for (p = &list; *p; )
     {
       tree l = *p;
-      gcc_assert (TREE_CODE (TREE_PURPOSE (l)) == IDENTIFIER_NODE);
-      if (is_attribute_with_length_p (attr_name, attr_len, TREE_PURPOSE (l)))
+      /* TODO: If we were storing attributes in normalized form, here
+        we could use a simple strcmp().  */
+      if (private_is_attribute_p (attr_name, attr_len, TREE_PURPOSE (l)))
        *p = TREE_CHAIN (l);
       else
        p = &TREE_CHAIN (l);
@@ -5367,11 +5386,9 @@ merge_attributes (tree a1, tree a2)
          for (; a2 != 0; a2 = TREE_CHAIN (a2))
            {
              tree a;
-             for (a = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),
-                                        attributes);
+             for (a = lookup_ident_attribute (TREE_PURPOSE (a2), attributes);
                   a != NULL_TREE && !attribute_value_equal (a, a2);
-                  a = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),
-                                        TREE_CHAIN (a)))
+                  a = lookup_ident_attribute (TREE_PURPOSE (a2), TREE_CHAIN (a)))
                ;
              if (a == NULL_TREE)
                {
@@ -5470,24 +5487,7 @@ merge_dllimport_decl_attributes (tree old, tree new_tree)
   a = merge_attributes (DECL_ATTRIBUTES (old), DECL_ATTRIBUTES (new_tree));
 
   if (delete_dllimport_p)
-    {
-      tree prev, t;
-      const size_t attr_len = strlen ("dllimport");
-
-      /* Scan the list for dllimport and delete it.  */
-      for (prev = NULL_TREE, t = a; t; prev = t, t = TREE_CHAIN (t))
-       {
-         if (is_attribute_with_length_p ("dllimport", attr_len,
-                                         TREE_PURPOSE (t)))
-           {
-             if (prev == NULL_TREE)
-               a = TREE_CHAIN (a);
-             else
-               TREE_CHAIN (prev) = TREE_CHAIN (t);
-             break;
-           }
-       }
-    }
+    a = remove_attribute ("dllimport", a);
 
   return a;
 }
@@ -5912,6 +5912,8 @@ decl_init_priority_insert (tree decl, priority_type priority)
   struct tree_priority_map *h;
 
   gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
+  if (priority == DEFAULT_INIT_PRIORITY)
+    return;
   h = decl_priority_info (decl);
   h->init = priority;
 }
@@ -5924,6 +5926,8 @@ decl_fini_priority_insert (tree decl, priority_type priority)
   struct tree_priority_map *h;
 
   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
+  if (priority == DEFAULT_INIT_PRIORITY)
+    return;
   h = decl_priority_info (decl);
   h->fini = priority;
 }
@@ -6012,6 +6016,49 @@ decl_value_expr_insert (tree from, tree to)
   *(struct tree_decl_map **) loc = h;
 }
 
+/* Lookup a vector of debug arguments for FROM, and return it if we
+   find one.  */
+
+VEC(tree, gc) **
+decl_debug_args_lookup (tree from)
+{
+  struct tree_vec_map *h, in;
+
+  if (!DECL_HAS_DEBUG_ARGS_P (from))
+    return NULL;
+  gcc_checking_assert (debug_args_for_decl != NULL);
+  in.base.from = from;
+  h = (struct tree_vec_map *)
+      htab_find_with_hash (debug_args_for_decl, &in, DECL_UID (from));
+  if (h)
+    return &h->to;
+  return NULL;
+}
+
+/* Insert a mapping FROM->empty vector of debug arguments in the value
+   expression hashtable.  */
+
+VEC(tree, gc) **
+decl_debug_args_insert (tree from)
+{
+  struct tree_vec_map *h;
+  void **loc;
+
+  if (DECL_HAS_DEBUG_ARGS_P (from))
+    return decl_debug_args_lookup (from);
+  if (debug_args_for_decl == NULL)
+    debug_args_for_decl = htab_create_ggc (64, tree_vec_map_hash,
+                                          tree_vec_map_eq, 0);
+  h = ggc_alloc_tree_vec_map ();
+  h->base.from = from;
+  h->to = NULL;
+  loc = htab_find_slot_with_hash (debug_args_for_decl, h, DECL_UID (from),
+                                 INSERT);
+  *(struct tree_vec_map **) loc = h;
+  DECL_HAS_DEBUG_ARGS_P (from) = 1;
+  return &h->to;
+}
+
 /* Hashing of types so that we don't make duplicates.
    The entry point is `type_hash_canon'.  */
 
@@ -6215,8 +6262,9 @@ type_hash_canon (unsigned int hashcode, tree type)
   if (t1 != 0)
     {
 #ifdef GATHER_STATISTICS
+      tree_code_counts[(int) TREE_CODE (type)]--;
       tree_node_counts[(int) t_kind]--;
-      tree_node_sizes[(int) t_kind] -= sizeof (struct tree_type);
+      tree_node_sizes[(int) t_kind] -= sizeof (struct tree_type_non_common);
 #endif
       return t1;
     }
@@ -6270,6 +6318,9 @@ attribute_hash_list (const_tree list, hashval_t hashcode)
 int
 attribute_list_equal (const_tree l1, const_tree l2)
 {
+  if (l1 == l2)
+    return 1;
+
   return attribute_list_contained (l1, l2)
         && attribute_list_contained (l2, l1);
 }
@@ -6296,7 +6347,8 @@ attribute_list_contained (const_tree l1, const_tree l2)
        t1 != 0 && t2 != 0
         && TREE_PURPOSE (t1) == TREE_PURPOSE (t2)
         && TREE_VALUE (t1) == TREE_VALUE (t2);
-       t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2));
+       t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
+    ;
 
   /* Maybe the lists are equal.  */
   if (t1 == 0 && t2 == 0)
@@ -6308,11 +6360,9 @@ attribute_list_contained (const_tree l1, const_tree l2)
       /* This CONST_CAST is okay because lookup_attribute does not
         modify its argument and the return value is assigned to a
         const_tree.  */
-      for (attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
-                                   CONST_CAST_TREE(l1));
+      for (attr = lookup_ident_attribute (TREE_PURPOSE (t2), CONST_CAST_TREE(l1));
           attr != NULL_TREE && !attribute_value_equal (t2, attr);
-          attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
-                                   TREE_CHAIN (attr)))
+          attr = lookup_ident_attribute (TREE_PURPOSE (t2), TREE_CHAIN (attr)))
        ;
 
       if (attr == NULL_TREE)
@@ -6459,21 +6509,34 @@ tree_low_cst (const_tree t, int pos)
   return TREE_INT_CST_LOW (t);
 }
 
-/* Return the most significant bit of the integer constant T.  */
+/* Return the HOST_WIDE_INT least significant bits of T, a sizetype
+   kind INTEGER_CST.  This makes sure to properly sign-extend the
+   constant.  */
+
+HOST_WIDE_INT
+size_low_cst (const_tree t)
+{
+  double_int d = tree_to_double_int (t);
+  return double_int_sext (d, TYPE_PRECISION (TREE_TYPE (t))).low;
+}
+
+/* Return the most significant (sign) bit of T.  */
 
 int
-tree_int_cst_msb (const_tree t)
+tree_int_cst_sign_bit (const_tree t)
 {
-  int prec;
-  HOST_WIDE_INT h;
-  unsigned HOST_WIDE_INT l;
+  unsigned bitno = TYPE_PRECISION (TREE_TYPE (t)) - 1;
+  unsigned HOST_WIDE_INT w;
+
+  if (bitno < HOST_BITS_PER_WIDE_INT)
+    w = TREE_INT_CST_LOW (t);
+  else
+    {
+      w = TREE_INT_CST_HIGH (t);
+      bitno -= HOST_BITS_PER_WIDE_INT;
+    }
 
-  /* Note that using TYPE_PRECISION here is wrong.  We care about the
-     actual bits, not the (arbitrary) range of the type.  */
-  prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (t))) - 1;
-  rshift_double (TREE_INT_CST_LOW (t), TREE_INT_CST_HIGH (t), prec,
-                2 * HOST_BITS_PER_WIDE_INT, &l, &h, 0);
-  return (l & 1) == 1;
+  return (w >> bitno) & 1;
 }
 
 /* Return an indication of the sign of the integer constant T.
@@ -6886,9 +6949,9 @@ iterative_hash_expr (const_tree t, hashval_t val)
         or front end builtins, since the function code is overloaded in those
         cases.  */
       if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
-         && built_in_decls[DECL_FUNCTION_CODE (t)])
+         && builtin_decl_explicit_p (DECL_FUNCTION_CODE (t)))
        {
-         t = built_in_decls[DECL_FUNCTION_CODE (t)];
+         t = builtin_decl_explicit (DECL_FUNCTION_CODE (t));
          code = TREE_CODE (t);
        }
       /* FALL THROUGH */
@@ -6938,7 +7001,6 @@ iterative_hash_expr (const_tree t, hashval_t val)
              val = iterative_hash_expr (TREE_OPERAND (t, i), val);
        }
       return val;
-      break;
     }
 }
 
@@ -7364,6 +7426,15 @@ build_nonshared_array_type (tree elt_type, tree index_type)
   return build_array_type_1 (elt_type, index_type, false);
 }
 
+/* Return a representation of ELT_TYPE[NELTS], using indices of type
+   sizetype.  */
+
+tree
+build_array_type_nelts (tree elt_type, unsigned HOST_WIDE_INT nelts)
+{
+  return build_array_type (elt_type, build_index_type (size_int (nelts - 1)));
+}
+
 /* Recursively examines the array elements of TYPE, until a non-array
    element type is found.  */
 
@@ -7655,6 +7726,44 @@ build_varargs_function_type_list (tree return_type, ...)
   return args;
 }
 
+/* Build a function type.  RETURN_TYPE is the type returned by the
+   function; VAARGS indicates whether the function takes varargs.  The
+   function takes N named arguments, the types of which are provided in
+   ARG_TYPES.  */
+
+static tree
+build_function_type_array_1 (bool vaargs, tree return_type, int n,
+                            tree *arg_types)
+{
+  int i;
+  tree t = vaargs ? NULL_TREE : void_list_node;
+
+  for (i = n - 1; i >= 0; i--)
+    t = tree_cons (NULL_TREE, arg_types[i], t);
+
+  return build_function_type (return_type, t);
+}
+
+/* Build a function type.  RETURN_TYPE is the type returned by the
+   function.  The function takes N named arguments, the types of which
+   are provided in ARG_TYPES.  */
+
+tree
+build_function_type_array (tree return_type, int n, tree *arg_types)
+{
+  return build_function_type_array_1 (false, return_type, n, arg_types);
+}
+
+/* Build a variable argument function type.  RETURN_TYPE is the type
+   returned by the function.  The function takes N named arguments, the
+   types of which are provided in ARG_TYPES.  */
+
+tree
+build_varargs_function_type_array (tree return_type, int n, tree *arg_types)
+{
+  return build_function_type_array_1 (true, return_type, n, arg_types);
+}
+
 /* Build a METHOD_TYPE for a member of BASETYPE.  The RETTYPE (a TYPE)
    and ARGTYPES (a TREE_LIST) are the return type and arguments types
    for the method.  An implicit additional parameter (of type
@@ -8524,6 +8633,11 @@ dump_tree_statistics (void)
   fprintf (stderr, "---------------------------------------\n");
   fprintf (stderr, "%-20s %7d %10d\n", "Total", total_nodes, total_bytes);
   fprintf (stderr, "---------------------------------------\n");
+  fprintf (stderr, "Code                   Nodes\n");
+  fprintf (stderr, "----------------------------\n");
+  for (i = 0; i < (int) MAX_TREE_CODES; i++)
+    fprintf (stderr, "%-20s %7d\n", tree_code_name[i], tree_code_counts[i]);
+  fprintf (stderr, "----------------------------\n");
   ssanames_print_statistics ();
   phinodes_print_statistics ();
 #else
@@ -8537,14 +8651,12 @@ dump_tree_statistics (void)
 \f
 #define FILE_FUNCTION_FORMAT "_GLOBAL__%s_%s"
 
-/* Generate a crc32 of a string.  */
+/* Generate a crc32 of a byte.  */
 
 unsigned
-crc32_string (unsigned chksum, const char *string)
+crc32_byte (unsigned chksum, char byte)
 {
-  do
-    {
-      unsigned value = *string << 24;
+  unsigned value = (unsigned) byte << 24;
       unsigned ix;
 
       for (ix = 8; ix--; value <<= 1)
@@ -8555,6 +8667,18 @@ crc32_string (unsigned chksum, const char *string)
          chksum <<= 1;
          chksum ^= feedback;
        }
+  return chksum;
+}
+
+
+/* Generate a crc32 of a string.  */
+
+unsigned
+crc32_string (unsigned chksum, const char *string)
+{
+  do
+    {
+      chksum = crc32_byte (chksum, *string);
     }
   while (*string++);
   return chksum;
@@ -8578,8 +8702,10 @@ clean_symbol_name (char *p)
       *p = '_';
 }
 
-/* Generate a name for a special-purpose function function.
+/* Generate a name for a special-purpose function.
    The generated name may need to be unique across the whole link.
+   Changes to this function may also require corresponding changes to
+   xstrdup_mask_random.
    TYPE is some string to identify the purpose of this function to the
    linker or collect2; it must start with an uppercase letter,
    one of:
@@ -8612,12 +8738,7 @@ get_file_function_name (const char *type)
        file = input_filename;
       /* Just use the file's basename, because the full pathname
         might be quite long.  */
-      p = strrchr (file, '/');
-      if (p)
-       p++;
-      else
-       p = file;
-      p = q = ASTRDUP (p);
+      p = q = ASTRDUP (lbasename (file));
     }
   else
     {
@@ -8634,11 +8755,11 @@ get_file_function_name (const char *type)
        file = input_filename;
 
       len = strlen (file);
-      q = (char *) alloca (9 * 2 + len + 1);
+      q = (char *) alloca (9 + 17 + len + 1);
       memcpy (q, file, len + 1);
 
-      sprintf (q + len, "_%08X_%08X", crc32_string (0, name),
-              crc32_string (0, get_random_seed (false)));
+      snprintf (q + len, 9 + 17 + 1, "_%08X_" HOST_WIDE_INT_PRINT_HEX, 
+               crc32_string (0, name), get_random_seed (false));
 
       p = q;
     }
@@ -9056,11 +9177,12 @@ make_or_reuse_accum_type (unsigned size, int unsignedp, int satp)
 }
 
 /* Create nodes for all integer types (and error_mark_node) using the sizes
-   of C datatypes.  The caller should call set_sizetype soon after calling
-   this function to select one of the types as sizetype.  */
+   of C datatypes.  SIGNED_CHAR specifies whether char is signed,
+   SHORT_DOUBLE specifies whether double should be of the same precision
+   as float.  */
 
 void
-build_common_tree_nodes (bool signed_char)
+build_common_tree_nodes (bool signed_char, bool short_double)
 {
   error_mark_node = make_node (ERROR_MARK);
   TREE_TYPE (error_mark_node) = error_mark_node;
@@ -9100,6 +9222,7 @@ build_common_tree_nodes (bool signed_char)
         int128_unsigned_type_node = make_unsigned_type (128);
       }
 #endif
+
   /* Define a boolean type.  This type only represents boolean values but
      may be larger than char depending on the value of BOOL_TYPE_SIZE.
      Front ends which want to override this size (i.e. Java) can redefine
@@ -9109,6 +9232,18 @@ build_common_tree_nodes (bool signed_char)
   TYPE_MAX_VALUE (boolean_type_node) = build_int_cst (boolean_type_node, 1);
   TYPE_PRECISION (boolean_type_node) = 1;
 
+  /* Define what type to use for size_t.  */
+  if (strcmp (SIZE_TYPE, "unsigned int") == 0)
+    size_type_node = unsigned_type_node;
+  else if (strcmp (SIZE_TYPE, "long unsigned int") == 0)
+    size_type_node = long_unsigned_type_node;
+  else if (strcmp (SIZE_TYPE, "long long unsigned int") == 0)
+    size_type_node = long_long_unsigned_type_node;
+  else if (strcmp (SIZE_TYPE, "short unsigned int") == 0)
+    size_type_node = short_unsigned_type_node;
+  else
+    gcc_unreachable ();
+
   /* Fill in the rest of the sized types.  Reuse existing type nodes
      when possible.  */
   intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 0);
@@ -9126,14 +9261,7 @@ build_common_tree_nodes (bool signed_char)
   access_public_node = get_identifier ("public");
   access_protected_node = get_identifier ("protected");
   access_private_node = get_identifier ("private");
-}
-
-/* Call this function after calling build_common_tree_nodes and set_sizetype.
-   It will create several other common tree nodes.  */
 
-void
-build_common_tree_nodes_2 (int short_double)
-{
   /* Define these next since types below may used them.  */
   integer_zero_node = build_int_cst (integer_type_node, 0);
   integer_one_node = build_int_cst (integer_type_node, 1);
@@ -9306,9 +9434,10 @@ local_define_builtin (const char *name, tree type, enum built_in_function code,
   if (ecf_flags & ECF_LEAF)
     DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"),
                                        NULL, DECL_ATTRIBUTES (decl));
+  if ((ecf_flags & ECF_TM_PURE) && flag_tm)
+    apply_tm_attr (decl, get_identifier ("transaction_pure"));
 
-  built_in_decls[code] = decl;
-  implicit_built_in_decls[code] = decl;
+  set_builtin_decl (code, decl, true);
 }
 
 /* Call this function after instantiating all builtins that the language
@@ -9319,23 +9448,24 @@ void
 build_common_builtin_nodes (void)
 {
   tree tmp, ftype;
+  int ecf_flags;
 
-  if (built_in_decls[BUILT_IN_MEMCPY] == NULL
-      || built_in_decls[BUILT_IN_MEMMOVE] == NULL)
+  if (!builtin_decl_explicit_p (BUILT_IN_MEMCPY)
+      || !builtin_decl_explicit_p (BUILT_IN_MEMMOVE))
     {
       ftype = build_function_type_list (ptr_type_node,
                                        ptr_type_node, const_ptr_type_node,
                                        size_type_node, NULL_TREE);
 
-      if (built_in_decls[BUILT_IN_MEMCPY] == NULL)
+      if (!builtin_decl_explicit_p (BUILT_IN_MEMCPY))
        local_define_builtin ("__builtin_memcpy", ftype, BUILT_IN_MEMCPY,
                              "memcpy", ECF_NOTHROW | ECF_LEAF);
-      if (built_in_decls[BUILT_IN_MEMMOVE] == NULL)
+      if (!builtin_decl_explicit_p (BUILT_IN_MEMMOVE))
        local_define_builtin ("__builtin_memmove", ftype, BUILT_IN_MEMMOVE,
                              "memmove", ECF_NOTHROW | ECF_LEAF);
     }
 
-  if (built_in_decls[BUILT_IN_MEMCMP] == NULL)
+  if (!builtin_decl_explicit_p (BUILT_IN_MEMCMP))
     {
       ftype = build_function_type_list (integer_type_node, const_ptr_type_node,
                                        const_ptr_type_node, size_type_node,
@@ -9344,7 +9474,7 @@ build_common_builtin_nodes (void)
                            "memcmp", ECF_PURE | ECF_NOTHROW | ECF_LEAF);
     }
 
-  if (built_in_decls[BUILT_IN_MEMSET] == NULL)
+  if (!builtin_decl_explicit_p (BUILT_IN_MEMSET))
     {
       ftype = build_function_type_list (ptr_type_node,
                                        ptr_type_node, integer_type_node,
@@ -9353,7 +9483,7 @@ build_common_builtin_nodes (void)
                            "memset", ECF_NOTHROW | ECF_LEAF);
     }
 
-  if (built_in_decls[BUILT_IN_ALLOCA] == NULL)
+  if (!builtin_decl_explicit_p (BUILT_IN_ALLOCA))
     {
       ftype = build_function_type_list (ptr_type_node,
                                        size_type_node, NULL_TREE);
@@ -9361,9 +9491,18 @@ build_common_builtin_nodes (void)
                            "alloca", ECF_MALLOC | ECF_NOTHROW | ECF_LEAF);
     }
 
+  ftype = build_function_type_list (ptr_type_node, size_type_node,
+                                   size_type_node, NULL_TREE);
+  local_define_builtin ("__builtin_alloca_with_align", ftype,
+                       BUILT_IN_ALLOCA_WITH_ALIGN, "alloca",
+                       ECF_MALLOC | ECF_NOTHROW | ECF_LEAF);
+
   /* If we're checking the stack, `alloca' can throw.  */
   if (flag_stack_check)
-    TREE_NOTHROW (built_in_decls[BUILT_IN_ALLOCA]) = 0;
+    {
+      TREE_NOTHROW (builtin_decl_explicit (BUILT_IN_ALLOCA)) = 0;
+      TREE_NOTHROW (builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN)) = 0;
+    }
 
   ftype = build_function_type_list (void_type_node,
                                    ptr_type_node, ptr_type_node,
@@ -9424,11 +9563,36 @@ build_common_builtin_nodes (void)
   ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
   local_define_builtin ("__builtin_unwind_resume", ftype,
                        BUILT_IN_UNWIND_RESUME,
-                       ((targetm.except_unwind_info (&global_options)
+                       ((targetm_common.except_unwind_info (&global_options)
                          == UI_SJLJ)
                         ? "_Unwind_SjLj_Resume" : "_Unwind_Resume"),
                        ECF_NORETURN);
 
+  if (builtin_decl_explicit (BUILT_IN_RETURN_ADDRESS) == NULL_TREE)
+    {
+      ftype = build_function_type_list (ptr_type_node, integer_type_node,
+                                       NULL_TREE);
+      local_define_builtin ("__builtin_return_address", ftype,
+                           BUILT_IN_RETURN_ADDRESS,
+                           "__builtin_return_address",
+                           ECF_NOTHROW);
+    }
+
+  if (!builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_ENTER)
+      || !builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_EXIT))
+    {
+      ftype = build_function_type_list (void_type_node, ptr_type_node,
+                                       ptr_type_node, NULL_TREE);
+      if (!builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_ENTER))
+       local_define_builtin ("__cyg_profile_func_enter", ftype,
+                             BUILT_IN_PROFILE_FUNC_ENTER,
+                             "__cyg_profile_func_enter", 0);
+      if (!builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_EXIT))
+       local_define_builtin ("__cyg_profile_func_exit", ftype,
+                             BUILT_IN_PROFILE_FUNC_EXIT,
+                             "__cyg_profile_func_exit", 0);
+    }
+
   /* The exception object and filter values from the runtime.  The argument
      must be zero before exception lowering, i.e. from the front end.  After
      exception lowering, it will be the region number for the exception
@@ -9437,8 +9601,12 @@ build_common_builtin_nodes (void)
      its value in the landing pad.  */
   ftype = build_function_type_list (ptr_type_node,
                                    integer_type_node, NULL_TREE);
+  ecf_flags = ECF_PURE | ECF_NOTHROW | ECF_LEAF;
+  /* Only use TM_PURE if we we have TM language support.  */
+  if (builtin_decl_explicit_p (BUILT_IN_TM_LOAD_1))
+    ecf_flags |= ECF_TM_PURE;
   local_define_builtin ("__builtin_eh_pointer", ftype, BUILT_IN_EH_POINTER,
-                       "__builtin_eh_pointer", ECF_PURE | ECF_NOTHROW | ECF_LEAF);
+                       "__builtin_eh_pointer", ecf_flags);
 
   tmp = lang_hooks.types.type_for_mode (targetm.eh_return_filter_mode (), 0);
   ftype = build_function_type_list (tmp, integer_type_node, NULL_TREE);
@@ -9465,6 +9633,10 @@ build_common_builtin_nodes (void)
        const char *p;
        enum built_in_function mcode, dcode;
        tree type, inner_type;
+       const char *prefix = "__";
+
+       if (targetm.libfunc_gnu_prefix)
+         prefix = "__gnu_";
 
        type = lang_hooks.types.type_for_mode ((enum machine_mode) mode, 0);
        if (type == NULL)
@@ -9483,13 +9655,17 @@ build_common_builtin_nodes (void)
          *q = TOLOWER (*p);
        *q = '\0';
 
-       built_in_names[mcode] = concat ("__mul", mode_name_buf, "3", NULL);
+       built_in_names[mcode] = concat (prefix, "mul", mode_name_buf, "3",
+                                       NULL);
         local_define_builtin (built_in_names[mcode], ftype, mcode,
-                             built_in_names[mcode], ECF_CONST | ECF_NOTHROW | ECF_LEAF);
+                             built_in_names[mcode],
+                             ECF_CONST | ECF_NOTHROW | ECF_LEAF);
 
-       built_in_names[dcode] = concat ("__div", mode_name_buf, "3", NULL);
+       built_in_names[dcode] = concat (prefix, "div", mode_name_buf, "3",
+                                       NULL);
         local_define_builtin (built_in_names[dcode], ftype, dcode,
-                             built_in_names[dcode], ECF_CONST | ECF_NOTHROW | ECF_LEAF);
+                             built_in_names[dcode],
+                             ECF_CONST | ECF_NOTHROW | ECF_LEAF);
       }
   }
 }
@@ -9597,17 +9773,29 @@ build_vector_type (tree innertype, int nunits)
   return make_vector_type (innertype, nunits, VOIDmode);
 }
 
-/* Similarly, but takes the inner type and number of units, which must be
-   a power of two.  */
+/* Similarly, but builds a variant type with TYPE_VECTOR_OPAQUE set.  */
 
 tree
 build_opaque_vector_type (tree innertype, int nunits)
 {
-  tree t;
-  innertype = build_distinct_type_copy (innertype);
-  t = make_vector_type (innertype, nunits, VOIDmode);
-  TYPE_VECTOR_OPAQUE (t) = true;
-  return t;
+  tree t = make_vector_type (innertype, nunits, VOIDmode);
+  tree cand;
+  /* We always build the non-opaque variant before the opaque one,
+     so if it already exists, it is TYPE_NEXT_VARIANT of this one.  */
+  cand = TYPE_NEXT_VARIANT (t);
+  if (cand
+      && TYPE_VECTOR_OPAQUE (cand)
+      && check_qualified_type (cand, t, TYPE_QUALS (t)))
+    return cand;
+  /* Othewise build a variant type and make sure to queue it after
+     the non-opaque type.  */
+  cand = build_distinct_type_copy (t);
+  TYPE_VECTOR_OPAQUE (cand) = true;
+  TYPE_CANONICAL (cand) = TYPE_CANONICAL (t);
+  TYPE_NEXT_VARIANT (cand) = TYPE_NEXT_VARIANT (t);
+  TYPE_NEXT_VARIANT (t) = cand;
+  TYPE_MAIN_VARIANT (cand) = TYPE_MAIN_VARIANT (t);
+  return cand;
 }
 
 
@@ -9897,50 +10085,6 @@ needs_to_live_in_memory (const_tree t)
              && aggregate_value_p (t, current_function_decl)));
 }
 
-/* There are situations in which a language considers record types
-   compatible which have different field lists.  Decide if two fields
-   are compatible.  It is assumed that the parent records are compatible.  */
-
-bool
-fields_compatible_p (const_tree f1, const_tree f2)
-{
-  if (!operand_equal_p (DECL_FIELD_BIT_OFFSET (f1),
-                       DECL_FIELD_BIT_OFFSET (f2), OEP_ONLY_CONST))
-    return false;
-
-  if (!operand_equal_p (DECL_FIELD_OFFSET (f1),
-                        DECL_FIELD_OFFSET (f2), OEP_ONLY_CONST))
-    return false;
-
-  if (!types_compatible_p (TREE_TYPE (f1), TREE_TYPE (f2)))
-    return false;
-
-  return true;
-}
-
-/* Locate within RECORD a field that is compatible with ORIG_FIELD.  */
-
-tree
-find_compatible_field (tree record, tree orig_field)
-{
-  tree f;
-
-  for (f = TYPE_FIELDS (record); f ; f = TREE_CHAIN (f))
-    if (TREE_CODE (f) == FIELD_DECL
-       && fields_compatible_p (f, orig_field))
-      return f;
-
-  /* ??? Why isn't this on the main fields list?  */
-  f = TYPE_VFIELD (record);
-  if (f && TREE_CODE (f) == FIELD_DECL
-      && fields_compatible_p (f, orig_field))
-    return f;
-
-  /* ??? We should abort here, but Java appears to do Bad Things
-     with inherited fields.  */
-  return orig_field;
-}
-
 /* Return value of a constant X and sign-extend it.  */
 
 HOST_WIDE_INT
@@ -10042,7 +10186,7 @@ signed_type_for (tree type)
 tree
 upper_bound_in_type (tree outer, tree inner)
 {
-  unsigned HOST_WIDE_INT lo, hi;
+  double_int high;
   unsigned int det = 0;
   unsigned oprec = TYPE_PRECISION (outer);
   unsigned iprec = TYPE_PRECISION (inner);
@@ -10089,18 +10233,18 @@ upper_bound_in_type (tree outer, tree inner)
   /* Compute 2^^prec - 1.  */
   if (prec <= HOST_BITS_PER_WIDE_INT)
     {
-      hi = 0;
-      lo = ((~(unsigned HOST_WIDE_INT) 0)
+      high.high = 0;
+      high.low = ((~(unsigned HOST_WIDE_INT) 0)
            >> (HOST_BITS_PER_WIDE_INT - prec));
     }
   else
     {
-      hi = ((~(unsigned HOST_WIDE_INT) 0)
+      high.high = ((~(unsigned HOST_WIDE_INT) 0)
            >> (2 * HOST_BITS_PER_WIDE_INT - prec));
-      lo = ~(unsigned HOST_WIDE_INT) 0;
+      high.low = ~(unsigned HOST_WIDE_INT) 0;
     }
 
-  return build_int_cst_wide (outer, lo, hi);
+  return double_int_to_tree (outer, high);
 }
 
 /* Returns the smallest value obtainable by casting something in INNER type to
@@ -10109,7 +10253,7 @@ upper_bound_in_type (tree outer, tree inner)
 tree
 lower_bound_in_type (tree outer, tree inner)
 {
-  unsigned HOST_WIDE_INT lo, hi;
+  double_int low;
   unsigned oprec = TYPE_PRECISION (outer);
   unsigned iprec = TYPE_PRECISION (inner);
 
@@ -10120,7 +10264,7 @@ lower_bound_in_type (tree outer, tree inner)
         contains all values of INNER type.  In particular, both INNER
         and OUTER types have zero in common.  */
       || (oprec > iprec && TYPE_UNSIGNED (inner)))
-    lo = hi = 0;
+    low.low = low.high = 0;
   else
     {
       /* If we are widening a signed type to another signed type, we
@@ -10131,18 +10275,18 @@ lower_bound_in_type (tree outer, tree inner)
 
       if (prec <= HOST_BITS_PER_WIDE_INT)
        {
-         hi = ~(unsigned HOST_WIDE_INT) 0;
-         lo = (~(unsigned HOST_WIDE_INT) 0) << (prec - 1);
+         low.high = ~(unsigned HOST_WIDE_INT) 0;
+         low.low = (~(unsigned HOST_WIDE_INT) 0) << (prec - 1);
        }
       else
        {
-         hi = ((~(unsigned HOST_WIDE_INT) 0)
+         low.high = ((~(unsigned HOST_WIDE_INT) 0)
                << (prec - HOST_BITS_PER_WIDE_INT - 1));
-         lo = 0;
+         low.low = 0;
        }
     }
 
-  return build_int_cst_wide (outer, lo, hi);
+  return double_int_to_tree (outer, low);
 }
 
 /* Return nonzero if two operands that are suitable for PHI nodes are
@@ -10440,6 +10584,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
        case OMP_CLAUSE_FIRSTPRIVATE:
        case OMP_CLAUSE_COPYIN:
        case OMP_CLAUSE_COPYPRIVATE:
+       case OMP_CLAUSE_FINAL:
        case OMP_CLAUSE_IF:
        case OMP_CLAUSE_NUM_THREADS:
        case OMP_CLAUSE_SCHEDULE:
@@ -10450,6 +10595,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
        case OMP_CLAUSE_ORDERED:
        case OMP_CLAUSE_DEFAULT:
        case OMP_CLAUSE_UNTIED:
+       case OMP_CLAUSE_MERGEABLE:
          WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
 
        case OMP_CLAUSE_LASTPRIVATE:
@@ -10515,9 +10661,14 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
          if (result || !walk_subtrees)
            return result;
 
-         result = walk_type_fields (*type_p, func, data, pset, lh);
-         if (result)
-           return result;
+         /* But do not walk a pointed-to type since it may itself need to
+            be walked in the declaration case if it isn't anonymous.  */
+         if (!POINTER_TYPE_P (*type_p))
+           {
+             result = walk_type_fields (*type_p, func, data, pset, lh);
+             if (result)
+               return result;
+           }
 
          /* If this is a record type, also walk the fields.  */
          if (RECORD_OR_UNION_TYPE_P (*type_p))
@@ -11004,6 +11155,37 @@ tree_strip_sign_nop_conversions (tree exp)
   return exp;
 }
 
+/* Strip out all handled components that produce invariant
+   offsets.  */
+
+const_tree
+strip_invariant_refs (const_tree op)
+{
+  while (handled_component_p (op))
+    {
+      switch (TREE_CODE (op))
+       {
+       case ARRAY_REF:
+       case ARRAY_RANGE_REF:
+         if (!is_gimple_constant (TREE_OPERAND (op, 1))
+             || TREE_OPERAND (op, 2) != NULL_TREE
+             || TREE_OPERAND (op, 3) != NULL_TREE)
+           return NULL;
+         break;
+
+       case COMPONENT_REF:
+         if (TREE_OPERAND (op, 2) != NULL_TREE)
+           return NULL;
+         break;
+
+       default:;
+       }
+      op = TREE_OPERAND (op, 0);
+    }
+
+  return op;
+}
+
 static GTY(()) tree gcc_eh_personality_decl;
 
 /* Return the GCC personality function decl.  */