This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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 +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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]