OSDN Git Service

* gcc-interface/gigi.h (enum standard_datatypes): Add new values
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 17 Apr 2010 08:14:08 +0000 (08:14 +0000)
committerMasaki Muranaka <monaka@monami-software.com>
Sun, 23 May 2010 01:04:39 +0000 (10:04 +0900)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158461 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c
gcc/ada/gcc-interface/gigi.h
gcc/ada/gcc-interface/misc.c
gcc/ada/gcc-interface/trans.c
gcc/ada/gcc-interface/utils.c
gcc/ada/gcc-interface/utils2.c

index 2612635..21800d8 100644 (file)
@@ -1,3 +1,28 @@
+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.
+
 2010-04-16  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/gigi.h (gnat_init_decl_processing): Delete.
index 02d7296..b7fd331 100644 (file)
@@ -2115,11 +2115,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
              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_entity, tree gnu_expr, int definition)
                      && 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_range)
 {
   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_range)
             || 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 int align, tree size,
   /* 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 int align, tree size,
 
      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 int align, tree size,
   /* 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 int align, tree size,
      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, unsigned int align,
   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 61baf34..224abe8 100644 (file)
@@ -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[(int) LAST_REASON_CODE + 1];
 #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 1b31890..52fe65a 100644 (file)
@@ -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 7f35bc2..4b7946c 100644 (file)
@@ -1356,15 +1356,9 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
          {
            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 e110ef5..668226b 100644 (file)
@@ -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 33f3a61..ca35cc7 100644 (file)
@@ -260,28 +260,27 @@ compare_arrays (tree result_type, tree a1, tree a2)
     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 a1, tree a2)
          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 a1, tree a2)
          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 a1, tree a2)
       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)
     {