pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
[PATCH v1 1/1] Auto-vectorize the varbit bitwise operators.
1+ messages / 1 participants
[nested] [flat]

* [PATCH v1 1/1] Auto-vectorize the varbit bitwise operators.
@ 2026-09-02 18:52 Nathan Bossart <nathan@postgresql.org>
  0 siblings, 0 replies; 1+ messages in thread

From: Nathan Bossart @ 2026-09-02 18:52 UTC (permalink / raw)

Compile varbit.c with -ftree-vectorize where available, and adjust
the loops in bit_and(), bit_or(), bitxor(), and bitnot() so that
they are amenable to being auto-vectorized.  (Mainly, that involves
reading the byte count into a local variable before the loop.  As
written, the bound is recomputed from the varlena header on every
iteration, because the compiler must assume that the loop might
modify the header.)
---
 src/backend/utils/adt/Makefile    |  3 ++-
 src/backend/utils/adt/meson.build |  9 ++++-----
 src/backend/utils/adt/varbit.c    | 25 +++++++++++++++++--------
 3 files changed, 23 insertions(+), 14 deletions(-)

inline patch 1: src/backend/utils/adt/Makefile, src/backend/utils/adt/meson.build, src/backend/utils/adt/varbit.c (+23/-14 lines) download inline-1.patchdiff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile index 0c7621957c1..94ac5169940 100644 --- a/src/backend/utils/adt/Makefile +++ b/src/backend/utils/adt/Makefile @@ -150,8 +150,9 @@ clean: like.o: like.c like_match.c -# Some code in numeric.c benefits from auto-vectorization +# Some code benefits from auto-vectorization numeric.o: CFLAGS += ${CFLAGS_VECTORIZE} +varbit.o: CFLAGS += ${CFLAGS_VECTORIZE} varlena.o: varlena.c levenshtein.c diff --git a/src/backend/utils/adt/meson.build b/src/backend/utils/adt/meson.build index d793f8145f6..04d6f8aa168 100644 --- a/src/backend/utils/adt/meson.build +++ b/src/backend/utils/adt/meson.build @@ -1,14 +1,14 @@ # Copyright (c) 2022-2026, PostgreSQL Global Development Group -# Some code in numeric.c benefits from auto-vectorization -numeric_backend_lib = static_library('numeric_backend_lib', - 'numeric.c', +# Some code benefits from auto-vectorization +vectorize_backend_lib = static_library('vectorize_backend_lib', + ['numeric.c', 'varbit.c'], dependencies: backend_build_deps, kwargs: internal_lib_args, c_args: vectorize_cflags, ) -backend_link_with += numeric_backend_lib +backend_link_with += vectorize_backend_lib backend_sources += files( 'acl.c', @@ -118,7 +118,6 @@ backend_sources += files( 'tsvector_op.c', 'tsvector_parser.c', 'uuid.c', - 'varbit.c', 'varchar.c', 'varlena.c', 'version.c', diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c index fe49ba851ac..cbb60e68335 100644 --- a/src/backend/utils/adt/varbit.c +++ b/src/backend/utils/adt/varbit.c @@ -1251,6 +1251,7 @@ bit_and(PG_FUNCTION_ARGS) uint8 *p1, *p2, *r; + size_t nbytes; bitlen1 = VARBITLEN(arg1); bitlen2 = VARBITLEN(arg2); @@ -1267,8 +1268,9 @@ bit_and(PG_FUNCTION_ARGS) p1 = VARBITS(arg1); p2 = VARBITS(arg2); r = VARBITS(result); - for (size_t i = 0; i < VARBITBYTES(arg1); i++) - *r++ = *p1++ & *p2++; + nbytes = VARBITBYTES(arg1); + for (size_t i = 0; i < nbytes; i++) + r[i] = p1[i] & p2[i]; /* Padding is not needed as & of 0 pads is 0 */ @@ -1291,6 +1293,7 @@ bit_or(PG_FUNCTION_ARGS) uint8 *p1, *p2, *r; + size_t nbytes; bitlen1 = VARBITLEN(arg1); bitlen2 = VARBITLEN(arg2); @@ -1306,8 +1309,9 @@ bit_or(PG_FUNCTION_ARGS) p1 = VARBITS(arg1); p2 = VARBITS(arg2); r = VARBITS(result); - for (size_t i = 0; i < VARBITBYTES(arg1); i++) - *r++ = *p1++ | *p2++; + nbytes = VARBITBYTES(arg1); + for (size_t i = 0; i < nbytes; i++) + r[i] = p1[i] | p2[i]; /* Padding is not needed as | of 0 pads is 0 */ @@ -1330,6 +1334,7 @@ bitxor(PG_FUNCTION_ARGS) uint8 *p1, *p2, *r; + size_t nbytes; bitlen1 = VARBITLEN(arg1); bitlen2 = VARBITLEN(arg2); @@ -1346,8 +1351,9 @@ bitxor(PG_FUNCTION_ARGS) p1 = VARBITS(arg1); p2 = VARBITS(arg2); r = VARBITS(result); - for (size_t i = 0; i < VARBITBYTES(arg1); i++) - *r++ = *p1++ ^ *p2++; + nbytes = VARBITBYTES(arg1); + for (size_t i = 0; i < nbytes; i++) + r[i] = p1[i] ^ p2[i]; /* Padding is not needed as ^ of 0 pads is 0 */ @@ -1365,6 +1371,7 @@ bitnot(PG_FUNCTION_ARGS) VarBit *result; uint8 *p, *r; + size_t nbytes; result = (VarBit *) palloc(VARSIZE(arg)); SET_VARSIZE(result, VARSIZE(arg)); @@ -1372,8 +1379,10 @@ bitnot(PG_FUNCTION_ARGS) p = VARBITS(arg); r = VARBITS(result); - for (; p < VARBITEND(arg); p++) - *r++ = ~*p; + nbytes = VARBITBYTES(arg); + for (size_t i = 0; i < nbytes; i++) + r[i] = ~p[i]; + r += nbytes; /* Must zero-pad the result, because extra bits are surely 1's here */ VARBIT_PAD_LAST(result, r); -- 2.55.0
--/PKgyr8biqo/qZ1W-- ^ permalink raw reply [nested|flat] 1+ messages in thread


only message in thread

Thread overview: 1+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2026-09-02 18:52 [PATCH v1 1/1] Auto-vectorize the varbit bitwise operators. Nathan Bossart <nathan@postgresql.org>

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox