[AArch64 Testsuite] vld1_lane.c: Remove unused test data
[platform/upstream/gcc.git] / gcc / stor-layout.c
index a592bda..9757777 100644 (file)
@@ -1,7 +1,5 @@
 /* C-compiler utilities for types and variables storage layout
-   Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1996, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-   2011 Free Software Foundation, Inc.
+   Copyright (C) 1987-2015 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -24,15 +22,26 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "alias.h"
 #include "tree.h"
+#include "fold-const.h"
+#include "stor-layout.h"
+#include "stringpool.h"
+#include "varasm.h"
+#include "print-tree.h"
 #include "rtl.h"
 #include "tm_p.h"
 #include "flags.h"
 #include "function.h"
+#include "insn-config.h"
+#include "expmed.h"
+#include "dojump.h"
+#include "explow.h"
+#include "calls.h"
+#include "emit-rtl.h"
+#include "stmt.h"
 #include "expr.h"
-#include "output.h"
 #include "diagnostic-core.h"
-#include "ggc.h"
 #include "target.h"
 #include "langhooks.h"
 #include "regs.h"
@@ -40,7 +49,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cgraph.h"
 #include "tree-inline.h"
 #include "tree-dump.h"
-#include "gimple.h"
+#include "gimplify.h"
 
 /* Data type for the expressions representing sizes of data types.
    It is the first integer type laid out.  */
@@ -59,10 +68,8 @@ static tree self_referential_size (tree);
 static void finalize_record_size (record_layout_info);
 static void finalize_type_size (tree);
 static void place_union_field (record_layout_info, tree);
-#if defined (PCC_BITFIELD_TYPE_MATTERS) || defined (BITFIELD_NBYTES_LIMITED)
 static int excess_unit_span (HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT,
                             HOST_WIDE_INT, tree);
-#endif
 extern void debug_rli (record_layout_info);
 \f
 /* Show that REFERENCE_TYPES are internal and should use address_mode.
@@ -99,32 +106,20 @@ variable_size (tree size)
 }
 
 /* An array of functions used for self-referential size computation.  */
-static GTY(()) VEC (tree, gc) *size_functions;
+static GTY(()) vec<tree, va_gc> *size_functions;
 
-/* Look inside EXPR into simple arithmetic operations involving constants.
-   Return the outermost non-arithmetic or non-constant node.  */
+/* Return true if T is a self-referential component reference.  */
 
-static tree
-skip_simple_constant_arithmetic (tree expr)
+static bool
+self_referential_component_ref_p (tree t)
 {
-  while (true)
-    {
-      if (UNARY_CLASS_P (expr))
-       expr = TREE_OPERAND (expr, 0);
-      else if (BINARY_CLASS_P (expr))
-       {
-         if (TREE_CONSTANT (TREE_OPERAND (expr, 1)))
-           expr = TREE_OPERAND (expr, 0);
-         else if (TREE_CONSTANT (TREE_OPERAND (expr, 0)))
-           expr = TREE_OPERAND (expr, 1);
-         else
-           break;
-       }
-      else
-       break;
-    }
+  if (TREE_CODE (t) != COMPONENT_REF)
+    return false;
+
+  while (REFERENCE_CLASS_P (t))
+    t = TREE_OPERAND (t, 0);
 
-  return expr;
+  return (TREE_CODE (t) == PLACEHOLDER_EXPR);
 }
 
 /* Similar to copy_tree_r but do not copy component references involving
@@ -154,19 +149,10 @@ copy_self_referential_tree_r (tree *tp, int *walk_subtrees, void *data)
     }
 
   /* Default case: the component reference.  */
-  else if (code == COMPONENT_REF)
+  else if (self_referential_component_ref_p (*tp))
     {
-      tree inner;
-      for (inner = TREE_OPERAND (*tp, 0);
-          REFERENCE_CLASS_P (inner);
-          inner = TREE_OPERAND (inner, 0))
-       ;
-
-      if (TREE_CODE (inner) == PLACEHOLDER_EXPR)
-       {
-         *walk_subtrees = 0;
-         return NULL_TREE;
-       }
+      *walk_subtrees = 0;
+      return NULL_TREE;
     }
 
   /* We're not supposed to have them in self-referential size trees
@@ -190,21 +176,21 @@ static tree
 self_referential_size (tree size)
 {
   static unsigned HOST_WIDE_INT fnno = 0;
-  VEC (tree, heap) *self_refs = NULL;
+  vec<tree> self_refs = vNULL;
   tree param_type_list = NULL, param_decl_list = NULL;
   tree t, ref, return_type, fntype, fnname, fndecl;
   unsigned int i;
   char buf[128];
-  VEC(tree,gc) *args = NULL;
+  vec<tree, va_gc> *args = NULL;
 
   /* Do not factor out simple operations.  */
   t = skip_simple_constant_arithmetic (size);
-  if (TREE_CODE (t) == CALL_EXPR)
+  if (TREE_CODE (t) == CALL_EXPR || self_referential_component_ref_p (t))
     return size;
 
   /* Collect the list of self-references in the expression.  */
   find_placeholder_in_expr (size, &self_refs);
-  gcc_assert (VEC_length (tree, self_refs) > 0);
+  gcc_assert (self_refs.length () > 0);
 
   /* Obtain a private copy of the expression.  */
   t = size;
@@ -214,8 +200,8 @@ self_referential_size (tree size)
 
   /* Build the parameter and argument lists in parallel; also
      substitute the former for the latter in the expression.  */
-  args = VEC_alloc (tree, gc, VEC_length (tree, self_refs));
-  FOR_EACH_VEC_ELT (tree, self_refs, i, ref)
+  vec_alloc (args, self_refs.length ());
+  FOR_EACH_VEC_ELT (self_refs, i, ref)
     {
       tree subst, param_name, param_type, param_decl;
 
@@ -237,12 +223,7 @@ self_referential_size (tree size)
       param_type = TREE_TYPE (ref);
       param_decl
        = build_decl (input_location, PARM_DECL, param_name, param_type);
-      if (targetm.calls.promote_prototypes (NULL_TREE)
-         && INTEGRAL_TYPE_P (param_type)
-         && TYPE_PRECISION (param_type) < TYPE_PRECISION (integer_type_node))
-       DECL_ARG_TYPE (param_decl) = integer_type_node;
-      else
-       DECL_ARG_TYPE (param_decl) = param_type;
+      DECL_ARG_TYPE (param_decl) = param_type;
       DECL_ARTIFICIAL (param_decl) = 1;
       TREE_READONLY (param_decl) = 1;
 
@@ -250,10 +231,10 @@ self_referential_size (tree size)
 
       param_type_list = tree_cons (NULL_TREE, param_type, param_type_list);
       param_decl_list = chainon (param_decl, param_decl_list);
-      VEC_quick_push (tree, args, ref);
+      args->quick_push (ref);
     }
 
-  VEC_free (tree, heap, self_refs);
+  self_refs.release ();
 
   /* Append 'void' to indicate that the number of parameters is fixed.  */
   param_type_list = tree_cons (NULL_TREE, void_type_node, param_type_list);
@@ -267,7 +248,7 @@ self_referential_size (tree size)
   fntype = build_function_type (return_type, param_type_list);
 
   /* Build the function declaration.  */
-  sprintf (buf, "SZ"HOST_WIDE_INT_PRINT_UNSIGNED, fnno++);
+  sprintf (buf, "SZ" HOST_WIDE_INT_PRINT_UNSIGNED, fnno++);
   fnname = get_file_function_name (buf);
   fndecl = build_decl (input_location, FUNCTION_DECL, fnname, fntype);
   for (t = param_decl_list; t; t = DECL_CHAIN (t))
@@ -298,7 +279,7 @@ self_referential_size (tree size)
   TREE_STATIC (fndecl) = 1;
 
   /* Put it onto the list of size functions.  */
-  VEC_safe_push (tree, gc, size_functions, fndecl);
+  vec_safe_push (size_functions, fndecl);
 
   /* Replace the original expression with a call to the size function.  */
   return build_call_expr_loc_vec (UNKNOWN_LOCATION, fndecl, args);
@@ -317,15 +298,16 @@ finalize_size_functions (void)
   unsigned int i;
   tree fndecl;
 
-  for (i = 0; VEC_iterate(tree, size_functions, i, fndecl); i++)
+  for (i = 0; size_functions && size_functions->iterate (i, &fndecl); i++)
     {
+      allocate_struct_function (fndecl, false);
+      set_cfun (NULL);
       dump_function (TDI_original, fndecl);
       gimplify_function_tree (fndecl);
-      dump_function (TDI_generic, fndecl);
-      cgraph_finalize_function (fndecl, false);
+      cgraph_node::finalize_function (fndecl, false);
     }
 
-  VEC_free (tree, gc, size_functions);
+  vec_free (size_functions);
 }
 \f
 /* Return the machine mode to use for a nonscalar of SIZE bits.  The
@@ -333,10 +315,11 @@ finalize_size_functions (void)
    it may have padding as well.  If LIMIT is nonzero, modes of wider
    than MAX_FIXED_MODE_SIZE will not be used.  */
 
-enum machine_mode
+machine_mode
 mode_for_size (unsigned int size, enum mode_class mclass, int limit)
 {
-  enum machine_mode mode;
+  machine_mode mode;
+  int i;
 
   if (limit && size > MAX_FIXED_MODE_SIZE)
     return BLKmode;
@@ -347,20 +330,26 @@ mode_for_size (unsigned int size, enum mode_class mclass, int limit)
     if (GET_MODE_PRECISION (mode) == size)
       return mode;
 
+  if (mclass == MODE_INT || mclass == MODE_PARTIAL_INT)
+    for (i = 0; i < NUM_INT_N_ENTS; i ++)
+      if (int_n_data[i].bitsize == size
+         && int_n_enabled_p[i])
+       return int_n_data[i].m;
+
   return BLKmode;
 }
 
 /* Similar, except passed a tree node.  */
 
-enum machine_mode
+machine_mode
 mode_for_size_tree (const_tree size, enum mode_class mclass, int limit)
 {
   unsigned HOST_WIDE_INT uhwi;
   unsigned int ui;
 
-  if (!host_integerp (size, 1))
+  if (!tree_fits_uhwi_p (size))
     return BLKmode;
-  uhwi = tree_low_cst (size, 1);
+  uhwi = tree_to_uhwi (size);
   ui = uhwi;
   if (uhwi != ui)
     return BLKmode;
@@ -370,25 +359,36 @@ mode_for_size_tree (const_tree size, enum mode_class mclass, int limit)
 /* Similar, but never return BLKmode; return the narrowest mode that
    contains at least the requested number of value bits.  */
 
-enum machine_mode
+machine_mode
 smallest_mode_for_size (unsigned int size, enum mode_class mclass)
 {
-  enum machine_mode mode;
+  machine_mode mode = VOIDmode;
+  int i;
 
   /* Get the first mode which has at least this size, in the
      specified class.  */
   for (mode = GET_CLASS_NARROWEST_MODE (mclass); mode != VOIDmode;
        mode = GET_MODE_WIDER_MODE (mode))
     if (GET_MODE_PRECISION (mode) >= size)
-      return mode;
+      break;
 
-  gcc_unreachable ();
+  if (mclass == MODE_INT || mclass == MODE_PARTIAL_INT)
+    for (i = 0; i < NUM_INT_N_ENTS; i ++)
+      if (int_n_data[i].bitsize >= size
+         && int_n_data[i].bitsize < GET_MODE_PRECISION (mode)
+         && int_n_enabled_p[i])
+       mode = int_n_data[i].m;
+
+  if (mode == VOIDmode)
+    gcc_unreachable ();
+
+  return mode;
 }
 
 /* Find an integer mode of the exact same size, or BLKmode on failure.  */
 
-enum machine_mode
-int_mode_for_mode (enum machine_mode mode)
+machine_mode
+int_mode_for_mode (machine_mode mode)
 {
   switch (GET_MODE_CLASS (mode))
     {
@@ -410,6 +410,7 @@ int_mode_for_mode (enum machine_mode mode)
     case MODE_VECTOR_ACCUM:
     case MODE_VECTOR_UFRACT:
     case MODE_VECTOR_UACCUM:
+    case MODE_POINTER_BOUNDS:
       mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
       break;
 
@@ -427,14 +428,81 @@ int_mode_for_mode (enum machine_mode mode)
   return mode;
 }
 
+/* Find a mode that can be used for efficient bitwise operations on MODE.
+   Return BLKmode if no such mode exists.  */
+
+machine_mode
+bitwise_mode_for_mode (machine_mode mode)
+{
+  /* Quick exit if we already have a suitable mode.  */
+  unsigned int bitsize = GET_MODE_BITSIZE (mode);
+  if (SCALAR_INT_MODE_P (mode) && bitsize <= MAX_FIXED_MODE_SIZE)
+    return mode;
+
+  /* Reuse the sanity checks from int_mode_for_mode.  */
+  gcc_checking_assert ((int_mode_for_mode (mode), true));
+
+  /* Try to replace complex modes with complex modes.  In general we
+     expect both components to be processed independently, so we only
+     care whether there is a register for the inner mode.  */
+  if (COMPLEX_MODE_P (mode))
+    {
+      machine_mode trial = mode;
+      if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT)
+       trial = mode_for_size (bitsize, MODE_COMPLEX_INT, false);
+      if (trial != BLKmode
+         && have_regs_of_mode[GET_MODE_INNER (trial)])
+       return trial;
+    }
+
+  /* Try to replace vector modes with vector modes.  Also try using vector
+     modes if an integer mode would be too big.  */
+  if (VECTOR_MODE_P (mode) || bitsize > MAX_FIXED_MODE_SIZE)
+    {
+      machine_mode trial = mode;
+      if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
+       trial = mode_for_size (bitsize, MODE_VECTOR_INT, 0);
+      if (trial != BLKmode
+         && have_regs_of_mode[trial]
+         && targetm.vector_mode_supported_p (trial))
+       return trial;
+    }
+
+  /* Otherwise fall back on integers while honoring MAX_FIXED_MODE_SIZE.  */
+  return mode_for_size (bitsize, MODE_INT, true);
+}
+
+/* Find a type that can be used for efficient bitwise operations on MODE.
+   Return null if no such mode exists.  */
+
+tree
+bitwise_type_for_mode (machine_mode mode)
+{
+  mode = bitwise_mode_for_mode (mode);
+  if (mode == BLKmode)
+    return NULL_TREE;
+
+  unsigned int inner_size = GET_MODE_UNIT_BITSIZE (mode);
+  tree inner_type = build_nonstandard_integer_type (inner_size, true);
+
+  if (VECTOR_MODE_P (mode))
+    return build_vector_type_for_mode (inner_type, mode);
+
+  if (COMPLEX_MODE_P (mode))
+    return build_complex_type (inner_type);
+
+  gcc_checking_assert (GET_MODE_INNER (mode) == mode);
+  return inner_type;
+}
+
 /* Find a mode that is suitable for representing a vector with
    NUNITS elements of mode INNERMODE.  Returns BLKmode if there
    is no suitable mode.  */
 
-enum machine_mode
-mode_for_vector (enum machine_mode innermode, unsigned nunits)
+machine_mode
+mode_for_vector (machine_mode innermode, unsigned nunits)
 {
-  enum machine_mode mode;
+  machine_mode mode;
 
   /* First, look for a supported vector type.  */
   if (SCALAR_FLOAT_MODE_P (innermode))
@@ -475,7 +543,7 @@ mode_for_vector (enum machine_mode innermode, unsigned nunits)
    BIGGEST_ALIGNMENT.  */
 
 unsigned int
-get_mode_alignment (enum machine_mode mode)
+get_mode_alignment (machine_mode mode)
 {
   return MIN (BIGGEST_ALIGNMENT, MAX (1, mode_base_align[mode]*BITS_PER_UNIT));
 }
@@ -483,7 +551,7 @@ get_mode_alignment (enum machine_mode mode)
 /* Return the natural mode of an array, given that it is SIZE bytes in
    total and has elements of type ELEM_TYPE.  */
 
-static enum machine_mode
+static machine_mode
 mode_for_array (tree elem_type, tree size)
 {
   tree elem_size;
@@ -496,10 +564,10 @@ mode_for_array (tree elem_type, tree size)
     return TYPE_MODE (elem_type);
 
   limit_p = true;
-  if (host_integerp (size, 1) && host_integerp (elem_size, 1))
+  if (tree_fits_uhwi_p (size) && tree_fits_uhwi_p (elem_size))
     {
-      int_size = tree_low_cst (size, 1);
-      int_elem_size = tree_low_cst (elem_size, 1);
+      int_size = tree_to_uhwi (size);
+      int_elem_size = tree_to_uhwi (elem_size);
       if (int_elem_size > 0
          && int_size % int_elem_size == 0
          && targetm.array_mode_supported_p (TYPE_MODE (elem_type),
@@ -603,11 +671,9 @@ layout_decl (tree decl, unsigned int known_align)
            {
              zero_bitfield = true;
              packed_p = false;
-#ifdef PCC_BITFIELD_TYPE_MATTERS
              if (PCC_BITFIELD_TYPE_MATTERS)
                do_type_align (type, decl);
              else
-#endif
                {
 #ifdef EMPTY_FIELD_BOUNDARY
                  if (EMPTY_FIELD_BOUNDARY > DECL_ALIGN (decl))
@@ -621,16 +687,12 @@ layout_decl (tree decl, unsigned int known_align)
 
          /* See if we can use an ordinary integer mode for a bit-field.
             Conditions are: a fixed size that is correct for another mode,
-            occupying a complete byte or bytes on proper boundary,
-            and not -fstrict-volatile-bitfields.  If the latter is set,
-            we unfortunately can't check TREE_THIS_VOLATILE, as a cast
-            may make a volatile object later.  */
+            occupying a complete byte or bytes on proper boundary.  */
          if (TYPE_SIZE (type) != 0
              && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
-             && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
-             && flag_strict_volatile_bitfields <= 0)
+             && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
            {
-             enum machine_mode xmode
+             machine_mode xmode
                = mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
              unsigned int xalign = GET_MODE_ALIGNMENT (xmode);
 
@@ -778,7 +840,7 @@ start_record_layout (tree t)
   rli->offset = size_zero_node;
   rli->bitpos = bitsize_zero_node;
   rli->prev_field = 0;
-  rli->pending_statics = NULL;
+  rli->pending_statics = 0;
   rli->packed_maybe_necessary = 0;
   rli->remaining_in_alignment = 0;
 
@@ -886,7 +948,7 @@ debug_rli (record_layout_info rli)
   if (rli->packed_maybe_necessary)
     fprintf (stderr, "packed may be necessary\n");
 
-  if (!VEC_empty (tree, rli->pending_statics))
+  if (!vec_safe_is_empty (rli->pending_statics))
     {
       fprintf (stderr, "pending statics:\n");
       debug_vec_tree (rli->pending_statics);
@@ -975,7 +1037,6 @@ update_alignment_for_field (record_layout_info rli, tree field,
          rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
        }
     }
-#ifdef PCC_BITFIELD_TYPE_MATTERS
   else if (is_bitfield && PCC_BITFIELD_TYPE_MATTERS)
     {
       /* Named bit-fields cause the entire structure to have the
@@ -1018,7 +1079,6 @@ update_alignment_for_field (record_layout_info rli, tree field,
          user_align |= TYPE_USER_ALIGN (type);
        }
     }
-#endif
   else
     {
       rli->record_align = MAX (rli->record_align, desired_align);
@@ -1056,7 +1116,6 @@ place_union_field (record_layout_info rli, tree field)
                               DECL_SIZE_UNIT (field), rli->offset);
 }
 
-#if defined (PCC_BITFIELD_TYPE_MATTERS) || defined (BITFIELD_NBYTES_LIMITED)
 /* A bitfield of SIZE with a required access alignment of ALIGN is allocated
    at BYTE_OFFSET / BIT_OFFSET.  Return nonzero if the field would span more
    units of alignment than the underlying TYPE.  */
@@ -1070,10 +1129,8 @@ excess_unit_span (HOST_WIDE_INT byte_offset, HOST_WIDE_INT bit_offset,
 
   offset = offset % align;
   return ((offset + size + align - 1) / align
-         > ((unsigned HOST_WIDE_INT) tree_low_cst (TYPE_SIZE (type), 1)
-            / align));
+         > tree_to_uhwi (TYPE_SIZE (type)) / align);
 }
-#endif
 
 /* RLI contains information about the layout of a RECORD_TYPE.  FIELD
    is a FIELD_DECL to be added after those fields already present in
@@ -1100,7 +1157,7 @@ place_field (record_layout_info rli, tree field)
      it *after* the record is laid out.  */
   if (TREE_CODE (field) == VAR_DECL)
     {
-      VEC_safe_push (tree, gc, rli->pending_statics, field);
+      vec_safe_push (rli->pending_statics, field);
       return;
     }
 
@@ -1130,14 +1187,14 @@ place_field (record_layout_info rli, tree field)
   /* Work out the known alignment so far.  Note that A & (-A) is the
      value of the least-significant bit in A that is one.  */
   if (! integer_zerop (rli->bitpos))
-    known_align = (tree_low_cst (rli->bitpos, 1)
-                  & - tree_low_cst (rli->bitpos, 1));
+    known_align = (tree_to_uhwi (rli->bitpos)
+                  & - tree_to_uhwi (rli->bitpos));
   else if (integer_zerop (rli->offset))
     known_align = 0;
-  else if (host_integerp (rli->offset, 1))
+  else if (tree_fits_uhwi_p (rli->offset))
     known_align = (BITS_PER_UNIT
-                  * (tree_low_cst (rli->offset, 1)
-                     & - tree_low_cst (rli->offset, 1)));
+                  * (tree_to_uhwi (rli->offset)
+                     & - tree_to_uhwi (rli->offset)));
   else
     known_align = rli->offset_align;
 
@@ -1200,7 +1257,6 @@ place_field (record_layout_info rli, tree field)
 
   /* Handle compatibility with PCC.  Note that if the record has any
      variable-sized fields, we need not worry about compatibility.  */
-#ifdef PCC_BITFIELD_TYPE_MATTERS
   if (PCC_BITFIELD_TYPE_MATTERS
       && ! targetm.ms_bitfield_layout_p (rli->t)
       && TREE_CODE (field) == FIELD_DECL
@@ -1211,15 +1267,15 @@ place_field (record_layout_info rli, tree field)
          || TYPE_ALIGN (type) <= BITS_PER_UNIT)
       && maximum_field_alignment == 0
       && ! integer_zerop (DECL_SIZE (field))
-      && host_integerp (DECL_SIZE (field), 1)
-      && host_integerp (rli->offset, 1)
-      && host_integerp (TYPE_SIZE (type), 1))
+      && tree_fits_uhwi_p (DECL_SIZE (field))
+      && tree_fits_uhwi_p (rli->offset)
+      && tree_fits_uhwi_p (TYPE_SIZE (type)))
     {
       unsigned int type_align = TYPE_ALIGN (type);
       tree dsize = DECL_SIZE (field);
-      HOST_WIDE_INT field_size = tree_low_cst (dsize, 1);
-      HOST_WIDE_INT offset = tree_low_cst (rli->offset, 0);
-      HOST_WIDE_INT bit_offset = tree_low_cst (rli->bitpos, 0);
+      HOST_WIDE_INT field_size = tree_to_uhwi (dsize);
+      HOST_WIDE_INT offset = tree_to_uhwi (rli->offset);
+      HOST_WIDE_INT bit_offset = tree_to_shwi (rli->bitpos);
 
 #ifdef ADJUST_FIELD_ALIGN
       if (! TYPE_USER_ALIGN (type))
@@ -1245,7 +1301,6 @@ place_field (record_layout_info rli, tree field)
       if (! DECL_PACKED (field))
        TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
     }
-#endif
 
 #ifdef BITFIELD_NBYTES_LIMITED
   if (BITFIELD_NBYTES_LIMITED
@@ -1255,15 +1310,15 @@ place_field (record_layout_info rli, tree field)
       && DECL_BIT_FIELD_TYPE (field)
       && ! DECL_PACKED (field)
       && ! integer_zerop (DECL_SIZE (field))
-      && host_integerp (DECL_SIZE (field), 1)
-      && host_integerp (rli->offset, 1)
-      && host_integerp (TYPE_SIZE (type), 1))
+      && tree_fits_uhwi_p (DECL_SIZE (field))
+      && tree_fits_uhwi_p (rli->offset)
+      && tree_fits_uhwi_p (TYPE_SIZE (type)))
     {
       unsigned int type_align = TYPE_ALIGN (type);
       tree dsize = DECL_SIZE (field);
-      HOST_WIDE_INT field_size = tree_low_cst (dsize, 1);
-      HOST_WIDE_INT offset = tree_low_cst (rli->offset, 0);
-      HOST_WIDE_INT bit_offset = tree_low_cst (rli->bitpos, 0);
+      HOST_WIDE_INT field_size = tree_to_uhwi (dsize);
+      HOST_WIDE_INT offset = tree_to_uhwi (rli->offset);
+      HOST_WIDE_INT bit_offset = tree_to_shwi (rli->bitpos);
 
 #ifdef ADJUST_FIELD_ALIGN
       if (! TYPE_USER_ALIGN (type))
@@ -1317,18 +1372,18 @@ place_field (record_layout_info rli, tree field)
          if (DECL_BIT_FIELD_TYPE (field)
              && !integer_zerop (DECL_SIZE (field))
              && !integer_zerop (DECL_SIZE (rli->prev_field))
-             && host_integerp (DECL_SIZE (rli->prev_field), 0)
-             && host_integerp (TYPE_SIZE (type), 0)
+             && tree_fits_shwi_p (DECL_SIZE (rli->prev_field))
+             && tree_fits_uhwi_p (TYPE_SIZE (type))
              && simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (prev_type)))
            {
              /* We're in the middle of a run of equal type size fields; make
                 sure we realign if we run out of bits.  (Not decl size,
                 type size!) */
-             HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 1);
+             HOST_WIDE_INT bitsize = tree_to_uhwi (DECL_SIZE (field));
 
              if (rli->remaining_in_alignment < bitsize)
                {
-                 HOST_WIDE_INT typesize = tree_low_cst (TYPE_SIZE (type), 1);
+                 HOST_WIDE_INT typesize = tree_to_uhwi (TYPE_SIZE (type));
 
                  /* out of bits; bump up to next 'word'.  */
                  rli->bitpos
@@ -1367,7 +1422,7 @@ place_field (record_layout_info rli, tree field)
 
              /* Cause a new bitfield to be captured, either this time (if
                 currently a bitfield) or next time we see one.  */
-             if (!DECL_BIT_FIELD_TYPE(field)
+             if (!DECL_BIT_FIELD_TYPE (field)
                  || integer_zerop (DECL_SIZE (field)))
                rli->prev_field = NULL;
            }
@@ -1375,7 +1430,7 @@ place_field (record_layout_info rli, tree field)
          normalize_rli (rli);
         }
 
-      /* If we're starting a new run of same size type bitfields
+      /* If we're starting a new run of same type size bitfields
         (or a run of non-bitfields), set up the "first of the run"
         fields.
 
@@ -1400,13 +1455,13 @@ place_field (record_layout_info rli, tree field)
             until we see a bitfield (and come by here again) we just skip
             calculating it.  */
          if (DECL_SIZE (field) != NULL
-             && host_integerp (TYPE_SIZE (TREE_TYPE (field)), 1)
-             && host_integerp (DECL_SIZE (field), 1))
+             && tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (field)))
+             && tree_fits_uhwi_p (DECL_SIZE (field)))
            {
              unsigned HOST_WIDE_INT bitsize
-               = tree_low_cst (DECL_SIZE (field), 1);
+               = tree_to_uhwi (DECL_SIZE (field));
              unsigned HOST_WIDE_INT typesize
-               = tree_low_cst (TYPE_SIZE (TREE_TYPE (field)), 1);
+               = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (field)));
 
              if (typesize < bitsize)
                rli->remaining_in_alignment = 0;
@@ -1434,18 +1489,22 @@ place_field (record_layout_info rli, tree field)
   DECL_FIELD_BIT_OFFSET (field) = rli->bitpos;
   SET_DECL_OFFSET_ALIGN (field, rli->offset_align);
 
+  /* Evaluate nonconstant offsets only once, either now or as soon as safe.  */
+  if (TREE_CODE (DECL_FIELD_OFFSET (field)) != INTEGER_CST)
+    DECL_FIELD_OFFSET (field) = variable_size (DECL_FIELD_OFFSET (field));
+
   /* If this field ended up more aligned than we thought it would be (we
      approximate this by seeing if its position changed), lay out the field
      again; perhaps we can use an integral mode for it now.  */
   if (! integer_zerop (DECL_FIELD_BIT_OFFSET (field)))
-    actual_align = (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
-                   & - tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1));
+    actual_align = (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
+                   & - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field)));
   else if (integer_zerop (DECL_FIELD_OFFSET (field)))
     actual_align = MAX (BIGGEST_ALIGNMENT, rli->record_align);
