commit d0565fe373f559312be54b6bc8d74aa7fd34fe2c
parent 48a2d06dc7b9dbde36d3979a019457b3d6fc188d
Author: Mattias Andrée <maandree@kth.se>
Date:   Tue,  3 May 2016 00:29:30 +0200
Optimise zswap
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat:
2 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/TODO b/TODO
@@ -7,6 +7,7 @@ Add zstr_radix
 Test big endian
 Test always having used > 0 for zero
   Test negative/non-negative instead of sign
+Test long .sign
 
 Test optimisation of zmul:
   bc = [(Hb * Hc) << (m2 << 1)]
diff --git a/zahl-inlines.h b/zahl-inlines.h
@@ -3,8 +3,8 @@
 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 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 zodd_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 zneg(z_t a, z_t b)   { ZAHL_SET(a, b); a->sign = -a->sign; }
@@ -18,6 +18,31 @@ ZAHL_INLINE void zabs(z_t a, z_t b)   { ZAHL_SET(a, b); a->sign = !!a->sign; }
 #endif
 
 
+#if ULONG_MAX != SIZE_MAX /* This variant should be equivalent to the second one if .sign was long. */
+ZAHL_INLINE void
+zswap(z_t a, z_t b)
+{
+	z_t t;
+	ZAHL_SWAP(a, b, t, sign);
+	ZAHL_SWAP(b, a, t, used);
+	ZAHL_SWAP(a, b, t, alloced);
+	ZAHL_SWAP(b, a, t, chars);
+}
+#else
+ZAHL_INLINE void
+zswap(z_t a_, z_t b_)
+{
+	register long t;
+	long *a = (long *)a_;
+	long *b = (long *)b_;
+	t = a[0], a[0] = b[0], b[0] = t;
+	t = b[1], b[1] = a[1], a[1] = t;
+	t = a[2], a[2] = b[2], b[2] = t;
+	t = b[3], b[3] = a[3], a[3] = t;
+}
+#endif
+
+
 ZAHL_INLINE void
 zset(z_t a, z_t b)
 {
@@ -33,18 +58,6 @@ zset(z_t a, z_t b)
 
 
 ZAHL_INLINE void
-zswap(z_t a, z_t b)
-{
-	/* Almost three times faster than the naïve method. */
-	z_t t;
-	ZAHL_SWAP(a, b, t, sign);
-	ZAHL_SWAP(b, a, t, used);
-	ZAHL_SWAP(a, b, t, alloced);
-	ZAHL_SWAP(b, a, t, chars);
-}
-
-
-ZAHL_INLINE void
 zseti(z_t a, int64_t b)
 {
 	if (ZAHL_UNLIKELY(b >= 0)) {