Richard Sandiford <[email protected]> wrote:
>When the wi:: patch went in, Kenny rightly complained that there were
>too many copy loops. This patch gets rid of an unnecessary loop in
>wi::abs and consolidates the rest into a single function. Again, it
>helps
>the ::is_sign_extended patch.
>
>Tested on x86_64-linux-gnu. OK to install?
Ok.
Thanks,
Richard.
>Thanks,
>Richard
>
>
>Index: gcc/wide-int.h
>===================================================================
>--- gcc/wide-int.h 2013-10-20 09:38:41.175501696 +0100
>+++ gcc/wide-int.h 2013-10-20 11:32:47.425353384 +0100
>@@ -347,6 +347,9 @@ typedef generic_wide_int <wide_int_ref_s
> template <typename T1, typename T2>
> unsigned int get_binary_precision (const T1 &, const T2 &);
>
>+ template <typename T1, typename T2>
>+ void copy (T1 &, const T2 &);
>+
> #define UNARY_PREDICATE \
> template <typename T> bool
> #define UNARY_FUNCTION \
>@@ -870,10 +873,7 @@ inline wide_int_storage::wide_int_storag
> STATIC_ASSERT (!wi::int_traits<T>::host_dependent_precision);
> wide_int_ref xi (x);
> precision = xi.precision;
>- unsigned int l = xi.len;
>- for (unsigned int i = 0; i < l; ++i)
>- val[i] = xi.val[i];
>- set_len (l);
>+ wi::copy (*this, xi);
> }
>
> inline unsigned int
>@@ -969,6 +969,21 @@ wi::int_traits <wide_int_storage>::get_b
> return wide_int::create (wi::get_precision (x));
> }
>
>+/* Copy the contents of Y to X, but keeping X's current precision. */
>+template <typename T1, typename T2>
>+void
>+wi::copy (T1 &x, const T2 &y)
>+{
>+ HOST_WIDE_INT *xval = x.write_val ();
>+ const HOST_WIDE_INT *yval = y.get_val ();
>+ unsigned int len = y.get_len ();
>+ unsigned int i = 0;
>+ do
>+ xval[i] = yval[i];
>+ while (++i < len);
>+ x.set_len (len);
>+}
>+
>/* An N-bit integer. Until we can use typedef templates, use this
>instead. */
> #define FIXED_WIDE_INT(N) \
> generic_wide_int < fixed_wide_int_storage <N> >
>@@ -1012,10 +1027,7 @@ inline fixed_wide_int_storage <N>::fixed
> /* Check for type compatibility. We don't want to initialize a
> fixed-width integer from something like a wide_int. */
> WI_BINARY_RESULT (T, FIXED_WIDE_INT (N)) *assertion ATTRIBUTE_UNUSED;
>- wide_int_ref xi (x, N);
>- len = xi.len;
>- for (unsigned int i = 0; i < len; ++i)
>- val[i] = xi.val[i];
>+ wi::copy (*this, wide_int_ref (x, N));
> }
>
> template <int N>
>@@ -1716,16 +1728,7 @@ wi::neg (const T &x, bool *overflow)
> inline WI_UNARY_RESULT (T)
> wi::abs (const T &x)
> {
>- if (neg_p (x))
>- return neg (x);
>-
>- WI_UNARY_RESULT_VAR (result, val, T, x);
>- wide_int_ref xi (x, get_precision (result));
>- for (unsigned int i = 0; i < xi.len; ++i)
>- val[i] = xi.val[i];
>- result.set_len (xi.len);
>-
>- return result;
>+ return neg_p (x) ? neg (x) : x;
> }
>
> /* Return the result of sign-extending the low OFFSET bits of X. */
>@@ -1760,9 +1763,7 @@ wi::zext (const T &x, unsigned int offse
> maintain canonization. */
> if (offset >= precision)
> {
>- for (unsigned int i = 0; i < xi.len; ++i)
>- val[i] = xi.val[i];
>- result.set_len (xi.len);
>+ wi::copy (result, xi);
> return result;
> }
>
>@@ -1809,22 +1810,12 @@ wi::set_bit (const T &x, unsigned int bi
> inline WI_BINARY_RESULT (T1, T2)
> wi::min (const T1 &x, const T2 &y, signop sgn)
> {
>- WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y);
>+ WI_BINARY_RESULT_VAR (result, val ATTRIBUTE_UNUSED, T1, x, T2, y);
> unsigned int precision = get_precision (result);
> if (wi::le_p (x, y, sgn))
>- {
>- wide_int_ref xi (x, precision);
>- for (unsigned int i = 0; i < xi.len; ++i)
>- val[i] = xi.val[i];
>- result.set_len (xi.len);
>- }
>+ wi::copy (result, wide_int_ref (x, precision));
> else
>- {
>- wide_int_ref yi (y, precision);
>- for (unsigned int i = 0; i < yi.len; ++i)
>- val[i] = yi.val[i];
>- result.set_len (yi.len);
>- }
>+ wi::copy (result, wide_int_ref (y, precision));
> return result;
> }
>
>@@ -1850,22 +1841,12 @@ wi::umin (const T1 &x, const T2 &y)
> inline WI_BINARY_RESULT (T1, T2)
> wi::max (const T1 &x, const T2 &y, signop sgn)
> {
>- WI_BINARY_RESULT_VAR (result, val, T1, x, T2, y);
>+ WI_BINARY_RESULT_VAR (result, val ATTRIBUTE_UNUSED, T1, x, T2, y);
> unsigned int precision = get_precision (result);
> if (wi::ge_p (x, y, sgn))
>- {
>- wide_int_ref xi (x, precision);
>- for (unsigned int i = 0; i < xi.len; ++i)
>- val[i] = xi.val[i];
>- result.set_len (xi.len);
>- }
>+ wi::copy (result, wide_int_ref (x, precision));
> else
>- {
>- wide_int_ref yi (y, precision);
>- for (unsigned int i = 0; i < yi.len; ++i)
>- val[i] = yi.val[i];
>- result.set_len (yi.len);
>- }
>+ wi::copy (result, wide_int_ref (y, precision));
> return result;
> }
>