-  else if (host_integerp (DECL_FIELD_OFFSET (field), 1))
+  else if (tree_fits_uhwi_p (DECL_FIELD_OFFSET (field)))
     actual_align = (BITS_PER_UNIT
-                  * (tree_low_cst (DECL_FIELD_OFFSET (field), 1)
-                     & - tree_low_cst (DECL_FIELD_OFFSET (field), 1)));
+                  * (tree_to_uhwi (DECL_FIELD_OFFSET (field))
+                     & - tree_to_uhwi (DECL_FIELD_OFFSET (field))));
   else
     actual_align = DECL_OFFSET_ALIGN (field);
   /* ACTUAL_ALIGN is still the actual alignment *within the record* .
@@ -1593,7 +1652,7 @@ void
 compute_record_mode (tree type)
 {
   tree field;
-  enum machine_mode mode = VOIDmode;
+  machine_mode mode = VOIDmode;
 
   /* Most RECORD_TYPEs have BLKmode, so we start off assuming that.
      However, if possible, we use a mode that fits in a register
@@ -1601,7 +1660,7 @@ compute_record_mode (tree type)
      line.  */
   SET_TYPE_MODE (type, BLKmode);
 
-  if (! host_integerp (TYPE_SIZE (type), 1))
+  if (! tree_fits_uhwi_p (TYPE_SIZE (type)))
     return;
 
   /* A record which has any BLKmode members must itself be
@@ -1617,9 +1676,9 @@ compute_record_mode (tree type)
              && ! TYPE_NO_FORCE_BLK (TREE_TYPE (field))
              && !(TYPE_SIZE (TREE_TYPE (field)) != 0
                   && integer_zerop (TYPE_SIZE (TREE_TYPE (field)))))
-         || ! host_integerp (bit_position (field), 1)
+         || ! tree_fits_uhwi_p (bit_position (field))
          || DECL_SIZE (field) == 0
-         || ! host_integerp (DECL_SIZE (field), 1))
+         || ! tree_fits_uhwi_p (DECL_SIZE (field)))
        return;
 
       /* If this field is the whole struct, remember its mode so
@@ -1628,21 +1687,18 @@ compute_record_mode (tree type)
       if (simple_cst_equal (TYPE_SIZE (type), DECL_SIZE (field)))
        mode = DECL_MODE (field);
 
-#ifdef MEMBER_TYPE_FORCES_BLK
-      /* With some targets, eg. c4x, it is sub-optimal
-        to access an aligned BLKmode structure as a scalar.  */
-
-      if (MEMBER_TYPE_FORCES_BLK (field, mode))
+      /* With some targets, it is sub-optimal to access an aligned
+        BLKmode structure as a scalar.  */
+      if (targetm.member_type_forces_blk (field, mode))
        return;
-#endif /* MEMBER_TYPE_FORCES_BLK  */
     }
 
   /* If we only have one real field; use its mode if that mode's size
      matches the type's size.  This only applies to RECORD_TYPE.  This
      does not apply to unions.  */
   if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode
-      && host_integerp (TYPE_SIZE (type), 1)
-      && GET_MODE_BITSIZE (mode) == TREE_INT_CST_LOW (TYPE_SIZE (type)))
+      && tree_fits_uhwi_p (TYPE_SIZE (type))
+      && GET_MODE_BITSIZE (mode) == tree_to_uhwi (TYPE_SIZE (type)))
     SET_TYPE_MODE (type, mode);
   else
     SET_TYPE_MODE (type, mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1));
@@ -1671,12 +1727,9 @@ finalize_type_size (tree type)
      However, where strict alignment is not required, avoid
      over-aligning structures, since most compilers do not do this
      alignment.  */
-
-  if (TYPE_MODE (type) != BLKmode && TYPE_MODE (type) != VOIDmode
-      && (STRICT_ALIGNMENT
-         || (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE
-             && TREE_CODE (type) != QUAL_UNION_TYPE
-             && TREE_CODE (type) != ARRAY_TYPE)))
+  if (TYPE_MODE (type) != BLKmode
+      && TYPE_MODE (type) != VOIDmode
+      && (STRICT_ALIGNMENT || !AGGREGATE_TYPE_P (type)))
     {
       unsigned mode_align = GET_MODE_ALIGNMENT (TYPE_MODE (type));
 
@@ -1729,8 +1782,9 @@ finalize_type_size (tree type)
       tree size = TYPE_SIZE (type);
       tree size_unit = TYPE_SIZE_UNIT (type);
       unsigned int align = TYPE_ALIGN (type);
+      unsigned int precision = TYPE_PRECISION (type);
       unsigned int user_align = TYPE_USER_ALIGN (type);
-      enum machine_mode mode = TYPE_MODE (type);
+      machine_mode mode = TYPE_MODE (type);
 
       /* Copy it into all variants.  */
       for (variant = TYPE_MAIN_VARIANT (type);
@@ -1739,8 +1793,13 @@ finalize_type_size (tree type)
        {
          TYPE_SIZE (variant) = size;
          TYPE_SIZE_UNIT (variant) = size_unit;
-         TYPE_ALIGN (variant) = align;
-         TYPE_USER_ALIGN (variant) = user_align;
+         unsigned valign = align;
+         if (TYPE_USER_ALIGN (variant))
+           valign = MAX (valign, TYPE_ALIGN (variant));
+         else
+           TYPE_USER_ALIGN (variant) = user_align;
+         TYPE_ALIGN (variant) = valign;
+         TYPE_PRECISION (variant) = precision;
          SET_TYPE_MODE (variant, mode);
        }
     }
@@ -1778,16 +1837,18 @@ static void
 finish_bitfield_representative (tree repr, tree field)
 {
   unsigned HOST_WIDE_INT bitsize, maxbitsize;
-  enum machine_mode mode;
+  machine_mode mode;
   tree nextf, size;
 
   size = size_diffop (DECL_FIELD_OFFSET (field),
                      DECL_FIELD_OFFSET (repr));
-  gcc_assert (host_integerp (size, 1));
-  bitsize = (tree_low_cst (size, 1) * BITS_PER_UNIT
-            + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
-            - tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1)
-            + tree_low_cst (DECL_SIZE (field), 1));
+  while (TREE_CODE (size) == COMPOUND_EXPR)
+    size = TREE_OPERAND (size, 1);
+  gcc_assert (tree_fits_uhwi_p (size));
+  bitsize = (tree_to_uhwi (size) * BITS_PER_UNIT
+            + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
+            - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr))
+            + tree_to_uhwi (DECL_SIZE (field)));
 
   /* Round up bitsize to multiples of BITS_PER_UNIT.  */
   bitsize = (bitsize + BITS_PER_UNIT - 1) & ~(BITS_PER_UNIT - 1);
