OSDN Git Service

* uintp.adb (UI_From_Dint): Remove useless code.
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 Apr 2010 10:16:52 +0000 (10:16 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 Apr 2010 10:16:52 +0000 (10:16 +0000)
(UI_From_Int): Likewise.
* uintp.h: Reorder declarations.
(UI_From_gnu): Declare.
(UI_Base): Likewise.
(Vector_Template): Likewise.
(Vector_To_Uint): Likewise.
(Uint_0): Remove.
(Uint_1): Likewise.
* gcc-interface/gigi.h: Tweak comments.
* gcc-interface/cuintp.c (UI_From_gnu): New global function.
* gcc-interface/decl.c (maybe_pad_type): Do not warn if either size
overflows.
(annotate_value) <INTEGER_CST>: Call UI_From_gnu.
* gcc-interface/trans.c (post_error_ne_num): Call post_error_ne.
(post_error_ne_tree): Call UI_From_gnu and post_error_ne.
* gcc-interface/utils.c (max_size) <tcc_binary>: Do not special-case
TYPE_MAX_VALUE.

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

gcc/ada/ChangeLog
gcc/ada/gcc-interface/cuintp.c
gcc/ada/gcc-interface/decl.c
gcc/ada/gcc-interface/gigi.h
gcc/ada/gcc-interface/trans.c
gcc/ada/gcc-interface/utils.c
gcc/ada/uintp.adb
gcc/ada/uintp.h

index a12e7db..802b4d4 100644 (file)
@@ -1,5 +1,26 @@
 2010-04-16  Eric Botcazou  <ebotcazou@adacore.com>
 
+       * uintp.adb (UI_From_Dint): Remove useless code.
+       (UI_From_Int): Likewise.
+       * uintp.h: Reorder declarations.
+       (UI_From_gnu): Declare.
+       (UI_Base): Likewise.
+       (Vector_Template): Likewise.
+       (Vector_To_Uint): Likewise.
+       (Uint_0): Remove.
+       (Uint_1): Likewise.
+       * gcc-interface/gigi.h: Tweak comments.
+       * gcc-interface/cuintp.c (UI_From_gnu): New global function.
+       * gcc-interface/decl.c (maybe_pad_type): Do not warn if either size
+       overflows.
+       (annotate_value) <INTEGER_CST>: Call UI_From_gnu.
+       * gcc-interface/trans.c (post_error_ne_num): Call post_error_ne.
+       (post_error_ne_tree): Call UI_From_gnu and post_error_ne.
+       * gcc-interface/utils.c (max_size) <tcc_binary>: Do not special-case
+       TYPE_MAX_VALUE.
+
+2010-04-16  Eric Botcazou  <ebotcazou@adacore.com>
+
        * gcc-interface/decl.c (make_type_from_size) <INTEGER_TYPE>: Just copy
        TYPE_NAME.
        * gcc-interface/trans.c (smaller_packable_type_p): Rename into...
index 642a71b..31ed801 100644 (file)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                          C Implementation File                           *
  *                                                                          *
- *          Copyright (C) 1992-2009, Free Software Foundation, Inc.         *
+ *          Copyright (C) 1992-2010, Free Software Foundation, Inc.         *
  *                                                                          *
  * GNAT is free software;  you can  redistribute it  and/or modify it under *
  * terms of the  GNU General Public License as published  by the Free Soft- *
@@ -142,3 +142,61 @@ UI_To_gnu (Uint Input, tree type)
 
   return gnu_ret;
 }
