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

2013-12-03 Thread Kenneth Zadeck

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

2013-12-02 Thread Richard Sandiford
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

2013-12-02 Thread Mike Stump
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.