Unroll the tail loops of the SSE2-improved code

Change-Id: I1a51ceab3bdabd39bdb9dc2714debb3ad2c2380c
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
bb10
Thiago Macieira 2013-12-17 16:53:03 -08:00 committed by The Qt Project
parent 4c9db39896
commit 388bfb2731
1 changed files with 53 additions and 0 deletions

View File

@ -155,6 +155,41 @@ static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
QLatin1String needle, Qt::CaseSensitivity cs);
#ifdef Q_COMPILER_LAMBDA
namespace {
template <uint MaxCount> struct UnrollTailLoop
{
template <typename RetType, typename Functor1, typename Functor2>
static inline RetType exec(int count, RetType returnIfExited, Functor1 loopCheck, Functor2 returnIfFailed, int i = 0)
{
/* equivalent to:
* while (count--) {
* if (loopCheck(i))
* return returnIfFailed(i);
* }
* return returnIfExited;
*/
if (!count)
return returnIfExited;
bool check = loopCheck(i);
if (check) {
const RetType &retval = returnIfFailed(i);
return retval;
}
return UnrollTailLoop<MaxCount - 1>::exec(count - 1, returnIfExited, loopCheck, returnIfFailed, i + 1);
}
};
template <> template <typename RetType, typename Functor1, typename Functor2>
inline RetType UnrollTailLoop<0>::exec(int, RetType returnIfExited, Functor1, Functor2, int)
{
return returnIfExited;
}
}
#endif
// Unicode case-insensitive comparison
static int ucstricmp(const ushort *a, const ushort *ae, const ushort *b, const ushort *be)
{
@ -256,6 +291,13 @@ static int ucstrncmp(const QChar *a, const QChar *b, int l)
- reinterpret_cast<const QChar *>(ptr + distance + idx)->unicode();
}
}
# ifdef Q_COMPILER_LAMBDA
const auto &lambda = [=](int i) -> int {
return reinterpret_cast<const QChar *>(ptr)[i].unicode()
- reinterpret_cast<const QChar *>(ptr + distance)[i].unicode();
};
return UnrollTailLoop<7>::exec(l, 0, lambda, lambda);
# endif
#endif
if (!l)
return 0;
@ -361,6 +403,11 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l)
// reset uc and c
uc += offset;
c += offset;
# ifdef Q_COMPILER_LAMBDA
const auto &lambda = [=](int i) { return uc[i] - ushort(c[i]); };
return UnrollTailLoop<7>::exec(e - uc, 0, lambda, lambda);
# endif
#endif
while (uc < e) {
@ -438,6 +485,12 @@ static int findChar(const QChar *str, int len, QChar ch, int from,
+ _bit_scan_forward(mask)) >> 1;
}
}
# ifdef Q_COMPILER_LAMBDA
return UnrollTailLoop<7>::exec(e - n, -1,
[=](int i) { return n[i] == c; },
[=](int i) { return n - s + i; });
# endif
#endif
--n;
while (++n != e)