/* C-compiler utilities for types and variables storage layout
   Copyright (C) 1987-2025 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */


#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "function.h"
#include "rtl.h"
#include "tree.h"
#include "memmodel.h"
#include "tm_p.h"
#include "stringpool.h"
#include "regs.h"
#include "emit-rtl.h"
#include "cgraph.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "varasm.h"
#include "print-tree.h"
#include "langhooks.h"
#include "tree-inline.h"
#include "dumpfile.h"
#include "gimplify.h"
#include "attribs.h"
#include "debug.h"
#include "calls.h"

/* Data type for the expressions representing sizes of data types.
   It is the first integer type laid out.  */
tree sizetype_tab[(int) stk_type_kind_last];

/* If nonzero, this is an upper limit on alignment of structure fields.
   The value is measured in bits.  */
unsigned int maximum_field_alignment = TARGET_DEFAULT_PACK_STRUCT * BITS_PER_UNIT;

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);
static int excess_unit_span (HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT,
			     HOST_WIDE_INT, tree);
extern void debug_rli (record_layout_info);

/* Given a size SIZE that may not be a constant, return a SAVE_EXPR
   to serve as the actual size-expression for a type or decl.  */

tree
variable_size (tree size)
{
  /* Obviously.  */
  if (TREE_CONSTANT (size))
    return size;

  /* If the size is self-referential, we can't make a SAVE_EXPR (see
     save_expr for the rationale).  But we can do something else.  */
  if (CONTAINS_PLACEHOLDER_P (size))
    return self_referential_size (size);

  /* If we are in the global binding level, we can't make a SAVE_EXPR
     since it may end up being shared across functions, so it is up
     to the front-end to deal with this case.  */
  if (lang_hooks.decls.global_bindings_p ())
    return size;

  return save_expr (size);
}

/* An array of functions used for self-referential size computation.  */
static GTY(()) vec<tree, va_gc> *size_functions;

/* Return true if T is a self-referential component reference.  */

static bool
self_referential_component_ref_p (tree t)
{
  if (TREE_CODE (t) != COMPONENT_REF)
    return false;

  while (REFERENCE_CLASS_P (t))
    t = TREE_OPERAND (t, 0);

  return (TREE_CODE (t) == PLACEHOLDER_EXPR);
}

/* Similar to copy_tree_r but do not copy component references involving
   PLACEHOLDER_EXPRs.  These nodes are spotted in find_placeholder_in_expr
   and substituted in substitute_in_expr.  */

static tree
copy_self_referential_tree_r (tree *tp, int *walk_subtrees, void *data)
{
  enum tree_code code = TREE_CODE (*tp);

  /* Stop at types, decls, constants like copy_tree_r.  */
  if (TREE_CODE_CLASS (code) == tcc_type
      || TREE_CODE_CLASS (code) == tcc_declaration
      || TREE_CODE_CLASS (code) == tcc_constant)
    {
      *walk_subtrees = 0;
      return NULL_TREE;
    }

  /* This is the pattern built in ada/make_aligning_type.  */
  else if (code == ADDR_EXPR
	   && TREE_CODE (TREE_OPERAND (*tp, 0)) == PLACEHOLDER_EXPR)
    {
      *walk_subtrees = 0;
      return NULL_TREE;
    }

  /* Default case: the component reference.  */
  else if (self_referential_component_ref_p (*tp))
    {
      *walk_subtrees = 0;
      return NULL_TREE;
    }

  /* We're not supposed to have them in self-referential size trees
     because we wouldn't properly control when they are evaluated.
     However, not creating superfluous SAVE_EXPRs requires accurate
     tracking of readonly-ness all the way down to here, which we
     cannot always guarantee in practice.  So punt in this case.  */
  else if (code == SAVE_EXPR)
    return error_mark_node;

  else if (code == STATEMENT_LIST)
    gcc_unreachable ();

  return copy_tree_r (tp, walk_subtrees, data);
}

/* Given a SIZE expression that is self-referential, return an equivalent
   expression to serve as the actual size expression for a type.  */

static tree
self_referential_size (tree size)
{
  static unsigned HOST_WIDE_INT fnno = 0;
  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, va_gc> *args = NULL;

  /* Do not factor out simple operations.  */
  t = skip_simple_constant_arithmetic (size);
  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 (self_refs.length () > 0);

  /* Obtain a private copy of the expression.  */
  t = size;
  if (walk_tree (&t, copy_self_referential_tree_r, NULL, NULL) != NULL_TREE)
    return size;
  size = t;

  /* Build the parameter and argument lists in parallel; also
     substitute the former for the latter in the expression.  */
  vec_alloc (args, self_refs.length ());
  FOR_EACH_VEC_ELT (self_refs, i, ref)
    {
      tree subst, param_name, param_type, param_decl;

      if (DECL_P (ref))
	{
	  /* We shouldn't have true variables here.  */
	  gcc_assert (TREE_READONLY (ref));
	  subst = ref;
	}
      /* This is the pattern built in ada/make_aligning_type.  */
      else if (TREE_CODE (ref) == ADDR_EXPR)
        subst = ref;
      /* Default case: the component reference.  */
      else
	subst = TREE_OPERAND (ref, 1);

      sprintf (buf, "p%d", i);
      param_name = get_identifier (buf);
      param_type = TREE_TYPE (ref);
      param_decl
	= build_decl (input_location, PARM_DECL, param_name, param_type);
      DECL_ARG_TYPE (param_decl) = param_type;
      DECL_ARTIFICIAL (param_decl) = 1;
      TREE_READONLY (param_decl) = 1;

      size = substitute_in_expr (size, subst, param_decl);

      param_type_list = tree_cons (NULL_TREE, param_type, param_type_list);
      param_decl_list = chainon (param_decl, param_decl_list);
      args->quick_push (ref);
    }

  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);

  /* The 3 lists have been created in reverse order.  */
  param_type_list = nreverse (param_type_list);
  param_decl_list = nreverse (param_decl_list);

  /* Build the function type.  */
  return_type = TREE_TYPE (size);
  fntype = build_function_type (return_type, param_type_list);

  /* Build the function declaration.  */
  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))
    DECL_CONTEXT (t) = fndecl;
  DECL_ARGUMENTS (fndecl) = param_decl_list;
  DECL_RESULT (fndecl)
    = build_decl (input_location, RESULT_DECL, 0, return_type);
  DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;

  /* The function has been created by the compiler and we don't
     want to emit debug info for it.  */
  DECL_ARTIFICIAL (fndecl) = 1;
  DECL_IGNORED_P (fndecl) = 1;

  /* It is supposed to be "const" and never throw.  */
  TREE_READONLY (fndecl) = 1;
  TREE_NOTHROW (fndecl) = 1;

  /* We want it to be inlined when this is deemed profitable, as
     well as discarded if every call has been integrated.  */
  DECL_DECLARED_INLINE_P (fndecl) = 1;

  /* It is made up of a unique return statement.  */
  DECL_INITIAL (fndecl) = make_node (BLOCK);
  BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
  t = build2 (MODIFY_EXPR, return_type, DECL_RESULT (fndecl), size);
  DECL_SAVED_TREE (fndecl) = build1 (RETURN_EXPR, void_type_node, t);
  TREE_STATIC (fndecl) = 1;

  /* Put it onto the list of size functions.  */
  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);
}

/* Take, queue and compile all the size functions.  It is essential that
   the size functions be gimplified at the very end of the compilation
   in order to guarantee transparent handling of self-referential sizes.
   Otherwise the GENERIC inliner would not be able to inline them back
   at each of their call sites, thus creating artificial non-constant
   size expressions which would trigger nasty problems later on.  */

void
finalize_size_functions (void)
{
  unsigned int i;
  tree fndecl;

  for (i = 0; size_functions && size_functions->iterate (i, &fndecl); i++)
    {
      allocate_struct_function (fndecl, false);
      set_cfun (NULL);
      dump_function (TDI_original, fndecl);

      /* As these functions are used to describe the layout of variable-length
         structures, debug info generation needs their implementation.  */
      debug_hooks->size_function (fndecl);
      gimplify_function_tree (fndecl);
      cgraph_node::finalize_function (fndecl, false);
    }

  vec_free (size_functions);
}

/* Return a machine mode of class MCLASS with SIZE bits of precision,
   if one exists.  The mode may have padding bits as well the SIZE
   value bits.  If LIMIT is nonzero, disregard modes wider than
   MAX_FIXED_MODE_SIZE.  */

opt_machine_mode
mode_for_size (poly_uint64 size, enum mode_class mclass, int limit)
{
  machine_mode mode;
  int i;

  if (limit && maybe_gt (size, (unsigned int) MAX_FIXED_MODE_SIZE))
    return opt_machine_mode ();

  /* Get the first mode which has this size, in the specified class.  */
  FOR_EACH_MODE_IN_CLASS (mode, mclass)
    if (known_eq (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 (known_eq (int_n_data[i].bitsize, size)
	  && int_n_enabled_p[i])
	return int_n_data[i].m;

  return opt_machine_mode ();
}

/* Similar, except passed a tree node.  */

opt_machine_mode
mode_for_size_tree (const_tree size, enum mode_class mclass, int limit)
{
  unsigned HOST_WIDE_INT uhwi;
  unsigned int ui;

  if (!tree_fits_uhwi_p (size))
    return opt_machine_mode ();
  uhwi = tree_to_uhwi (size);
  ui = uhwi;
  if (uhwi != ui)
    return opt_machine_mode ();
  return mode_for_size (ui, mclass, limit);
}

/* Return the narrowest mode of class MCLASS that contains at least
   SIZE bits, if such a mode exists.  */

opt_machine_mode
smallest_mode_for_size (poly_uint64 size, enum mode_class mclass)
{
  machine_mode mode = VOIDmode;
  int i;

  /* Get the first mode which has at least this size, in the
     specified class.  */
  FOR_EACH_MODE_IN_CLASS (mode, mclass)
    if (known_ge (GET_MODE_PRECISION (mode), size))
      break;

  if (mode == VOIDmode)
    return opt_machine_mode ();

  if (mclass == MODE_INT || mclass == MODE_PARTIAL_INT)
    for (i = 0; i < NUM_INT_N_ENTS; i ++)
      if (known_ge (int_n_data[i].bitsize, size)
	  && known_lt (int_n_data[i].bitsize, GET_MODE_PRECISION (mode))
	  && int_n_enabled_p[i])
	mode = int_n_data[i].m;

  return mode;
}

/* Return an integer mode of exactly the same size as MODE, if one exists.  */

opt_scalar_int_mode
int_mode_for_mode (machine_mode mode)
{
  switch (GET_MODE_CLASS (mode))
    {
    case MODE_INT:
    case MODE_PARTIAL_INT:
      return as_a <scalar_int_mode> (mode);

    case MODE_COMPLEX_INT:
    case MODE_COMPLEX_FLOAT:
    case MODE_FLOAT:
    case MODE_DECIMAL_FLOAT:
    case MODE_FRACT:
    case MODE_ACCUM:
    case MODE_UFRACT:
    case MODE_UACCUM:
    case MODE_VECTOR_BOOL:
    case MODE_VECTOR_INT:
    case MODE_VECTOR_FLOAT:
    case MODE_VECTOR_FRACT:
    case MODE_VECTOR_ACCUM:
    case MODE_VECTOR_UFRACT:
    case MODE_VECTOR_UACCUM:
      return int_mode_for_size (GET_MODE_BITSIZE (mode), 0);

    case MODE_OPAQUE:
	return opt_scalar_int_mode ();

    case MODE_RANDOM:
      if (mode == BLKmode)
	return opt_scalar_int_mode ();

      /* fall through */

    case MODE_CC:
    default:
      gcc_unreachable ();
    }
}

/* Find a mode that can be used for efficient bitwise operations on MODE,
   if one exists.  */

opt_machine_mode
bitwise_mode_for_mode (machine_mode mode)
{
  /* Quick exit if we already have a suitable mode.  */
  scalar_int_mode int_mode;
  if (is_a <scalar_int_mode> (mode, &int_mode)
      && GET_MODE_BITSIZE (int_mode) <= MAX_FIXED_MODE_SIZE)
    return int_mode;

  /* Reuse the sanity checks from int_mode_for_mode.  */
  gcc_checking_assert ((int_mode_for_mode (mode), true));

  poly_int64 bitsize = GET_MODE_BITSIZE (mode);

  /* 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 (trial) == MODE_COMPLEX_INT
	   || mode_for_size (bitsize, MODE_COMPLEX_INT, false).exists (&trial))
	  && 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)
      || maybe_gt (bitsize, MAX_FIXED_MODE_SIZE))
    {
      machine_mode trial = mode;
      if ((GET_MODE_CLASS (trial) == MODE_VECTOR_INT
	   || mode_for_size (bitsize, MODE_VECTOR_INT, 0).exists (&trial))
	  && 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)
{
  if (!bitwise_mode_for_mode (mode).exists (&mode))
    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 can be used for efficient bitwise operations on SIZE
   bits, if one exists.  */

opt_machine_mode
bitwise_mode_for_size (poly_uint64 size)
{
  if (known_le (size, (unsigned int) MAX_FIXED_MODE_SIZE))
    return mode_for_size (size, MODE_INT, true);

  machine_mode mode, ret = VOIDmode;
  FOR_EACH_MODE_FROM (mode, MIN_MODE_VECTOR_INT)
    if (known_eq (GET_MODE_BITSIZE (mode), size)
	&& (ret == VOIDmode || GET_MODE_INNER (mode) == QImode)
	&& have_regs_of_mode[mode]
	&& targetm.vector_mode_supported_p (mode))
      {
	if (GET_MODE_INNER (mode) == QImode)
	  return mode;
	else if (ret == VOIDmode)
	  ret = mode;
      }
  if (ret != VOIDmode)
    return ret;
  return opt_machine_mode ();
}

/* Find a mode that is suitable for representing a vector with NUNITS
   elements of mode INNERMODE, if one exists.  The returned mode can be
   either an integer mode or a vector mode.  */

opt_machine_mode
mode_for_vector (scalar_mode innermode, poly_uint64 nunits)
{
  machine_mode mode;

  /* First, look for a supported vector type.  */
  if (SCALAR_FLOAT_MODE_P (innermode))
    mode = MIN_MODE_VECTOR_FLOAT;
  else if (SCALAR_FRACT_MODE_P (innermode))
    mode = MIN_MODE_VECTOR_FRACT;
  else if (SCALAR_UFRACT_MODE_P (innermode))
    mode = MIN_MODE_VECTOR_UFRACT;
  else if (SCALAR_ACCUM_MODE_P (innermode))
    mode = MIN_MODE_VECTOR_ACCUM;
  else if (SCALAR_UACCUM_MODE_P (innermode))
    mode = MIN_MODE_VECTOR_UACCUM;
  else
    mode = MIN_MODE_VECTOR_INT;

  /* Only check the broader vector_mode_supported_any_target_p here.
     We'll filter through target-specific availability and
     vector_mode_supported_p later in vector_type_mode.  */
  FOR_EACH_MODE_FROM (mode, mode)
    if (known_eq (GET_MODE_NUNITS (mode), nunits)
	&& GET_MODE_INNER (mode) == innermode
	&& targetm.vector_mode_supported_any_target_p (mode))
      return mode;

  /* For integers, try mapping it to a same-sized scalar mode.  */
  if (GET_MODE_CLASS (innermode) == MODE_INT)
    {
      poly_uint64 nbits = nunits * GET_MODE_BITSIZE (innermode);
      if (int_mode_for_size (nbits, 0).exists (&mode)
	  && have_regs_of_mode[mode])
	return mode;
    }

  return opt_machine_mode ();
}

/* If a piece of code is using vector mode VECTOR_MODE and also wants
   to operate on elements of mode ELEMENT_MODE, return the vector mode
   it should use for those elements.  If NUNITS is nonzero, ensure that
   the mode has exactly NUNITS elements, otherwise pick whichever vector
   size pairs the most naturally with VECTOR_MODE; this may mean choosing
   a mode with a different size and/or number of elements, depending on
   what the target prefers.  Return an empty opt_machine_mode if there
   is no supported vector mode with the required properties.

   Unlike mode_for_vector. any returned mode is guaranteed to satisfy
   both VECTOR_MODE_P and targetm.vector_mode_supported_p.  */

opt_machine_mode
related_vector_mode (machine_mode vector_mode, scalar_mode element_mode,
		     poly_uint64 nunits)
{
  gcc_assert (VECTOR_MODE_P (vector_mode));
  return targetm.vectorize.related_mode (vector_mode, element_mode, nunits);
}

/* If a piece of code is using vector mode VECTOR_MODE and also wants
   to operate on integer vectors with the same element size and number
   of elements, return the vector mode it should use.  Return an empty
   opt_machine_mode if there is no supported vector mode with the
   required properties.

   Unlike mode_for_vector. any returned mode is guaranteed to satisfy
   both VECTOR_MODE_P and targetm.vector_mode_supported_p.  */

opt_machine_mode
related_int_vector_mode (machine_mode vector_mode)
{
  gcc_assert (VECTOR_MODE_P (vector_mode));
  scalar_int_mode int_mode;
  if (int_mode_for_mode (GET_MODE_INNER (vector_mode)).exists (&int_mode))
    return related_vector_mode (vector_mode, int_mode,
				GET_MODE_NUNITS (vector_mode));
  return opt_machine_mode ();
}

/* Return the alignment of MODE. This will be bounded by 1 and
   BIGGEST_ALIGNMENT.  */

unsigned int
get_mode_alignment (machine_mode mode)
{
  return MIN (BIGGEST_ALIGNMENT, MAX (1, mode_base_align[mode]*BITS_PER_UNIT));
}

/* Return the natural mode of an array, given that it is SIZE bytes in
   total and has elements of type ELEM_TYPE.  */

static machine_mode
mode_for_array (tree elem_type, tree size)
{
  tree elem_size;
  poly_uint64 int_size, int_elem_size;
  unsigned HOST_WIDE_INT num_elems;
  bool limit_p;

  /* One-element arrays get the component type's mode.  */
  elem_size = TYPE_SIZE (elem_type);
  if (simple_cst_equal (size, elem_size))
    return TYPE_MODE (elem_type);

  limit_p = true;
  if (poly_int_tree_p (size, &int_size)
      && poly_int_tree_p (elem_size, &int_elem_size)
      && maybe_ne (int_elem_size, 0U)
      && constant_multiple_p (int_size, int_elem_size, &num_elems))
    {
      machine_mode elem_mode = TYPE_MODE (elem_type);
      machine_mode mode;
      if (targetm.array_mode (elem_mode, num_elems).exists (&mode))
	return mode;
      if (targetm.array_mode_supported_p (elem_mode, num_elems))
	limit_p = false;
    }
  return mode_for_size_tree (size, MODE_INT, limit_p).else_blk ();
}

/* Subroutine of layout_decl: Force alignment required for the data type.
   But if the decl itself wants greater alignment, don't override that.  */

static inline void
do_type_align (tree type, tree decl)
{
  if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
    {
      SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
      if (TREE_CODE (decl) == FIELD_DECL)
	DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
    }
  if (TYPE_WARN_IF_NOT_ALIGN (type) > DECL_WARN_IF_NOT_ALIGN (decl))
    SET_DECL_WARN_IF_NOT_ALIGN (decl, TYPE_WARN_IF_NOT_ALIGN (type));
}

/* Set the size, mode and alignment of a ..._DECL node.
   TYPE_DECL does need this for C++.
   Note that LABEL_DECL and CONST_DECL nodes do not need this,
   and FUNCTION_DECL nodes have them set up in a special (and simple) way.
   Don't call layout_decl for them.

   KNOWN_ALIGN is the amount of alignment we can assume this
   decl has with no special effort.  It is relevant only for FIELD_DECLs
   and depends on the previous fields.
   All that matters about KNOWN_ALIGN is which powers of 2 divide it.
   If KNOWN_ALIGN is 0, it means, "as much alignment as you like":
   the record will be aligned to suit.  */

void
layout_decl (tree decl, unsigned int known_align)
{
  tree type = TREE_TYPE (decl);
  enum tree_code code = TREE_CODE (decl);
  rtx rtl = NULL_RTX;
  location_t loc = DECL_SOURCE_LOCATION (decl);

  if (code == CONST_DECL)
    return;

  gcc_assert (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL
	      || code == TYPE_DECL || code == FIELD_DECL);

  rtl = DECL_RTL_IF_SET (decl);

  if (type == error_mark_node)
    type = void_type_node;

  /* Usually the size and mode come from the data type without change,
     however, the front-end may set the explicit width of the field, so its
     size may not be the same as the size of its type.  This happens with
     bitfields, of course (an `int' bitfield may be only 2 bits, say), but it
     also happens with other fields.  For example, the C++ front-end creates
     zero-sized fields corresponding to empty base classes, and depends on
     layout_type setting DECL_FIELD_BITPOS correctly for the field.  Set the
     size in bytes from the size in bits.  If we have already set the mode,
     don't set it again since we can be called twice for FIELD_DECLs.  */

  DECL_UNSIGNED (decl) = TYPE_UNSIGNED (type);
  if (DECL_MODE (decl) == VOIDmode)
    SET_DECL_MODE (decl, TYPE_MODE (type));

  if (DECL_SIZE (decl) == 0)
    {
      DECL_SIZE (decl) = TYPE_SIZE (type);
      DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
    }
  else if (DECL_SIZE_UNIT (decl) == 0)
    DECL_SIZE_UNIT (decl)
      = fold_convert_loc (loc, sizetype,
			  size_binop_loc (loc, CEIL_DIV_EXPR, DECL_SIZE (decl),
					  bitsize_unit_node));

  if (code != FIELD_DECL)
    /* For non-fields, update the alignment from the type.  */
    do_type_align (type, decl);
  else
    /* For fields, it's a bit more complicated...  */
    {
      bool old_user_align = DECL_USER_ALIGN (decl);
      bool zero_bitfield = false;
      bool packed_p = DECL_PACKED (decl);
      unsigned int mfa;

      if (DECL_BIT_FIELD (decl))
	{
	  DECL_BIT_FIELD_TYPE (decl) = type;

	  /* A zero-length bit-field affects the alignment of the next
	     field.  In essence such bit-fields are not influenced by
	     any packing due to #pragma pack or attribute packed.  */
	  if (integer_zerop (DECL_SIZE (decl))
	      && ! targetm.ms_bitfield_layout_p (DECL_FIELD_CONTEXT (decl)))
	    {
	      zero_bitfield = true;
	      packed_p = false;
	      if (PCC_BITFIELD_TYPE_MATTERS)
		do_type_align (type, decl);
	      else
		{
#ifdef EMPTY_FIELD_BOUNDARY
		  if (EMPTY_FIELD_BOUNDARY > DECL_ALIGN (decl))
		    {
		      SET_DECL_ALIGN (decl, EMPTY_FIELD_BOUNDARY);
		      DECL_USER_ALIGN (decl) = 0;
		    }
#endif
		}
	    }

	  /* 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.  */
	  if (TYPE_SIZE (type) != 0
	      && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
	      && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
	    {
	      machine_mode xmode;
	      if (mode_for_size_tree (DECL_SIZE (decl),
				      MODE_INT, 1).exists (&xmode))
		{
		  unsigned int xalign = GET_MODE_ALIGNMENT (xmode);
		  if (!(xalign > BITS_PER_UNIT && DECL_PACKED (decl))
		      && (known_align == 0 || known_align >= xalign))
		    {
		      SET_DECL_ALIGN (decl, MAX (xalign, DECL_ALIGN (decl)));
		      SET_DECL_MODE (decl, xmode);
		      DECL_BIT_FIELD (decl) = 0;
		    }
		}
	    }

	  /* Turn off DECL_BIT_FIELD if we won't need it set.  */
	  if (TYPE_MODE (type) == BLKmode && DECL_MODE (decl) == BLKmode
	      && known_align >= TYPE_ALIGN (type)
	      && DECL_ALIGN (decl) >= TYPE_ALIGN (type))
	    DECL_BIT_FIELD (decl) = 0;
	}
      else if (packed_p && DECL_USER_ALIGN (decl))
	/* Don't touch DECL_ALIGN.  For other packed fields, go ahead and
	   round up; we'll reduce it again below.  We want packing to
	   supersede USER_ALIGN inherited from the type, but defer to
	   alignment explicitly specified on the field decl.  */;
      else
	do_type_align (type, decl);

      /* If the field is packed and not explicitly aligned, give it the
	 minimum alignment.  Note that do_type_align may set
	 DECL_USER_ALIGN, so we need to check old_user_align instead.  */
      if (packed_p
	  && !old_user_align)
	SET_DECL_ALIGN (decl, MIN (DECL_ALIGN (decl), BITS_PER_UNIT));

      if (! packed_p && ! DECL_USER_ALIGN (decl))
	{
	  /* Some targets (i.e. i386, VMS) limit struct field alignment
	     to a lower boundary than alignment of variables unless
	     it was overridden by attribute aligned.  */
#ifdef BIGGEST_FIELD_ALIGNMENT
	  SET_DECL_ALIGN (decl, MIN (DECL_ALIGN (decl),
				     (unsigned) BIGGEST_FIELD_ALIGNMENT));
#endif
#ifdef ADJUST_FIELD_ALIGN
	  SET_DECL_ALIGN (decl, ADJUST_FIELD_ALIGN (decl, TREE_TYPE (decl),
						    DECL_ALIGN (decl)));
#endif
	}

      if (zero_bitfield)
        mfa = initial_max_fld_align * BITS_PER_UNIT;
      else
	mfa = maximum_field_alignment;
      /* Should this be controlled by DECL_USER_ALIGN, too?  */
      if (mfa != 0)
	SET_DECL_ALIGN (decl, MIN (DECL_ALIGN (decl), mfa));
    }

  /* Evaluate nonconstant size only once, either now or as soon as safe.  */
  if (DECL_SIZE (decl) != 0 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
    DECL_SIZE (decl) = variable_size (DECL_SIZE (decl));
  if (DECL_SIZE_UNIT (decl) != 0
      && TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST)
    DECL_SIZE_UNIT (decl) = variable_size (DECL_SIZE_UNIT (decl));

  /* If requested, warn about definitions of large data objects.  */
  if ((code == PARM_DECL || (code == VAR_DECL && !DECL_NONLOCAL_FRAME (decl)))
      && !DECL_EXTERNAL (decl))
    {
      tree size = DECL_SIZE_UNIT (decl);

      if (size != 0 && TREE_CODE (size) == INTEGER_CST)
	{
	  /* -Wlarger-than= argument of HOST_WIDE_INT_MAX is treated
	     as if PTRDIFF_MAX had been specified, with the value
	     being that on the target rather than the host.  */
	  unsigned HOST_WIDE_INT max_size = warn_larger_than_size;
	  if (max_size == HOST_WIDE_INT_MAX)
	    max_size = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));

	  if (compare_tree_int (size, max_size) > 0)
	    warning (OPT_Wlarger_than_, "size of %q+D %E bytes exceeds "
		     "maximum object size %wu",
		     decl, size, max_size);
	}
    }

  /* If the RTL was already set, update its mode and mem attributes.  */
  if (rtl)
    {
      PUT_MODE (rtl, DECL_MODE (decl));
      SET_DECL_RTL (decl, 0);
      if (MEM_P (rtl))
	set_mem_attributes (rtl, decl, 1);
      SET_DECL_RTL (decl, rtl);
    }
}

/* Given a VAR_DECL, PARM_DECL, RESULT_DECL, or FIELD_DECL, clears the
   results of a previous call to layout_decl and calls it again.  */

void
relayout_decl (tree decl)
{
  DECL_SIZE (decl) = DECL_SIZE_UNIT (decl) = 0;
  SET_DECL_MODE (decl, VOIDmode);
  if (!DECL_USER_ALIGN (decl))
    SET_DECL_ALIGN (decl, 0);
  if (DECL_RTL_SET_P (decl))
    SET_DECL_RTL (decl, 0);

  layout_decl (decl, 0);
}

/* Begin laying out type T, which may be a RECORD_TYPE, UNION_TYPE, or
   QUAL_UNION_TYPE.  Return a pointer to a struct record_layout_info which
   is to be passed to all other layout functions for this record.  It is the
   responsibility of the caller to call `free' for the storage returned.
   Note that garbage collection is not permitted until we finish laying
   out the record.  */

record_layout_info
start_record_layout (tree t)
{
  record_layout_info rli = XNEW (struct record_layout_info_s);

  rli->t = t;

  /* If the type has a minimum specified alignment (via an attribute
     declaration, for example) use it -- otherwise, start with a
     one-byte alignment.  */
  rli->record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (t));
  rli->unpacked_align = rli->record_align;
  rli->offset_align = MAX (rli->record_align, BIGGEST_ALIGNMENT);

#ifdef STRUCTURE_SIZE_BOUNDARY
  /* Packed structures don't need to have minimum size.  */
  if (! TYPE_PACKED (t))
    {
      unsigned tmp;

      /* #pragma pack overrides STRUCTURE_SIZE_BOUNDARY.  */
      tmp = (unsigned) STRUCTURE_SIZE_BOUNDARY;
      if (maximum_field_alignment != 0)
	tmp = MIN (tmp, maximum_field_alignment);
      rli->record_align = MAX (rli->record_align, tmp);
    }
#endif

  rli->offset = size_zero_node;
  rli->bitpos = bitsize_zero_node;
  rli->prev_field = 0;
  rli->pending_statics = 0;
  rli->packed_maybe_necessary = 0;
  rli->remaining_in_alignment = 0;

  return rli;
}

/* Fold sizetype value X to bitsizetype, given that X represents a type
   size or offset.  */

static tree
bits_from_bytes (tree x)
{
  if (POLY_INT_CST_P (x))
    /* The runtime calculation isn't allowed to overflow sizetype;
       increasing the runtime values must always increase the size
       or offset of the object.  This means that the object imposes
       a maximum value on the runtime parameters, but we don't record
       what that is.  */
    return build_poly_int_cst
      (bitsizetype,
       poly_wide_int::from (poly_int_cst_value (x),
			    TYPE_PRECISION (bitsizetype),
			    TYPE_SIGN (TREE_TYPE (x))));
  x = fold_convert (bitsizetype, x);
  gcc_checking_assert (x);
  return x;
}

/* Return the combined bit position for the byte offset OFFSET and the
   bit position BITPOS.

   These functions operate on byte and bit positions present in FIELD_DECLs
   and assume that these expressions result in no (intermediate) overflow.
   This assumption is necessary to fold the expressions as much as possible,
   so as to avoid creating artificially variable-sized types in languages
   supporting variable-sized types like Ada.  */

tree
bit_from_pos (tree offset, tree bitpos)
{
  return size_binop (PLUS_EXPR, bitpos,
		     size_binop (MULT_EXPR, bits_from_bytes (offset),
				 bitsize_unit_node));
}

/* Return the combined truncated byte position for the byte offset OFFSET and
   the bit position BITPOS.  */

tree
byte_from_pos (tree offset, tree bitpos)
{
  tree bytepos;
  if (TREE_CODE (bitpos) == MULT_EXPR
      && tree_int_cst_equal (TREE_OPERAND (bitpos, 1), bitsize_unit_node))
    bytepos = TREE_OPERAND (bitpos, 0);
  else
    bytepos = size_binop (TRUNC_DIV_EXPR, bitpos, bitsize_unit_node);
  return size_binop (PLUS_EXPR, offset, fold_convert (sizetype, bytepos));
}

/* Split the bit position POS into a byte offset *POFFSET and a bit
   position *PBITPOS with the byte offset aligned to OFF_ALIGN bits.  */

void
pos_from_bit (tree *poffset, tree *pbitpos, unsigned int off_align,
	      tree pos)
{
  tree toff_align = bitsize_int (off_align);
  if (TREE_CODE (pos) == MULT_EXPR
      && tree_int_cst_equal (TREE_OPERAND (pos, 1), toff_align))
    {
      *poffset = size_binop (MULT_EXPR,
			     fold_convert (sizetype, TREE_OPERAND (pos, 0)),
			     size_int (off_align / BITS_PER_UNIT));
      *pbitpos = bitsize_zero_node;
    }
  else
    {
      *poffset = size_binop (MULT_EXPR,
			     fold_convert (sizetype,
					   size_binop (FLOOR_DIV_EXPR, pos,
						       toff_align)),
			     size_int (off_align / BITS_PER_UNIT));
      *pbitpos = size_binop (FLOOR_MOD_EXPR, pos, toff_align);
    }
}

/* Given a pointer to bit and byte offsets and an offset alignment,
   normalize the offsets so they are within the alignment.  */

void
normalize_offset (tree *poffset, tree *pbitpos, unsigned int off_align)
{
  /* If the bit position is now larger than it should be, adjust it
     downwards.  */
  if (compare_tree_int (*pbitpos, off_align) >= 0)
    {
      tree offset, bitpos;
      pos_from_bit (&offset, &bitpos, off_align, *pbitpos);
      *poffset = size_binop (PLUS_EXPR, *poffset, offset);
      *pbitpos = bitpos;
    }
}

/* Print debugging information about the information in RLI.  */

DEBUG_FUNCTION void
debug_rli (record_layout_info rli)
{
  print_node_brief (stderr, "type", rli->t, 0);
  print_node_brief (stderr, "\noffset", rli->offset, 0);
  print_node_brief (stderr, " bitpos", rli->bitpos, 0);

  fprintf (stderr, "\naligns: rec = %u, unpack = %u, off = %u\n",
	   rli->record_align, rli->unpacked_align,
	   rli->offset_align);

  /* The ms_struct code is the only that uses this.  */
  if (targetm.ms_bitfield_layout_p (rli->t))
    fprintf (stderr, "remaining in alignment = %u\n", rli->remaining_in_alignment);

  if (rli->packed_maybe_necessary)
    fprintf (stderr, "packed may be necessary\n");

  if (!vec_safe_is_empty (rli->pending_statics))
    {
      fprintf (stderr, "pending statics:\n");
      debug (rli->pending_statics);
    }
}

/* Given an RLI with a possibly-incremented BITPOS, adjust OFFSET and
   BITPOS if necessary to keep BITPOS below OFFSET_ALIGN.  */

void
normalize_rli (record_layout_info rli)
{
  normalize_offset (&rli->offset, &rli->bitpos, rli->offset_align);
}

/* Returns the size in bytes allocated so far.  */

tree
rli_size_unit_so_far (record_layout_info rli)
{
  return byte_from_pos (rli->offset, rli->bitpos);
}

/* Returns the size in bits allocated so far.  */

tree
rli_size_so_far (record_layout_info rli)
{
  return bit_from_pos (rli->offset, rli->bitpos);
}

/* FIELD is about to be added to RLI->T.  The alignment (in bits) of
   the next available location within the record is given by KNOWN_ALIGN.
   Update the variable alignment fields in RLI, and return the alignment
   to give the FIELD.  */

unsigned int
update_alignment_for_field (record_layout_info rli, tree field,
			    unsigned int known_align)
{
  /* The alignment required for FIELD.  */
  unsigned int desired_align;
  /* The type of this field.  */
  tree type = TREE_TYPE (field);
  /* True if the field was explicitly aligned by the user.  */
  bool user_align;
  bool is_bitfield;

  /* Do not attempt to align an ERROR_MARK node */
  if (TREE_CODE (type) == ERROR_MARK)
    return 0;

  /* Lay out the field so we know what alignment it needs.  */
  layout_decl (field, known_align);
  desired_align = DECL_ALIGN (field);
  user_align = DECL_USER_ALIGN (field);

  is_bitfield = (type != error_mark_node
		 && DECL_BIT_FIELD_TYPE (field)
		 && ! integer_zerop (TYPE_SIZE (type)));

  /* Record must have at least as much alignment as any field.
     Otherwise, the alignment of the field within the record is
     meaningless.  */
  if (targetm.ms_bitfield_layout_p (rli->t))
    {
      /* Here, the alignment of the underlying type of a bitfield can
	 affect the alignment of a record; even a zero-sized field
	 can do this.  The alignment should be to the alignment of
	 the type, except that for zero-size bitfields this only
	 applies if there was an immediately prior, nonzero-size
	 bitfield.  (That's the way it is, experimentally.) */
      if (!is_bitfield
	  || ((DECL_SIZE (field) == NULL_TREE
	       || !integer_zerop (DECL_SIZE (field)))
	      ? !DECL_PACKED (field)
	      : (rli->prev_field
		 && DECL_BIT_FIELD_TYPE (rli->prev_field)
		 && ! integer_zerop (DECL_SIZE (rli->prev_field)))))
	{
	  unsigned int type_align = TYPE_ALIGN (type);
	  if (!is_bitfield && DECL_PACKED (field))
	    type_align = desired_align;
	  else
	    type_align = MAX (type_align, desired_align);
	  if (maximum_field_alignment != 0)
	    type_align = MIN (type_align, maximum_field_alignment);
	  rli->record_align = MAX (rli->record_align, type_align);
	  rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
	}
    }
  else if (is_bitfield && PCC_BITFIELD_TYPE_MATTERS)
    {
      /* Named bit-fields cause the entire structure to have the
	 alignment implied by their type.  Some targets also apply the same
	 rules to unnamed bitfields.  */
      if (DECL_NAME (field) != 0
	  || targetm.align_anon_bitfield ())
	{
	  unsigned int type_align = TYPE_ALIGN (type);

#ifdef ADJUST_FIELD_ALIGN
	  if (! TYPE_USER_ALIGN (type))
	    type_align = ADJUST_FIELD_ALIGN (field, type, type_align);
#endif

	  /* Targets might chose to handle unnamed and hence possibly
	     zero-width bitfield.  Those are not influenced by #pragmas
	     or packed attributes.  */
	  if (integer_zerop (DECL_SIZE (field)))
	    {
	      if (initial_max_fld_align)
	        type_align = MIN (type_align,
				  initial_max_fld_align * BITS_PER_UNIT);
	    }
	  else if (maximum_field_alignment != 0)
	    type_align = MIN (type_align, maximum_field_alignment);
	  else if (DECL_PACKED (field))
	    type_align = MIN (type_align, BITS_PER_UNIT);

	  /* The alignment of the record is increased to the maximum
	     of the current alignment, the alignment indicated on the
	     field (i.e., the alignment specified by an __aligned__
	     attribute), and the alignment indicated by the type of
	     the field.  */
	  rli->record_align = MAX (rli->record_align, desired_align);
	  rli->record_align = MAX (rli->record_align, type_align);

	  if (warn_packed)
	    rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
	  user_align |= TYPE_USER_ALIGN (type);
	}
    }
  else
    {
      rli->record_align = MAX (rli->record_align, desired_align);
      rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
    }

  TYPE_USER_ALIGN (rli->t) |= user_align;

  return desired_align;
}

/* Issue a warning if the record alignment, RECORD_ALIGN, is less than
   the field alignment of FIELD or FIELD isn't aligned. */

static void
handle_warn_if_not_align (tree field, unsigned int record_align)
{
  tree type = TREE_TYPE (field);

  if (type == error_mark_node)
    return;

  unsigned int warn_if_not_align = 0;

  int opt_w = 0;

  if (warn_if_not_aligned)
    {
      warn_if_not_align = DECL_WARN_IF_NOT_ALIGN (field);
      if (!warn_if_not_align)
	warn_if_not_align = TYPE_WARN_IF_NOT_ALIGN (type);
      if (warn_if_not_align)
	opt_w = OPT_Wif_not_aligned;
    }

  if (!warn_if_not_align
      && warn_packed_not_aligned
      && lookup_attribute ("aligned", TYPE_ATTRIBUTES (type)))
    {
      warn_if_not_align = TYPE_ALIGN (type);
      opt_w = OPT_Wpacked_not_aligned;
    }

  if (!warn_if_not_align)
    return;

  tree context = DECL_CONTEXT (field);

  warn_if_not_align /= BITS_PER_UNIT;
  record_align /= BITS_PER_UNIT;
  if ((record_align % warn_if_not_align) != 0)
    warning (opt_w, "alignment %u of %qT is less than %u",
	     record_align, context, warn_if_not_align);

  tree off = byte_position (field);
  if (!multiple_of_p (TREE_TYPE (off), off, size_int (warn_if_not_align)))
    {
      if (TREE_CODE (off) == INTEGER_CST)
	warning (opt_w, "%q+D offset %E in %qT isn%'t aligned to %u",
		 field, off, context, warn_if_not_align);
      else
	warning (opt_w, "%q+D offset %E in %qT may not be aligned to %u",
		 field, off, context, warn_if_not_align);
    }
}

/* Called from place_field to handle unions.  */

static void
place_union_field (record_layout_info rli, tree field)
{
  update_alignment_for_field (rli, field, /*known_align=*/0);

  DECL_FIELD_OFFSET (field) = size_zero_node;
  DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
  SET_DECL_OFFSET_ALIGN (field, BIGGEST_ALIGNMENT);
  handle_warn_if_not_align (field, rli->record_align);

  /* If this is an ERROR_MARK return *after* having set the
     field at the start of the union. This helps when parsing
     invalid fields. */
  if (TREE_CODE (TREE_TYPE (field)) == ERROR_MARK)
    return;

  if (AGGREGATE_TYPE_P (TREE_TYPE (field))
      && TYPE_TYPELESS_STORAGE (TREE_TYPE (field)))
    TYPE_TYPELESS_STORAGE (rli->t) = 1;

  /* We might see a flexible array member field (with no DECL_SIZE_UNIT), use
     zero size for such field.  */
  tree field_size_unit = DECL_SIZE_UNIT (field)
			 ? DECL_SIZE_UNIT (field)
			 : build_int_cst (sizetype, 0);
  /* We assume the union's size will be a multiple of a byte so we don't
     bother with BITPOS.  */
  if (TREE_CODE (rli->t) == UNION_TYPE)
    rli->offset = size_binop (MAX_EXPR, rli->offset, field_size_unit);
  else if (TREE_CODE (rli->t) == QUAL_UNION_TYPE)
    rli->offset = fold_build3 (COND_EXPR, sizetype, DECL_QUALIFIER (field),
			       field_size_unit, rli->offset);
}

/* 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.  */
static int
excess_unit_span (HOST_WIDE_INT byte_offset, HOST_WIDE_INT bit_offset,
		  HOST_WIDE_INT size, HOST_WIDE_INT align, tree type)
{
  /* Note that the calculation of OFFSET might overflow; we calculate it so
     that we still get the right result as long as ALIGN is a power of two.  */
  unsigned HOST_WIDE_INT offset = byte_offset * BITS_PER_UNIT + bit_offset;

  offset = offset % align;
  return ((offset + size + align - 1) / align
	  > tree_to_uhwi (TYPE_SIZE (type)) / align);
}

/* RLI contains information about the layout of a RECORD_TYPE.  FIELD
   is a FIELD_DECL to be added after those fields already present in
   T.  (FIELD is not actually added to the TYPE_FIELDS list here;
   callers that desire that behavior must manually perform that step.)  */

void
place_field (record_layout_info rli, tree field)
{
  /* The alignment required for FIELD.  */
  unsigned int desired_align;
  /* The alignment FIELD would have if we just dropped it into the
     record as it presently stands.  */
  unsigned int known_align;
  unsigned int actual_align;
  /* The type of this field.  */
  tree type = TREE_TYPE (field);

  gcc_assert (TREE_CODE (field) != ERROR_MARK);

  /* If FIELD is static, then treat it like a separate variable, not
     really like a structure field.  If it is a FUNCTION_DECL, it's a
     method.  In both cases, all we do is lay out the decl, and we do
     it *after* the record is laid out.  */
  if (VAR_P (field))
    {
      vec_safe_push (rli->pending_statics, field);
      return;
    }

  /* Enumerators and enum types which are local to this class need not
     be laid out.  Likewise for initialized constant fields.  */
  else if (TREE_CODE (field) != FIELD_DECL)
    return;

  /* Unions are laid out very differently than records, so split
     that code off to another function.  */
  else if (TREE_CODE (rli->t) != RECORD_TYPE)
    {
      place_union_field (rli, field);
      return;
    }

  else if (TREE_CODE (type) == ERROR_MARK)
    {
      /* Place this field at the current allocation position, so we
	 maintain monotonicity.  */
      DECL_FIELD_OFFSET (field) = rli->offset;
      DECL_FIELD_BIT_OFFSET (field) = rli->bitpos;
      SET_DECL_OFFSET_ALIGN (field, rli->offset_align);
      handle_warn_if_not_align (field, rli->record_align);
      return;
    }

  if (AGGREGATE_TYPE_P (type)
      && TYPE_TYPELESS_STORAGE (type))
    TYPE_TYPELESS_STORAGE (rli->t) = 1;

  /* 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 = least_bit_hwi (tree_to_uhwi (rli->bitpos));
  else if (integer_zerop (rli->offset))
    known_align = 0;
  else if (tree_fits_uhwi_p (rli->offset))
    known_align = (BITS_PER_UNIT
		   * least_bit_hwi (tree_to_uhwi (rli->offset)));
  else
    known_align = rli->offset_align;

  desired_align = update_alignment_for_field (rli, field, known_align);
  if (known_align == 0)
    known_align = MAX (BIGGEST_ALIGNMENT, rli->record_align);

  if (warn_packed && DECL_PACKED (field))
    {
      if (known_align >= TYPE_ALIGN (type))
	{
	  if (TYPE_ALIGN (type) > desired_align)
	    {
	      if (STRICT_ALIGNMENT)
		warning (OPT_Wattributes, "packed attribute causes "
                         "inefficient alignment for %q+D", field);
	      /* Don't warn if DECL_PACKED was set by the type.  */
	      else if (!TYPE_PACKED (rli->t))
		warning (OPT_Wattributes, "packed attribute is "
			 "unnecessary for %q+D", field);
	    }
	}
      else
	rli->packed_maybe_necessary = 1;
    }

  /* Does this field automatically have alignment it needs by virtue
     of the fields that precede it and the record's own alignment?  */
  if (known_align < desired_align
      && (! targetm.ms_bitfield_layout_p (rli->t)
	  || rli->prev_field == NULL))
    {
      /* No, we need to skip space before this field.
	 Bump the cumulative size to multiple of field alignment.  */

      if (!targetm.ms_bitfield_layout_p (rli->t)
	  && DECL_SOURCE_LOCATION (field) != BUILTINS_LOCATION
	  && !TYPE_ARTIFICIAL (rli->t))
	warning (OPT_Wpadded, "padding struct to align %q+D", field);

      /* If the alignment is still within offset_align, just align
	 the bit position.  */
      if (desired_align < rli->offset_align)
	rli->bitpos = round_up (rli->bitpos, desired_align);
      else
	{
	  /* First adjust OFFSET by the partial bits, then align.  */
	  rli->offset
	    = size_binop (PLUS_EXPR, rli->offset,
			  fold_convert (sizetype,
					size_binop (CEIL_DIV_EXPR, rli->bitpos,
						    bitsize_unit_node)));
	  rli->bitpos = bitsize_zero_node;

	  rli->offset = round_up (rli->offset, desired_align / BITS_PER_UNIT);
	}

      if (! TREE_CONSTANT (rli->offset))
	rli->offset_align = desired_align;
    }

  /* Handle compatibility with PCC.  Note that if the record has any
     variable-sized fields, we need not worry about compatibility.  */
  if (PCC_BITFIELD_TYPE_MATTERS
      && ! targetm.ms_bitfield_layout_p (rli->t)
      && TREE_CODE (field) == FIELD_DECL
      && type != error_mark_node
      && DECL_BIT_FIELD (field)
      && (! DECL_PACKED (field)
	  /* Enter for these packed fields only to issue a warning.  */
	  || TYPE_ALIGN (type) <= BITS_PER_UNIT)
      && maximum_field_alignment == 0
      && ! integer_zerop (DECL_SIZE (field))
      && 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_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))
	type_align = ADJUST_FIELD_ALIGN (field, type, type_align);
