This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Remove artificial dependencies on sizetype signedness


This is preparatory work for the switch to unsigned sizetypes.  It removes the 
artificial dependencies on the signedness of sizetypes, so that the remaining 
ones are real.

Tested on x86_64-suse-linux, applied on the mainline.


2010-04-17  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/gigi.h (enum standard_datatypes): Add new values
	ADT_sbitsize_one_node and ADT_sbitsize_unit_node.
	(sbitsize_one_node): New macro.
	(sbitsize_unit_node): Likewise.
	* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Subtype>: Fix
	latent bug in the computation of subrange_p.  Fold wider_p predicate.
	(cannot_be_superflat_p): Use an explicitly signed 64-bit type to do
	the final comparison.
	(make_aligning_type): Build real negation and use sizetype throughout
	the offset computation.
	(maybe_pad_type): Do not issue the warning when the new size expression
	is too complex.
	(annotate_value) <INTEGER_CST>: Simplify code handling negative values.
	* gcc-interface/misc.c (gnat_init): Initialize sbitsize_one_node and
	sbitsize_unit_node.
	* gcc-interface/trans.c (Attribute_to_gnu) <Attr_Pool_Address>: Fold
	double negation.
	(gnat_to_gnu) <N_Free_Statement>: Likewise.
	* gcc-interface/utils.c (convert): Use sbitsize_unit_node.
	* gcc-interface/utils2.c (compare_arrays): Compute real lengths and use
	constants in sizetype.  Remove dead code and tweak comments.  Generate
	equality instead of inequality comparisons for zero length tests.


-- 
Eric Botcazou
Index: gcc-interface/utils.c
===================================================================
--- gcc-interface/utils.c	(revision 158459)
+++ gcc-interface/utils.c	(working copy)
@@ -4066,9 +4066,8 @@ convert (tree type, tree expr)
 	  tree bit_diff
 	    = size_diffop (bit_position (TYPE_FIELDS (TREE_TYPE (etype))),
 			   bit_position (TYPE_FIELDS (TREE_TYPE (type))));
-	  tree byte_diff = size_binop (CEIL_DIV_EXPR, bit_diff,
-				       sbitsize_int (BITS_PER_UNIT));
-
+	  tree byte_diff
+	    = size_binop (CEIL_DIV_EXPR, bit_diff, sbitsize_unit_node);
 	  expr = build1 (NOP_EXPR, type, expr);
 	  TREE_CONSTANT (expr) = TREE_CONSTANT (TREE_OPERAND (expr, 0));
 	  if (integer_zerop (byte_diff))
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c	(revision 158459)
+++ gcc-interface/decl.c	(working copy)
@@ -2115,11 +2115,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 	      const int prec_comp
 		= compare_tree_int (TYPE_RM_SIZE (gnu_index_type),
 				    TYPE_PRECISION (sizetype));
-	      const bool subrange_p = (prec_comp < 0)
-				      || (prec_comp == 0
-					  && TYPE_UNSIGNED (gnu_index_type)
-					     == TYPE_UNSIGNED (sizetype));
-	      const bool wider_p = (prec_comp > 0);
+	      const bool subrange_p = (prec_comp < 0
+				       && (TYPE_UNSIGNED (gnu_index_type)
+					   || !TYPE_UNSIGNED (sizetype)))
+ 				      || (prec_comp == 0
+ 					  && TYPE_UNSIGNED (gnu_index_type)
+ 					     == TYPE_UNSIGNED (sizetype));
 	      tree gnu_orig_min = TYPE_MIN_VALUE (gnu_index_type);
 	      tree gnu_orig_max = TYPE_MAX_VALUE (gnu_index_type);
 	      tree gnu_min = convert (sizetype, gnu_orig_min);
@@ -2298,7 +2299,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 		      && TREE_CODE (TREE_TYPE (gnu_index_type))
 			 != INTEGER_TYPE)
 		  || TYPE_BIASED_REPRESENTATION_P (gnu_index_type)
-		  || wider_p)
+		  || prec_comp > 0)
 		need_index_type_struct = true;
 	    }
 