+
+/* Similar to UI_From_Int, but take a GCC INTEGER_CST.  We use UI_From_Int
+   when possible, i.e. for a 32-bit signed value, to take advantage of its
+   built-in caching mechanism.  For values of larger magnitude, we compute
+   digits into a vector and call Vector_To_Uint.  */
+
+Uint
+UI_From_gnu (tree Input)
+{
+  tree gnu_type = TREE_TYPE (Input), gnu_base, gnu_temp;
+  /* UI_Base is defined so that 5 Uint digits is sufficient to hold the
+     largest possible signed 64-bit value.  */
+  const int Max_For_Dint = 5;
+  int v[Max_For_Dint], i;
+  Vector_Template temp;
+  Int_Vector vec;
+
+#if HOST_BITS_PER_WIDE_INT == 64
+  /* On 64-bit hosts, host_integerp tells whether the input fits in a
+     signed 64-bit integer.  Then a truncation tells whether it fits
+     in a signed 32-bit integer.  */
+  if (host_integerp (Input, 0))
+    {
+      HOST_WIDE_INT hw_input = TREE_INT_CST_LOW (Input);
+      if (hw_input == (int) hw_input)
+       return UI_From_Int (hw_input);
+    }
+  else
+    return No_Uint;
+#else
+  /* On 32-bit hosts, host_integerp tells whether the input fits in a
+     signed 32-bit integer.  Then a sign test tells whether it fits
+     in a signed 64-bit integer.  */
+  if (host_integerp (Input, 0))
+    return UI_From_Int (TREE_INT_CST_LOW (Input));
+  else if (TREE_INT_CST_HIGH (Input) < 0
+          && TYPE_UNSIGNED (gnu_type)
+          && !(TREE_CODE (gnu_type) == INTEGER_TYPE
+               && TYPE_IS_SIZETYPE (gnu_type)))
+    return No_Uint;
+#endif
+
+  gnu_base = build_int_cst (gnu_type, UI_Base);
+  gnu_temp = Input;
+
+  for (i = Max_For_Dint - 1; i >= 0; i--)
+    {
+      v[i] = tree_low_cst (fold_build1 (ABS_EXPR, gnu_type,
+                                       fold_build2 (TRUNC_MOD_EXPR, gnu_type,
+                                                    gnu_temp, gnu_base)),
+                          0);
+      gnu_temp = fold_build2 (TRUNC_DIV_EXPR, gnu_type, gnu_temp, gnu_base);
+    }
+
+  temp.Low_Bound = 1, temp.High_Bound = Max_For_Dint;
+  vec.Array = v, vec.Bounds = &temp;
+  return Vector_To_Uint (vec, tree_int_cst_sgn (Input) < 0);
+}
index 44c3929..1a42ff7 100644 (file)
@@ -6281,7 +6281,9 @@ maybe_pad_type (tree type, tree size, unsigned int align,
       && !operand_equal_p (size, orig_size, 0)
       && !(TREE_CODE (size) == INTEGER_CST
           && TREE_CODE (orig_size) == INTEGER_CST
-          && tree_int_cst_lt (size, orig_size)))
+          && (TREE_OVERFLOW (size)
+              || TREE_OVERFLOW (orig_size)
+              || tree_int_cst_lt (size, orig_size))))
     {
       Node_Id gnat_error_node = Empty;
 
@@ -7087,7 +7089,7 @@ annotate_value (tree gnu_size)
   TCode tcode;
   Node_Ref_Or_Val ops[3], ret;
   struct tree_int_map **h = NULL;
-  int size, i;
+  int i;
 
   /* See if we've already saved the value for this node.  */
   if (EXPR_P (gnu_size))
@@ -7143,17 +7145,7 @@ annotate_value (tree gnu_size)
          return annotate_value (temp);
        }
 
-      if (!host_integerp (gnu_size, 1))
-       return No_Uint;
-
-      size = tree_low_cst (gnu_size, 1);
-
-      /* This peculiar test is to make sure that the size fits in an int
-        on machines where HOST_WIDE_INT is not "int".  */
-      if (tree_low_cst (gnu_size, 1) == size)
-       return UI_From_Int (size);
-      else
-       return No_Uint;
+      return UI_From_gnu (gnu_size);
 
     case COMPONENT_REF:
       /* The only case we handle here is a simple discriminant reference.  */