#endif

      /* A bit field may not span more units of alignment of its type
	 than its type itself.  Advance to next boundary if necessary.  */
      if (excess_unit_span (offset, bit_offset, field_size, type_align, type))
	{
	  if (DECL_PACKED (field))
	    {
	      if (warn_packed_bitfield_compat == 1)
		inform
		  (input_location,
		   "offset of packed bit-field %qD has changed in GCC 4.4",
		   field);
	    }
	  else
	    rli->bitpos = round_up (rli->bitpos, type_align);
	}

      if (! DECL_PACKED (field))
	TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);

      SET_TYPE_WARN_IF_NOT_ALIGN (rli->t,
				  TYPE_WARN_IF_NOT_ALIGN (type));
    }

#ifdef BITFIELD_NBYTES_LIMITED
  if (BITFIELD_NBYTES_LIMITED
      && ! targetm.ms_bitfield_layout_p (rli->t)
      && TREE_CODE (field) == FIELD_DECL
      && type != error_mark_node
      && DECL_BIT_FIELD_TYPE (field)
      && ! DECL_PACKED (field)
      && ! integer_zerop (DECL_SIZE (field))
      && 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_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))
	type_align = ADJUST_FIELD_ALIGN (field, type, type_align);
#endif

      if (maximum_field_alignment != 0)
	type_align = MIN (type_align, maximum_field_alignment);
      /* ??? This test is opposite the test in the containing if
	 statement, so this code is unreachable currently.  */
      else if (DECL_PACKED (field))
	type_align = MIN (type_align, BITS_PER_UNIT);

      /* A bit field may not span the unit of alignment of its type.
	 Advance to next boundary if necessary.  */
      if (excess_unit_span (offset, bit_offset, field_size, type_align, type))
	rli->bitpos = round_up (rli->bitpos, type_align);

      TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
      SET_TYPE_WARN_IF_NOT_ALIGN (rli->t,
				  TYPE_WARN_IF_NOT_ALIGN (type));
    }
