SHA256
1
0
forked from pool/zlib
zlib/zlib-1.2.12-add-optimized-slide_hash-for-power.patch
Dirk Mueller f6c5a01beb Accepting request 1009574 from home:dspinella:branches:devel:libraries:c_c++
- Add Power8 optimizations:
  * zlib-1.2.12-add-optimized-slide_hash-for-power.patch
  * zlib-1.2.12-add-vectorized-longest_match-for-power.patch
  * zlib-1.2.12-adler32-vector-optimizations-for-power.patch
  * zlib-1.2.12-fix-invalid-memory-access-on-ppc-and-ppc64.patch
- Update zlib-1.2.12-IBM-Z-hw-accelerated-deflate-s390x.patch

OBS-URL: https://build.opensuse.org/request/show/1009574
OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/zlib?expand=0&rev=82
2022-10-11 12:40:29 +00:00

220 lines
7.7 KiB
Diff

From 4a8d89ae49aa17d1634a2816c8d159f533a07eae Mon Sep 17 00:00:00 2001
From: Matheus Castanho <msc@linux.ibm.com>
Date: Wed, 27 Nov 2019 10:18:10 -0300
Subject: [PATCH] Add optimized slide_hash for Power
Considerable time is spent on deflate.c:slide_hash() during
deflate. This commit introduces a new slide_hash function that
uses VSX vector instructions to slide 8 hash elements at a time,
instead of just one as the standard code does.
The choice between the optimized and default versions is made only
on the first call to the function, enabling a fallback to standard
behavior if the host processor does not support VSX instructions,
so the same binary can be used for multiple Power processor
versions.
Author: Matheus Castanho <msc@linux.ibm.com>
---
CMakeLists.txt | 3 +-
Makefile.in | 8 ++++
configure | 4 +-
contrib/power/power.h | 3 ++
contrib/power/slide_hash_power8.c | 63 +++++++++++++++++++++++++++++
contrib/power/slide_hash_resolver.c | 15 +++++++
deflate.c | 12 ++++++
7 files changed, 105 insertions(+), 3 deletions(-)
create mode 100644 contrib/power/slide_hash_power8.c
create mode 100644 contrib/power/slide_hash_resolver.c
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 44de486f6..8208c626b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -186,7 +186,8 @@ if(CMAKE_COMPILER_IS_GNUCC)
add_definitions(-DZ_POWER8)
set(ZLIB_POWER8
contrib/power/adler32_power8.c
- contrib/power/crc32_z_power8.c)
+ contrib/power/crc32_z_power8.c
+ contrib/power/slide_hash_power8.c)
set_source_files_properties(
${ZLIB_POWER8}
diff --git a/Makefile.in b/Makefile.in
index 9ef9fa9b5..f71c6eae0 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -183,6 +183,9 @@ crc32_z_power8.o: $(SRCDIR)contrib/power/crc32_z_power8.c
deflate.o: $(SRCDIR)deflate.c
$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c
+slide_hash_power8.o: $(SRCDIR)contrib/power/slide_hash_power8.c
+ $(CC) $(CFLAGS) -mcpu=power8 $(ZINC) -c -o $@ $(SRCDIR)contrib/power/slide_hash_power8.c
+
infback.o: $(SRCDIR)infback.c
$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)infback.c
@@ -245,6 +248,11 @@ deflate.lo: $(SRCDIR)deflate.c
$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/deflate.o $(SRCDIR)deflate.c
-@mv objs/deflate.o $@
+slide_hash_power8.lo: $(SRCDIR)contrib/power/slide_hash_power8.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) -mcpu=power8 $(ZINC) -DPIC -c -o objs/slide_hash_power8.o $(SRCDIR)contrib/power/slide_hash_power8.c
+ -@mv objs/slide_hash_power8.o $@
+
infback.lo: $(SRCDIR)infback.c
-@mkdir objs 2>/dev/null || test -d objs
$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/infback.o $(SRCDIR)infback.c
diff --git a/configure b/configure
index 810a7404d..d0dacf9c2 100755
--- a/configure
+++ b/configure
@@ -879,8 +879,8 @@ if tryboth $CC -c $CFLAGS $test.c; then
if tryboth $CC -c $CFLAGS -mcpu=power8 $test.c; then
POWER8="-DZ_POWER8"
- PIC_OBJC="${PIC_OBJC} adler32_power8.lo crc32_z_power8.lo"
- OBJC="${OBJC} adler32_power8.o crc32_z_power8.o"
+ PIC_OBJC="${PIC_OBJC} adler32_power8.lo crc32_z_power8.lo slide_hash_power8.lo"
+ OBJC="${OBJC} adler32_power8.o crc32_z_power8.o slide_hash_power8.o"
echo "Checking for -mcpu=power8 support... Yes." | tee -a configure.log
else
echo "Checking for -mcpu=power8 support... No." | tee -a configure.log
diff --git a/contrib/power/power.h b/contrib/power/power.h
index f57c76167..28c8f78ca 100644
--- a/contrib/power/power.h
+++ b/contrib/power/power.h
@@ -4,7 +4,10 @@
*/
#include "../../zconf.h"
#include "../../zutil.h"
+#include "../../deflate.h"
uLong _adler32_power8(uLong adler, const Bytef* buf, uInt len);
unsigned long _crc32_z_power8(unsigned long, const Bytef *, z_size_t);
+
+void _slide_hash_power8(deflate_state *s);
diff --git a/contrib/power/slide_hash_power8.c b/contrib/power/slide_hash_power8.c
new file mode 100644
index 000000000..c5a0eb5a6
--- /dev/null
+++ b/contrib/power/slide_hash_power8.c
@@ -0,0 +1,63 @@
+ /* Copyright (C) 2019 Matheus Castanho <msc@linux.ibm.com>, IBM
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include <altivec.h>
+#include "../../deflate.h"
+
+local inline void slide_hash_power8_loop OF((deflate_state *s,
+ unsigned n_elems, Posf *table_end)) __attribute__((always_inline));
+
+local void slide_hash_power8_loop(
+ deflate_state *s,
+ unsigned n_elems,
+ Posf *table_end)
+{
+ vector unsigned short vw, vm, *vp;
+ unsigned chunks;
+
+ /* Each vector register (chunk) corresponds to 128 bits == 8 Posf,
+ * so instead of processing each of the n_elems in the hash table
+ * individually, we can do it in chunks of 8 with vector instructions.
+ *
+ * This function is only called from slide_hash_power8(), and both calls
+ * pass n_elems as a power of 2 higher than 2^7, as defined by
+ * deflateInit2_(), so n_elems will always be a multiple of 8. */
+ chunks = n_elems >> 3;
+ Assert(n_elems % 8 == 0, "Weird hash table size!");
+
+ /* This type casting is safe since s->w_size is always <= 64KB
+ * as defined by deflateInit2_() and Posf == unsigned short */
+ vw[0] = (Posf) s->w_size;
+ vw = vec_splat(vw,0);
+
+ vp = (vector unsigned short *) table_end;
+
+ do {
+ /* Processing 8 elements at a time */
+ vp--;
+ vm = *vp;
+
+ /* This is equivalent to: m >= w_size ? m - w_size : 0
+ * Since we are using a saturated unsigned subtraction, any
+ * values that are > w_size will be set to 0, while the others
+ * will be subtracted by w_size. */
+ *vp = vec_subs(vm,vw);
+ } while (--chunks);
+};
+
+void ZLIB_INTERNAL _slide_hash_power8(deflate_state *s)
+{
+ unsigned n;
+ Posf *p;
+
+ n = s->hash_size;
+ p = &s->head[n];
+ slide_hash_power8_loop(s,n,p);
+
+#ifndef FASTEST
+ n = s->w_size;
+ p = &s->prev[n];
+ slide_hash_power8_loop(s,n,p);
+#endif
+}
diff --git a/contrib/power/slide_hash_resolver.c b/contrib/power/slide_hash_resolver.c
new file mode 100644
index 000000000..54fa1eb21
--- /dev/null
+++ b/contrib/power/slide_hash_resolver.c
@@ -0,0 +1,15 @@
+/* Copyright (C) 2019 Matheus Castanho <msc@linux.ibm.com>, IBM
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "../gcc/zifunc.h"
+#include "power.h"
+
+Z_IFUNC(slide_hash) {
+#ifdef Z_POWER8
+ if (__builtin_cpu_supports("arch_2_07"))
+ return _slide_hash_power8;
+#endif
+
+ return slide_hash_default;
+}
diff --git a/deflate.c b/deflate.c
index 799fb93cc..b2db576dc 100644
--- a/deflate.c
+++ b/deflate.c
@@ -196,6 +196,13 @@ local const config configuration_table[10] = {
(unsigned)(s->hash_size-1)*sizeof(*s->head)); \
} while (0)
+#ifdef Z_POWER_OPT
+/* Rename function so resolver can use its symbol. The default version will be
+ * returned by the resolver if the host has no support for an optimized version.
+ */
+#define slide_hash slide_hash_default
+#endif /* Z_POWER_OPT */
+
/* ===========================================================================
* Slide the hash table when sliding the window down (could be avoided with 32
* bit values at the expense of memory usage). We slide even when level == 0 to
@@ -227,6 +234,11 @@ local void slide_hash(s)
#endif
}
+#ifdef Z_POWER_OPT
+#undef slide_hash
+#include "contrib/power/slide_hash_resolver.c"
+#endif /* Z_POWER_OPT */
+
/* ========================================================================= */
int ZEXPORT deflateInit_(strm, level, version, stream_size)
z_streamp strm;