aboutsummaryrefslogtreecommitdiffstats
path: root/zahl-inlines.h
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2016-04-30 02:20:20 +0200
committerMattias Andrée <maandree@kth.se>2016-04-30 02:20:20 +0200
commit599a71a058b8913a4d166485fff6b964247763e9 (patch)
tree99334b6a64ffaa4c926b4e72df87df555d5479b3 /zahl-inlines.h
parentSpecify optimisation level on functions in zahl-inlines.h (diff)
downloadlibzahl-599a71a058b8913a4d166485fff6b964247763e9.tar.gz
libzahl-599a71a058b8913a4d166485fff6b964247763e9.tar.bz2
libzahl-599a71a058b8913a4d166485fff6b964247763e9.tar.xz
Some optimisations
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r--zahl-inlines.h69
1 files changed, 41 insertions, 28 deletions
diff --git a/zahl-inlines.h b/zahl-inlines.h
index 1f04a05..09e09a6 100644
--- a/zahl-inlines.h
+++ b/zahl-inlines.h
@@ -1,17 +1,24 @@
/* See LICENSE file for copyright and license details. */
ZAHL_INLINE void zinit(z_t a) { a->alloced = 0; a->chars = 0; }
-ZAHL_INLINE int zeven(z_t a) { return !a->sign || !(a->chars[0] & 1); }
+ZAHL_INLINE int zeven(z_t a) { return !a->sign || (~a->chars[0] & 1); }
ZAHL_INLINE int zodd(z_t a) { return a->sign && (a->chars[0] & 1); }
-ZAHL_INLINE int zeven_nonzero(z_t a) { return !(a->chars[0] & 1); }
+ZAHL_INLINE int zeven_nonzero(z_t a) { return (~a->chars[0] & 1); }
ZAHL_INLINE int zodd_nonzero(z_t a) { return (a->chars[0] & 1); }
ZAHL_INLINE int zzero(z_t a) { return !a->sign; }
ZAHL_INLINE int zsignum(z_t a) { return a->sign; }
-ZAHL_INLINE void zabs(z_t a, z_t b) { ZAHL_SET(a, b); a->sign = !!a->sign; }
ZAHL_INLINE void zneg(z_t a, z_t b) { ZAHL_SET(a, b); a->sign = -a->sign; }
+#if 1 && (-1 & 1) /* In the future, tuning will select the fastest implementation. */
+ZAHL_INLINE void zabs(z_t a, z_t b) { ZAHL_SET(a, b); a->sign &= 1; }
+#elif 1
+ZAHL_INLINE void zabs(z_t a, z_t b) { ZAHL_SET(a, b); if (ZAHL_LIKELY(a->sign < 0)) a->sign = 1; }
+#else
+ZAHL_INLINE void zabs(z_t a, z_t b) { ZAHL_SET(a, b); a->sign = !!a->sign; }
+#endif
+
-ZAHL_INLINE ZAHL_O3 void
+ZAHL_INLINE void
zswap(z_t a, z_t b)
{
/* Almost three times faster than the naïve method. */
@@ -23,22 +30,24 @@ zswap(z_t a, z_t b)
}
-ZAHL_INLINE ZAHL_O3 void
+ZAHL_INLINE void
zseti(z_t a, int64_t b)
{
if (ZAHL_UNLIKELY(b >= 0)) {
zsetu(a, (uint64_t)b);
- } else {
- zsetu(a, (uint64_t)-b);
- ZAHL_SET_SIGNUM(a, -1);
+ return;
}
+ ZAHL_ENSURE_SIZE(a, 1);
+ ZAHL_SET_SIGNUM(a, -1);
+ a->chars[0] = (zahl_char_t)-b;
+ a->used = 1;
}
-ZAHL_INLINE ZAHL_O3 void
+ZAHL_INLINE void
zsetu(z_t a, uint64_t b)
{
- if (!b) {
+ if (ZAHL_UNLIKELY(!b)) {
ZAHL_SET_SIGNUM(a, 0);
return;
}
@@ -49,7 +58,7 @@ zsetu(z_t a, uint64_t b)
}
-ZAHL_INLINE ZAHL_O3 size_t
+ZAHL_INLINE size_t
zlsb(z_t a)
{
size_t i = 0;
@@ -62,7 +71,7 @@ zlsb(z_t a)
}
-ZAHL_INLINE ZAHL_O3 size_t
+ZAHL_INLINE size_t
zbits(z_t a)
{
size_t rc;
@@ -75,7 +84,7 @@ zbits(z_t a)
}
-ZAHL_INLINE ZAHL_O3 int
+ZAHL_INLINE int
zcmpmag(z_t a, z_t b)
{
size_t i, j;
@@ -103,7 +112,7 @@ zcmpmag(z_t a, z_t b)
}
-ZAHL_INLINE ZAHL_O3 int
+ZAHL_INLINE int
zcmp(z_t a, z_t b)
{
if (zsignum(a) != zsignum(b))
@@ -112,23 +121,23 @@ zcmp(z_t a, z_t b)
}
-ZAHL_INLINE ZAHL_O3 int
+ZAHL_INLINE int
zcmpu(z_t a, uint64_t b)
{
- extern z_t libzahl_tmp_cmp;
if (ZAHL_UNLIKELY(!b))
return zsignum(a);
if (ZAHL_UNLIKELY(zsignum(a) <= 0))
return -1;
- libzahl_tmp_cmp->chars[0] = b;
- return zcmpmag(a, libzahl_tmp_cmp);
+ while (!a->chars[a->used - 1]) a->used--; /* TODO should not be necessary */
+ if (a->used > 1)
+ return +1;
+ return a->chars[0] < b ? -1 : a->chars[0] > b;
}
-ZAHL_INLINE ZAHL_O3 int
+ZAHL_INLINE int
zcmpi(z_t a, int64_t b)
{
- extern z_t libzahl_tmp_cmp;
if (ZAHL_UNLIKELY(!b))
return zsignum(a);
if (ZAHL_UNLIKELY(zzero(a)))
@@ -136,18 +145,22 @@ zcmpi(z_t a, int64_t b)
if (ZAHL_LIKELY(b < 0)) {
if (zsignum(a) > 0)
return +1;
- libzahl_tmp_cmp->chars[0] = (zahl_char_t)-b;
- return -zcmpmag(a, libzahl_tmp_cmp);
+ while (!a->chars[a->used - 1]) a->used--; /* TODO should not be necessary */
+ if (a->used > 1)
+ return -1;
+ return a->chars[0] > (zahl_char_t)-b ? -1 : a->chars[0] < (zahl_char_t)-b;
} else {
if (zsignum(a) < 0)
return -1;
- libzahl_tmp_cmp->chars[0] = (zahl_char_t)b;
- return +zcmpmag(a, libzahl_tmp_cmp);
+ while (!a->chars[a->used - 1]) a->used--; /* TODO should not be necessary */
+ if (a->used > 1)
+ return +1;
+ return a->chars[0] < (zahl_char_t)b ? -1 : a->chars[0] > (zahl_char_t)b;
}
}
-ZAHL_INLINE ZAHL_O3 void
+ZAHL_INLINE void
zbset(z_t a, z_t b, size_t bit, int action)
{
if (ZAHL_UNLIKELY(a != b))
@@ -185,7 +198,7 @@ fallback:
}
-ZAHL_INLINE ZAHL_O3 int
+ZAHL_O3 ZAHL_INLINE int
zbtest(z_t a, size_t bit)
{
size_t chars;
@@ -201,7 +214,7 @@ zbtest(z_t a, size_t bit)
}
-ZAHL_INLINE ZAHL_O3 void
+ZAHL_O3 ZAHL_INLINE void
zsplit(z_t high, z_t low, z_t a, size_t delim)
{
if (ZAHL_UNLIKELY(high == a)) {
@@ -214,7 +227,7 @@ zsplit(z_t high, z_t low, z_t a, size_t delim)
}
-ZAHL_INLINE ZAHL_O3 size_t
+ZAHL_O2 ZAHL_INLINE size_t
zsave(z_t a, void *buffer)
{
if (ZAHL_LIKELY(buffer)) {