#endif

  /* See the docs for TARGET_MS_BITFIELD_LAYOUT_P for details.
     A subtlety:
	When a bit field is inserted into a packed record, the whole
	size of the underlying type is used by one or more same-size
	adjacent bitfields.  (That is, if its long:3, 32 bits is
	used in the record, and any additional adjacent long bitfields are
	packed into the same chunk of 32 bits. However, if the size
	changes, a new field of that size is allocated.)  In an unpacked
	record, this is the same as using alignment, but not equivalent
	when packing.

     Note: for compatibility, we use the type size, not the type alignment
     to determine alignment, since that matches the documentation */

  if (targetm.ms_bitfield_layout_p (rli->t))
    {
      tree prev_saved = rli->prev_field;
      tree prev_type = prev_saved ? DECL_BIT_FIELD_TYPE (prev_saved) : NULL;

      /* This is a bitfield if it exists.  */
      if (rli->prev_field)
	{
	  bool realign_p = known_align < desired_align;

	  /* If both are bitfields, nonzero, and the same size, this is
	     the middle of a run.  Zero declared size fields are special
	     and handled as "end of run". (Note: it's nonzero declared
	     size, but equal type sizes!) (Since we know that both
	     the current and previous fields are bitfields by the
	     time we check it, DECL_SIZE must be present for both.) */
	  if (DECL_BIT_FIELD_TYPE (field)
	      && !integer_zerop (DECL_SIZE (field))
	      && !integer_zerop (DECL_SIZE (rli->prev_field))
	      && 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_to_uhwi (DECL_SIZE (field));

	      if (rli->remaining_in_alignment < bitsize)
		{
		  HOST_WIDE_INT typesize = tree_to_uhwi (TYPE_SIZE (type));

		  /* out of bits; bump up to next 'word'.  */
		  rli->bitpos
		    = size_binop (PLUS_EXPR, rli->bitpos,
				  bitsize_int (rli->remaining_in_alignment));
		  rli->prev_field = field;
		  if (typesize < bitsize)
		    rli->remaining_in_alignment = 0;
		  else
		    rli->remaining_in_alignment = typesize - bitsize;
		}
	      else
		{
		  rli->remaining_in_alignment -= bitsize;
		  realign_p = false;
		}
	    }
	  else
	    {
	      /* End of a run: if leaving a run of bitfields of the same type
		 size, we have to "use up" the rest of the bits of the type
		 size.

		 Compute the new position as the sum of the size for the prior
		 type and where we first started working on that type.
		 Note: since the beginning of the field was aligned then
		 of course the end will be too.  No round needed.  */

	      if (!integer_zerop (DECL_SIZE (rli->prev_field)))
		{
		  rli->bitpos
		    = size_binop (PLUS_EXPR, rli->bitpos,
				  bitsize_int (rli->remaining_in_alignment));
		}
	      else
		/* We "use up" size zero fields; the code below should behave
		   as if the prior field was not a bitfield.  */
		prev_saved = NULL;

	      /* 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)
		  || integer_zerop (DECL_SIZE (field)))
		rli->prev_field = NULL;
	    }

	  /* Does this field automatically have alignment it needs by virtue
	     of the fields that precede it and the record's own alignment?  */
	  if (realign_p)
	    {
	      /* If the alignment is still within offset_align, just align
		 the bit position.  */
	      if (desired_align < rli->offset_align)
		rli->bitpos = round_up (rli->bitpos, desired_align);
	      else
		{
		  /* First adjust OFFSET by the partial bits, then align.  */
		  tree d = size_binop (CEIL_DIV_EXPR, rli->bitpos,
				       bitsize_unit_node);
		  rli->offset = size_binop (PLUS_EXPR, rli->offset,
					    fold_convert (sizetype, d));
		  rli->bitpos = bitsize_zero_node;

		  rli->offset = round_up (rli->offset,
					  desired_align / BITS_PER_UNIT);
		}

	      if (! TREE_CONSTANT (rli->offset))
		rli->offset_align = desired_align;
	    }

	  normalize_rli (rli);
        }

      /* 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.

	 That is, if the current field is not a bitfield, or if there
	 was a prior bitfield the type sizes differ, or if there wasn't
	 a prior bitfield the size of the current field is nonzero.

	 Note: we must be sure to test ONLY the type size if there was
	 a prior bitfield and ONLY for the current field being zero if
	 there wasn't.  */

      if (!DECL_BIT_FIELD_TYPE (field)
	  || (prev_saved != NULL
	      ? !simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (prev_type))
	      : !integer_zerop (DECL_SIZE (field))))
	{
	  /* Never smaller than a byte for compatibility.  */
	  unsigned int type_align = BITS_PER_UNIT;

	  /* (When not a bitfield), we could be seeing a flex array (with
	     no DECL_SIZE).  Since we won't be using remaining_in_alignment
	     until we see a bitfield (and come by here again) we just skip
	     calculating it.  */
	  if (DECL_SIZE (field) != NULL
	      && tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (field)))
	      && tree_fits_uhwi_p (DECL_SIZE (field)))
	    {
	      unsigned HOST_WIDE_INT bitsize
		= tree_to_uhwi (DECL_SIZE (field));
	      unsigned HOST_WIDE_INT typesize
		= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (field)));

	      if (typesize < bitsize)
		rli->remaining_in_alignment = 0;
	      else
		rli->remaining_in_alignment = typesize - bitsize;
	    }

	  /* Now align (conventionally) for the new type.  */
	  if (! DECL_PACKED (field))
	    type_align = TYPE_ALIGN (TREE_TYPE (field));

	  if (maximum_field_alignment != 0)
	    type_align = MIN (type_align, maximum_field_alignment);

	  rli->bitpos = round_up (rli->bitpos, type_align);

          /* If we really aligned, don't allow subsequent bitfields
	     to undo that.  */
	  rli->prev_field = NULL;
	}
    }

  /* Offset so far becomes the position of this field after normalizing.  */
  normalize_rli (rli);
  DECL_FIELD_OFFSET (field) = rli->offset;
  DECL_FIELD_BIT_OFFSET (field) = rli->bitpos;
  SET_DECL_OFFSET_ALIGN (field, rli->offset_align);
  handle_warn_if_not_align (field, rli->record_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 = least_bit_hwi (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 (tree_fits_uhwi_p (DECL_FIELD_OFFSET (field)))
    actual_align = (BITS_PER_UNIT
		    * least_bit_hwi (tree_to_uhwi (DECL_FIELD_OFFSET (field))));
  else
    actual_align = DECL_OFFSET_ALIGN (field);
  /* ACTUAL_ALIGN is still the actual alignment *within the record* .
     store / extract bit field operations will check the alignment of the
     record against the mode of bit fields.  */

  if (known_align != actual_align)
    layout_decl (field, actual_align);

  if (rli->prev_field == NULL && DECL_BIT_FIELD_TYPE (field))
    rli->prev_field = field;

  /* Now add size of this field to the size of the record.  If the size is
     not constant, treat the field as being a multiple of bytes and just
     adjust the offset, resetting the bit position.  Otherwise, apportion the
     size amongst the bit position and offset.  First handle the case of an
     unspecified size, which can happen when we have an invalid nested struct
     definition, such as struct j { struct j { int i; } }.  The error message
     is printed in finish_struct.  */
  if (DECL_SIZE (field) == 0)
    /* Do nothing.  */;
  else if (TREE_CODE (DECL_SIZE (field)) != INTEGER_CST
	   || TREE_OVERFLOW (DECL_SIZE (field)))
    {
      rli->offset
	= size_binop (PLUS_EXPR, rli->offset,
		      fold_convert (sizetype,
				    size_binop (CEIL_DIV_EXPR, rli->bitpos,
						bitsize_unit_node)));
      rli->offset
	= size_binop (PLUS_EXPR, rli->offset, DECL_SIZE_UNIT (field));
      rli->bitpos = bitsize_zero_node;
      rli->offset_align = MIN (rli->offset_align, desired_align);

      if (!multiple_of_p (bitsizetype, DECL_SIZE (field),
			  bitsize_int (rli->offset_align)))
	{
	  tree type = strip_array_types (TREE_TYPE (field));
	  /* The above adjusts offset_align just based on the start of the
	     field.  The field might not have a size that is a multiple of
	     that offset_align though.  If the field is an array of fixed
	     sized elements, assume there can be any multiple of those
	     sizes.  If it is a variable length aggregate or array of
	     variable length aggregates, assume worst that the end is
	     just BITS_PER_UNIT aligned.  */
	  if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
	    {
	      if (TREE_INT_CST_LOW (TYPE_SIZE (type)))
		{
		  unsigned HOST_WIDE_INT sz
		    = least_bit_hwi (TREE_INT_CST_LOW (TYPE_SIZE (type)));
		  rli->offset_align = MIN (rli->offset_align, sz);
		}
	    }
	  else
	    rli->offset_align = MIN (rli->offset_align, BITS_PER_UNIT);
	}
    }
  else if (targetm.ms_bitfield_layout_p (rli->t))
    {
      rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, DECL_SIZE (field));

      /* If FIELD is the last field and doesn't end at the full length
	 of the type then pad the struct out to the full length of the
	 last type.  */
      if (DECL_BIT_FIELD_TYPE (field)
	  && !integer_zerop (DECL_SIZE (field)))
	{
	  /* We have to scan, because non-field DECLS are also here.  */
	  tree probe = field;
	  while ((probe = DECL_CHAIN (probe)))
	    if (TREE_CODE (probe) == FIELD_DECL)
	      break;
	  if (!probe)
	    rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos,
				      bitsize_int (rli->remaining_in_alignment));
	}

      normalize_rli (rli);
    }
  else
    {
      rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, DECL_SIZE (field));
      normalize_rli (rli);
    }
}