@@ -1799,17 +1860,17 @@ finish_bitfield_representative (tree repr, tree field)
   if (nextf)
     {
       tree maxsize;
-      /* If there was an error, the field may be not layed out
+      /* If there was an error, the field may be not laid out
          correctly.  Don't bother to do anything.  */
       if (TREE_TYPE (nextf) == error_mark_node)
        return;
       maxsize = size_diffop (DECL_FIELD_OFFSET (nextf),
                             DECL_FIELD_OFFSET (repr));
-      if (host_integerp (maxsize, 1))
+      if (tree_fits_uhwi_p (maxsize))
        {
-         maxbitsize = (tree_low_cst (maxsize, 1) * BITS_PER_UNIT
-                       + tree_low_cst (DECL_FIELD_BIT_OFFSET (nextf), 1)
-                       - tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1));
+         maxbitsize = (tree_to_uhwi (maxsize) * BITS_PER_UNIT
+                       + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (nextf))
+                       - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
          /* If the group ends within a bitfield nextf does not need to be
             aligned to BITS_PER_UNIT.  Thus round up.  */
          maxbitsize = (maxbitsize + BITS_PER_UNIT - 1) & ~(BITS_PER_UNIT - 1);
@@ -1826,9 +1887,9 @@ finish_bitfield_representative (tree repr, tree field)
         use bitsize as fallback for this case.  */
       tree maxsize = size_diffop (TYPE_SIZE_UNIT (DECL_CONTEXT (field)),
                                  DECL_FIELD_OFFSET (repr));
-      if (host_integerp (maxsize, 1))
-       maxbitsize = (tree_low_cst (maxsize, 1) * BITS_PER_UNIT
-                     - tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1));
+      if (tree_fits_uhwi_p (maxsize))
+       maxbitsize = (tree_to_uhwi (maxsize) * BITS_PER_UNIT
+                     - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
       else
        maxbitsize = bitsize;
     }
@@ -1880,10 +1941,10 @@ finish_bitfield_representative (tree repr, tree field)
 }
 
 /* Compute and set FIELD_DECLs for the underlying objects we should
-   use for bitfield access for the structure layed out with RLI.  */
+   use for bitfield access for the structure T.  */
 
-static void
-finish_bitfield_layout (record_layout_info rli)
+void
+finish_bitfield_layout (tree t)
 {
   tree field, prev;
   tree repr = NULL_TREE;
@@ -1892,10 +1953,10 @@ finish_bitfield_layout (record_layout_info rli)
      we could use the underlying type as hint for the representative
      if the bitfield would fit and the representative would not exceed
      the union in size.  */
-  if (TREE_CODE (rli->t) != RECORD_TYPE)
+  if (TREE_CODE (t) != RECORD_TYPE)
     return;
 
-  for (prev = NULL_TREE, field = TYPE_FIELDS (rli->t);
+  for (prev = NULL_TREE, field = TYPE_FIELDS (t);
        field; field = DECL_CHAIN (field))
     {
       if (TREE_CODE (field) != FIELD_DECL)
@@ -1939,8 +2000,8 @@ finish_bitfield_layout (record_layout_info rli)
             representative to be generated.  That will at most
             generate worse code but still maintain correctness with
             respect to the C++ memory model.  */
-         else if (!((host_integerp (DECL_FIELD_OFFSET (repr), 1)
-                     && host_integerp (DECL_FIELD_OFFSET (field), 1))
+         else if (!((tree_fits_uhwi_p (DECL_FIELD_OFFSET (repr))
+                     && tree_fits_uhwi_p (DECL_FIELD_OFFSET (field)))
                     || operand_equal_p (DECL_FIELD_OFFSET (repr),
                                         DECL_FIELD_OFFSET (field), 0)))
            {
@@ -1982,7 +2043,7 @@ finish_record_layout (record_layout_info rli, int free_p)
   finalize_type_size (rli->t);
 
   /* Compute bitfield representatives.  */
-  finish_bitfield_layout (rli);
+  finish_bitfield_layout (rli->t);
 
   /* Propagate TYPE_PACKED to variants.  With C++ templates,
      handle_packed_attribute is too early to do this.  */
@@ -1992,13 +2053,13 @@ finish_record_layout (record_layout_info rli, int free_p)
 
   /* Lay out any static members.  This is done now because their type
      may use the record's type.  */
-  while (!VEC_empty (tree, rli->pending_statics))
-    layout_decl (VEC_pop (tree, rli->pending_statics), 0);
+  while (!vec_safe_is_empty (rli->pending_statics))
+    layout_decl (rli->pending_statics->pop (), 0);
 
   /* Clean up.  */
   if (free_p)
     {
-      VEC_free (tree, gc, rli->pending_statics);
+      vec_free (rli->pending_statics);
       free (rli);
     }
 }
@@ -2059,6 +2120,10 @@ layout_type (tree type)
   if (type == error_mark_node)
     return;
 
+  /* We don't want finalize_type_size to copy an alignment attribute to
+     variants that don't have it.  */
+  type = TYPE_MAIN_VARIANT (type);
+
   /* Do nothing if type has been laid out before.  */
   if (TYPE_SIZE (type))
     return;
@@ -2070,21 +2135,13 @@ layout_type (tree type)
         of the language-specific code.  */
       gcc_unreachable ();
 
-    case BOOLEAN_TYPE:  /* Used for Java, Pascal, and Chill.  */
-      if (TYPE_PRECISION (type) == 0)
-       TYPE_PRECISION (type) = 1; /* default to one byte/boolean.  */
-
-      /* ... fall through ...  */
-
+    case BOOLEAN_TYPE:
     case INTEGER_TYPE:
     case ENUMERAL_TYPE:
-      if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
-         && tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0)
-       TYPE_UNSIGNED (type) = 1;
-
       SET_TYPE_MODE (type,
                     smallest_mode_for_size (TYPE_PRECISION (type), MODE_INT));
       TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
+      /* Don't set TYPE_PRECISION here, as it may be set by a bitfield.  */
       TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
       break;
 
@@ -2132,9 +2189,17 @@ layout_type (tree type)
        TYPE_SIZE (type) = int_const_binop (MULT_EXPR, TYPE_SIZE (innertype),
                                            bitsize_int (nunits));
 
-       /* Always naturally align vectors.  This prevents ABI changes
-          depending on whether or not native vector modes are supported.  */
-       TYPE_ALIGN (type) = tree_low_cst (TYPE_SIZE (type), 0);
+       /* For vector types, we do not default to the mode's alignment.
+          Instead, query a target hook, defaulting to natural alignment.
+          This prevents ABI changes depending on whether or not native
+          vector modes are supported.  */
+       TYPE_ALIGN (type) = targetm.vector_alignment (type);
+
+       /* However, if the underlying mode requires a bigger alignment than
+          what the target hook provides, we cannot use the mode.  For now,
+          simply reject that case.  */
+       gcc_assert (TYPE_ALIGN (type)
+                   >= GET_MODE_ALIGNMENT (TYPE_MODE (type)));
         break;
       }
 
@@ -2145,11 +2210,16 @@ layout_type (tree type)
       SET_TYPE_MODE (type, VOIDmode);
       break;
 
+    case POINTER_BOUNDS_TYPE:
+      TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
+      TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
+      break;
+
     case OFFSET_TYPE:
       TYPE_SIZE (type) = bitsize_int (POINTER_SIZE);
-      TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT);
-      /* A pointer might be MODE_PARTIAL_INT,
-        but ptrdiff_t must be integral.  */
+      TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE_UNITS);
+      /* A pointer might be MODE_PARTIAL_INT, but ptrdiff_t must be
+        integral, which may be an __intN.  */
       SET_TYPE_MODE (type, mode_for_size (POINTER_SIZE, MODE_INT, 0));
       TYPE_PRECISION (type) = POINTER_SIZE;
       break;
@@ -2167,7 +2237,7 @@ layout_type (tree type)
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       {
-       enum machine_mode mode = TYPE_MODE (type);
+       machine_mode mode = TYPE_MODE (type);
        if (TREE_CODE (type) == REFERENCE_TYPE && reference_types_internal)
          {
            addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type));
@@ -2177,7 +2247,7 @@ layout_type (tree type)
        TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (mode));
        TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
        TYPE_UNSIGNED (type) = 1;
