decl.c (maybe_pad_type): Use TYPE_SIZE_UNIT of the input type for TYPE_SIZE_UNIT of result type if...
* decl.c (maybe_pad_type): Use TYPE_SIZE_UNIT of the input type for TYPE_SIZE_UNIT of result type if SIZE is not specified. (make_aligning_type): Pass -1 as ADDRESSABLE to prevent the creation of a bitfield, which we know is useless and causes trouble because of alignment implications. * utils.c (create_var_decl): Set DECL_COMMON again on targets without BSS sections. (process_attributes): Clear DECL_COMMON again when a section attribute is present. (finish_record_type): Independently track if RECORD_TYPE has SIZE and/or SIZE_UNIT already set and use to compute final SIZE and SIZE_UNIT. (create_field_decl): Special case ADDRESSABLE negative to mean "no bitfield creation", to be used by make_aligning_type. Don't restrict bitfield creation to !ADDRESSABLE any more, as some BLKmode fields claimed addressable still have to be bitfields. Use value_factor_p instead of a raw binop construction to check for the position's alignment. From-SVN: r91879
This commit is contained in:
parent
a4c1cd8065
commit
0da07eae29
|
@ -4618,7 +4618,6 @@ make_aligning_type (tree type, int align, tree size)
|
||||||
/* The bit position is obtained by "and"ing the alignment minus 1
|
/* The bit position is obtained by "and"ing the alignment minus 1
|
||||||
with the two's complement of the address and multiplying
|
with the two's complement of the address and multiplying
|
||||||
by the number of bits per unit. Do all this in sizetype. */
|
by the number of bits per unit. Do all this in sizetype. */
|
||||||
|
|
||||||
pos = size_binop (MULT_EXPR,
|
pos = size_binop (MULT_EXPR,
|
||||||
convert (bitsizetype,
|
convert (bitsizetype,
|
||||||
size_binop (BIT_AND_EXPR,
|
size_binop (BIT_AND_EXPR,
|
||||||
|
@ -4628,9 +4627,13 @@ make_aligning_type (tree type, int align, tree size)
|
||||||
- 1))),
|
- 1))),
|
||||||
bitsize_unit_node);
|
bitsize_unit_node);
|
||||||
|
|
||||||
field = create_field_decl (get_identifier ("F"), type, record_type,
|
/* Create the field, with -1 as the 'addressable' indication to avoid the
|
||||||
1, size, pos, 1);
|
creation of a bitfield. We don't need one, it would have damaging
|
||||||
DECL_BIT_FIELD (field) = 0;
|
consequences on the alignment computation, and create_field_decl would
|
||||||
|
make one without this special argument, for instance because of the
|
||||||
|
complex position expression. */
|
||||||
|
field = create_field_decl (get_identifier ("F"), type, record_type, 1, size,
|
||||||
|
pos, -1);
|
||||||
|
|
||||||
finish_record_type (record_type, field, true, false);
|
finish_record_type (record_type, field, true, false);
|
||||||
TYPE_ALIGN (record_type) = BIGGEST_ALIGNMENT;
|
TYPE_ALIGN (record_type) = BIGGEST_ALIGNMENT;
|
||||||
|
@ -4822,9 +4825,10 @@ maybe_pad_type (tree type, tree size, unsigned int align,
|
||||||
DECL_INTERNAL_P (field) = 1;
|
DECL_INTERNAL_P (field) = 1;
|
||||||
TYPE_SIZE (record) = size ? size : orig_size;
|
TYPE_SIZE (record) = size ? size : orig_size;
|
||||||
TYPE_SIZE_UNIT (record)
|
TYPE_SIZE_UNIT (record)
|
||||||
= convert (sizetype,
|
= (size ? convert (sizetype,
|
||||||
size_binop (CEIL_DIV_EXPR, TYPE_SIZE (record),
|
size_binop (CEIL_DIV_EXPR, size, bitsize_unit_node))
|
||||||
bitsize_unit_node));
|
: TYPE_SIZE_UNIT (type));
|
||||||
|
|
||||||
TYPE_ALIGN (record) = align;
|
TYPE_ALIGN (record) = align;
|
||||||
TYPE_IS_PADDING_P (record) = 1;
|
TYPE_IS_PADDING_P (record) = 1;
|
||||||
TYPE_VOLATILE (record)
|
TYPE_VOLATILE (record)
|
||||||
|
|
|
@ -740,6 +740,8 @@ finish_record_type (tree record_type, tree fieldlist, bool has_rep,
|
||||||
tree ada_size = bitsize_zero_node;
|
tree ada_size = bitsize_zero_node;
|
||||||
tree size = bitsize_zero_node;
|
tree size = bitsize_zero_node;
|
||||||
bool var_size = false;
|
bool var_size = false;
|
||||||
|
bool had_size = TYPE_SIZE (record_type) != 0;
|
||||||
|
bool had_size_unit = TYPE_SIZE_UNIT (record_type) != 0;
|
||||||
tree field;
|
tree field;
|
||||||
|
|
||||||
TYPE_FIELDS (record_type) = fieldlist;
|
TYPE_FIELDS (record_type) = fieldlist;
|
||||||
|
@ -757,11 +759,12 @@ finish_record_type (tree record_type, tree fieldlist, bool has_rep,
|
||||||
{
|
{
|
||||||
TYPE_ALIGN (record_type) = MAX (BITS_PER_UNIT, TYPE_ALIGN (record_type));
|
TYPE_ALIGN (record_type) = MAX (BITS_PER_UNIT, TYPE_ALIGN (record_type));
|
||||||
TYPE_MODE (record_type) = BLKmode;
|
TYPE_MODE (record_type) = BLKmode;
|
||||||
if (!TYPE_SIZE (record_type))
|
|
||||||
{
|
if (!had_size_unit)
|
||||||
TYPE_SIZE (record_type) = bitsize_zero_node;
|
|
||||||
TYPE_SIZE_UNIT (record_type) = size_zero_node;
|
TYPE_SIZE_UNIT (record_type) = size_zero_node;
|
||||||
}
|
|
||||||
|
if (!had_size)
|
||||||
|
TYPE_SIZE (record_type) = bitsize_zero_node;
|
||||||
/* For all-repped records with a size specified, lay the QUAL_UNION_TYPE
|
/* For all-repped records with a size specified, lay the QUAL_UNION_TYPE
|
||||||
out just like a UNION_TYPE, since the size will be fixed. */
|
out just like a UNION_TYPE, since the size will be fixed. */
|
||||||
else if (code == QUAL_UNION_TYPE)
|
else if (code == QUAL_UNION_TYPE)
|
||||||
|
@ -881,18 +884,14 @@ finish_record_type (tree record_type, tree fieldlist, bool has_rep,
|
||||||
|
|
||||||
if (has_rep)
|
if (has_rep)
|
||||||
{
|
{
|
||||||
if (!(TREE_CODE (record_type) == RECORD_TYPE
|
tree size_unit
|
||||||
&& TYPE_IS_PADDING_P (record_type)
|
= (had_size_unit ? TYPE_SIZE_UNIT (record_type)
|
||||||
&& CONTAINS_PLACEHOLDER_P (size)))
|
: convert (sizetype, size_binop (CEIL_DIV_EXPR, size,
|
||||||
{
|
bitsize_unit_node)));
|
||||||
tree size_unit
|
|
||||||
= convert (sizetype, size_binop (CEIL_DIV_EXPR, size,
|
TYPE_SIZE (record_type) = round_up (size, TYPE_ALIGN (record_type));
|
||||||
bitsize_unit_node));
|
TYPE_SIZE_UNIT (record_type)
|
||||||
TYPE_SIZE (record_type) = round_up (size, TYPE_ALIGN (record_type));
|
= round_up (size_unit, TYPE_ALIGN (record_type) / BITS_PER_UNIT);
|
||||||
TYPE_SIZE_UNIT (record_type)
|
|
||||||
= round_up (size_unit,
|
|
||||||
TYPE_ALIGN (record_type) / BITS_PER_UNIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
compute_record_mode (record_type);
|
compute_record_mode (record_type);
|
||||||
}
|
}
|
||||||
|
@ -1339,6 +1338,13 @@ create_var_decl (tree var_name, tree asm_name, tree type, tree var_init,
|
||||||
|| (type_annotate_only && var_init && !TREE_CONSTANT (var_init)))
|
|| (type_annotate_only && var_init && !TREE_CONSTANT (var_init)))
|
||||||
var_init = NULL_TREE;
|
var_init = NULL_TREE;
|
||||||
|
|
||||||
|
/* Ada doesn't feature Fortran-like COMMON variables so we shouldn't
|
||||||
|
try to fiddle with DECL_COMMON. However, on platforms that don't
|
||||||
|
support global BSS sections, uninitialized global variables would
|
||||||
|
go in DATA instead, thus increasing the size of the executable. */
|
||||||
|
#if !defined(ASM_OUTPUT_BSS) && !defined(ASM_OUTPUT_ALIGNED_BSS)
|
||||||
|
DECL_COMMON (var_decl) = !flag_no_common;
|
||||||
|
#endif
|
||||||
DECL_INITIAL (var_decl) = var_init;
|
DECL_INITIAL (var_decl) = var_init;
|
||||||
TREE_READONLY (var_decl) = const_flag;
|
TREE_READONLY (var_decl) = const_flag;
|
||||||
DECL_EXTERNAL (var_decl) = extern_flag;
|
DECL_EXTERNAL (var_decl) = extern_flag;
|
||||||
|
@ -1376,7 +1382,8 @@ create_var_decl (tree var_name, tree asm_name, tree type, tree var_init,
|
||||||
this field is in a record type with a "pragma pack". If SIZE is nonzero
|
this field is in a record type with a "pragma pack". If SIZE is nonzero
|
||||||
it is the specified size for this field. If POS is nonzero, it is the bit
|
it is the specified size for this field. If POS is nonzero, it is the bit
|
||||||
position. If ADDRESSABLE is nonzero, it means we are allowed to take
|
position. If ADDRESSABLE is nonzero, it means we are allowed to take
|
||||||
the address of this field for aliasing purposes. */
|
the address of this field for aliasing purposes. If it is negative, we
|
||||||
|
should not make a bitfield, which is used by make_aligning_type. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
create_field_decl (tree field_name, tree field_type, tree record_type,
|
create_field_decl (tree field_name, tree field_type, tree record_type,
|
||||||
|
@ -1410,13 +1417,13 @@ create_field_decl (tree field_name, tree field_type, tree record_type,
|
||||||
size = round_up (size, BITS_PER_UNIT);
|
size = round_up (size, BITS_PER_UNIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make a bitfield if a size is specified for two reasons: first if the size
|
/* If we may, according to ADDRESSABLE, make a bitfield if a size is
|
||||||
differs from the natural size. Second, if the alignment is insufficient.
|
specified for two reasons: first if the size differs from the natural
|
||||||
There are a number of ways the latter can be true.
|
size. Second, if the alignment is insufficient. There are a number of
|
||||||
|
ways the latter can be true.
|
||||||
|
|
||||||
We never make a bitfield if the type of the field has a nonconstant size,
|
We never make a bitfield if the type of the field has a nonconstant size,
|
||||||
or if it is claimed to be addressable, because no such entity requiring
|
because no such entity requiring bitfield operations should reach here.
|
||||||
bitfield operations should reach here.
|
|
||||||
|
|
||||||
We do *preventively* make a bitfield when there might be the need for it
|
We do *preventively* make a bitfield when there might be the need for it
|
||||||
but we don't have all the necessary information to decide, as is the case
|
but we don't have all the necessary information to decide, as is the case
|
||||||
|
@ -1424,15 +1431,13 @@ create_field_decl (tree field_name, tree field_type, tree record_type,
|
||||||
|
|
||||||
We also don't look at STRICT_ALIGNMENT here, and rely on later processing
|
We also don't look at STRICT_ALIGNMENT here, and rely on later processing
|
||||||
in layout_decl or finish_record_type to clear the bit_field indication if
|
in layout_decl or finish_record_type to clear the bit_field indication if
|
||||||
it is in fact not needed. */
|
it is in fact not needed. */
|
||||||
if (size && TREE_CODE (size) == INTEGER_CST
|
if (addressable >= 0
|
||||||
|
&& size
|
||||||
|
&& TREE_CODE (size) == INTEGER_CST
|
||||||
&& TREE_CODE (TYPE_SIZE (field_type)) == INTEGER_CST
|
&& TREE_CODE (TYPE_SIZE (field_type)) == INTEGER_CST
|
||||||
&& !addressable
|
|
||||||
&& (!operand_equal_p (TYPE_SIZE (field_type), size, 0)
|
&& (!operand_equal_p (TYPE_SIZE (field_type), size, 0)
|
||||||
|| (pos
|
|| (pos && !value_factor_p (pos, TYPE_ALIGN (field_type)))
|
||||||
&& !value_zerop (size_binop (TRUNC_MOD_EXPR, pos,
|
|
||||||
bitsize_int (TYPE_ALIGN
|
|
||||||
(field_type)))))
|
|
||||||
|| packed
|
|| packed
|
||||||
|| (TYPE_ALIGN (record_type) != 0
|
|| (TYPE_ALIGN (record_type) != 0
|
||||||
&& TYPE_ALIGN (record_type) < TYPE_ALIGN (field_type))))
|
&& TYPE_ALIGN (record_type) < TYPE_ALIGN (field_type))))
|
||||||
|
@ -1588,6 +1593,7 @@ process_attributes (tree decl, struct attrib *attr_list)
|
||||||
DECL_SECTION_NAME (decl)
|
DECL_SECTION_NAME (decl)
|
||||||
= build_string (IDENTIFIER_LENGTH (attr_list->name),
|
= build_string (IDENTIFIER_LENGTH (attr_list->name),
|
||||||
IDENTIFIER_POINTER (attr_list->name));
|
IDENTIFIER_POINTER (attr_list->name));
|
||||||
|
DECL_COMMON (decl) = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
post_error ("?section attributes are not supported for this target",
|
post_error ("?section attributes are not supported for this target",
|
||||||
|
|
Loading…
Reference in New Issue