/* Assuming that all the fields have been laid out, this function uses
   RLI to compute the final TYPE_SIZE, TYPE_ALIGN, etc. for the type
   indicated by RLI.  */

static void
finalize_record_size (record_layout_info rli)
{
  tree unpadded_size, unpadded_size_unit;

  /* Now we want just byte and bit offsets, so set the offset alignment
     to be a byte and then normalize.  */
  rli->offset_align = BITS_PER_UNIT;
  normalize_rli (rli);

  /* Determine the desired alignment.  */
#ifdef ROUND_TYPE_ALIGN
  SET_TYPE_ALIGN (rli->t, ROUND_TYPE_ALIGN (rli->t, TYPE_ALIGN (rli->t),
					    rli->record_align));
#else
  SET_TYPE_ALIGN (rli->t, MAX (TYPE_ALIGN (rli->t), rli->record_align));
#endif

  /* Compute the size so far.  Be sure to allow for extra bits in the
     size in bytes.  We have guaranteed above that it will be no more
     than a single byte.  */
  unpadded_size = rli_size_so_far (rli);
  unpadded_size_unit = rli_size_unit_so_far (rli);
  if (! integer_zerop (rli->bitpos))
    unpadded_size_unit
      = size_binop (PLUS_EXPR, unpadded_size_unit, size_one_node);

  /* Round the size up to be a multiple of the required alignment.  */
  TYPE_SIZE (rli->t) = round_up (unpadded_size, TYPE_ALIGN (rli->t));
  TYPE_SIZE_UNIT (rli->t)
    = round_up (unpadded_size_unit, TYPE_ALIGN_UNIT (rli->t));

  if (TREE_CONSTANT (unpadded_size)
      && simple_cst_equal (unpadded_size, TYPE_SIZE (rli->t)) == 0
      && input_location != BUILTINS_LOCATION
      && !TYPE_ARTIFICIAL (rli->t))
  {
	tree pad_size
	  = size_binop (MINUS_EXPR, TYPE_SIZE_UNIT (rli->t), unpadded_size_unit);
	  warning (OPT_Wpadded,
		"padding struct size to alignment boundary with %E bytes", pad_size);
  }

  if (warn_packed && TREE_CODE (rli->t) == RECORD_TYPE
      && TYPE_PACKED (rli->t) && ! rli->packed_maybe_necessary
      && TREE_CONSTANT (unpadded_size))
    {
      tree unpacked_size;

#ifdef ROUND_TYPE_ALIGN
      rli->unpacked_align
	= ROUND_TYPE_ALIGN (rli->t, TYPE_ALIGN (rli->t), rli->unpacked_align);
#else
      rli->unpacked_align = MAX (TYPE_ALIGN (rli->t), rli->unpacked_align);
#endif

      unpacked_size = round_up (TYPE_SIZE (rli->t), rli->unpacked_align);
      if (simple_cst_equal (unpacked_size, TYPE_SIZE (rli->t)))
	{
	  if (TYPE_NAME (rli->t))
	    {
	      tree name;

	      if (TREE_CODE (TYPE_NAME (rli->t)) == IDENTIFIER_NODE)
		name = TYPE_NAME (rli->t);
	      else
		name = DECL_NAME (TYPE_NAME (rli->t));

	      if (STRICT_ALIGNMENT)
		warning (OPT_Wpacked, "packed attribute causes inefficient "
			 "alignment for %qE", name);
	      else
		warning (OPT_Wpacked,
			 "packed attribute is unnecessary for %qE", name);
	    }
	  else
	    {
	      if (STRICT_ALIGNMENT)
		warning (OPT_Wpacked,
			 "packed attribute causes inefficient alignment");
	      else
		warning (OPT_Wpacked, "packed attribute is unnecessary");
	    }
	}
    }
}

/* Compute the TYPE_MODE for the TYPE (which is a RECORD_TYPE).  */

void
compute_record_mode (tree type)
{
  tree field;
  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
     instead, in order to allow for better optimization down the
     line.  */
  SET_TYPE_MODE (type, BLKmode);

  poly_uint64 type_size;
  if (!poly_int_tree_p (TYPE_SIZE (type), &type_size))
    return;

  /* A record which has any BLKmode members must itself be
     BLKmode; it can't go in a register.  Unless the member is
     BLKmode only because it isn't aligned.  */
  for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    {
      if (TREE_CODE (field) != FIELD_DECL)
	continue;

      poly_uint64 field_size;
      if (TREE_CODE (TREE_TYPE (field)) == ERROR_MARK
	  || (TYPE_MODE (TREE_TYPE (field)) == BLKmode
	      && ! TYPE_NO_FORCE_BLK (TREE_TYPE (field))
	      && !(TYPE_SIZE (TREE_TYPE (field)) != 0
		   && integer_zerop (TYPE_SIZE (TREE_TYPE (field)))))
	  || !tree_fits_poly_uint64_p (bit_position (field))
	  || DECL_SIZE (field) == 0
	  || !poly_int_tree_p (DECL_SIZE (field), &field_size))
	return;

      /* If this field is the whole struct, remember its mode so
	 that, say, we can put a double in a class into a DF
	 register instead of forcing it to live in the stack.  */
      if (known_eq (field_size, type_size)
	  /* Partial int types (e.g. __int20) may have TYPE_SIZE equal to
	     wider types (e.g. int32), despite precision being less.  Ensure
	     that the TYPE_MODE of the struct does not get set to the partial
	     int mode if there is a wider type also in the struct.  */
	  && known_gt (GET_MODE_PRECISION (DECL_MODE (field)),
		       GET_MODE_PRECISION (mode)))
	mode = DECL_MODE (field);

      /* 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;
    }

  /* If we only have one real field; use its mode if that mode's size
     matches the type's size.  This generally only applies to RECORD_TYPE.
     For UNION_TYPE, if the widest field is MODE_INT then use that mode.
     If the widest field is MODE_PARTIAL_INT, and the union will be passed
     by reference, then use that mode.  */
  if ((TREE_CODE (type) == RECORD_TYPE
       || (TREE_CODE (type) == UNION_TYPE
	   && (GET_MODE_CLASS (mode) == MODE_INT
	       || (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT
		   && (targetm.calls.pass_by_reference
		       (pack_cumulative_args (0),
			function_arg_info (type, mode, /*named=*/false)))))))
      && mode != VOIDmode
      && known_eq (GET_MODE_BITSIZE (mode), type_size))
    ;
  else
    mode = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1).else_blk ();

  /* If structure's known alignment is less than what the scalar
     mode would need, and it matters, then stick with BLKmode.  */
  if (mode != BLKmode
      && STRICT_ALIGNMENT
      && ! (TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT
	    || TYPE_ALIGN (type) >= GET_MODE_ALIGNMENT (mode)))
    {
      /* If this is the only reason this type is BLKmode, then
	 don't force containing types to be BLKmode.  */
      TYPE_NO_FORCE_BLK (type) = 1;
      mode = BLKmode;
    }

  SET_TYPE_MODE (type, mode);
}

