Re: [wide-int] Drop some lingering uses of precision 0
if i did not already say so, this is fine. kenny On 12/02/2013 03:20 PM, Richard Sandiford wrote: I noticed that there were still a couple of tests for zero precision. This patch replaces them with asserts when handling separately-supplied precisions and simply drops them when handling existing wide_ints. (The idea is that most code would break for zero precision wide_ints and only asserting in some use sites would be inconsistent.) Also, to_shwi is called either with a nonzero precision argument or with no argument. I think it'd be clearer to split the two cases into separate (overloaded) functions. It's also more efficient, since the compiler doesn't know that a variable-precision argument must be nonzero. Tested on x86_64-linux-gnu. OK to install? Thanks, Richard Index: gcc/wide-int.cc === --- gcc/wide-int.cc 2013-12-02 20:03:50.112581766 + +++ gcc/wide-int.cc 2013-12-02 20:12:22.178998274 + @@ -275,9 +275,8 @@ wi::from_mpz (const_tree type, mpz_t x, wide_int wi::max_value (unsigned int precision, signop sgn) { - if (precision == 0) -return shwi (0, precision); - else if (sgn == UNSIGNED) + gcc_checking_assert (precision != 0); + if (sgn == UNSIGNED) /* The unsigned max is just all ones. */ return shwi (-1, precision); else @@ -290,7 +289,8 @@ wi::max_value (unsigned int precision, s wide_int wi::min_value (unsigned int precision, signop sgn) { - if (precision == 0 || sgn == UNSIGNED) + gcc_checking_assert (precision != 0); + if (sgn == UNSIGNED) return uhwi (0, precision); else /* The signed min is all zeros except the top bit. This must be @@ -1487,9 +1487,6 @@ wi::popcount (const wide_int_ref x) unsigned int i; int count; - if (x.precision == 0) -return 0; - /* The high order block is special if it is the last block and the precision is not an even multiple of HOST_BITS_PER_WIDE_INT. We have to clear out any ones above the precision before doing @@ -2082,10 +2079,6 @@ wi::ctz (const wide_int_ref x) int wi::exact_log2 (const wide_int_ref x) { - /* 0-precision values can only hold 0. */ - if (x.precision == 0) -return -1; - /* Reject cases where there are implicit -1 blocks above HIGH. */ if (x.len * HOST_BITS_PER_WIDE_INT x.precision x.sign_mask () 0) return -1; Index: gcc/wide-int.h === --- gcc/wide-int.h 2013-12-02 19:52:05.424989079 + +++ gcc/wide-int.h 2013-12-02 20:12:22.179998282 + @@ -644,8 +644,10 @@ class GTY(()) generic_wide_int : public generic_wide_int (const T , unsigned int); /* Conversions. */ - HOST_WIDE_INT to_shwi (unsigned int = 0) const; - unsigned HOST_WIDE_INT to_uhwi (unsigned int = 0) const; + HOST_WIDE_INT to_shwi (unsigned int) const; + HOST_WIDE_INT to_shwi () const; + unsigned HOST_WIDE_INT to_uhwi (unsigned int) const; + unsigned HOST_WIDE_INT to_uhwi () const; HOST_WIDE_INT to_short_addr () const; /* Public accessors for the interior of a wide int. */ @@ -735,18 +737,23 @@ inline generic_wide_int storage::gener inline HOST_WIDE_INT generic_wide_int storage::to_shwi (unsigned int precision) const { - if (precision == 0) -{ - if (is_sign_extended) - return this-get_val ()[0]; - precision = this-get_precision (); -} if (precision HOST_BITS_PER_WIDE_INT) return sext_hwi (this-get_val ()[0], precision); else return this-get_val ()[0]; } +/* Return THIS as a signed HOST_WIDE_INT, in its natural precision. */ +template typename storage +inline HOST_WIDE_INT +generic_wide_int storage::to_shwi () const +{ + if (is_sign_extended) +return this-get_val ()[0]; + else +return to_shwi (this-get_precision ()); +} + /* Return THIS as an unsigned HOST_WIDE_INT, zero-extending from PRECISION. If THIS does not fit in PRECISION, the information is lost. */ @@ -754,14 +761,20 @@ generic_wide_int storage::to_shwi (uns inline unsigned HOST_WIDE_INT generic_wide_int storage::to_uhwi (unsigned int precision) const { - if (precision == 0) -precision = this-get_precision (); if (precision HOST_BITS_PER_WIDE_INT) return zext_hwi (this-get_val ()[0], precision); else return this-get_val ()[0]; } +/* Return THIS as an signed HOST_WIDE_INT, in its natural precision. */ +template typename storage +inline unsigned HOST_WIDE_INT +generic_wide_int storage::to_uhwi () const +{ + return to_uhwi (this-get_precision ()); +} + /* TODO: The compiler is half converted from using HOST_WIDE_INT to represent addresses to using offset_int to represent addresses. We use to_short_addr at the interface from new code to old, @@ -2289,9 +2302,7 @@ wi::add (const T1 x, const T2 y, signo unsigned HOST_WIDE_INT xl = xi.ulow (); unsigned HOST_WIDE_INT yl
[wide-int] Drop some lingering uses of precision 0
I noticed that there were still a couple of tests for zero precision. This patch replaces them with asserts when handling separately-supplied precisions and simply drops them when handling existing wide_ints. (The idea is that most code would break for zero precision wide_ints and only asserting in some use sites would be inconsistent.) Also, to_shwi is called either with a nonzero precision argument or with no argument. I think it'd be clearer to split the two cases into separate (overloaded) functions. It's also more efficient, since the compiler doesn't know that a variable-precision argument must be nonzero. Tested on x86_64-linux-gnu. OK to install? Thanks, Richard Index: gcc/wide-int.cc === --- gcc/wide-int.cc 2013-12-02 20:03:50.112581766 + +++ gcc/wide-int.cc 2013-12-02 20:12:22.178998274 + @@ -275,9 +275,8 @@ wi::from_mpz (const_tree type, mpz_t x, wide_int wi::max_value (unsigned int precision, signop sgn) { - if (precision == 0) -return shwi (0, precision); - else if (sgn == UNSIGNED) + gcc_checking_assert (precision != 0); + if (sgn == UNSIGNED) /* The unsigned max is just all ones. */ return shwi (-1, precision); else @@ -290,7 +289,8 @@ wi::max_value (unsigned int precision, s wide_int wi::min_value (unsigned int precision, signop sgn) { - if (precision == 0 || sgn == UNSIGNED) + gcc_checking_assert (precision != 0); + if (sgn == UNSIGNED) return uhwi (0, precision); else /* The signed min is all zeros except the top bit. This must be @@ -1487,9 +1487,6 @@ wi::popcount (const wide_int_ref x) unsigned int i; int count; - if (x.precision == 0) -return 0; - /* The high order block is special if it is the last block and the precision is not an even multiple of HOST_BITS_PER_WIDE_INT. We have to clear out any ones above the precision before doing @@ -2082,10 +2079,6 @@ wi::ctz (const wide_int_ref x) int wi::exact_log2 (const wide_int_ref x) { - /* 0-precision values can only hold 0. */ - if (x.precision == 0) -return -1; - /* Reject cases where there are implicit -1 blocks above HIGH. */ if (x.len * HOST_BITS_PER_WIDE_INT x.precision x.sign_mask () 0) return -1; Index: gcc/wide-int.h === --- gcc/wide-int.h 2013-12-02 19:52:05.424989079 + +++ gcc/wide-int.h 2013-12-02 20:12:22.179998282 + @@ -644,8 +644,10 @@ class GTY(()) generic_wide_int : public generic_wide_int (const T , unsigned int); /* Conversions. */ - HOST_WIDE_INT to_shwi (unsigned int = 0) const; - unsigned HOST_WIDE_INT to_uhwi (unsigned int = 0) const; + HOST_WIDE_INT to_shwi (unsigned int) const; + HOST_WIDE_INT to_shwi () const; + unsigned HOST_WIDE_INT to_uhwi (unsigned int) const; + unsigned HOST_WIDE_INT to_uhwi () const; HOST_WIDE_INT to_short_addr () const; /* Public accessors for the interior of a wide int. */ @@ -735,18 +737,23 @@ inline generic_wide_int storage::gener inline HOST_WIDE_INT generic_wide_int storage::to_shwi (unsigned int precision) const { - if (precision == 0) -{ - if (is_sign_extended) - return this-get_val ()[0]; - precision = this-get_precision (); -} if (precision HOST_BITS_PER_WIDE_INT) return sext_hwi (this-get_val ()[0], precision); else return this-get_val ()[0]; } +/* Return THIS as a signed HOST_WIDE_INT, in its natural precision. */ +template typename storage +inline HOST_WIDE_INT +generic_wide_int storage::to_shwi () const +{ + if (is_sign_extended) +return this-get_val ()[0]; + else +return to_shwi (this-get_precision ()); +} + /* Return THIS as an unsigned HOST_WIDE_INT, zero-extending from PRECISION. If THIS does not fit in PRECISION, the information is lost. */ @@ -754,14 +761,20 @@ generic_wide_int storage::to_shwi (uns inline unsigned HOST_WIDE_INT generic_wide_int storage::to_uhwi (unsigned int precision) const { - if (precision == 0) -precision = this-get_precision (); if (precision HOST_BITS_PER_WIDE_INT) return zext_hwi (this-get_val ()[0], precision); else return this-get_val ()[0]; } +/* Return THIS as an signed HOST_WIDE_INT, in its natural precision. */ +template typename storage +inline unsigned HOST_WIDE_INT +generic_wide_int storage::to_uhwi () const +{ + return to_uhwi (this-get_precision ()); +} + /* TODO: The compiler is half converted from using HOST_WIDE_INT to represent addresses to using offset_int to represent addresses. We use to_short_addr at the interface from new code to old, @@ -2289,9 +2302,7 @@ wi::add (const T1 x, const T2 y, signo unsigned HOST_WIDE_INT xl = xi.ulow (); unsigned HOST_WIDE_INT yl = yi.ulow (); unsigned HOST_WIDE_INT resultl = xl + yl; - if (precision == 0) - *overflow = false; - else if (sgn == SIGNED) + if (sgn
Re: [wide-int] Drop some lingering uses of precision 0
On Dec 2, 2013, at 12:20 PM, Richard Sandiford rdsandif...@googlemail.com wrote: I noticed that there were still a couple of tests for zero precision. OK to install? Ok.