Richard Sandiford <rdsandif...@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);