This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Remove fit_double_type
- From: Anatoly Sokolov <aesok at post dot ru>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Richard Guenther <richard dot guenther at gmail dot com>
- Date: Sun, 4 Jul 2010 15:01:34 +0400
- Subject: [PATCH] Remove fit_double_type
Hi.
This patch remove fit_double_type function from the GCC. It can be replaced
by double_int_fits_to_tree_p when it is used for test of that constant fits
into range of type and by double_int_ext when it is used for truncate or
sign-extend constant to type precision.
Bootstrapped/regtested on x86_64-unknown-linux-gnu.
OK for mainline?
* double-int.h (fit_double_type): Remove declaration.
* double-int.c (fit_double_type): Remove function.
* tree.h (int_fits_type_p): Adjust prototype.
* tree.c (int_fits_type_p): Return bool. Use double_int_fits_to_tree_p
instead of fit_double_type.
(build_int_cst_type): Use double_int_to_tree and shwi_to_double_int
instead of fit_double_type and build_int_cst_wide.
* builtins.c (): Use double_int_fits_to_tree_p and double_int_to_tree
instead of fit_double_type and build_int_cst_wide.
(fold_builtin_object_size): Use double_int_fits_to_tree_p instead
of fit_double_type.
Index: gcc/tree.c
===================================================================
--- gcc/tree.c (revision 161718)
+++ gcc/tree.c (working copy)
@@ -1049,14 +1049,9 @@
tree
build_int_cst_type (tree type, HOST_WIDE_INT low)
{
- unsigned HOST_WIDE_INT low1;
- HOST_WIDE_INT hi;
-
gcc_assert (type);
- fit_double_type (low, low < 0 ? -1 : 0, &low1, &hi, type);
-
- return build_int_cst_wide (type, low1, hi);
+ return double_int_to_tree (type, shwi_to_double_int (low));
}
/* Constructs tree in type TYPE from with value given by CST. Signedness
@@ -7886,7 +7881,7 @@
/* Nonzero if integer constant C has a value that is permissible
for type TYPE (an INTEGER_TYPE). */
-int
+bool
int_fits_type_p (const_tree c, const_tree type)
{
tree type_low_bound, type_high_bound;
@@ -7915,7 +7910,7 @@
/* If at least one bound of the type is a constant integer, we can check
ourselves and maybe make a decision. If no such decision is possible, but
this type is a subtype, try checking against that. Otherwise, use
- fit_double_type, which checks against the precision.
+ double_int_fits_to_tree_p, which checks against the precision.
Compute the status for each possibly constant bound, and return if we see
one does not match. Use ok_for_xxx_bound for this purpose, assigning -1
@@ -7936,12 +7931,12 @@
int t_neg = (unsc && double_int_negative_p (dd));
if (c_neg && !t_neg)
- return 0;
+ return false;
if ((c_neg || !t_neg) && double_int_ucmp (dc, dd) < 0)
- return 0;
+ return false;
}
else if (double_int_cmp (dc, dd, unsc) < 0)
- return 0;
+ return false;
ok_for_low_bound = true;
}
else
@@ -7961,12 +7956,12 @@
int t_neg = (unsc && double_int_negative_p (dd));
if (t_neg && !c_neg)
- return 0;
+ return false;
if ((t_neg || !c_neg) && double_int_ucmp (dc, dd) > 0)
- return 0;
+ return false;
}
else if (double_int_cmp (dc, dd, unsc) > 0)
- return 0;
+ return false;
ok_for_high_bound = true;
}
else
@@ -7974,17 +7969,17 @@
/* If the constant fits both bounds, the result is known. */
if (ok_for_low_bound && ok_for_high_bound)
- return 1;
+ return true;
/* Perform some generic filtering which may allow making a decision
even if the bounds are not constant. First, negative integers
never fit in unsigned types, */
if (TYPE_UNSIGNED (type) && !unsc && double_int_negative_p (dc))
- return 0;
+ return false;
/* Second, narrower types always fit in wider ones. */
if (TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (c)))
- return 1;
+ return true;
/* Third, unsigned integers with top bit set never fit signed types. */
if (! TYPE_UNSIGNED (type) && unsc)
@@ -7993,11 +7988,11 @@
if (prec < HOST_BITS_PER_WIDE_INT)
{
if (((((unsigned HOST_WIDE_INT) 1) << prec) & dc.low) != 0)
- return 0;
+ return false;
}
else if (((((unsigned HOST_WIDE_INT) 1)
<< (prec - HOST_BITS_PER_WIDE_INT)) & dc.high) != 0)
- return 0;
+ return false;
}
/* If we haven't been able to decide at this point, there nothing more we
@@ -8011,8 +8006,8 @@
goto retry;
}
- /* Or to fit_double_type, if nothing else. */
- return !fit_double_type (dc.low, dc.high, &dc.low, &dc.high, type);
+ /* Or to double_int_fits_to_tree_p, if nothing else. */
+ return double_int_fits_to_tree_p (type, dc);
}
/* Stores bounds of an integer TYPE in MIN and MAX. If TYPE has non-constant
Index: gcc/tree.h
===================================================================
--- gcc/tree.h (revision 161718)
+++ gcc/tree.h (working copy)
@@ -5050,7 +5050,7 @@
extern int really_constant_p (const_tree);
extern bool decl_address_invariant_p (const_tree);
extern bool decl_address_ip_invariant_p (const_tree);
-extern int int_fits_type_p (const_tree, const_tree);
+extern bool int_fits_type_p (const_tree, const_tree);
#ifndef GENERATOR_FILE
extern void get_type_static_bounds (const_tree, mpz_t, mpz_t);
#endif
Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c (revision 161718)
+++ gcc/builtins.c (working copy)
@@ -7627,8 +7627,7 @@
{
tree itype = TREE_TYPE (TREE_TYPE (fndecl));
tree ftype = TREE_TYPE (arg);
- unsigned HOST_WIDE_INT lo2;
- HOST_WIDE_INT hi, lo;
+ double_int val;
REAL_VALUE_TYPE r;
switch (DECL_FUNCTION_CODE (fndecl))
@@ -7652,9 +7651,9 @@
gcc_unreachable ();
}
- REAL_VALUE_TO_INT (&lo, &hi, r);
- if (!fit_double_type (lo, hi, &lo2, &hi, itype))
- return build_int_cst_wide (itype, lo2, hi);
+ real_to_integer2 ((HOST_WIDE_INT *)&val.low, &val.high, &r);
+ if (double_int_fits_to_tree_p (itype, val))
+ return double_int_to_tree (itype, val);
}
}
@@ -12037,7 +12036,7 @@
tree
fold_builtin_object_size (tree ptr, tree ost)
{
- tree ret = NULL_TREE;
+ unsigned HOST_WIDE_INT bytes;
int object_size_type;
if (!validate_arg (ptr, POINTER_TYPE)
@@ -12060,31 +12059,25 @@
return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
if (TREE_CODE (ptr) == ADDR_EXPR)
- ret = build_int_cstu (size_type_node,
- compute_builtin_object_size (ptr, object_size_type));
-
+ {
+ bytes = compute_builtin_object_size (ptr, object_size_type);
+ if (double_int_fits_to_tree_p (size_type_node,
+ uhwi_to_double_int (bytes)))
+ return build_int_cstu (size_type_node, bytes);
+ }
else if (TREE_CODE (ptr) == SSA_NAME)
{
- unsigned HOST_WIDE_INT bytes;
-
/* If object size is not known yet, delay folding until
later. Maybe subsequent passes will help determining
it. */
bytes = compute_builtin_object_size (ptr, object_size_type);
- if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
- ? -1 : 0))
- ret = build_int_cstu (size_type_node, bytes);
+ if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2 ? -1 : 0)
+ && double_int_fits_to_tree_p (size_type_node,
+ uhwi_to_double_int (bytes)))
+ return build_int_cstu (size_type_node, bytes);
}
- if (ret)
- {
- unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (ret);
- HOST_WIDE_INT high = TREE_INT_CST_HIGH (ret);
- if (fit_double_type (low, high, &low, &high, TREE_TYPE (ret)))
- ret = NULL_TREE;
- }
-
- return ret;
+ return NULL_TREE;
}
/* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
Index: gcc/double-int.c
===================================================================
--- gcc/double-int.c (revision 161718)
+++ gcc/double-int.c (working copy)
@@ -69,71 +69,6 @@
*hi = words[2] + words[3] * BASE;
}
-/* Force the double-word integer L1, H1 to be within the range of the
- integer type TYPE. Stores the properly truncated and sign-extended
- double-word integer in *LV, *HV. Returns true if the operation
- overflows, that is, argument and result are different. */
-
-int
-fit_double_type (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
- unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv, const_tree type)
-{
- unsigned HOST_WIDE_INT low0 = l1;
- HOST_WIDE_INT high0 = h1;
- unsigned int prec = TYPE_PRECISION (type);
- int sign_extended_type;
-
- /* Size types *are* sign extended. */
- sign_extended_type = (!TYPE_UNSIGNED (type)
- || (TREE_CODE (type) == INTEGER_TYPE
- && TYPE_IS_SIZETYPE (type)));
-
- /* First clear all bits that are beyond the type's precision. */
- if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
- ;
- else if (prec > HOST_BITS_PER_WIDE_INT)
- h1 &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
- else
- {
- h1 = 0;
- if (prec < HOST_BITS_PER_WIDE_INT)
- l1 &= ~((HOST_WIDE_INT) (-1) << prec);
- }
-
- /* Then do sign extension if necessary. */
- if (!sign_extended_type)
- /* No sign extension */;
- else if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
- /* Correct width already. */;
- else if (prec > HOST_BITS_PER_WIDE_INT)
- {
- /* Sign extend top half? */
- if (h1 & ((unsigned HOST_WIDE_INT)1
- << (prec - HOST_BITS_PER_WIDE_INT - 1)))
- h1 |= (HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT);
- }
- else if (prec == HOST_BITS_PER_WIDE_INT)
- {
- if ((HOST_WIDE_INT)l1 < 0)
- h1 = -1;
- }
- else
- {
- /* Sign extend bottom half? */
- if (l1 & ((unsigned HOST_WIDE_INT)1 << (prec - 1)))
- {
- h1 = -1;
- l1 |= (HOST_WIDE_INT)(-1) << prec;
- }
- }
-
- *lv = l1;
- *hv = h1;
-
- /* If the value didn't fit, signal overflow. */
- return l1 != low0 || h1 != high0;
-}
-
/* Add two doubleword integers with doubleword result.
Return nonzero if the operation overflows according to UNSIGNED_P.
Each argument is given as two `HOST_WIDE_INT' pieces.
Index: gcc/double-int.h
===================================================================
--- gcc/double-int.h (revision 161718)
+++ gcc/double-int.h (working copy)
@@ -269,9 +269,6 @@
/* Legacy interface with decomposed high/low parts. */
-extern int fit_double_type (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
- const_tree);
extern int add_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
unsigned HOST_WIDE_INT, HOST_WIDE_INT,
unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
Anatoly.