diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2021-05-21 10:19:32 +0200 |
---|---|---|
committer | Eric Botcazou <ebotcazou@adacore.com> | 2021-05-21 10:21:09 +0200 |
commit | e5bfda020425f22b67936e916f0b284bad108b65 (patch) | |
tree | 94903a334e1554905aaffabf984923a4671e4d02 /gcc | |
parent | dcde81134cb24da8e261a4346c806c676297922b (diff) | |
download | gcc-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.c | 2 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/misc.c | 2 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils.c | 25 |
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)); } |