-       TYPE_PRECISION (type) = GET_MODE_BITSIZE (mode);
+       TYPE_PRECISION (type) = GET_MODE_PRECISION (mode);
       }
       break;
 
@@ -2214,14 +2284,10 @@ layout_type (tree type)
                    && TYPE_UNSIGNED (TREE_TYPE (lb))
                    && tree_int_cst_lt (ub, lb))
                  {
-                   lb = double_int_to_tree
-                          (ssizetype,
-                           double_int_sext (tree_to_double_int (lb),
-                                            TYPE_PRECISION (TREE_TYPE (lb))));
-                   ub = double_int_to_tree
-                          (ssizetype,
-                           double_int_sext (tree_to_double_int (ub),
-                                            TYPE_PRECISION (TREE_TYPE (ub))));
+                   lb = wide_int_to_tree (ssizetype,
+                                          offset_int::from (lb, SIGNED));
+                   ub = wide_int_to_tree (ssizetype,
+                                          offset_int::from (ub, SIGNED));
                  }
                length
                  = fold_convert (sizetype,
@@ -2230,12 +2296,12 @@ layout_type (tree type)
                                              size_binop (MINUS_EXPR, ub, lb)));
              }
 
-           /* If we arrived at a length of zero ignore any overflow
-              that occured as part of the calculation.  There exists
-              an association of the plus one where that overflow would
-              not happen.  */
+           /* ??? We have no way to distinguish a null-sized array from an
+              array spanning the whole sizetype range, so we arbitrarily
+              decide that [0, -1] is the only valid representation.  */
            if (integer_zerop (length)
-               && TREE_OVERFLOW (length))
+               && TREE_OVERFLOW (length)
+               && integer_zerop (lb))
              length = size_zero_node;
 
            TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size,
@@ -2254,18 +2320,20 @@ layout_type (tree type)
        /* Now round the alignment and size,
           using machine-dependent criteria if any.  */
 
+       unsigned align = TYPE_ALIGN (element);
+       if (TYPE_USER_ALIGN (type))
+         align = MAX (align, TYPE_ALIGN (type));
+       else
+         TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
 #ifdef ROUND_TYPE_ALIGN
-       TYPE_ALIGN (type)
-         = ROUND_TYPE_ALIGN (type, TYPE_ALIGN (element), BITS_PER_UNIT);
+       align = ROUND_TYPE_ALIGN (type, align, BITS_PER_UNIT);
 #else
-       TYPE_ALIGN (type) = MAX (TYPE_ALIGN (element), BITS_PER_UNIT);
+       align = MAX (align, BITS_PER_UNIT);
 #endif
