static int excess_unit_span (HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT,
HOST_WIDE_INT, tree);
#endif
-static void force_type_save_exprs_1 (tree);
-static unsigned int update_alignment_for_field (record_layout_info, tree,
- unsigned int);
extern void debug_rli (record_layout_info);
\f
/* SAVE_EXPRs for sizes of types and decls, waiting to be expanded. */
static GTY(()) tree pending_sizes;
-/* Nonzero means cannot safely call expand_expr now,
- so put variable sizes onto `pending_sizes' instead. */
-
-int immediate_size_expand;
-
/* Show that REFERENCE_TYPES are internal and should be Pmode. Called only
by front end. */
get_pending_sizes (void)
{
tree chain = pending_sizes;
- tree t;
-
- /* Put each SAVE_EXPR into the current function. */
- for (t = chain; t; t = TREE_CHAIN (t))
- SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = current_function_decl;
pending_sizes = 0;
return chain;
not wish to do that here; the array-size is the same in both
places. */
save = skip_simple_arithmetic (size);
- if (TREE_CODE (save) == SAVE_EXPR)
- SAVE_EXPR_PERSISTENT_P (save) = 1;
+
+ if (cfun && cfun->x_dont_save_pending_sizes_p)
+ /* The front-end doesn't want us to keep a list of the expressions
+ that determine sizes for variable size objects. Trust it. */
+ return size;
if (lang_hooks.decls.global_bindings_p ())
{
return size_one_node;
}
- if (immediate_size_expand)
- expand_expr (save, const0_rtx, VOIDmode, 0);
- else if (cfun != 0 && cfun->x_dont_save_pending_sizes_p)
- /* The front-end doesn't want us to keep a list of the expressions
- that determine sizes for variable size objects. */
- ;
- else
- put_pending_size (save);
+ put_pending_size (save);
return size;
}
-
-/* Given a type T, force elaboration of any SAVE_EXPRs used in the definition
- of that type. */
-
-void
-force_type_save_exprs (tree t)
-{
- tree field;
-
- switch (TREE_CODE (t))
- {
- case ERROR_MARK:
- return;
-
- case ARRAY_TYPE:
- case SET_TYPE:
- case VECTOR_TYPE:
- /* It's probably overly-conservative to force elaboration of bounds and
- also the sizes, but it's better to be safe than sorry. */
- force_type_save_exprs_1 (TYPE_MIN_VALUE (TYPE_DOMAIN (t)));
- force_type_save_exprs_1 (TYPE_MAX_VALUE (TYPE_DOMAIN (t)));
- break;
-
- case RECORD_TYPE:
- case UNION_TYPE:
- case QUAL_UNION_TYPE:
- for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
- if (TREE_CODE (field) == FIELD_DECL)
- {
- force_type_save_exprs (TREE_TYPE (field));
- force_type_save_exprs_1 (DECL_FIELD_OFFSET (field));
- }
- break;
-
- default:
- break;
- }
-
- force_type_save_exprs_1 (TYPE_SIZE (t));
- force_type_save_exprs_1 (TYPE_SIZE_UNIT (t));
-}
-
-/* Utility routine of above, to verify that SIZE has been elaborated and
- do so it it is a SAVE_EXPR and has not been. */
-
-static void
-force_type_save_exprs_1 (tree size)
-{
- if (size
- && (size = skip_simple_arithmetic (size))
- && TREE_CODE (size) == SAVE_EXPR
- && !SAVE_EXPR_RTL (size))
- expand_expr (size, NULL_RTX, VOIDmode, 0);
-}
\f
#ifndef MAX_FIXED_MODE_SIZE
#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode)
|| TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST))
DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
- /* Should this be controlled by DECL_USER_ALIGN, too? */
- if (maximum_field_alignment != 0)
- DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
- if (! DECL_USER_ALIGN (decl))
+ if (! DECL_USER_ALIGN (decl) && ! DECL_PACKED (decl))
{
/* Some targets (i.e. i386, VMS) limit struct field alignment
to a lower boundary than alignment of variables unless
DECL_ALIGN (decl) = ADJUST_FIELD_ALIGN (decl, DECL_ALIGN (decl));
#endif
}
+
+ /* Should this be controlled by DECL_USER_ALIGN, too? */
+ if (maximum_field_alignment != 0)
+ DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
}
/* Evaluate nonconstant size only once, either now or as soon as safe. */
variable alignment fields in RLI, and return the alignment to give
the FIELD. */
-static unsigned int
+unsigned int
update_alignment_for_field (record_layout_info rli, tree field,
unsigned int known_align)
{
else if (is_bitfield && PCC_BITFIELD_TYPE_MATTERS)
{
/* Named bit-fields cause the entire structure to have the
- alignment implied by their type. */
- if (DECL_NAME (field) != 0)
+ 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);
rli->prev_field = NULL;
}
- rli->offset_align = tree_low_cst (TYPE_SIZE (type), 0);
normalize_rli (rli);
}
if (type == 0)
abort ();
+ if (type == error_mark_node)
+ return;
+
/* Do nothing if type has been laid out before. */
if (TYPE_SIZE (type))
return;
}
/* Gets minimal and maximal values for MODE (signed or unsigned depending on
- SIGN). */
+ SIGN). The returned constants are made to be usable in TARGET_MODE. */
void
-get_mode_bounds (enum machine_mode mode, int sign, rtx *mmin, rtx *mmax)
+get_mode_bounds (enum machine_mode mode, int sign,
+ enum machine_mode target_mode,
+ rtx *mmin, rtx *mmax)
{
- int size = GET_MODE_BITSIZE (mode);
+ unsigned size = GET_MODE_BITSIZE (mode);
+ unsigned HOST_WIDE_INT min_val, max_val;
if (size > HOST_BITS_PER_WIDE_INT)
abort ();
if (sign)
{
- *mmin = GEN_INT (-((unsigned HOST_WIDE_INT) 1 << (size - 1)));
- *mmax = GEN_INT (((unsigned HOST_WIDE_INT) 1 << (size - 1)) - 1);
+ min_val = -((unsigned HOST_WIDE_INT) 1 << (size - 1));
+ max_val = ((unsigned HOST_WIDE_INT) 1 << (size - 1)) - 1;
}
else
{
- *mmin = const0_rtx;
- *mmax = GEN_INT (((unsigned HOST_WIDE_INT) 1 << (size - 1) << 1) - 1);
+ min_val = 0;
+ max_val = ((unsigned HOST_WIDE_INT) 1 << (size - 1) << 1) - 1;
}
+
+ *mmin = GEN_INT (trunc_int_for_mode (min_val, target_mode));
+ *mmax = GEN_INT (trunc_int_for_mode (max_val, target_mode));
}
#include "gt-stor-layout.h"