committed as revision 205599 to wide-int branch.

kenny

On 12/02/2013 05:50 AM, Richard Biener wrote:
On Sat, Nov 30, 2013 at 1:55 AM, Kenneth Zadeck
<zad...@naturalbridge.com> wrote:
Richi,

this is the first of either 2 or 3 patches to fix this.    There are two
places that need be fixed for us to do 1X + 1 and this patch fixes the first
one.   There was an unnecessary call to mul_full and this was the only call
to mul_full.   So this patch removes the call and also the function itself.

The other place is the tree-vpn that is discussed here and will be dealt
with in the other patches.

tested on x86-64.

Ok to commit?
Ok.

Thanks,
Richard.

Kenny



On 11/29/2013 05:24 AM, Richard Biener wrote:
On Thu, Nov 28, 2013 at 6:11 PM, Kenneth Zadeck
<zad...@naturalbridge.com> wrote:
This patch does three things in wide-int:

1) it cleans up some comments.
2) removes a small amount of trash.
3) it changes the max size of the wide int from being 4x of
MAX_BITSIZE_MODE_ANY_INT to 2x +1.   This should improve large muls and
divs
as well as perhaps help with some cache behavior.
@@ -235,8 +233,8 @@ along with GCC; see the file COPYING3.
      range of a multiply.  This code needs 2n + 2 bits.  */

   #define WIDE_INT_MAX_ELTS \
-  ((4 * MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) \
-   / HOST_BITS_PER_WIDE_INT)
+  (((2 * MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) \
+    / HOST_BITS_PER_WIDE_INT) + 1)

I always wondered why VRP (if that is the only reason we do 2*n+1)
cannot simply use FIXED_WIDE_INT(MAX_BITSIZE_MODE_ANY_INT*2 + 1)?
Other widest_int users should not suffer IMHO.  widest_int should
strictly cover all modes that the target can do any arithmetic on
(thus not XImode or OImode on x86_64).

Richard.

ok to commit


Index: gcc/wide-int.cc
===================================================================
--- gcc/wide-int.cc	(revision 205597)
+++ gcc/wide-int.cc	(working copy)
@@ -1247,22 +1247,18 @@ wi_pack (unsigned HOST_WIDE_INT *result,
 }
 
 /* Multiply Op1 by Op2.  If HIGH is set, only the upper half of the
-   result is returned.  If FULL is set, the entire result is returned
-   in a mode that is twice the width of the inputs.  However, that
-   mode needs to exist if the value is to be usable.  Clients that use
-   FULL need to check for this.
-
-   If HIGH or FULL are not set, throw away the upper half after the
-   check is made to see if it overflows.  Unfortunately there is no
-   better way to check for overflow than to do this.  If OVERFLOW is
-   nonnull, record in *OVERFLOW whether the result overflowed.  SGN
-   controls the signedness and is used to check overflow or if HIGH or
-   FULL is set.  */
+   result is returned.  
+
+   If HIGH is not set, throw away the upper half after the check is
+   made to see if it overflows.  Unfortunately there is no better way
+   to check for overflow than to do this.  If OVERFLOW is nonnull,
+   record in *OVERFLOW whether the result overflowed.  SGN controls
+   the signedness and is used to check overflow or if HIGH is set.  */
 unsigned int
 wi::mul_internal (HOST_WIDE_INT *val, const HOST_WIDE_INT *op1,
 		  unsigned int op1len, const HOST_WIDE_INT *op2,
 		  unsigned int op2len, unsigned int prec, signop sgn,
-		  bool *overflow, bool high, bool full)
+		  bool *overflow, bool high)
 {
   unsigned HOST_WIDE_INT o0, o1, k, t;
   unsigned int i;
@@ -1313,7 +1309,7 @@ wi::mul_internal (HOST_WIDE_INT *val, co
   /* If we need to check for overflow, we can only do half wide
      multiplies quickly because we need to look at the top bits to
      check for the overflow.  */
-  if ((high || full || needs_overflow)
+  if ((high || needs_overflow)
       && (prec <= HOST_BITS_PER_HALF_WIDE_INT))
     {
       unsigned HOST_WIDE_INT r;
@@ -1372,7 +1368,7 @@ wi::mul_internal (HOST_WIDE_INT *val, co
 
   /* We did unsigned math above.  For signed we must adjust the
      product (assuming we need to see that).  */
-  if (sgn == SIGNED && (full || high || needs_overflow))
+  if (sgn == SIGNED && (high || needs_overflow))
     {
       unsigned HOST_WIDE_INT b;
       if (op1[op1len-1] < 0)
@@ -1420,13 +1416,7 @@ wi::mul_internal (HOST_WIDE_INT *val, co
 	  *overflow = true;
     }
 
-  if (full)
-    {
-      /* compute [2prec] <- [prec] * [prec] */
-      wi_pack ((unsigned HOST_WIDE_INT *) val, r, 2 * half_blocks_needed);
-      return canonize (val, blocks_needed * 2, prec * 2);
-    }
-  else if (high)
+  if (high)
     {
       /* compute [prec] <- ([prec] * [prec]) >> [prec] */
       wi_pack ((unsigned HOST_WIDE_INT *) val,
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 205597)
+++ gcc/fold-const.c	(working copy)
@@ -5962,11 +5962,12 @@ extract_muldiv_1 (tree t, tree c, enum t
 	 assuming no overflow.  */
       if (tcode == code)
 	{
-	  bool overflow_p;
+	  bool overflow_p = false;
+	  bool overflow_mul_p;
 	  signop sign = TYPE_SIGN (ctype);
-	  wide_int mul = wi::mul_full (op1, c, sign);
+	  wide_int mul = wi::mul (op1, c, sign, &overflow_mul_p);
 	  overflow_p = TREE_OVERFLOW (c) | TREE_OVERFLOW (op1);
-	  if (!wi::fits_to_tree_p (mul, ctype)
+	  if (overflow_mul_p
 	      && ((sign == UNSIGNED && tcode != MULT_EXPR) || sign == SIGNED))
 	    overflow_p = true;
 	  if (!overflow_p)
Index: gcc/wide-int.h
===================================================================
--- gcc/wide-int.h	(revision 205597)
+++ gcc/wide-int.h	(working copy)
@@ -1575,7 +1575,7 @@ namespace wi
   unsigned int mul_internal (HOST_WIDE_INT *, const HOST_WIDE_INT *,
 			     unsigned int, const HOST_WIDE_INT *,
 			     unsigned int, unsigned int, signop, bool *,
-			     bool, bool);
+			     bool);
   unsigned int divmod_internal (HOST_WIDE_INT *, unsigned int *,
 				HOST_WIDE_INT *, const HOST_WIDE_INT *,
 				unsigned int, unsigned int,
@@ -2394,7 +2394,7 @@ wi::mul (const T1 &x, const T2 &y)
     }
   else
     result.set_len (mul_internal (val, xi.val, xi.len, yi.val, yi.len,
-				  precision, UNSIGNED, 0, false, false));
+				  precision, UNSIGNED, 0, false));
   return result;
 }
 
@@ -2410,7 +2410,7 @@ wi::mul (const T1 &x, const T2 &y, signo
   WIDE_INT_REF_FOR (T2) yi (y, precision);
   result.set_len (mul_internal (val, xi.val, xi.len,
 				yi.val, yi.len, precision,
-				sgn, overflow, false, false));
+				sgn, overflow, false));
   return result;
 }
 
@@ -2444,7 +2444,7 @@ wi::mul_high (const T1 &x, const T2 &y,
   WIDE_INT_REF_FOR (T2) yi (y, precision);
   result.set_len (mul_internal (val, xi.val, xi.len,
 				yi.val, yi.len, precision,
-				sgn, 0, true, false));
+				sgn, 0, true));
   return result;
 }
 
@@ -3033,8 +3033,6 @@ namespace wi
   wide_int max_value (never_used1 *);
   wide_int max_value (never_used2 *);
 
-  wide_int mul_full (const wide_int_ref &, const wide_int_ref &, signop);
-
   /* FIXME: this is target dependent, so should be elsewhere.
      It also seems to assume that CHAR_BIT == BITS_PER_UNIT.  */
   wide_int from_buffer (const unsigned char *, unsigned int);
@@ -3065,19 +3063,6 @@ namespace wi
 			   unsigned int, unsigned int, bool);
 }
 
-/* Perform a widening multiplication of X and Y, extending the values
-   according according to SGN.  */
-inline wide_int
-wi::mul_full (const wide_int_ref &x, const wide_int_ref &y, signop sgn)
-{
-  gcc_checking_assert (x.precision == y.precision);
-  wide_int result = wide_int::create (x.precision * 2);
-  result.set_len (mul_internal (result.write_val (), x.val, x.len,
-				y.val, y.len, x.precision,
-				sgn, 0, false, true));
-  return result;
-}
-
 /* Return a PRECISION-bit integer in which the low WIDTH bits are set
    and the other bits are clear, or the inverse if NEGATE_P.  */
 inline wide_int

Reply via email to