-       TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
+       TYPE_ALIGN (type) = align;
        SET_TYPE_MODE (type, BLKmode);
        if (TYPE_SIZE (type) != 0
-#ifdef MEMBER_TYPE_FORCES_BLK
-           && ! MEMBER_TYPE_FORCES_BLK (type, VOIDmode)
-#endif
+           && ! targetm.member_type_forces_blk (type, VOIDmode)
            /* BLKmode elements force BLKmode aggregate;
               else extract/store fields may lose.  */
            && (TYPE_MODE (TREE_TYPE (type)) != BLKmode
@@ -2330,9 +2398,7 @@ layout_type (tree type)
   /* Compute the final TYPE_SIZE, TYPE_ALIGN, etc. for TYPE.  For
      records and unions, finish_record_layout already called this
      function.  */
-  if (TREE_CODE (type) != RECORD_TYPE
-      && TREE_CODE (type) != UNION_TYPE
-      && TREE_CODE (type) != QUAL_UNION_TYPE)
+  if (!RECORD_OR_UNION_TYPE_P (type))
     finalize_type_size (type);
 
   /* We should never see alias sets on incomplete aggregates.  And we
@@ -2341,6 +2407,29 @@ layout_type (tree type)
     gcc_assert (!TYPE_ALIAS_SET_KNOWN_P (type));
 }
 
+/* Return the least alignment required for type TYPE.  */
+
+unsigned int
+min_align_of_type (tree type)
+{
+  unsigned int align = TYPE_ALIGN (type);
+  if (!TYPE_USER_ALIGN (type))
+    {
+      align = MIN (align, BIGGEST_ALIGNMENT);
+#ifdef BIGGEST_FIELD_ALIGNMENT
+      align = MIN (align, BIGGEST_FIELD_ALIGNMENT);
+#endif
+      unsigned int field_align = align;
+#ifdef ADJUST_FIELD_ALIGN
+      tree field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, type);
+      field_align = ADJUST_FIELD_ALIGN (field, field_align);
+      ggc_free (field);
+#endif
+      align = MIN (align, field_align);
+    }
+  return align / BITS_PER_UNIT;
+}
+
 /* Vector types need to re-check the target flags each time we report
    the machine mode.  We need to do this because attribute target can
    change the result of vector_mode_supported_p and have_regs_of_mode
@@ -2350,10 +2439,10 @@ layout_type (tree type)
    referenced by a function and re-compute the TYPE_MODE once, rather
    than make the TYPE_MODE macro call a function.  */
 
-enum machine_mode
+machine_mode
 vector_type_mode (const_tree t)
 {
-  enum machine_mode mode;
+  machine_mode mode;
 
   gcc_assert (TREE_CODE (t) == VECTOR_TYPE);
 
@@ -2362,7 +2451,7 @@ vector_type_mode (const_tree t)
       && (!targetm.vector_mode_supported_p (mode)
          || !have_regs_of_mode[mode]))
     {
-      enum machine_mode innermode = TREE_TYPE (t)->type_common.mode;
+      machine_mode innermode = TREE_TYPE (t)->type_common.mode;
 
       /* For integers, try mapping it to a same-sized scalar mode.  */
       if (GET_MODE_CLASS (innermode) == MODE_INT)
@@ -2475,14 +2564,31 @@ initialize_sizetypes (void)
   else if (strcmp (SIZETYPE, "short unsigned int") == 0)
     precision = SHORT_TYPE_SIZE;
   else
-    gcc_unreachable ();
+    {
+      int i;
+
+      precision = -1;
+      for (i = 0; i < NUM_INT_N_ENTS; i++)
+       if (int_n_enabled_p[i])
+         {
+           char name[50];
+           sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
+
+           if (strcmp (name, SIZETYPE) == 0)
+             {
+               precision = int_n_data[i].bitsize;
+             }
+         }
+      if (precision == -1)
+       gcc_unreachable ();
+    }
 
   bprecision
     = MIN (precision + BITS_PER_UNIT_LOG + 1, MAX_FIXED_MODE_SIZE);
   bprecision
     = GET_MODE_PRECISION (smallest_mode_for_size (bprecision, MODE_INT));
-  if (bprecision > HOST_BITS_PER_WIDE_INT * 2)
-    bprecision = HOST_BITS_PER_WIDE_INT * 2;
+  if (bprecision > HOST_BITS_PER_DOUBLE_INT)
+    bprecision = HOST_BITS_PER_DOUBLE_INT;
 
   /* Create stubs for sizetype and bitsizetype so we can create constants.  */
   sizetype = make_node (INTEGER_TYPE);
@@ -2499,16 +2605,14 @@ initialize_sizetypes (void)
   TYPE_ALIGN (sizetype) = GET_MODE_ALIGNMENT (TYPE_MODE (sizetype));
   TYPE_SIZE (sizetype) = bitsize_int (precision);
   TYPE_SIZE_UNIT (sizetype) = size_int (GET_MODE_SIZE (TYPE_MODE (sizetype)));
-  set_min_and_max_values_for_integral_type (sizetype, precision,
-                                           /*is_unsigned=*/true);
+  set_min_and_max_values_for_integral_type (sizetype, precision, UNSIGNED);
 
   SET_TYPE_MODE (bitsizetype, smallest_mode_for_size (bprecision, MODE_INT));
   TYPE_ALIGN (bitsizetype) = GET_MODE_ALIGNMENT (TYPE_MODE (bitsizetype));
   TYPE_SIZE (bitsizetype) = bitsize_int (bprecision);
   TYPE_SIZE_UNIT (bitsizetype)
     = size_int (GET_MODE_SIZE (TYPE_MODE (bitsizetype)));
-  set_min_and_max_values_for_integral_type (bitsizetype, bprecision,
-                                           /*is_unsigned=*/true);
+  set_min_and_max_values_for_integral_type (bitsizetype, bprecision, UNSIGNED);
 
   /* Create the signed variants of *sizetype.  */
   ssizetype = make_signed_type (TYPE_PRECISION (sizetype));
@@ -2528,48 +2632,18 @@ initialize_sizetypes (void)
 void
 set_min_and_max_values_for_integral_type (tree type,
                                          int precision,
-                                         bool is_unsigned)
+                                         signop sgn)
 {
-  tree min_value;
-  tree max_value;
-
-  if (is_unsigned)
-    {
-      min_value = build_int_cst (type, 0);
-      max_value
-       = build_int_cst_wide (type, precision - HOST_BITS_PER_WIDE_INT >= 0
-                             ? -1
-                             : ((HOST_WIDE_INT) 1 << precision) - 1,
-                             precision - HOST_BITS_PER_WIDE_INT > 0
-                             ? ((unsigned HOST_WIDE_INT) ~0
-                                >> (HOST_BITS_PER_WIDE_INT
-                                    - (precision - HOST_BITS_PER_WIDE_INT)))
-                             : 0);
-    }
-  else
-    {
-      min_value
-       = build_int_cst_wide (type,
-                             (precision - HOST_BITS_PER_WIDE_INT > 0
-                              ? 0
-                              : (HOST_WIDE_INT) (-1) << (precision - 1)),
-                             (((HOST_WIDE_INT) (-1)
-                               << (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
-                                   ? precision - HOST_BITS_PER_WIDE_INT - 1
-                                   : 0))));
-      max_value
-       = build_int_cst_wide (type,
-                             (precision - HOST_BITS_PER_WIDE_INT > 0
-                              ? -1
-                              : ((HOST_WIDE_INT) 1 << (precision - 1)) - 1),
-                             (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
-                              ? (((HOST_WIDE_INT) 1
-                                  << (precision - HOST_BITS_PER_WIDE_INT - 1))) - 1
-                              : 0));
-    }
+  /* For bitfields with zero width we end up creating integer types
+     with zero precision.  Don't assign any minimum/maximum values
+     to those types, they don't have any valid value.  */
+  if (precision < 1)
+    return;
 
-  TYPE_MIN_VALUE (type) = min_value;
-  TYPE_MAX_VALUE (type) = max_value;
+  TYPE_MIN_VALUE (type)
+    = wide_int_to_tree (type, wi::min_value (precision, sgn));
+  TYPE_MAX_VALUE (type)
+    = wide_int_to_tree (type, wi::max_value (precision, sgn));
 }
 
 /* Set the extreme values of TYPE based on its precision in bits,
@@ -2582,14 +2656,7 @@ fixup_signed_type (tree type)
 {
   int precision = TYPE_PRECISION (type);
 
-  /* We can not represent properly constants greater then
-     2 * HOST_BITS_PER_WIDE_INT, still we need the types
-     as they are used by i386 vector extensions and friends.  */
-  if (precision > HOST_BITS_PER_WIDE_INT * 2)
-    precision = HOST_BITS_PER_WIDE_INT * 2;
-
-  set_min_and_max_values_for_integral_type (type, precision,
-                                           /*is_unsigned=*/false);
+  set_min_and_max_values_for_integral_type (type, precision, SIGNED);
 
   /* Lay out the type: set its alignment, size, etc.  */
   layout_type (type);
@@ -2604,29 +2671,120 @@ fixup_unsigned_type (tree type)
 {
   int precision = TYPE_PRECISION (type);
 
-  /* We can not represent properly constants greater then
-     2 * HOST_BITS_PER_WIDE_INT, still we need the types
-     as they are used by i386 vector extensions and friends.  */
-  if (precision > HOST_BITS_PER_WIDE_INT * 2)
-    precision = HOST_BITS_PER_WIDE_INT * 2;
-
   TYPE_UNSIGNED (type) = 1;
 
-  set_min_and_max_values_for_integral_type (type, precision,
-                                           /*is_unsigned=*/true);
+  set_min_and_max_values_for_integral_type (type, precision, UNSIGNED);
 
   /* Lay out the type: set its alignment, size, etc.  */
   layout_type (type);
 }
 \f
+/* Construct an iterator for a bitfield that spans BITSIZE bits,
+   starting at BITPOS.
+
+   BITREGION_START is the bit position of the first bit in this
+   sequence of bit fields.  BITREGION_END is the last bit in this
+   sequence.  If these two fields are non-zero, we should restrict the
+   memory access to that range.  Otherwise, we are allowed to touch
+   any adjacent non bit-fields.
+
+   ALIGN is the alignment of the underlying object in bits.
+   VOLATILEP says whether the bitfield is volatile.  */
+
+bit_field_mode_iterator
+::bit_field_mode_iterator (HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
+                          HOST_WIDE_INT bitregion_start,
+                          HOST_WIDE_INT bitregion_end,
+                          unsigned int align, bool volatilep)
+: m_mode (GET_CLASS_NARROWEST_MODE (MODE_INT)), m_bitsize (bitsize),
+  m_bitpos (bitpos), m_bitregion_start (bitregion_start),
+  m_bitregion_end (bitregion_end), m_align (align),
+  m_volatilep (volatilep), m_count (0)
+{
+  if (!m_bitregion_end)
+    {
+      /* We can assume that any aligned chunk of ALIGN bits that overlaps
+        the bitfield is mapped and won't trap, provided that ALIGN isn't
+        too large.  The cap is the biggest required alignment for data,
+        or at least the word size.  And force one such chunk at least.  */
+      unsigned HOST_WIDE_INT units
+       = MIN (align, MAX (BIGGEST_ALIGNMENT, BITS_PER_WORD));
+      if (bitsize <= 0)
+       bitsize = 1;
+      m_bitregion_end = bitpos + bitsize + units - 1;
+      m_bitregion_end -= m_bitregion_end % units + 1;
+    }
+}
+
+/* Calls to this function return successively larger modes that can be used
+   to represent the bitfield.  Return true if another bitfield mode is
+   available, storing it in *OUT_MODE if so.  */
+
+bool
+bit_field_mode_iterator::next_mode (machine_mode *out_mode)
+{
+  for (; m_mode != VOIDmode; m_mode = GET_MODE_WIDER_MODE (m_mode))
+    {
+      unsigned int unit = GET_MODE_BITSIZE (m_mode);
+
+      /* Skip modes that don't have full precision.  */
+      if (unit != GET_MODE_PRECISION (m_mode))
+       continue;
+
+      /* Stop if the mode is too wide to handle efficiently.  */
+      if (unit > MAX_FIXED_MODE_SIZE)
+       break;
+
+      /* Don't deliver more than one multiword mode; the smallest one
+        should be used.  */
+      if (m_count > 0 && unit > BITS_PER_WORD)
+       break;
+
+      /* Skip modes that are too small.  */
+      unsigned HOST_WIDE_INT substart = (unsigned HOST_WIDE_INT) m_bitpos % unit;
+      unsigned HOST_WIDE_INT subend = substart + m_bitsize;
+      if (subend > unit)
+       continue;
+
+      /* Stop if the mode goes outside the bitregion.  */
+      HOST_WIDE_INT start = m_bitpos - substart;
+      if (m_bitregion_start && start < m_bitregion_start)
+       break;
+      HOST_WIDE_INT end = start + unit;
+      if (end > m_bitregion_end + 1)
+       break;
+
+      /* Stop if the mode requires too much alignment.  */
+      if (GET_MODE_ALIGNMENT (m_mode) > m_align
+         && SLOW_UNALIGNED_ACCESS (m_mode, m_align))
+       break;
+
+      *out_mode = m_mode;
+      m_mode = GET_MODE_WIDER_MODE (m_mode);
+      m_count++;
+      return true;
+    }
+  return false;
+}
+
+/* Return true if smaller modes are generally preferred for this kind
+   of bitfield.  */
+
+bool
+bit_field_mode_iterator::prefer_smaller_modes ()
+{
+  return (m_volatilep
+         ? targetm.narrow_volatile_bitfield ()
+         : !SLOW_BYTE_ACCESS);
+}
+
 /* Find the best machine mode to use when referencing a bit field of length
    BITSIZE bits starting at BITPOS.
 
    BITREGION_START is the bit position of the first bit in this
    sequence of bit fields.  BITREGION_END is the last bit in this
    sequence.  If these two fields are non-zero, we should restrict the
-   memory access to a maximum sized chunk of
-   BITREGION_END - BITREGION_START + 1.  Otherwise, we are allowed to touch
+   memory access to that range.  Otherwise, we are allowed to touch
    any adjacent non bit-fields.
 
    The underlying object is known to be aligned to a boundary of ALIGN bits.
@@ -2645,90 +2803,113 @@ fixup_unsigned_type (tree type)
    If VOLATILEP is true the narrow_volatile_bitfields target hook is used to
    decide which of the above modes should be used.  */
 
-enum machine_mode
+machine_mode
 get_best_mode (int bitsize, int bitpos,
               unsigned HOST_WIDE_INT bitregion_start,
               unsigned HOST_WIDE_INT bitregion_end,
               unsigned int align,
-              enum machine_mode largest_mode, int volatilep)
+              machine_mode largest_mode, bool volatilep)
 {
-  enum machine_mode mode;
-  unsigned int unit = 0;
-  unsigned HOST_WIDE_INT maxbits;
-
-  /* If unset, no restriction.  */
-  if (!bitregion_end)
-    maxbits = MAX_FIXED_MODE_SIZE;
-  else
-    maxbits = bitregion_end - bitregion_start + 1;
-
-  /* Find the narrowest integer mode that contains the bit field.  */
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  bit_field_mode_iterator iter (bitsize, bitpos, bitregion_start,
+                               bitregion_end, align, volatilep);
+  machine_mode widest_mode = VOIDmode;
+  machine_mode mode;
+  while (iter.next_mode (&mode)
+        /* ??? For historical reasons, reject modes that would normally
+           receive greater alignment, even if unaligned accesses are
+           acceptable.  This has both advantages and disadvantages.
+           Removing this check means that something like:
+
+              struct s { unsigned int x; unsigned int y; };
+              int f (struct s *s) { return s->x == 0 && s->y == 0; }
+
+           can be implemented using a single load and compare on
+           64-bit machines that have no alignment restrictions.
+           For example, on powerpc64-linux-gnu, we would generate:
+
+                   ld 3,0(3)
+                   cntlzd 3,3
+                   srdi 3,3,6
+                   blr
+
+           rather than:
+
+                   lwz 9,0(3)
+                   cmpwi 7,9,0
+                   bne 7,.L3
+                   lwz 3,4(3)
+                   cntlzw 3,3
+                   srwi 3,3,5
+                   extsw 3,3
+                   blr
+                   .p2align 4,,15
+           .L3:
+                   li 3,0
+                   blr
+
+           However, accessing more than one field can make life harder
+           for the gimple optimizers.  For example, gcc.dg/vect/bb-slp-5.c
+           has a series of unsigned short copies followed by a series of
+           unsigned short comparisons.  With this check, both the copies
+           and comparisons remain 16-bit accesses and FRE is able
+           to eliminate the latter.  Without the check, the comparisons
+           can be done using 2 64-bit operations, which FRE isn't able
+           to handle in the same way.
+
+           Either way, it would probably be worth disabling this check
+           during expand.  One particular example where removing the
+           check would help is the get_best_mode call in store_bit_field.
+           If we are given a memory bitregion of 128 bits that is aligned
+           to a 64-bit boundary, and the bitfield we want to modify is
+           in the second half of the bitregion, this check causes
+           store_bitfield to turn the memory into a 64-bit reference
+           to the _first_ half of the region.  We later use
+           adjust_bitfield_address to get a reference to the correct half,
+           but doing so looks to adjust_bitfield_address as though we are
+           moving past the end of the original object, so it drops the
+           associated MEM_EXPR and MEM_OFFSET.  Removing the check
+           causes store_bit_field to keep a 128-bit memory reference,
+           so that the final bitfield reference still has a MEM_EXPR
+           and MEM_OFFSET.  */
+        && GET_MODE_ALIGNMENT (mode) <= align
+        && (largest_mode == VOIDmode
+            || GET_MODE_SIZE (mode) <= GET_MODE_SIZE (largest_mode)))
     {
-      unit = GET_MODE_BITSIZE (mode);
-      if (unit == GET_MODE_PRECISION (mode)
-         && (bitpos % unit) + bitsize <= unit)
+      widest_mode = mode;
+      if (iter.prefer_smaller_modes ())
        break;
     }
-
-  if (mode == VOIDmode
-      /* It is tempting to omit the following line
-        if STRICT_ALIGNMENT is true.
-        But that is incorrect, since if the bitfield uses part of 3 bytes
-        and we use a 4-byte mode, we could get a spurious segv
-        if the extra 4th byte is past the end of memory.
-        (Though at least one Unix compiler ignores this problem:
-        that on the Sequent 386 machine.  */
-      || MIN (unit, BIGGEST_ALIGNMENT) > align
-      || (largest_mode != VOIDmode && unit > GET_MODE_BITSIZE (largest_mode))
-      || unit > maxbits
-      || (bitregion_end
-         && bitpos - (bitpos % unit) + unit > bitregion_end + 1))
-    return VOIDmode;
-
-  if ((SLOW_BYTE_ACCESS && ! volatilep)
-      || (volatilep && !targetm.narrow_volatile_bitfield ()))
-    {
-      enum machine_mode wide_mode = VOIDmode, tmode;
-
-      for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT); tmode != VOIDmode;
-          tmode = GET_MODE_WIDER_MODE (tmode))
-       {
-         unit = GET_MODE_BITSIZE (tmode);
-         if (unit == GET_MODE_PRECISION (tmode)
-             && bitpos / unit == (bitpos + bitsize - 1) / unit
-             && unit <= BITS_PER_WORD
-             && unit <= MIN (align, BIGGEST_ALIGNMENT)
-             && unit <= maxbits
-             && (largest_mode == VOIDmode
-                 || unit <= GET_MODE_BITSIZE (largest_mode))
-             && (bitregion_end == 0
-                 || bitpos - (bitpos % unit) + unit <= bitregion_end + 1))
-           wide_mode = tmode;
-       }
-
-      if (wide_mode != VOIDmode)
-       return wide_mode;
-    }
-
-  return mode;
+  return widest_mode;
 }
 
 /* Gets minimal and maximal values for MODE (signed or unsigned depending on
    SIGN).  The returned constants are made to be usable in TARGET_MODE.  */
 
 void
-get_mode_bounds (enum machine_mode mode, int sign,
-                enum machine_mode target_mode,
+get_mode_bounds (machine_mode mode, int sign,
+                machine_mode target_mode,
                 rtx *mmin, rtx *mmax)
 {
-  unsigned size = GET_MODE_BITSIZE (mode);
+  unsigned size = GET_MODE_PRECISION (mode);
   unsigned HOST_WIDE_INT min_val, max_val;
 
   gcc_assert (size <= HOST_BITS_PER_WIDE_INT);
 
-  if (sign)
+  /* Special case BImode, which has values 0 and STORE_FLAG_VALUE.  */
+  if (mode == BImode)
+    {
+      if (STORE_FLAG_VALUE < 0)
+       {
+         min_val = STORE_FLAG_VALUE;
+         max_val = 0;
+       }
+      else
+       {
+         min_val = 0;
+         max_val = STORE_FLAG_VALUE;
+       }
+    }
+  else if (sign)
     {
       min_val = -((unsigned HOST_WIDE_INT) 1 << (size - 1));
       max_val = ((unsigned HOST_WIDE_INT) 1 << (size - 1)) - 1;