/* Compute TYPE_SIZE and TYPE_ALIGN for TYPE, once it has been laid
   out.  */

static void
finalize_type_size (tree type)
{
  /* Normally, use the alignment corresponding to the mode chosen.
     However, where strict alignment is not required, avoid
     over-aligning structures, since most compilers do not do this
     alignment.  */
  bool tua_cleared_p = false;
  if (TYPE_MODE (type) != BLKmode
      && TYPE_MODE (type) != VOIDmode
      && (STRICT_ALIGNMENT || !AGGREGATE_TYPE_P (type)))
    {
      unsigned mode_align = GET_MODE_ALIGNMENT (TYPE_MODE (type));

      /* Don't override a larger alignment requirement coming from a user
	 alignment of one of the fields.  */
      if (mode_align >= TYPE_ALIGN (type))
	{
	  SET_TYPE_ALIGN (type, mode_align);
	  /* Remember that we're about to reset this flag.  */
	  tua_cleared_p = TYPE_USER_ALIGN (type);
	  TYPE_USER_ALIGN (type) = false;
	}
    }

  /* Do machine-dependent extra alignment.  */
#ifdef ROUND_TYPE_ALIGN
  SET_TYPE_ALIGN (type,
                  ROUND_TYPE_ALIGN (type, TYPE_ALIGN (type), BITS_PER_UNIT));
#endif

  /* If we failed to find a simple way to calculate the unit size
     of the type, find it by division.  */
  if (TYPE_SIZE_UNIT (type) == 0 && TYPE_SIZE (type) != 0)
    /* TYPE_SIZE (type) is computed in bitsizetype.  After the division, the
       result will fit in sizetype.  We will get more efficient code using
       sizetype, so we force a conversion.  */
    TYPE_SIZE_UNIT (type)
      = fold_convert (sizetype,
		      size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (type),
				  bitsize_unit_node));

  if (TYPE_SIZE (type) != 0)
    {
      TYPE_SIZE (type) = round_up (TYPE_SIZE (type), TYPE_ALIGN (type));
      TYPE_SIZE_UNIT (type)
	= round_up (TYPE_SIZE_UNIT (type), TYPE_ALIGN_UNIT (type));
    }

  /* Evaluate nonconstant sizes only once, either now or as soon as safe.  */
  if (TYPE_SIZE (type) != 0 && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
    TYPE_SIZE (type) = variable_size (TYPE_SIZE (type));
  if (TYPE_SIZE_UNIT (type) != 0
      && TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
    TYPE_SIZE_UNIT (type) = variable_size (TYPE_SIZE_UNIT (type));

  /* Handle empty records as per the x86-64 psABI.  */
  TYPE_EMPTY_P (type) = targetm.calls.empty_record_p (type);

  /* Also layout any other variants of the type.  */
  if (TYPE_NEXT_VARIANT (type)
      || type != TYPE_MAIN_VARIANT (type))
    {
      tree variant;
      /* Record layout info of this variant.  */
      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);
      machine_mode mode = TYPE_MODE (type);
      bool empty_p = TYPE_EMPTY_P (type);
      bool typeless = AGGREGATE_TYPE_P (type) && TYPE_TYPELESS_STORAGE (type);

      /* Copy it into all variants.  */
      for (variant = TYPE_MAIN_VARIANT (type);
	   variant != NULL_TREE;
	   variant = TYPE_NEXT_VARIANT (variant))
	{
	  TYPE_SIZE (variant) = size;
	  TYPE_SIZE_UNIT (variant) = size_unit;
	  unsigned valign = align;
	  if (TYPE_USER_ALIGN (variant))
	    {
	      valign = MAX (valign, TYPE_ALIGN (variant));
	      /* If we reset TYPE_USER_ALIGN on the main variant, we might
		 need to reset it on the variants too.  TYPE_MODE will be set
		 to MODE in this variant, so we can use that.  */
	      if (tua_cleared_p && GET_MODE_ALIGNMENT (mode) >= valign)
		TYPE_USER_ALIGN (variant) = false;
	    }
	  else
	    TYPE_USER_ALIGN (variant) = user_align;
	  SET_TYPE_ALIGN (variant, valign);
	  TYPE_PRECISION (variant) = precision;
	  SET_TYPE_MODE (variant, mode);
	  TYPE_EMPTY_P (variant) = empty_p;
	  if (AGGREGATE_TYPE_P (variant))
	    TYPE_TYPELESS_STORAGE (variant) = typeless;
	}
    }
}

/* Return a new underlying object for a bitfield started with FIELD.  */

static tree
start_bitfield_representative (tree field)
{
  tree repr = make_node (FIELD_DECL);
  DECL_FIELD_OFFSET (repr) = DECL_FIELD_OFFSET (field);
  /* Force the representative to begin at a BITS_PER_UNIT aligned
     boundary - C++ may use tail-padding of a base object to
     continue packing bits so the bitfield region does not start
     at bit zero (see g++.dg/abi/bitfield5.C for example).
     Unallocated bits may happen for other reasons as well,
     for example Ada which allows explicit bit-granular structure layout.  */
  DECL_FIELD_BIT_OFFSET (repr)
    = size_binop (BIT_AND_EXPR,
		  DECL_FIELD_BIT_OFFSET (field),
		  bitsize_int (~(BITS_PER_UNIT - 1)));
  SET_DECL_OFFSET_ALIGN (repr, DECL_OFFSET_ALIGN (field));
  DECL_SIZE (repr) = DECL_SIZE (field);
  DECL_SIZE_UNIT (repr) = DECL_SIZE_UNIT (field);
  DECL_PACKED (repr) = DECL_PACKED (field);
  DECL_CONTEXT (repr) = DECL_CONTEXT (field);
  /* There are no indirect accesses to this field.  If we introduce
     some then they have to use the record alias set.  This makes
     sure to properly conflict with [indirect] accesses to addressable
     fields of the bitfield group.  */
  DECL_NONADDRESSABLE_P (repr) = 1;
  return repr;
}

/* Finish up a bitfield group that was started by creating the underlying
   object REPR with the last field in the bitfield group FIELD.  */

static void
finish_bitfield_representative (tree repr, tree field)
{
  unsigned HOST_WIDE_INT bitsize, maxbitsize;
  tree nextf, size;

  size = size_diffop (DECL_FIELD_OFFSET (field),
		      DECL_FIELD_OFFSET (repr));
  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);

  /* Now nothing tells us how to pad out bitsize ...  */
  if (TREE_CODE (DECL_CONTEXT (field)) == RECORD_TYPE)
    {
      nextf = DECL_CHAIN (field);
      while (nextf && TREE_CODE (nextf) != FIELD_DECL)
	nextf = DECL_CHAIN (nextf);
    }
  else
    nextf = NULL_TREE;
  if (nextf)
    {
      tree maxsize;
      /* 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)
	{
	  TREE_TYPE (repr) = error_mark_node;
	  return;
	}
      maxsize = size_diffop (DECL_FIELD_OFFSET (nextf),
			     DECL_FIELD_OFFSET (repr));
      if (tree_fits_uhwi_p (maxsize))
	{
	  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);
	}
      else
	maxbitsize = bitsize;
    }
  else
    {
      /* Note that if the C++ FE sets up tail-padding to be re-used it
         creates a as-base variant of the type with TYPE_SIZE adjusted
	 accordingly.  So it is safe to include tail-padding here.  */
      tree aggsize = lang_hooks.types.unit_size_without_reusable_padding
							(DECL_CONTEXT (field));
      tree maxsize = size_diffop (aggsize, DECL_FIELD_OFFSET (repr));
      /* We cannot generally rely on maxsize to fold to an integer constant,
	 so use bitsize as fallback for this case.  */
      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;
    }

  /* Only if we don't artificially break up the representative in
     the middle of a large bitfield with different possibly
     overlapping representatives.  And all representatives start
     at byte offset.  */
  gcc_assert (maxbitsize % BITS_PER_UNIT == 0);

  /* Find the smallest nice mode to use.  */
  opt_scalar_int_mode mode_iter;
  FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
    if (GET_MODE_BITSIZE (mode_iter.require ()) >= bitsize)
      break;

  scalar_int_mode mode;
  if (!mode_iter.exists (&mode)
      || GET_MODE_BITSIZE (mode) > maxbitsize
      || GET_MODE_BITSIZE (mode) > MAX_FIXED_MODE_SIZE)
    {
      if (TREE_CODE (TREE_TYPE (field)) == BITINT_TYPE)
	{
	  struct bitint_info info;
	  unsigned prec = TYPE_PRECISION (TREE_TYPE (field));
	  bool ok = targetm.c.bitint_type_info (prec, &info);
	  gcc_assert (ok);
	  scalar_int_mode limb_mode
	    = as_a <scalar_int_mode> (info.abi_limb_mode);
	  unsigned lprec = GET_MODE_PRECISION (limb_mode);
	  if (prec > lprec)
	    {
	      /* For middle/large/huge _BitInt prefer bitsize being a multiple
		 of limb precision.  */
	      unsigned HOST_WIDE_INT bsz = CEIL (bitsize, lprec) * lprec;
	      if (bsz <= maxbitsize)
		bitsize = bsz;
	    }
	}
      /* We really want a BLKmode representative only as a last resort,
         considering the member b in
	   struct { int a : 7; int b : 17; int c; } __attribute__((packed));
	 Otherwise we simply want to split the representative up
	 allowing for overlaps within the bitfield region as required for
	   struct { int a : 7; int b : 7;
		    int c : 10; int d; } __attribute__((packed));
	 [0, 15] HImode for a and b, [8, 23] HImode for c.  */
      DECL_SIZE (repr) = bitsize_int (bitsize);
      DECL_SIZE_UNIT (repr) = size_int (bitsize / BITS_PER_UNIT);
      SET_DECL_MODE (repr, BLKmode);
      TREE_TYPE (repr) = build_array_type_nelts (unsigned_char_type_node,
						 bitsize / BITS_PER_UNIT);
    }
  else
    {
      unsigned HOST_WIDE_INT modesize = GET_MODE_BITSIZE (mode);
      DECL_SIZE (repr) = bitsize_int (modesize);
      DECL_SIZE_UNIT (repr) = size_int (modesize / BITS_PER_UNIT);
      SET_DECL_MODE (repr, mode);
      TREE_TYPE (repr) = lang_hooks.types.type_for_mode (mode, 1);
    }

  /* Remember whether the bitfield group is at the end of the
     structure or not.  */
  DECL_CHAIN (repr) = nextf;
}

/* Compute and set FIELD_DECLs for the underlying objects we should
   use for bitfield access for the structure T.  */

void
finish_bitfield_layout (tree t)
{
  tree field, prev;
  tree repr = NULL_TREE;

  if (TREE_CODE (t) == QUAL_UNION_TYPE)
    return;

  for (prev = NULL_TREE, field = TYPE_FIELDS (t);
       field; field = DECL_CHAIN (field))
    {
      if (TREE_CODE (field) != FIELD_DECL)
	continue;

      /* In the C++ memory model, consecutive bit fields in a structure are
	 considered one memory location and updating a memory location
	 may not store into adjacent memory locations.  */
      if (!repr
	  && DECL_BIT_FIELD_TYPE (field))
	{
	  /* Start new representative.  */
	  repr = start_bitfield_representative (field);
	}
      else if (repr
	       && ! DECL_BIT_FIELD_TYPE (field))
	{
	  /* Finish off new representative.  */
	  finish_bitfield_representative (repr, prev);
	  repr = NULL_TREE;
	}
      else if (DECL_BIT_FIELD_TYPE (field))
	{
	  gcc_assert (repr != NULL_TREE);

	  /* Zero-size bitfields finish off a representative and
	     do not have a representative themselves.  This is
	     required by the C++ memory model.  */
	  if (integer_zerop (DECL_SIZE (field)))
	    {
	      finish_bitfield_representative (repr, prev);
	      repr = NULL_TREE;
	    }

	  /* We assume that either DECL_FIELD_OFFSET of the representative
	     and each bitfield member is a constant or they are equal.
	     This is because we need to be able to compute the bit-offset
	     of each field relative to the representative in get_bit_range
	     during RTL expansion.
	     If these constraints are not met, simply force a new
	     representative to be generated.  That will at most
	     generate worse code but still maintain correctness with
	     respect to the C++ memory model.  */
	  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)))
	    {
	      finish_bitfield_representative (repr, prev);
	      repr = start_bitfield_representative (field);
	    }
	}
      else
	continue;

      if (repr)
	DECL_BIT_FIELD_REPRESENTATIVE (field) = repr;

      if (TREE_CODE (t) == RECORD_TYPE)
	prev = field;
      else if (repr)
	{
	  finish_bitfield_representative (repr, field);
	  repr = NULL_TREE;
	}
    }

  if (repr)
    finish_bitfield_representative (repr, prev);
}

/* Do all of the work required to layout the type indicated by RLI,
   once the fields have been laid out.  This function will call `free'
   for RLI, unless FREE_P is false.  Passing a value other than false
   for FREE_P is bad practice; this option only exists to support the
   G++ 3.2 ABI.  */

