Message ID | 87vbz7c8dz.fsf@talisman.default |
---|---|
State | New |
Headers | show |
On Dec 2, 2013, at 12:20 PM, Richard Sandiford <rdsandiford@googlemail.com> wrote: > I noticed that there were still a couple of tests for zero precision. > OK to install? Ok.
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 +0000 > +++ gcc/wide-int.cc 2013-12-02 20:12:22.178998274 +0000 > @@ -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 +0000 > +++ gcc/wide-int.h 2013-12-02 20:12:22.179998282 +0000 > @@ -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 == SIGNED) > *overflow = (((resultl ^ xl) & (resultl ^ yl)) > >> (precision - 1)) & 1; > else > @@ -2364,9 +2375,7 @@ wi::sub (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 == SIGNED) > *overflow = (((xl ^ yl) & (resultl ^ xl)) >> (precision - 1)) & 1; > else > *overflow = ((resultl << (HOST_BITS_PER_WIDE_INT - precision))
Index: gcc/wide-int.cc =================================================================== --- gcc/wide-int.cc 2013-12-02 20:03:50.112581766 +0000 +++ gcc/wide-int.cc 2013-12-02 20:12:22.178998274 +0000 @@ -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 +0000 +++ gcc/wide-int.h 2013-12-02 20:12:22.179998282 +0000 @@ -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 == SIGNED) *overflow = (((resultl ^ xl) & (resultl ^ yl)) >> (precision - 1)) & 1; else @@ -2364,9 +2375,7 @@ wi::sub (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 == SIGNED) *overflow = (((xl ^ yl) & (resultl ^ xl)) >> (precision - 1)) & 1; else *overflow = ((resultl << (HOST_BITS_PER_WIDE_INT - precision))