index f0c5777..d6101be 100644 (file)
@@ -232,28 +232,25 @@ extern bool Sloc_to_locus (Source_Ptr Sloc, location_t *locus);
 
 /* Post an error message.  MSG is the error message, properly annotated.
    NODE is the node at which to post the error and the node to use for the
-   "&" substitution.  */
+   '&' substitution.  */
 extern void post_error (const char *msg, Node_Id node);
 
-/* Similar, but NODE is the node at which to post the error and ENT
-   is the node to use for the "&" substitution.  */
+/* Similar to post_error, but NODE is the node at which to post the error and
+   ENT is the node to use for the '&' substitution.  */
 extern void post_error_ne (const char *msg, Node_Id node, Entity_Id ent);
 
-/* Similar, but NODE is the node at which to post the error, ENT is the node
-   to use for the "&" substitution, and NUM is the number to use for ^.  */
+/* Similar to post_error_ne, but NUM is the number to use for the '^'.  */
 extern void post_error_ne_num (const char *msg, Node_Id node, Entity_Id ent,
                                int num);
 
-/* Similar to post_error_ne_num, but T is a GCC tree representing the number
-   to write.  If the tree represents a constant that fits within a
-   host integer, the text inside curly brackets in MSG will be output
-   (presumably including a '^').  Otherwise that text will not be output
-   and the text inside square brackets will be output instead.  */
+/* Similar to post_error_ne, but T is a GCC tree representing the number to
+   write.  If T represents a constant, the text inside curly brackets in
+   MSG will be output (presumably including a '^').  Otherwise it will not
+   be output and the text inside square brackets will be output instead.  */
 extern void post_error_ne_tree (const char *msg, Node_Id node, Entity_Id ent,
                                 tree t);
 
-/* Similar to post_error_ne_tree, except that NUM is a second integer to write
-   in the message.  */
+/* Similar to post_error_ne_tree, but NUM is a second integer to write.  */
 extern void post_error_ne_tree_2 (const char *msg, Node_Id node, Entity_Id ent,
                                   tree t, int num);
 
index ee8eedc..7cf15da 100644 (file)
@@ -7404,7 +7404,7 @@ decode_name (const char *name)
 \f
 /* Post an error message.  MSG is the error message, properly annotated.
    NODE is the node at which to post the error and the node to use for the
-   "&" substitution.  */
+   '&' substitution.  */
 
 void
 post_error (const char *msg, Node_Id node)
@@ -7418,8 +7418,8 @@ post_error (const char *msg, Node_Id node)
     Error_Msg_N (fp, node);
 }
 
-/* Similar, but NODE is the node at which to post the error and ENT
-   is the node to use for the "&" substitution.  */
+/* Similar to post_error, but NODE is the node at which to post the error and
+   ENT is the node to use for the '&' substitution.  */
 
 void
 post_error_ne (const char *msg, Node_Id node, Entity_Id ent)
@@ -7433,56 +7433,37 @@ post_error_ne (const char *msg, Node_Id node, Entity_Id ent)
     Error_Msg_NE (fp, node, ent);
 }
 
-/* Similar, but NODE is the node at which to post the error, ENT is the node
-   to use for the "&" substitution, and NUM is the number to use for ^.  */
+/* Similar to post_error_ne, but NUM is the number to use for the '^'.  */
 
 void
 post_error_ne_num (const char *msg, Node_Id node, Entity_Id ent, int num)
 {
-  String_Template temp;
-  Fat_Pointer fp;
-
-  temp.Low_Bound = 1, temp.High_Bound = strlen (msg);
-  fp.Array = msg, fp.Bounds = &temp;
   Error_Msg_Uint_1 = UI_From_Int (num);
-
-  if (Present (node))
-    Error_Msg_NE (fp, node, ent);
+  post_error_ne (msg, node, ent);
 }
 \f
-/* Similar to post_error_ne_num, but T is a GCC tree representing the
-   number to write.  If the tree represents a constant that fits within
-   a host integer, the text inside curly brackets in MSG will be output
-   (presumably including a '^').  Otherwise that text will not be output
-   and the text inside square brackets will be output instead.  */
+/* Similar to post_error_ne, but T is a GCC tree representing the number to
+   write.  If T represents a constant, the text inside curly brackets in
+   MSG will be output (presumably including a '^').  Otherwise it will not
+   be output and the text inside square brackets will be output instead.  */
 
 void
 post_error_ne_tree (const char *msg, Node_Id node, Entity_Id ent, tree t)
 {
-  char *newmsg = XALLOCAVEC (char, strlen (msg) + 1);
-  String_Template temp = {1, 0};
-  Fat_Pointer fp;
+  char *new_msg = XALLOCAVEC (char, strlen (msg) + 1);
   char start_yes, end_yes, start_no, end_no;
   const char *p;
   char *q;
 
-  fp.Array = newmsg, fp.Bounds = &temp;
-
-  if (host_integerp (t, 1)
-#if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_INT
-      &&
-      compare_tree_int
-      (t, (((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_INT - 1)) - 1)) < 0
-#endif
-      )
+  if (TREE_CODE (t) == INTEGER_CST)
     {
-      Error_Msg_Uint_1 = UI_From_Int (tree_low_cst (t, 1));
+      Error_Msg_Uint_1 = UI_From_gnu (t);
       start_yes = '{', end_yes = '}', start_no = '[', end_no = ']';
     }
   else
     start_yes = '[', end_yes = ']', start_no = '{', end_no = '}';
 
-  for (p = msg, q = newmsg; *p; p++)
+  for (p = msg, q = new_msg; *p; p++)
     {
       if (*p == start_yes)
        for (p++; *p != end_yes; p++)
@@ -7496,13 +7477,10 @@ post_error_ne_tree (const char *msg, Node_Id node, Entity_Id ent, tree t)
 
   *q = 0;
 
-  temp.High_Bound = strlen (newmsg);
-  if (Present (node))
-    Error_Msg_NE (fp, node, ent);
+  post_error_ne (new_msg, node, ent);
 }
 
-/* Similar to post_error_ne_tree, except that NUM is a second integer to write
-   in the message.  */
+/* Similar to post_error_ne_tree, but NUM is a second integer to write.  */
 
 void
 post_error_ne_tree_2 (const char *msg, Node_Id node, Entity_Id ent, tree t,
index 27959ea..68a0d0f 100644 (file)
@@ -2228,8 +2228,7 @@ max_size (tree exp, bool max_p)
               In that case, if one side overflows, return the other.
               sizetype is signed, but we know sizes are non-negative.
               Likewise, handle a MINUS_EXPR or PLUS_EXPR with the LHS
-              overflowing or the maximum possible value and the RHS
-              a variable.  */
+              overflowing and the RHS a variable.  */
            if (max_p
                && code == MIN_EXPR
                && TREE_CODE (rhs) == INTEGER_CST
@@ -2241,9 +2240,8 @@ max_size (tree exp, bool max_p)
                     && TREE_OVERFLOW (lhs))
              return rhs;
            else if ((code == MINUS_EXPR || code == PLUS_EXPR)
-                    && ((TREE_CODE (lhs) == INTEGER_CST
-                         && TREE_OVERFLOW (lhs))
-                        || operand_equal_p (lhs, TYPE_MAX_VALUE (type), 0))
+                    && TREE_CODE (lhs) == INTEGER_CST
+                    && TREE_OVERFLOW (lhs)
                     && !TREE_CONSTANT (rhs))
              return lhs;
            else
index 9337721..3b72d15 100644 (file)
@@ -1703,15 +1703,9 @@ package body Uintp is
 
             V : UI_Vector (1 .. Max_For_Dint);
 
-            Temp_Integer : Dint;
+            Temp_Integer : Dint := Input;
 
          begin
-            for J in V'Range loop
-               V (J) := 0;
-            end loop;
-
-            Temp_Integer := Input;
-
             for J in reverse V'Range loop
                V (J) := Int (abs (Temp_Integer rem Dint (Base)));
                Temp_Integer := Temp_Integer / Dint (Base);
@@ -1752,15 +1746,9 @@ package body Uintp is
 
          V : UI_Vector (1 .. Max_For_Int);
 
-         Temp_Integer : Int;
+         Temp_Integer : Int := Input;
 
       begin
-         for J in V'Range loop
-            V (J) := 0;
-         end loop;
-
-         Temp_Integer := Input;
-
          for J in reverse V'Range loop
             V (J) := abs (Temp_Integer rem Base);
             Temp_Integer := Temp_Integer / Base;
index 5921945..de70e11 100644 (file)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                              C Header File                               *
  *                                                                          *
- *            Copyright (C) 1992-2007, Free Software Foundation, Inc.       *
+ *            Copyright (C) 1992-2010, Free Software Foundation, Inc.       *
  *                                                                          *
  * GNAT is free software;  you can  redistribute it  and/or modify it under *
  * terms of the  GNU General Public License as published  by the Free Soft- *
@@ -38,27 +38,42 @@ struct Uint_Entry
 #define UI_Is_In_Int_Range  uintp__ui_is_in_int_range
 extern Boolean UI_Is_In_Int_Range      (Uint);
 
-/* Obtain Char_Code value from Uint input. Value must be in range.  */
+/* Obtain Char_Code value from Uint input.  Value must be in range.  */
 #define UI_To_CC uintp__ui_to_cc
-extern Char_Code UI_To_CC               (Uint);
+extern Char_Code UI_To_CC              (Uint);
 
-/* Obtain Int value from Uint input. This will abort if the result is
-   out of range.  */
+/* Convert a Char_Code into a Uint.  */
+#define UI_From_CC uintp__ui_from_cc
+extern Uint UI_From_CC                 (Char_Code);
+
+/* Obtain Int value from Uint input.  Abort if the result is out of range.  */
 #define UI_To_Int uintp__ui_to_int
 extern Int UI_To_Int                   (Uint);
 
+/* Similarly, but return a GCC INTEGER_CST.  */
+extern tree UI_To_gnu                  (Uint, tree);
+
 /* Convert an Int into a Uint.  */
 #define UI_From_Int uintp__ui_from_int
 extern Uint UI_From_Int                        (int);
 
-/* Convert a Char_Code into a Uint.  */
-#define UI_From_CC uintp__ui_from_cc
-extern Uint UI_From_CC                  (Char_Code);
+/* Similarly, but take a GCC INTEGER_CST.  */
+extern Uint UI_From_gnu                        (tree);
 
-/* Similarly, but return a GCC INTEGER_CST.  Overflow is tested by the
-   constant-folding used to build the node.  TYPE is the GCC type of the
-   resulting node.  */
-extern tree UI_To_gnu                  (Uint, tree);
+/* Uint values are represented as multiple precision integers stored in a
+   multi-digit format using UI_Base as the base.  This value is chosen so
+   that the product UI_Base*UI_Base is within the range of Int values.  */
+#define UI_Base uintp__base
+extern const int UI_Base;
+
+/* Types for the fat pointer of Int vectors and the template it points to.  */
+typedef struct {int Low_Bound, High_Bound; } Vector_Template;
+typedef struct {const int *Array; Vector_Template *Bounds; }
+       __attribute ((aligned (sizeof (char *) * 2))) Int_Vector;
+
+/* Create and return the Uint value from the Int vector.  */
+#define Vector_To_Uint uintp__vector_to_uint
+extern Uint Vector_To_Uint             (Int_Vector, Boolean);
 
 /* Universal integers are represented by the Uint type which is an index into
    the Uints_Ptr table containing Uint_Entry values.  A Uint_Entry contains an
@@ -75,6 +90,3 @@ extern struct Uint_Entry *uintp__uints__table;
 
 #define Udigits_Ptr uintp__udigits__table
 extern int *uintp__udigits__table;
-
-#define Uint_0 (Uint_Direct_Bias + 0)
-#define Uint_1 (Uint_Direct_Bias + 1)