diff mbox

[wide-int] Drop some lingering uses of precision 0

Message ID 87vbz7c8dz.fsf@talisman.default
State New
Headers show

Commit Message

Richard Sandiford Dec. 2, 2013, 8:20 p.m. UTC
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

Comments

Mike Stump Dec. 3, 2013, 12:48 a.m. UTC | #1
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.
Kenneth Zadeck Dec. 3, 2013, 3:10 p.m. UTC | #2
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))
diff mbox

Patch

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))