void
finish_record_layout (record_layout_info rli, int free_p)
{
  tree variant;

  /* Compute the final size.  */
  finalize_record_size (rli);

  /* Compute the TYPE_MODE for the record.  */
  compute_record_mode (rli->t);

  /* Perform any last tweaks to the TYPE_SIZE, etc.  */
  finalize_type_size (rli->t);

  /* Compute bitfield representatives.  */
  finish_bitfield_layout (rli->t);

  /* Propagate TYPE_PACKED and TYPE_REVERSE_STORAGE_ORDER to variants.
     With C++ templates, it is too early to do this when the attribute
     is being parsed.  */
  for (variant = TYPE_NEXT_VARIANT (rli->t); variant;
       variant = TYPE_NEXT_VARIANT (variant))
    {
      TYPE_PACKED (variant) = TYPE_PACKED (rli->t);
      TYPE_REVERSE_STORAGE_ORDER (variant)
	= TYPE_REVERSE_STORAGE_ORDER (rli->t);
    }

  /* Lay out any static members.  This is done now because their type
     may use the record's type.  */
  while (!vec_safe_is_empty (rli->pending_statics))
    layout_decl (rli->pending_statics->pop (), 0);

  /* Clean up.  */
  if (free_p)
    {
      vec_free (rli->pending_statics);
      free (rli);
    }
}


/* Finish processing a builtin RECORD_TYPE type TYPE.  It's name is
   NAME, its fields are chained in reverse on FIELDS.

   If ALIGN_TYPE is non-null, it is given the same alignment as
   ALIGN_TYPE.  */

void
finish_builtin_struct (tree type, const char *name, tree fields,
		       tree align_type)
{
  tree tail, next;

  for (tail = NULL_TREE; fields; tail = fields, fields = next)
    {
      DECL_FIELD_CONTEXT (fields) = type;
      next = DECL_CHAIN (fields);
      DECL_CHAIN (fields) = tail;
    }
  TYPE_FIELDS (type) = tail;

  if (align_type)
    {
      SET_TYPE_ALIGN (type, TYPE_ALIGN (align_type));
      TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (align_type);
      SET_TYPE_WARN_IF_NOT_ALIGN (type,
				  TYPE_WARN_IF_NOT_ALIGN (align_type));
    }

  layout_type (type);
#if 0 /* not yet, should get fixed properly later */
  TYPE_NAME (type) = make_type_decl (get_identifier (name), type);
#else
  TYPE_NAME (type) = build_decl (BUILTINS_LOCATION,
				 TYPE_DECL, get_identifier (name), type);
#endif
  TYPE_STUB_DECL (type) = TYPE_NAME (type);
  layout_decl (TYPE_NAME (type), 0);
}

/* Compute TYPE_MODE for TYPE (which is ARRAY_TYPE).  */

void compute_array_mode (tree type)
{
  gcc_assert (TREE_CODE (type) == ARRAY_TYPE);

  SET_TYPE_MODE (type, BLKmode);
  if (TYPE_SIZE (type) != 0
      && ! targetm.member_type_forces_blk (type, VOIDmode)
      /* BLKmode elements force BLKmode aggregate;
	 else extract/store fields may lose.  */
      && (TYPE_MODE (TREE_TYPE (type)) != BLKmode
	  || TYPE_NO_FORCE_BLK (TREE_TYPE (type))))
    {
      SET_TYPE_MODE (type, mode_for_array (TREE_TYPE (type),
					   TYPE_SIZE (type)));
      if (TYPE_MODE (type) != BLKmode
	  && STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT
	  && TYPE_ALIGN (type) < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
	{
	  TYPE_NO_FORCE_BLK (type) = 1;
	  SET_TYPE_MODE (type, BLKmode);
	}
    }
}

/* Calculate the mode, size, and alignment for TYPE.
   For an array type, calculate the element separation as well.
   Record TYPE on the chain of permanent or temporary types
   so that dbxout will find out about it.

   TYPE_SIZE of a type is nonzero if the type has been laid out already.
   layout_type does nothing on such a type.

   If the type is incomplete, its TYPE_SIZE remains zero.  */

void
layout_type (tree type)
{
  gcc_assert (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;

  switch (TREE_CODE (type))
    {
    case LANG_TYPE:
      /* This kind of type is the responsibility
	 of the language-specific code.  */
      gcc_unreachable ();

    case BOOLEAN_TYPE:
    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
      {
	scalar_int_mode mode
	  = smallest_int_mode_for_size (TYPE_PRECISION (type)).require ();
	SET_TYPE_MODE (type, mode);
	TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (mode));
	/* Don't set TYPE_PRECISION here, as it may be set by a bitfield.  */
	TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
	break;
      }

    case BITINT_TYPE:
      {
	struct bitint_info info;
	int cnt;
	bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
	gcc_assert (ok);
	scalar_int_mode limb_mode
	  = as_a <scalar_int_mode> (info.abi_limb_mode);
	if (TYPE_PRECISION (type) <= GET_MODE_PRECISION (limb_mode))
	  {
	    SET_TYPE_MODE (type, limb_mode);
	    gcc_assert (info.abi_limb_mode == info.limb_mode);
	    cnt = 1;
	  }
	else
	  {
	    SET_TYPE_MODE (type, BLKmode);
	    cnt = CEIL (TYPE_PRECISION (type), GET_MODE_PRECISION (limb_mode));
	    gcc_assert (info.abi_limb_mode == info.limb_mode
			|| !info.big_endian == !WORDS_BIG_ENDIAN);
	  }
	TYPE_SIZE (type) = bitsize_int (cnt * GET_MODE_BITSIZE (limb_mode));
	TYPE_SIZE_UNIT (type) = size_int (cnt * GET_MODE_SIZE (limb_mode));
	SET_TYPE_ALIGN (type, GET_MODE_ALIGNMENT (limb_mode));
	if (cnt > 1)
	  {
	    /* Use same mode as compute_record_mode would use for a structure
	       containing cnt limb_mode elements.  */
	    machine_mode mode = mode_for_size_tree (TYPE_SIZE (type),
						    MODE_INT, 1).else_blk ();
	    if (mode == BLKmode)
	      break;
	    finalize_type_size (type);
	    SET_TYPE_MODE (type, mode);
	    if (STRICT_ALIGNMENT
		&& !(TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT
		     || TYPE_ALIGN (type) >= GET_MODE_ALIGNMENT (mode)))
	      {
		/* If this is the only reason this type is BLKmode, then
		   don't force containing types to be BLKmode.  */
		TYPE_NO_FORCE_BLK (type) = 1;
		SET_TYPE_MODE (type, BLKmode);
	      }
	    if (TYPE_NEXT_VARIANT (type) || type != TYPE_MAIN_VARIANT (type))
	      for (tree variant = TYPE_MAIN_VARIANT (type);
		   variant != NULL_TREE;
		   variant = TYPE_NEXT_VARIANT (variant))
		{
		  SET_TYPE_MODE (variant, mode);
		  if (STRICT_ALIGNMENT
		      && !(TYPE_ALIGN (variant) >= BIGGEST_ALIGNMENT
			   || (TYPE_ALIGN (variant)
			       >= GET_MODE_ALIGNMENT (mode))))
		    {
		      TYPE_NO_FORCE_BLK (variant) = 1;
		      SET_TYPE_MODE (variant, BLKmode);
		    }
		}
	    return;
	  }
	break;
      }

    case REAL_TYPE:
      {
	/* Allow the caller to choose the type mode, which is how decimal
	   floats are distinguished from binary ones.  */
	if (TYPE_MODE (type) == VOIDmode)
	  SET_TYPE_MODE
	    (type, float_mode_for_size (TYPE_PRECISION (type)).require ());
	scalar_float_mode mode = as_a <scalar_float_mode> (TYPE_MODE (type));
	TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (mode));
	TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
	break;
      }

   case FIXED_POINT_TYPE:
     {
       /* TYPE_MODE (type) has been set already.  */
       scalar_mode mode = SCALAR_TYPE_MODE (type);
       TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (mode));
       TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
       break;
     }

    case COMPLEX_TYPE:
      TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
      if (TYPE_MODE (TREE_TYPE (type)) == BLKmode)
	{
	  gcc_checking_assert (TREE_CODE (TREE_TYPE (type)) == BITINT_TYPE);
	  SET_TYPE_MODE (type, BLKmode);
	  TYPE_SIZE (type)
	    = int_const_binop (MULT_EXPR, TYPE_SIZE (TREE_TYPE (type)),
			       bitsize_int (2));
	  TYPE_SIZE_UNIT (type)
	    = int_const_binop (MULT_EXPR, TYPE_SIZE_UNIT (TREE_TYPE (type)),
			       bitsize_int (2));
	  break;
	}
      SET_TYPE_MODE (type,
		     GET_MODE_COMPLEX_MODE (TYPE_MODE (TREE_TYPE (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 VECTOR_TYPE:
      {
	poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (type);
	tree innertype = TREE_TYPE (type);

	/* Find an appropriate mode for the vector type.  */
	if (TYPE_MODE (type) == VOIDmode)
	  SET_TYPE_MODE (type,
			 mode_for_vector (SCALAR_TYPE_MODE (innertype),
					  nunits).else_blk ());

	TYPE_SATURATING (type) = TYPE_SATURATING (TREE_TYPE (type));
        TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
	/* Several boolean vector elements may fit in a single unit.  */
	if (VECTOR_BOOLEAN_TYPE_P (type)
	    && type->type_common.mode != BLKmode)
	  {
	    TYPE_SIZE_UNIT (type)
	      = size_int (GET_MODE_SIZE (type->type_common.mode));
	    TYPE_SIZE (type)
	      = bitsize_int (GET_MODE_BITSIZE (type->type_common.mode));
	  }
	else
	  {
	    TYPE_SIZE_UNIT (type)
	      = size_int (GET_MODE_SIZE (SCALAR_TYPE_MODE (innertype))
			  * nunits);
	    TYPE_SIZE (type)
	      = bitsize_int (GET_MODE_BITSIZE (SCALAR_TYPE_MODE (innertype))
			     * nunits);
	  }

	/* 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.  */
	SET_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;
      }

    case VOID_TYPE:
      /* This is an incomplete type and so doesn't have a size.  */
      SET_TYPE_ALIGN (type, 1);
      TYPE_USER_ALIGN (type) = 0;
      SET_TYPE_MODE (type, VOIDmode);
      break;

    case OFFSET_TYPE:
      TYPE_SIZE (type) = bitsize_int (POINTER_SIZE);
      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, int_mode_for_size (POINTER_SIZE, 0).require ());
      TYPE_PRECISION (type) = POINTER_SIZE;
      break;

    case FUNCTION_TYPE:
    case METHOD_TYPE:
      /* It's hard to see what the mode and size of a function ought to
	 be, but we do know the alignment is FUNCTION_BOUNDARY, so
	 make it consistent with that.  */
      SET_TYPE_MODE (type,
		     int_mode_for_size (FUNCTION_BOUNDARY, 0).else_blk ());
      TYPE_SIZE (type) = bitsize_int (FUNCTION_BOUNDARY);
      TYPE_SIZE_UNIT (type) = size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
      break;

    case POINTER_TYPE:
    case REFERENCE_TYPE:
      {
	scalar_int_mode mode = SCALAR_INT_TYPE_MODE (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_PRECISION (mode);
      }
      break;

    case ARRAY_TYPE:
      {
	tree index = TYPE_DOMAIN (type);
	tree element = TREE_TYPE (type);

	/* We need to know both bounds in order to compute the size.  */
	if (index && TYPE_MAX_VALUE (index) && TYPE_MIN_VALUE (index)
	    && TYPE_SIZE (element))
	  {
	    tree ub = TYPE_MAX_VALUE (index);
	    tree lb = TYPE_MIN_VALUE (index);
	    tree element_size = TYPE_SIZE (element);
	    tree length;

	    /* Make sure that an array of zero-sized element is zero-sized
	       regardless of its extent.  */
	    if (integer_zerop (element_size))
	      length = size_zero_node;

	    /* The computation should happen in the original signedness so
	       that (possible) negative values are handled appropriately
	       when determining overflow.  */
	    else
	      {
		/* ???  When it is obvious that the range is signed
		   represent it using ssizetype.  */
		if (TREE_CODE (lb) == INTEGER_CST
		    && TREE_CODE (ub) == INTEGER_CST
		    && TYPE_UNSIGNED (TREE_TYPE (lb))
		    && tree_int_cst_lt (ub, lb))
		  {
		    lb = wide_int_to_tree (ssizetype,
					   offset_int::from (wi::to_wide (lb),
							     SIGNED));
		    ub = wide_int_to_tree (ssizetype,
					   offset_int::from (wi::to_wide (ub),
							     SIGNED));
		  }
		length
		  = fold_convert (sizetype,
				  size_binop (PLUS_EXPR,
					      build_int_cst (TREE_TYPE (lb), 1),
					      size_binop (MINUS_EXPR, ub, lb)));
	      }

	    /* ??? 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)
		&& integer_zerop (lb))
	      length = size_zero_node;

	    TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size,
					   bits_from_bytes (length));

	    /* If we know the size of the element, calculate the total size
	       directly, rather than do some division thing below.  This
	       optimization helps Fortran assumed-size arrays (where the
	       size of the array is determined at runtime) substantially.  */
	    if (TYPE_SIZE_UNIT (element))
	      TYPE_SIZE_UNIT (type)
		= size_binop (MULT_EXPR, TYPE_SIZE_UNIT (element), length);
	  }

	/* 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);
	if (!TYPE_WARN_IF_NOT_ALIGN (type))
	  SET_TYPE_WARN_IF_NOT_ALIGN (type,
				      TYPE_WARN_IF_NOT_ALIGN (element));
#ifdef ROUND_TYPE_ALIGN
	align = ROUND_TYPE_ALIGN (type, align, BITS_PER_UNIT);
#else
	align = MAX (align, BITS_PER_UNIT);
#endif
	SET_TYPE_ALIGN (type, align);
	compute_array_mode (type);
	if (AGGREGATE_TYPE_P (element))
	  TYPE_TYPELESS_STORAGE (type) = TYPE_TYPELESS_STORAGE (element);
	/* When the element size is constant, check that it is at least as
	   large as the element alignment.  */
	if (TYPE_SIZE_UNIT (element)
	    && TREE_CODE (TYPE_SIZE_UNIT (element)) == INTEGER_CST
	    /* If TYPE_SIZE_UNIT overflowed, then it is certainly larger than
	       TYPE_ALIGN_UNIT.  */
	    && !TREE_OVERFLOW (TYPE_SIZE_UNIT (element))
	    && !integer_zerop (TYPE_SIZE_UNIT (element)))
	  {
	    if (compare_tree_int (TYPE_SIZE_UNIT (element),
				  TYPE_ALIGN_UNIT (element)) < 0)
	      error ("alignment of array elements is greater than "
		     "element size");
	    else if (TYPE_ALIGN_UNIT (element) > 1
		     && (wi::zext (wi::to_wide (TYPE_SIZE_UNIT (element)),
				  ffs_hwi (TYPE_ALIGN_UNIT (element)) - 1)
			 != 0))
	      error ("size of array element is not a multiple of its "
		     "alignment");
	  }
	break;
      }

    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      {
	tree field;
	record_layout_info rli;

	/* Initialize the layout information.  */
	rli = start_record_layout (type);

	/* If this is a QUAL_UNION_TYPE, we want to process the fields
	   in the reverse order in building the COND_EXPR that denotes
	   its size.  We reverse them again later.  */
	if (TREE_CODE (type) == QUAL_UNION_TYPE)
	  TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type));

	/* Place all the fields.  */
	for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
	  place_field (rli, field);

	if (TREE_CODE (type) == QUAL_UNION_TYPE)
	  TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type));

	/* Finish laying out the record.  */
	finish_record_layout (rli, /*free_p=*/true);
      }
      break;

    default:
      gcc_unreachable ();
    }

  /* Compute the final TYPE_SIZE, TYPE_ALIGN, etc. for TYPE.  For
     records and unions, finish_record_layout already called this
     function.  */
  if (!RECORD_OR_UNION_TYPE_P (type))
    finalize_type_size (type);

  /* We should never see alias sets on incomplete aggregates.  And we
     should not call layout_type on not incomplete aggregates.  */
  if (AGGREGATE_TYPE_P (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
      field_align = ADJUST_FIELD_ALIGN (NULL_TREE, type, field_align);
#endif
      align = MIN (align, field_align);
    }
  return align / BITS_PER_UNIT;
}