@@ -5381,7 +5382,7 @@ cannot_be_superflat_p (Node_Id gnat_rang
 {
   Node_Id gnat_lb = Low_Bound (gnat_range), gnat_hb = High_Bound (gnat_range);
   Node_Id scalar_range;
-  tree gnu_lb, gnu_hb;
+  tree gnu_lb, gnu_hb, gnu_lb_minus_one;
 
   /* If the low bound is not constant, try to find an upper bound.  */
   while (Nkind (gnat_lb) != N_Integer_Literal
@@ -5401,19 +5402,23 @@ cannot_be_superflat_p (Node_Id gnat_rang
 	     || Nkind (scalar_range) == N_Range))
     gnat_hb = Low_Bound (scalar_range);
 
-  if (!(Nkind (gnat_lb) == N_Integer_Literal
-	&& Nkind (gnat_hb) == N_Integer_Literal))
+  /* If we have failed to find constant bounds, punt.  */
+  if (Nkind (gnat_lb) != N_Integer_Literal
+      || Nkind (gnat_hb) != N_Integer_Literal)
     return false;
 
-  gnu_lb = UI_To_gnu (Intval (gnat_lb), bitsizetype);
-  gnu_hb = UI_To_gnu (Intval (gnat_hb), bitsizetype);
+  /* We need at least a signed 64-bit type to catch most cases.  */
+  gnu_lb = UI_To_gnu (Intval (gnat_lb), sbitsizetype);
+  gnu_hb = UI_To_gnu (Intval (gnat_hb), sbitsizetype);
+  if (TREE_OVERFLOW (gnu_lb) || TREE_OVERFLOW (gnu_hb))
+    return false;
 
   /* If the low bound is the smallest integer, nothing can be smaller.  */
-  gnu_lb = size_binop (MINUS_EXPR, gnu_lb, bitsize_one_node);
-  if (TREE_OVERFLOW (gnu_lb))
+  gnu_lb_minus_one = size_binop (MINUS_EXPR, gnu_lb, sbitsize_one_node);
+  if (TREE_OVERFLOW (gnu_lb_minus_one))
     return true;
 
-  return (tree_int_cst_lt (gnu_hb, gnu_lb) == 0);
+  return !tree_int_cst_lt (gnu_hb, gnu_lb_minus_one);
 }
 
 /* Return true if GNU_EXPR is (essentially) the address of a CONSTRUCTOR.  */
@@ -5876,7 +5881,6 @@ make_aligning_type (tree type, unsigned
   /* We will be crafting a record type with one field at a position set to be
      the next multiple of ALIGN past record'address + room bytes.  We use a
      record placeholder to express record'address.  */
-
   tree record_type = make_node (RECORD_TYPE);
   tree record = build0 (PLACEHOLDER_EXPR, record_type);
 
@@ -5896,7 +5900,6 @@ make_aligning_type (tree type, unsigned
 
      Every length is in sizetype bytes there, except "pos" which has to be
      set as a bit position in the GCC tree for the record.  */
-
   tree room_st = size_int (room);
   tree vblock_addr_st = size_binop (PLUS_EXPR, record_addr_st, room_st);
   tree voffset_st, pos, field;
@@ -5911,13 +5914,11 @@ make_aligning_type (tree type, unsigned
   /* Compute VOFFSET and then POS.  The next byte position multiple of some
      alignment after some address is obtained by "and"ing the alignment minus
      1 with the two's complement of the address.   */
-
   voffset_st = size_binop (BIT_AND_EXPR,
-			   size_diffop (size_zero_node, vblock_addr_st),
-			   ssize_int ((align / BITS_PER_UNIT) - 1));
+			   fold_build1 (NEGATE_EXPR, sizetype, vblock_addr_st),
+			   size_int ((align / BITS_PER_UNIT) - 1));
 
   /* POS = (ROOM + VOFFSET) * BIT_PER_UNIT, in bitsizetype.  */
-
   pos = size_binop (MULT_EXPR,
 		    convert (bitsizetype,
 			     size_binop (PLUS_EXPR, room_st, voffset_st)),
@@ -5936,7 +5937,6 @@ make_aligning_type (tree type, unsigned
      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);
   TYPE_FIELDS (record_type) = field;
@@ -6287,6 +6287,7 @@ maybe_pad_type (tree type, tree size, un
   if (Present (gnat_entity)
       && size
       && TREE_CODE (size) != MAX_EXPR
+      && TREE_CODE (size) != COND_EXPR
       && !operand_equal_p (size, orig_size, 0)
       && !(TREE_CODE (size) == INTEGER_CST
 	   && TREE_CODE (orig_size) == INTEGER_CST
@@ -7123,33 +7124,16 @@ annotate_value (tree gnu_size)
       if (TREE_OVERFLOW (gnu_size))
 	return No_Uint;
 
-      /* This may have come from a conversion from some smaller type,
-	 so ensure this is in bitsizetype.  */
+      /* This may come from a conversion from some smaller type, so ensure
+	 this is in bitsizetype.  */
       gnu_size = convert (bitsizetype, gnu_size);
 
-      /* For negative values, use NEGATE_EXPR of the supplied value.  */
+      /* For a negative value, use NEGATE_EXPR of the opposite.  Such values
+	 appear in expressions containing aligning patterns.  */
       if (tree_int_cst_sgn (gnu_size) < 0)
 	{
-	  /* The ridiculous code below is to handle the case of the largest
-	     negative integer.  */
-	  tree negative_size = size_diffop (bitsize_zero_node, gnu_size);
-	  bool adjust = false;
-	  tree temp;
-
-	  if (TREE_OVERFLOW (negative_size))
-	    {
-	      negative_size
-		= size_binop (MINUS_EXPR, bitsize_zero_node,
-			      size_binop (PLUS_EXPR, gnu_size,
-					  bitsize_one_node));
-	      adjust = true;
-	    }
-
-	  temp = build1 (NEGATE_EXPR, bitsizetype, negative_size);
-	  if (adjust)
-	    temp = build2 (MINUS_EXPR, bitsizetype, temp, bitsize_one_node);
-
-	  return annotate_value (temp);
+	  tree op_size = fold_build1 (NEGATE_EXPR, bitsizetype, gnu_size);
+	  return annotate_value (build1 (NEGATE_EXPR, bitsizetype, op_size));
 	}
 
       return UI_From_gnu (gnu_size);
Index: gcc-interface/utils2.c
===================================================================
--- gcc-interface/utils2.c	(revision 158459)
+++ gcc-interface/utils2.c	(working copy)
@@ -260,28 +260,27 @@ compare_arrays (tree result_type, tree a
     a2 = gnat_protect_expr (a2);
 
   /* Process each dimension separately and compare the lengths.  If any
-     dimension has a size known to be zero, set SIZE_ZERO_P to 1 to
-     suppress the comparison of the data.  */
+     dimension has a length known to be zero, set LENGTH_ZERO_P to true
+     in order to suppress the comparison of the data at the end.  */
   while (TREE_CODE (t1) == ARRAY_TYPE && TREE_CODE (t2) == ARRAY_TYPE)
     {
       tree lb1 = TYPE_MIN_VALUE (TYPE_DOMAIN (t1));
       tree ub1 = TYPE_MAX_VALUE (TYPE_DOMAIN (t1));
       tree lb2 = TYPE_MIN_VALUE (TYPE_DOMAIN (t2));
       tree ub2 = TYPE_MAX_VALUE (TYPE_DOMAIN (t2));
-      tree bt = get_base_type (TREE_TYPE (lb1));
-      tree length1 = fold_build2 (MINUS_EXPR, bt, ub1, lb1);
-      tree length2 = fold_build2 (MINUS_EXPR, bt, ub2, lb2);
+      tree length1 = size_binop (PLUS_EXPR, size_binop (MINUS_EXPR, ub1, lb1),
+				 size_one_node);
+      tree length2 = size_binop (PLUS_EXPR, size_binop (MINUS_EXPR, ub2, lb2),
+				 size_one_node);
       tree comparison, this_a1_is_null, this_a2_is_null;
-      tree nbt, tem;
-      bool btem;
 
       /* If the length of the first array is a constant, swap our operands
-	 unless the length of the second array is the constant zero.
-	 Note that we have set the `length' values to the length - 1.  */
-      if (TREE_CODE (length1) == INTEGER_CST
-	  && !integer_zerop (fold_build2 (PLUS_EXPR, bt, length2,
-					  convert (bt, integer_one_node))))
+	 unless the length of the second array is the constant zero.  */
+      if (TREE_CODE (length1) == INTEGER_CST && !integer_zerop (length2))
 	{
+	  tree tem;
+	  bool btem;
+
 	  tem = a1, a1 = a2, a2 = tem;
 	  tem = t1, t1 = t2, t2 = tem;
 	  tem = lb1, lb1 = lb2, lb2 = tem;
@@ -292,57 +291,56 @@ compare_arrays (tree result_type, tree a
 	  a2_side_effects_p = btem;
 	}
 
-      /* If the length of this dimension in the second array is the constant
-	 zero, we can just go inside the original bounds for the first
-	 array and see if last < first.  */
-      if (integer_zerop (fold_build2 (PLUS_EXPR, bt, length2,
-				      convert (bt, integer_one_node))))
+      /* If the length of the second array is the constant zero, we can just
+	 use the original stored bounds for the first array and see whether
+	 last < first holds.  */
+      if (integer_zerop (length2))
 	{
-	  tree ub = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
-	  tree lb = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
+	  length_zero_p = true;
 
-	  comparison = build_binary_op (LT_EXPR, result_type, ub, lb);
+	  ub1 = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
+	  lb1 = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
+
+	  comparison = build_binary_op (LT_EXPR, result_type, ub1, lb1);
 	  comparison = SUBSTITUTE_PLACEHOLDER_IN_EXPR (comparison, a1);
 	  if (EXPR_P (comparison))
 	    SET_EXPR_LOCATION (comparison, input_location);
 
-	  length1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length1, a1);
-
-	  length_zero_p = true;
 	  this_a1_is_null = comparison;
 	  this_a2_is_null = convert (result_type, boolean_true_node);
 	}
 
-      /* If the length is some other constant value, we know that the
-	 this dimension in the first array cannot be superflat, so we
-	 can just use its length from the actual stored bounds.  */
+      /* Otherwise, if the length is some other constant value, we know that
+	 this dimension in the second array cannot be superflat, so we can
+	 just use its length computed from the actual stored bounds.  */
       else if (TREE_CODE (length2) == INTEGER_CST)
 	{
+	  tree bt;
+
 	  ub1 = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
 	  lb1 = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t1)));
 	  /* Note that we know that UB2 and LB2 are constant and hence
 	     cannot contain a PLACEHOLDER_EXPR.  */
 	  ub2 = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t2)));
 	  lb2 = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (t2)));
-	  nbt = get_base_type (TREE_TYPE (ub1));
+	  bt = get_base_type (TREE_TYPE (ub1));
 
 	  comparison
 	    = build_binary_op (EQ_EXPR, result_type,
-			       build_binary_op (MINUS_EXPR, nbt, ub1, lb1),
-			       build_binary_op (MINUS_EXPR, nbt, ub2, lb2));
+			       build_binary_op (MINUS_EXPR, bt, ub1, lb1),
+			       build_binary_op (MINUS_EXPR, bt, ub2, lb2));
 	  comparison = SUBSTITUTE_PLACEHOLDER_IN_EXPR (comparison, a1);
 	  if (EXPR_P (comparison))
 	    SET_EXPR_LOCATION (comparison, input_location);
 
-	  length1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length1, a1);
-
 	  this_a1_is_null = build_binary_op (LT_EXPR, result_type, ub1, lb1);
 	  if (EXPR_P (this_a1_is_null))
 	    SET_EXPR_LOCATION (this_a1_is_null, input_location);
