Message ID | 1119599263.20100704150134@post.ru |
---|---|
State | New |
Headers | show |
On 07/04/2010 01:01 PM, Anatoly Sokolov wrote: > @@ -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) > Looks like the comment should be slightly adjusted, like saying true instead of nonzero? Paolo.
2010/7/4 Anatoly Sokolov <aesok@post.ru>: > 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? This is ok with Paolos comments. Thanks, Richard. > * 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. > >
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 *,