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]

Re: [wide-int] Turn lts_p & co. back into template functions


Richard Sandiford <rdsandiford@googlemail.com> wrote:
>This patch just converts some functions back to template functions,
>for the benefit of the upcoming ::is_sign_extended patch.  There's no
>behavioural change.
>
>Tested on x86_64-linux-gnu.  OK for wide-int?

Ok.

Thanks,
Richard.

>Thanks,
>Richard
>
>
>Index: gcc/gcc/wide-int.h
>===================================================================
>--- gcc.orig/gcc/wide-int.h
>+++ gcc/gcc/wide-int.h
>@@ -347,42 +347,48 @@ namespace wi
>   template <typename T1, typename T2>
>   unsigned int get_binary_precision (const T1 &, const T2 &);
> 
>-  bool fits_shwi_p (const wide_int_ref &);
>-  bool fits_uhwi_p (const wide_int_ref &);
>-  bool neg_p (const wide_int_ref &, signop = SIGNED);
>-  bool only_sign_bit_p (const wide_int_ref &, unsigned int);
>-  bool only_sign_bit_p (const wide_int_ref &);
>-  HOST_WIDE_INT sign_mask (const wide_int_ref &);
>-
>-  template <typename T1, typename T2>
>-  bool eq_p (const T1 &, const T2 &);
>-
>-  template <typename T1, typename T2>
>-  bool ne_p (const T1 &, const T2 &);
>-
>-  bool lt_p (const wide_int_ref &, const wide_int_ref &, signop);
>-  bool lts_p (const wide_int_ref &, const wide_int_ref &);
>-  bool ltu_p (const wide_int_ref &, const wide_int_ref &);
>-  bool le_p (const wide_int_ref &, const wide_int_ref &, signop);
>-  bool les_p (const wide_int_ref &, const wide_int_ref &);
>-  bool leu_p (const wide_int_ref &, const wide_int_ref &);
>-  bool gt_p (const wide_int_ref &, const wide_int_ref &, signop);
>-  bool gts_p (const wide_int_ref &, const wide_int_ref &);
>-  bool gtu_p (const wide_int_ref &, const wide_int_ref &);
>-  bool ge_p (const wide_int_ref &, const wide_int_ref &, signop);
>-  bool ges_p (const wide_int_ref &, const wide_int_ref &);
>-  bool geu_p (const wide_int_ref &, const wide_int_ref &);
>-  int cmp (const wide_int_ref &, const wide_int_ref &, signop);
>-  int cmps (const wide_int_ref &, const wide_int_ref &);
>-  int cmpu (const wide_int_ref &, const wide_int_ref &);
>-
>+#define UNARY_PREDICATE \
>+  template <typename T> bool
> #define UNARY_FUNCTION \
>   template <typename T> WI_UNARY_RESULT (T)
>+#define BINARY_PREDICATE \
>+  template <typename T1, typename T2> bool
> #define BINARY_FUNCTION \
>   template <typename T1, typename T2> WI_BINARY_RESULT (T1, T2)
> #define SHIFT_FUNCTION \
>   template <typename T> WI_UNARY_RESULT (T)
> 
>+  UNARY_PREDICATE fits_shwi_p (const T &);
>+  UNARY_PREDICATE fits_uhwi_p (const T &);
>+  UNARY_PREDICATE neg_p (const T &, signop = SIGNED);
>+
>+  template <typename T>
>+  HOST_WIDE_INT sign_mask (const T &);
>+
>+  BINARY_PREDICATE eq_p (const T1 &, const T2 &);
>+  BINARY_PREDICATE ne_p (const T1 &, const T2 &);
>+  BINARY_PREDICATE lt_p (const T1 &, const T2 &, signop);
>+  BINARY_PREDICATE lts_p (const T1 &, const T2 &);
>+  BINARY_PREDICATE ltu_p (const T1 &, const T2 &);
>+  BINARY_PREDICATE le_p (const T1 &, const T2 &, signop);
>+  BINARY_PREDICATE les_p (const T1 &, const T2 &);
>+  BINARY_PREDICATE leu_p (const T1 &, const T2 &);
>+  BINARY_PREDICATE gt_p (const T1 &, const T2 &, signop);
>+  BINARY_PREDICATE gts_p (const T1 &, const T2 &);
>+  BINARY_PREDICATE gtu_p (const T1 &, const T2 &);
>+  BINARY_PREDICATE ge_p (const T1 &, const T2 &, signop);
>+  BINARY_PREDICATE ges_p (const T1 &, const T2 &);
>+  BINARY_PREDICATE geu_p (const T1 &, const T2 &);
>+
>+  template <typename T1, typename T2>
>+  int cmp (const T1 &, const T2 &, signop);
>+
>+  template <typename T1, typename T2>
>+  int cmps (const T1 &, const T2 &);
>+
>+  template <typename T1, typename T2>
>+  int cmpu (const T1 &, const T2 &);
>+
>   UNARY_FUNCTION bit_not (const T &);
>   UNARY_FUNCTION neg (const T &);
>   UNARY_FUNCTION neg (const T &, bool *);
>@@ -446,9 +452,13 @@ namespace wi
>SHIFT_FUNCTION rrotate (const T &, const wide_int_ref &, unsigned int =
>0);
> 
> #undef SHIFT_FUNCTION
>+#undef BINARY_PREDICATE
> #undef BINARY_FUNCTION
>+#undef UNARY_PREDICATE
> #undef UNARY_FUNCTION
> 
>+  bool only_sign_bit_p (const wide_int_ref &, unsigned int);
>+  bool only_sign_bit_p (const wide_int_ref &);
>   int clz (const wide_int_ref &);
>   int clrsb (const wide_int_ref &);
>   int ctz (const wide_int_ref &);
>@@ -1401,40 +1411,48 @@ wi::get_binary_precision (const T1 &x, c
> 
> /* Return true if X fits in a HOST_WIDE_INT with no loss of
>    precision.  */
>+template <typename T>
> inline bool
>-wi::fits_shwi_p (const wide_int_ref &x)
>+wi::fits_shwi_p (const T &x)
> {
>-  return x.len == 1;
>+  wide_int_ref xi (x);
>+  return xi.len == 1;
> }
> 
> /* Return true if X fits in an unsigned HOST_WIDE_INT with no loss of
>    precision.  */
>+template <typename T>
> inline bool
>-wi::fits_uhwi_p (const wide_int_ref &x)
>+wi::fits_uhwi_p (const T &x)
> {
>-  if (x.precision <= HOST_BITS_PER_WIDE_INT)
>+  wide_int_ref xi (x);
>+  if (xi.precision <= HOST_BITS_PER_WIDE_INT)
>     return true;
>-  if (x.len == 1)
>-    return x.slow () >= 0;
>-  return x.len == 2 && x.uhigh () == 0;
>+  if (xi.len == 1)
>+    return xi.slow () >= 0;
>+  return xi.len == 2 && xi.uhigh () == 0;
> }
> 
> /* Return true if X is negative based on the interpretation of SGN.
>    For UNSIGNED, this is always false.  */
>+template <typename T>
> inline bool
>-wi::neg_p (const wide_int_ref &x, signop sgn)
>+wi::neg_p (const T &x, signop sgn)
> {
>+  wide_int_ref xi (x);
>   if (sgn == UNSIGNED)
>     return false;
>-  return x.sign_mask () < 0;
>+  return xi.sign_mask () < 0;
> }
> 
> /* Return -1 if the top bit of X is set and 0 if the top bit is
>    clear.  */
>+template <typename T>
> inline HOST_WIDE_INT
>-wi::sign_mask (const wide_int_ref &x)
>+wi::sign_mask (const T &x)
> {
>-  return x.sign_mask ();
>+  wide_int_ref xi (x);
>+  return xi.sign_mask ();
> }
> 
> /* Return true if X == Y.  X and Y must be binary-compatible.  */
>@@ -1464,19 +1482,22 @@ wi::ne_p (const T1 &x, const T2 &y)
> }
> 
> /* Return true if X < Y when both are treated as signed values.  */
>+template <typename T1, typename T2>
> inline bool
>-wi::lts_p (const wide_int_ref &x, const wide_int_ref &y)
>+wi::lts_p (const T1 &x, const T2 &y)
> {
>   // We optimize x < y, where y is 64 or fewer bits.
>   // We have to be careful to not allow comparison to a large positive
>   // unsigned value like 0x8000000000000000, those would be encoded
>   // with a y.len == 2.
>-  if (y.precision <= HOST_BITS_PER_WIDE_INT
>-      && y.len == 1)
>+  wide_int_ref xi (x);
>+  wide_int_ref yi (y);
>+  if (yi.precision <= HOST_BITS_PER_WIDE_INT
>+      && yi.len == 1)
>     {
>       // If x fits directly into a shwi, we can compare directly.
>       if (wi::fits_shwi_p (x))
>-	return x.to_shwi () < y.to_shwi ();
>+	return xi.to_shwi () < yi.to_shwi ();
>       // If x doesn't fit and is negative, then it must be more
>       // negative than any value in y, and hence smaller than y.
>       if (neg_p (x, SIGNED))
>@@ -1485,29 +1506,33 @@ wi::lts_p (const wide_int_ref &x, const
>       // and hence greater than y.
>       return false;
>     }
>-  return lts_p_large (x.val, x.len, x.precision, y.val, y.len,
>-		      y.precision);
>+  return lts_p_large (xi.val, xi.len, xi.precision, yi.val, yi.len,
>+		      yi.precision);
> }
> 
> /* Return true if X < Y when both are treated as unsigned values.  */
>+template <typename T1, typename T2>
> inline bool
>-wi::ltu_p (const wide_int_ref &x, const wide_int_ref &y)
>+wi::ltu_p (const T1 &x, const T2 &y)
> {
>-  if (x.precision <= HOST_BITS_PER_WIDE_INT
>-      && y.precision <= HOST_BITS_PER_WIDE_INT)
>+  wide_int_ref xi (x);
>+  wide_int_ref yi (y);
>+  if (xi.precision <= HOST_BITS_PER_WIDE_INT
>+      && yi.precision <= HOST_BITS_PER_WIDE_INT)
>     {
>-      unsigned HOST_WIDE_INT xl = x.to_uhwi ();
>-      unsigned HOST_WIDE_INT yl = y.to_uhwi ();
>+      unsigned HOST_WIDE_INT xl = xi.to_uhwi ();
>+      unsigned HOST_WIDE_INT yl = yi.to_uhwi ();
>       return xl < yl;
>     }
>   else
>-    return ltu_p_large (x.val, x.len, x.precision, 
>-			y.val, y.len, y.precision);
>+    return ltu_p_large (xi.val, xi.len, xi.precision,
>+			yi.val, yi.len, yi.precision);
> }
> 
>/* Return true if X < Y.  Signedness of X and Y is indicated by SGN. 
>*/
>+template <typename T1, typename T2>
> inline bool
>-wi::lt_p (const wide_int_ref &x, const wide_int_ref &y, signop sgn)
>+wi::lt_p (const T1 &x, const T2 &y, signop sgn)
> {
>   if (sgn == SIGNED)
>     return lts_p (x, y);
>@@ -1516,22 +1541,25 @@ wi::lt_p (const wide_int_ref &x, const w
> }
> 
> /* Return true if X <= Y when both are treated as signed values.  */
>+template <typename T1, typename T2>
> inline bool
>-wi::les_p (const wide_int_ref &x, const wide_int_ref &y)
>+wi::les_p (const T1 &x, const T2 &y)
> {
>   return !lts_p (y, x);
> }
> 
> /* Return true if X <= Y when both are treated as unsigned values.  */
>+template <typename T1, typename T2>
> inline bool
>-wi::leu_p (const wide_int_ref &x, const wide_int_ref &y)
>+wi::leu_p (const T1 &x, const T2 &y)
> {
>   return !ltu_p (y, x);
> }
> 
>/* Return true if X <= Y.  Signedness of X and Y is indicated by SGN. 
>*/
>+template <typename T1, typename T2>
> inline bool
>-wi::le_p (const wide_int_ref &x, const wide_int_ref &y, signop sgn)
>+wi::le_p (const T1 &x, const T2 &y, signop sgn)
> {
>   if (sgn == SIGNED)
>     return les_p (x, y);
>@@ -1540,22 +1568,25 @@ wi::le_p (const wide_int_ref &x, const w
> }
> 
> /* Return true if X > Y when both are treated as signed values.  */
>+template <typename T1, typename T2>
> inline bool
>-wi::gts_p (const wide_int_ref &x, const wide_int_ref &y)
>+wi::gts_p (const T1 &x, const T2 &y)
> {
>   return lts_p (y, x);
> }
> 
> /* Return true if X > Y when both are treated as unsigned values.  */
>+template <typename T1, typename T2>
> inline bool
>-wi::gtu_p (const wide_int_ref &x, const wide_int_ref &y)
>+wi::gtu_p (const T1 &x, const T2 &y)
> {
>   return ltu_p (y, x);
> }
> 
>/* Return true if X > Y.  Signedness of X and Y is indicated by SGN. 
>*/
>+template <typename T1, typename T2>
> inline bool
>-wi::gt_p (const wide_int_ref &x, const wide_int_ref &y, signop sgn)
>+wi::gt_p (const T1 &x, const T2 &y, signop sgn)
> {
>   if (sgn == SIGNED)
>     return gts_p (x, y);
>@@ -1564,22 +1595,25 @@ wi::gt_p (const wide_int_ref &x, const w
> }
> 
> /* Return true if X >= Y when both are treated as signed values.  */
>+template <typename T1, typename T2>
> inline bool
>-wi::ges_p (const wide_int_ref &x, const wide_int_ref &y)
>+wi::ges_p (const T1 &x, const T2 &y)
> {
>   return !lts_p (x, y);
> }
> 
> /* Return true if X >= Y when both are treated as unsigned values.  */
>+template <typename T1, typename T2>
> inline bool
>-wi::geu_p (const wide_int_ref &x, const wide_int_ref &y)
>+wi::geu_p (const T1 &x, const T2 &y)
> {
>   return !ltu_p (x, y);
> }
> 
>/* Return true if X >= Y.  Signedness of X and Y is indicated by SGN. 
>*/
>+template <typename T1, typename T2>
> inline bool
>-wi::ge_p (const wide_int_ref &x, const wide_int_ref &y, signop sgn)
>+wi::ge_p (const T1 &x, const T2 &y, signop sgn)
> {
>   if (sgn == SIGNED)
>     return ges_p (x, y);
>@@ -1589,14 +1623,17 @@ wi::ge_p (const wide_int_ref &x, const w
> 
> /* Return -1 if X < Y, 0 if X == Y and 1 if X > Y.  Treat both X and Y
>    as signed values.  */
>+template <typename T1, typename T2>
> inline int
>-wi::cmps (const wide_int_ref &x, const wide_int_ref &y)
>+wi::cmps (const T1 &x, const T2 &y)
> {
>-  if (x.precision <= HOST_BITS_PER_WIDE_INT
>-      && y.precision <= HOST_BITS_PER_WIDE_INT)
>+  wide_int_ref xi (x);
>+  wide_int_ref yi (y);
>+  if (xi.precision <= HOST_BITS_PER_WIDE_INT
>+      && yi.precision <= HOST_BITS_PER_WIDE_INT)
>     {
>-      HOST_WIDE_INT xl = x.to_shwi ();
>-      HOST_WIDE_INT yl = y.to_shwi ();
>+      HOST_WIDE_INT xl = xi.to_shwi ();
>+      HOST_WIDE_INT yl = yi.to_shwi ();
>       if (xl < yl)
> 	return -1;
>       else if (xl > yl)
>@@ -1604,20 +1641,23 @@ wi::cmps (const wide_int_ref &x, const w
>       else
> 	return 0;
>     }
>-  return cmps_large (x.val, x.len, x.precision, y.val, y.len,
>-		     y.precision);
>+  return cmps_large (xi.val, xi.len, xi.precision, yi.val, yi.len,
>+		     yi.precision);
> }
> 
> /* Return -1 if X < Y, 0 if X == Y and 1 if X > Y.  Treat both X and Y
>    as unsigned values.  */
>+template <typename T1, typename T2>
> inline int
>-wi::cmpu (const wide_int_ref &x, const wide_int_ref &y)
>+wi::cmpu (const T1 &x, const T2 &y)
> {
>-  if (x.precision <= HOST_BITS_PER_WIDE_INT
>-      && y.precision <= HOST_BITS_PER_WIDE_INT)
>+  wide_int_ref xi (x);
>+  wide_int_ref yi (y);
>+  if (xi.precision <= HOST_BITS_PER_WIDE_INT
>+      && yi.precision <= HOST_BITS_PER_WIDE_INT)
>     {
>-      unsigned HOST_WIDE_INT xl = x.to_uhwi ();
>-      unsigned HOST_WIDE_INT yl = y.to_uhwi ();
>+      unsigned HOST_WIDE_INT xl = xi.to_uhwi ();
>+      unsigned HOST_WIDE_INT yl = yi.to_uhwi ();
>       if (xl < yl)
> 	return -1;
>       else if (xl == yl)
>@@ -1625,14 +1665,15 @@ wi::cmpu (const wide_int_ref &x, const w
>       else
> 	return 1;
>     }
>-  return cmpu_large (x.val, x.len, x.precision, y.val, y.len,
>-		     y.precision);
>+  return cmpu_large (xi.val, xi.len, xi.precision, yi.val, yi.len,
>+		     yi.precision);
> }
> 
> /* Return -1 if X < Y, 0 if X == Y and 1 if X > Y.  Signedness of
>    X and Y indicated by SGN.  */
>+template <typename T1, typename T2>
> inline int
>-wi::cmp (const wide_int_ref &x, const wide_int_ref &y, signop sgn)
>+wi::cmp (const T1 &x, const T2 &y, signop sgn)
> {
>   if (sgn == SIGNED)
>     return cmps (x, y);



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]