aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2021-05-21 10:19:32 +0200
committerEric Botcazou <ebotcazou@adacore.com>2021-05-21 10:21:09 +0200
commite5bfda020425f22b67936e916f0b284bad108b65 (patch)
tree94903a334e1554905aaffabf984923a4671e4d02 /gcc
parentdcde81134cb24da8e261a4346c806c676297922b (diff)
downloadgcc-e5bfda020425f22b67936e916f0b284bad108b65.zip
gcc-e5bfda020425f22b67936e916f0b284bad108b65.tar.gz
gcc-e5bfda020425f22b67936e916f0b284bad108b65.tar.bz2
Use EXACT_DIV_EXPR as much as possible
...when the division is exact, typically dividing TYPE_SIZE by BITS_PER_UNIT. gcc/ada/ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: Replace CEIL_DIV_EXPR with EXACT_DIV_EXPR. * gcc-interface/misc.c (gnat_type_max_size): Likewise. * gcc-interface/utils.c (maybe_pad_type): Likewise. (finish_record_type): Likewise. And always compute the unit size.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/gcc-interface/decl.c2
-rw-r--r--gcc/ada/gcc-interface/misc.c2
-rw-r--r--gcc/ada/gcc-interface/utils.c25
3 files changed, 14 insertions, 15 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 232b552..a7595cb 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -1343,7 +1343,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
|| (gnu_size
&& !allocatable_size_p (convert (sizetype,
size_binop
- (CEIL_DIV_EXPR, gnu_size,
+ (EXACT_DIV_EXPR, gnu_size,
bitsize_unit_node)),
global_bindings_p ()
|| !definition
diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index f302cf0..72a2624 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -752,7 +752,7 @@ gnat_type_max_size (const_tree gnu_type)
type's alignment and return the result in units. */
if (tree_fits_uhwi_p (max_ada_size))
max_size_unit
- = size_binop (CEIL_DIV_EXPR,
+ = size_binop (EXACT_DIV_EXPR,
round_up (max_ada_size, TYPE_ALIGN (gnu_type)),
bitsize_unit_node);
}
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 80a4160..8539fe4 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -1547,7 +1547,7 @@ maybe_pad_type (tree type, tree size, unsigned int align,
TYPE_SIZE (record) = size ? size : orig_size;
TYPE_SIZE_UNIT (record)
= convert (sizetype,
- size_binop (CEIL_DIV_EXPR, TYPE_SIZE (record),
+ size_binop (EXACT_DIV_EXPR, TYPE_SIZE (record),
bitsize_unit_node));
/* If we are changing the alignment and the input type is a record with
@@ -1970,7 +1970,6 @@ finish_record_type (tree record_type, tree field_list, int rep_level,
{
const enum tree_code orig_code = TREE_CODE (record_type);
const bool had_size = TYPE_SIZE (record_type) != NULL_TREE;
- const bool had_size_unit = TYPE_SIZE_UNIT (record_type) != NULL_TREE;
const bool had_align = TYPE_ALIGN (record_type) > 0;
/* 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. */
@@ -1997,9 +1996,6 @@ finish_record_type (tree record_type, tree field_list, int rep_level,
if (!had_size)
TYPE_SIZE (record_type) = bitsize_zero_node;
-
- if (!had_size_unit)
- TYPE_SIZE_UNIT (record_type) = size_zero_node;
}
else
{
@@ -2155,19 +2151,22 @@ finish_record_type (tree record_type, tree field_list, int rep_level,
/* We need to set the regular sizes if REP_LEVEL is one. */
if (rep_level == 1)
{
+ /* We round TYPE_SIZE and TYPE_SIZE_UNIT up to TYPE_ALIGN separately
+ to avoid having very large masking constants in TYPE_SIZE_UNIT. */
+ const unsigned int align = TYPE_ALIGN (record_type);
+
/* If this is a padding record, we never want to make the size smaller
than what was specified in it, if any. */
- if (TYPE_IS_PADDING_P (record_type) && TYPE_SIZE (record_type))
+ if (TYPE_IS_PADDING_P (record_type) && had_size)
size = TYPE_SIZE (record_type);
-
- tree size_unit = had_size_unit
- ? TYPE_SIZE_UNIT (record_type)
- : convert (sizetype,
- size_binop (CEIL_DIV_EXPR, size,
- bitsize_unit_node));
- const unsigned int align = TYPE_ALIGN (record_type);
+ else
+ size = round_up (size, BITS_PER_UNIT);
TYPE_SIZE (record_type) = variable_size (round_up (size, align));
+
+ tree size_unit
+ = convert (sizetype,
+ size_binop (EXACT_DIV_EXPR, size, bitsize_unit_node));
TYPE_SIZE_UNIT (record_type)
= variable_size (round_up (size_unit, align / BITS_PER_UNIT));
}