+
 	  this_a2_is_null = convert (result_type, boolean_false_node);
 	}
 
-      /* Otherwise compare the computed lengths.  */
+      /* Otherwise, compare the computed lengths.  */
       else
 	{
 	  length1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length1, a1);
@@ -353,24 +351,24 @@ compare_arrays (tree result_type, tree a
 	  if (EXPR_P (comparison))
 	    SET_EXPR_LOCATION (comparison, input_location);
 
-	  this_a1_is_null
-	    = build_binary_op (LT_EXPR, result_type, length1,
-			       convert (bt, integer_zero_node));
+	  this_a1_is_null = build_binary_op (EQ_EXPR, result_type, length1,
+					     size_zero_node);
 	  if (EXPR_P (this_a1_is_null))
 	    SET_EXPR_LOCATION (this_a1_is_null, input_location);
 
-	  this_a2_is_null
-	    = build_binary_op (LT_EXPR, result_type, length2,
-			       convert (bt, integer_zero_node));
+	  this_a2_is_null = build_binary_op (EQ_EXPR, result_type, length2,
+					     size_zero_node);
 	  if (EXPR_P (this_a2_is_null))
 	    SET_EXPR_LOCATION (this_a2_is_null, input_location);
 	}
 
+      /* Append expressions for this dimension to the final expressions.  */
       result = build_binary_op (TRUTH_ANDIF_EXPR, result_type,
 				result, comparison);
 
       a1_is_null = build_binary_op (TRUTH_ORIF_EXPR, result_type,
 				    this_a1_is_null, a1_is_null);
