diff mbox

[wide-int] small cleanup in wide-int.*

Message ID 5299378F.1060009@naturalbridge.com
State New
Headers show

Commit Message

Kenneth Zadeck Nov. 30, 2013, 12:55 a.m. UTC
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?

Kenny


On 11/29/2013 05:24 AM, Richard Biener wrote:
> On Thu, Nov 28, 2013 at 6:11 PM, Kenneth Zadeck
> <zadeck@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

Comments

Richard Biener Dec. 2, 2013, 10:50 a.m. UTC | #1
On Sat, Nov 30, 2013 at 1:55 AM, Kenneth Zadeck
<zadeck@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
>> <zadeck@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
>
>
diff mbox

Patch

Index: fold-const.c
===================================================================
--- fold-const.c	(revision 205496)
+++ 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: wide-int.cc
===================================================================
--- wide-int.cc	(revision 205508)
+++ 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;
@@ -1292,7 +1288,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;
@@ -1351,7 +1347,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)
@@ -1399,13 +1395,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: wide-int.h
===================================================================
--- wide-int.h	(revision 205496)
+++ wide-int.h	(working copy)
@@ -1566,7 +1566,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,
@@ -2308,7 +2308,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;
 }
 
@@ -2324,7 +2324,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;
 }
 
@@ -2358,7 +2358,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;
 }
 
@@ -2924,8 +2924,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);
@@ -2956,19 +2954,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