mirror of git://gcc.gnu.org/git/gcc.git
re PR middle-end/36041 (Speed up builtin_popcountll)
PR middle-end/36041 * libgcc2.c (POPCOUNTCST2, POPCOUNTCST4, POPCOUNTCST8, POPCOUNTCST): Define. (__popcountSI2): For __SIZEOF_INT__ > 2 targets use arithmetics instead of table lookups. (__popcountDI2): Likewise. From-SVN: r200506
This commit is contained in:
parent
ebf8f0eaeb
commit
4ea3d77451
|
|
@ -1,3 +1,12 @@
|
||||||
|
2013-06-28 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR middle-end/36041
|
||||||
|
* libgcc2.c (POPCOUNTCST2, POPCOUNTCST4, POPCOUNTCST8, POPCOUNTCST):
|
||||||
|
Define.
|
||||||
|
(__popcountSI2): For __SIZEOF_INT__ > 2 targets use arithmetics
|
||||||
|
instead of table lookups.
|
||||||
|
(__popcountDI2): Likewise.
|
||||||
|
|
||||||
2013-06-25 Chung-Ju Wu <jasonwucj@gmail.com>
|
2013-06-25 Chung-Ju Wu <jasonwucj@gmail.com>
|
||||||
|
|
||||||
* Makefile.in (clean, distclean): Remove auto-target.h and stamp-h
|
* Makefile.in (clean, distclean): Remove auto-target.h and stamp-h
|
||||||
|
|
|
||||||
|
|
@ -819,17 +819,42 @@ const UQItype __popcount_tab[256] =
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(L_popcountsi2) || defined(L_popcountdi2)
|
||||||
|
#define POPCOUNTCST2(x) (((UWtype) x << BITS_PER_UNIT) | x)
|
||||||
|
#define POPCOUNTCST4(x) (((UWtype) x << (2 * BITS_PER_UNIT)) | x)
|
||||||
|
#define POPCOUNTCST8(x) (((UWtype) x << (4 * BITS_PER_UNIT)) | x)
|
||||||
|
#if W_TYPE_SIZE == BITS_PER_UNIT
|
||||||
|
#define POPCOUNTCST(x) x
|
||||||
|
#elif W_TYPE_SIZE == 2 * BITS_PER_UNIT
|
||||||
|
#define POPCOUNTCST(x) POPCOUNTCST2 (x)
|
||||||
|
#elif W_TYPE_SIZE == 4 * BITS_PER_UNIT
|
||||||
|
#define POPCOUNTCST(x) POPCOUNTCST4 (POPCOUNTCST2 (x))
|
||||||
|
#elif W_TYPE_SIZE == 8 * BITS_PER_UNIT
|
||||||
|
#define POPCOUNTCST(x) POPCOUNTCST8 (POPCOUNTCST4 (POPCOUNTCST2 (x)))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef L_popcountsi2
|
#ifdef L_popcountsi2
|
||||||
#undef int
|
#undef int
|
||||||
int
|
int
|
||||||
__popcountSI2 (UWtype x)
|
__popcountSI2 (UWtype x)
|
||||||
{
|
{
|
||||||
|
/* Force table lookup on targets like AVR and RL78 which only
|
||||||
|
pretend they have LIBGCC2_UNITS_PER_WORD 4, but actually
|
||||||
|
have 1, and other small word targets. */
|
||||||
|
#if __SIZEOF_INT__ > 2 && defined (POPCOUNTCST) && BITS_PER_UNIT == 8
|
||||||
|
x = x - ((x >> 1) & POPCOUNTCST (0x55));
|
||||||
|
x = (x & POPCOUNTCST (0x33)) + ((x >> 2) & POPCOUNTCST (0x33));
|
||||||
|
x = (x + (x >> 4)) & POPCOUNTCST (0x0F);
|
||||||
|
return (x * POPCOUNTCST (0x01)) >> (W_TYPE_SIZE - BITS_PER_UNIT);
|
||||||
|
#else
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
for (i = 0; i < W_TYPE_SIZE; i += 8)
|
for (i = 0; i < W_TYPE_SIZE; i += 8)
|
||||||
ret += __popcount_tab[(x >> i) & 0xff];
|
ret += __popcount_tab[(x >> i) & 0xff];
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -838,12 +863,28 @@ __popcountSI2 (UWtype x)
|
||||||
int
|
int
|
||||||
__popcountDI2 (UDWtype x)
|
__popcountDI2 (UDWtype x)
|
||||||
{
|
{
|
||||||
|
/* Force table lookup on targets like AVR and RL78 which only
|
||||||
|
pretend they have LIBGCC2_UNITS_PER_WORD 4, but actually
|
||||||
|
have 1, and other small word targets. */
|
||||||
|
#if __SIZEOF_INT__ > 2 && defined (POPCOUNTCST) && BITS_PER_UNIT == 8
|
||||||
|
const DWunion uu = {.ll = x};
|
||||||
|
UWtype x1 = uu.s.low, x2 = uu.s.high;
|
||||||
|
x1 = x1 - ((x1 >> 1) & POPCOUNTCST (0x55));
|
||||||
|
x2 = x2 - ((x2 >> 1) & POPCOUNTCST (0x55));
|
||||||
|
x1 = (x1 & POPCOUNTCST (0x33)) + ((x1 >> 2) & POPCOUNTCST (0x33));
|
||||||
|
x2 = (x2 & POPCOUNTCST (0x33)) + ((x2 >> 2) & POPCOUNTCST (0x33));
|
||||||
|
x1 = (x1 + (x1 >> 4)) & POPCOUNTCST (0x0F);
|
||||||
|
x2 = (x2 + (x2 >> 4)) & POPCOUNTCST (0x0F);
|
||||||
|
x1 += x2;
|
||||||
|
return (x1 * POPCOUNTCST (0x01)) >> (W_TYPE_SIZE - BITS_PER_UNIT);
|
||||||
|
#else
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
for (i = 0; i < 2*W_TYPE_SIZE; i += 8)
|
for (i = 0; i < 2*W_TYPE_SIZE; i += 8)
|
||||||
ret += __popcount_tab[(x >> i) & 0xff];
|
ret += __popcount_tab[(x >> i) & 0xff];
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue