diff mbox series

[Ada] Use EXACT_DIV_EXPR as much as possible

Message ID 2775265.e9J7NaK4W3@fomalhaut
State New
Headers show
Series [Ada] Use EXACT_DIV_EXPR as much as possible | expand

Commit Message

Eric Botcazou May 21, 2021, 8:21 a.m. UTC
...when the division is exact, typically dividing TYPE_SIZE by BITS_PER_UNIT.

Tested on x86-64/Linux, applied on the mainline.


2021-05-21  Eric Botcazou  <ebotcazou@adacore.com>

	* 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.
diff mbox series

Patch

diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 232b552a60c..a7595cbf514 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 f302cf0a6f0..72a2624b9da 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 80a4160adf3..8539fe497e1 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));
     }