summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qstring.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2013-12-17 16:53:03 -0800
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-31 21:51:29 +0100
commit388bfb273115de603d5000342168a0d4307e824b (patch)
tree83c470df659169090293163ffa9ce6477f4141c6 /src/corelib/tools/qstring.cpp
parent4c9db3989633119756af6fcb61eac5d01d364892 (diff)
Unroll the tail loops of the SSE2-improved code
Change-Id: I1a51ceab3bdabd39bdb9dc2714debb3ad2c2380c Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/corelib/tools/qstring.cpp')
-rw-r--r--src/corelib/tools/qstring.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index a3b0f26044..829132815a 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -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)