+
       a2_is_null = build_binary_op (TRUTH_ORIF_EXPR, result_type,
 				    this_a2_is_null, a2_is_null);
 
@@ -378,7 +376,7 @@ compare_arrays (tree result_type, tree a
       t2 = TREE_TYPE (t2);
     }
 
-  /* Unless the size of some bound is known to be zero, compare the
+  /* Unless the length of some dimension is known to be zero, compare the
      data in the array.  */
   if (!length_zero_p)
     {
Index: gcc-interface/gigi.h
===================================================================
--- gcc-interface/gigi.h	(revision 158459)
+++ gcc-interface/gigi.h	(working copy)
@@ -356,9 +356,15 @@ enum standard_datatypes
   /* Type declaration node  <==> typedef virtual void *T() */
   ADT_fdesc_type,
 
-  /* Null pointer for above type */
+  /* Null pointer for above type.  */
   ADT_null_fdesc,
 
+  /* Value 1 in signed bitsizetype.  */
+  ADT_sbitsize_one_node,
+
+  /* Value BITS_PER_UNIT in signed bitsizetype.  */
+  ADT_sbitsize_unit_node,
+
   /* Function declaration nodes for run-time functions for allocating memory.
      Ada allocators cause calls to these functions to be generated.  Malloc32
      is used only on 64bit systems needing to allocate 32bit memory.  */
@@ -401,6 +407,8 @@ extern GTY(()) tree gnat_raise_decls[(in
 #define ptr_void_ftype gnat_std_decls[(int) ADT_ptr_void_ftype]
 #define fdesc_type_node gnat_std_decls[(int) ADT_fdesc_type]
 #define null_fdesc_node gnat_std_decls[(int) ADT_null_fdesc]
+#define sbitsize_one_node gnat_std_decls[(int) ADT_sbitsize_one_node]
+#define sbitsize_unit_node gnat_std_decls[(int) ADT_sbitsize_unit_node]
 #define malloc_decl gnat_std_decls[(int) ADT_malloc_decl]
 #define malloc32_decl gnat_std_decls[(int) ADT_malloc32_decl]
 #define free_decl gnat_std_decls[(int) ADT_free_decl]
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 158459)
+++ gcc-interface/trans.c	(working copy)
@@ -1356,15 +1356,9 @@ Attribute_to_gnu (Node_Id gnat_node, tre
 	  {
 	    tree gnu_char_ptr_type = build_pointer_type (char_type_node);
 	    tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type));
-	    tree gnu_byte_offset
-	      = convert (sizetype,
-			 size_diffop (size_zero_node, gnu_pos));
-	    gnu_byte_offset
-	      = fold_build1 (NEGATE_EXPR, sizetype, gnu_byte_offset);
-
 	    gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr);
 	    gnu_ptr = build_binary_op (POINTER_PLUS_EXPR, gnu_char_ptr_type,
-				       gnu_ptr, gnu_byte_offset);
+				       gnu_ptr, gnu_pos);
 	  }
 
 	gnu_result = convert (gnu_result_type, gnu_ptr);
@@ -5399,15 +5393,9 @@ gnat_to_gnu (Node_Id gnat_node)
 	    {
 	      tree gnu_char_ptr_type = build_pointer_type (char_type_node);
 	      tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type));
-	      tree gnu_byte_offset
-		= convert (sizetype,
-			   size_diffop (size_zero_node, gnu_pos));
-	      gnu_byte_offset
-		= fold_build1 (NEGATE_EXPR, sizetype, gnu_byte_offset);
-
 	      gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr);
 	      gnu_ptr = build_binary_op (POINTER_PLUS_EXPR, gnu_char_ptr_type,
-					 gnu_ptr, gnu_byte_offset);
+					 gnu_ptr, gnu_pos);
 	    }
 
 	  gnu_result
Index: gcc-interface/misc.c
===================================================================
--- gcc-interface/misc.c	(revision 158459)
+++ gcc-interface/misc.c	(working copy)
@@ -407,6 +407,8 @@ gnat_init (void)
   SET_TYPE_RM_SIZE (boolean_type_node, bitsize_int (1));
 
   build_common_tree_nodes_2 (0);
+  sbitsize_one_node = sbitsize_int (1);
+  sbitsize_unit_node = sbitsize_int (BITS_PER_UNIT);
   boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
 
   ptr_void_type_node = build_pointer_type (void_type_node);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]