/* Create and return a type for signed integers of PRECISION bits.  */

tree
make_signed_type (int precision)
{
  tree type = make_node (INTEGER_TYPE);

  TYPE_PRECISION (type) = precision;

  fixup_signed_type (type);
  return type;
}

/* Create and return a type for unsigned integers of PRECISION bits.  */

tree
make_unsigned_type (int precision)
{
  tree type = make_node (INTEGER_TYPE);

  TYPE_PRECISION (type) = precision;

  fixup_unsigned_type (type);
  return type;
}

/* Create and return a type for fract of PRECISION bits, UNSIGNEDP,
   and SATP.  */

tree
make_fract_type (int precision, int unsignedp, int satp)
{
  tree type = make_node (FIXED_POINT_TYPE);

  TYPE_PRECISION (type) = precision;

  if (satp)
    TYPE_SATURATING (type) = 1;

  /* Lay out the type: set its alignment, size, etc.  */
  TYPE_UNSIGNED (type) = unsignedp;
  enum mode_class mclass = unsignedp ? MODE_UFRACT : MODE_FRACT;
  SET_TYPE_MODE (type, mode_for_size (precision, mclass, 0).require ());
  layout_type (type);

  return type;
}

/* Create and return a type for accum of PRECISION bits, UNSIGNEDP,
   and SATP.  */

tree
make_accum_type (int precision, int unsignedp, int satp)
{
  tree type = make_node (FIXED_POINT_TYPE);

  TYPE_PRECISION (type) = precision;

  if (satp)
    TYPE_SATURATING (type) = 1;

  /* Lay out the type: set its alignment, size, etc.  */
  TYPE_UNSIGNED (type) = unsignedp;
  enum mode_class mclass = unsignedp ? MODE_UACCUM : MODE_ACCUM;
  SET_TYPE_MODE (type, mode_for_size (precision, mclass, 0).require ());
  layout_type (type);

  return type;
}

/* Initialize sizetypes so layout_type can use them.  */

void
initialize_sizetypes (void)
{
  int precision, bprecision;

  /* Get sizetypes precision from the SIZE_TYPE target macro.  */
  if (strcmp (SIZETYPE, "unsigned int") == 0)
    precision = INT_TYPE_SIZE;
  else if (strcmp (SIZETYPE, "long unsigned int") == 0)
    precision = LONG_TYPE_SIZE;
  else if (strcmp (SIZETYPE, "long long unsigned int") == 0)
    precision = LONG_LONG_TYPE_SIZE;
  else if (strcmp (SIZETYPE, "short unsigned int") == 0)
    precision = SHORT_TYPE_SIZE;
  else
    {
      int i;

      precision = -1;
      for (i = 0; i < NUM_INT_N_ENTS; i++)
	if (int_n_enabled_p[i])
	  {
	    char name[50], altname[50];
	    sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
	    sprintf (altname, "__int%d__ unsigned", int_n_data[i].bitsize);

	    if (strcmp (name, SIZETYPE) == 0
		|| strcmp (altname, SIZETYPE) == 0)
	      {
		precision = int_n_data[i].bitsize;
	      }
	  }
      if (precision == -1)
	gcc_unreachable ();
    }

  bprecision
    = MIN (precision + LOG2_BITS_PER_UNIT + 1, MAX_FIXED_MODE_SIZE);
  bprecision
    = GET_MODE_PRECISION (smallest_int_mode_for_size (bprecision).require ());
  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);
  TYPE_NAME (sizetype) = get_identifier ("sizetype");
  TYPE_PRECISION (sizetype) = precision;
  TYPE_UNSIGNED (sizetype) = 1;
  bitsizetype = make_node (INTEGER_TYPE);
  TYPE_NAME (bitsizetype) = get_identifier ("bitsizetype");
  TYPE_PRECISION (bitsizetype) = bprecision;
  TYPE_UNSIGNED (bitsizetype) = 1;

  /* Now layout both types manually.  */
  scalar_int_mode mode = smallest_int_mode_for_size (precision).require ();
  SET_TYPE_MODE (sizetype, mode);
  SET_TYPE_ALIGN (sizetype, GET_MODE_ALIGNMENT (TYPE_MODE (sizetype)));
  TYPE_SIZE (sizetype) = bitsize_int (precision);
  TYPE_SIZE_UNIT (sizetype) = size_int (GET_MODE_SIZE (mode));
  set_min_and_max_values_for_integral_type (sizetype, precision, UNSIGNED);

  mode = smallest_int_mode_for_size (bprecision).require ();
  SET_TYPE_MODE (bitsizetype, mode);
  SET_TYPE_ALIGN (bitsizetype, GET_MODE_ALIGNMENT (TYPE_MODE (bitsizetype)));
  TYPE_SIZE (bitsizetype) = bitsize_int (bprecision);
  TYPE_SIZE_UNIT (bitsizetype) = size_int (GET_MODE_SIZE (mode));
  set_min_and_max_values_for_integral_type (bitsizetype, bprecision, UNSIGNED);

  /* Create the signed variants of *sizetype.  */
  ssizetype = make_signed_type (TYPE_PRECISION (sizetype));
  TYPE_NAME (ssizetype) = get_identifier ("ssizetype");
  sbitsizetype = make_signed_type (TYPE_PRECISION (bitsizetype));
  TYPE_NAME (sbitsizetype) = get_identifier ("sbitsizetype");
}

/* TYPE is an integral type, i.e., an INTEGRAL_TYPE, ENUMERAL_TYPE
   or BOOLEAN_TYPE.  Set TYPE_MIN_VALUE and TYPE_MAX_VALUE
   for TYPE, based on the PRECISION and whether or not the TYPE
   IS_UNSIGNED.  PRECISION need not correspond to a width supported
   natively by the hardware; for example, on a machine with 8-bit,
   16-bit, and 32-bit register modes, PRECISION might be 7, 23, or
   61.  */

void
set_min_and_max_values_for_integral_type (tree type,
					  int precision,
					  signop sgn)
{
  /* 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;

  gcc_assert (precision <= WIDE_INT_MAX_PRECISION);

  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,
   then lay it out.  Used when make_signed_type won't do
   because the tree code is not INTEGER_TYPE.  */

void
fixup_signed_type (tree type)
{
  int precision = TYPE_PRECISION (type);

  set_min_and_max_values_for_integral_type (type, precision, SIGNED);

  /* Lay out the type: set its alignment, size, etc.  */
  layout_type (type);
}

/* Set the extreme values of TYPE based on its precision in bits,
   then lay it out.  This is used both in `make_unsigned_type'
   and for enumeral types.  */

void
fixup_unsigned_type (tree type)
{
  int precision = TYPE_PRECISION (type);

  TYPE_UNSIGNED (type) = 1;

  set_min_and_max_values_for_integral_type (type, precision, UNSIGNED);

  /* Lay out the type: set its alignment, size, etc.  */
  layout_type (type);
}

/* 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,
			   poly_int64 bitregion_start,
			   poly_int64 bitregion_end,
			   unsigned int align, bool volatilep)
: m_mode (NARROWEST_INT_MODE), 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 (known_eq (m_bitregion_end, 0))
    {
      /* 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;
      HOST_WIDE_INT end = bitpos + bitsize + units - 1;
      m_bitregion_end = end - 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 (scalar_int_mode *out_mode)
{
  scalar_int_mode mode;
  for (; m_mode.exists (&mode); m_mode = GET_MODE_WIDER_MODE (mode))
    {
      unsigned int unit = GET_MODE_BITSIZE (mode);

      /* Skip modes that don't have full precision.  */
      if (unit != GET_MODE_PRECISION (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 (maybe_ne (m_bitregion_start, 0)
	  && maybe_lt (start, m_bitregion_start))
	break;
      HOST_WIDE_INT end = start + unit;
      if (maybe_gt (end, m_bitregion_end + 1))
	break;

      /* Stop if the mode requires too much alignment.  */
      if (GET_MODE_ALIGNMENT (mode) > m_align
	  && targetm.slow_unaligned_access (mode, m_align))
	break;

      *out_mode = mode;
      m_mode = GET_MODE_WIDER_MODE (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 that range.  Otherwise, we are allowed to touch
   any adjacent non bit-fields.

   The chosen mode must have no more than LARGEST_MODE_BITSIZE bits.
   INT_MAX is a suitable value for LARGEST_MODE_BITSIZE if the caller
   doesn't want to apply a specific limit.

   If no mode meets all these conditions, we return VOIDmode.

   The underlying object is known to be aligned to a boundary of ALIGN bits.

   If VOLATILEP is false and SLOW_BYTE_ACCESS is false, we return the
   smallest mode meeting these conditions.

   If VOLATILEP is false and SLOW_BYTE_ACCESS is true, we return the
   largest mode (but a mode no wider than UNITS_PER_WORD) that meets
   all the conditions.

   If VOLATILEP is true the narrow_volatile_bitfields target hook is used to
   decide which of the above modes should be used.  */

bool
get_best_mode (HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
	       poly_uint64 bitregion_start, poly_uint64 bitregion_end,
	       unsigned int align,
	       unsigned HOST_WIDE_INT largest_mode_bitsize, bool volatilep,
	       scalar_int_mode *best_mode)
{
  bit_field_mode_iterator iter (bitsize, bitpos, bitregion_start,
				bitregion_end, align, volatilep);
  scalar_int_mode mode;
  bool found = false;
  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
	 && GET_MODE_BITSIZE (mode) <= largest_mode_bitsize)
    {
      *best_mode = mode;
      found = true;
      if (iter.prefer_smaller_modes ())
	break;
    }

  return found;
}

/* 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 (scalar_int_mode mode, int sign,
		 scalar_int_mode target_mode,
		 rtx *mmin, rtx *mmax)
{
  unsigned size = GET_MODE_PRECISION (mode);
  unsigned HOST_WIDE_INT min_val, max_val;

  gcc_assert (size <= HOST_BITS_PER_WIDE_INT);

  /* 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 = -(HOST_WIDE_INT_1U << (size - 1));
      max_val = (HOST_WIDE_INT_1U << (size - 1)) - 1;
    }
  else
    {
      min_val = 0;
      max_val = (HOST_WIDE_INT_1U << (size - 1) << 1) - 1;
    }

  *mmin = gen_int_mode (min_val, target_mode);
  *mmax = gen_int_mode (max_val, target_mode);
}

#include "gt-stor-layout.h"
