Skip to content

Commit 059ca75

Browse files
authored
define Spopcount in scheme.h and use intrinsics when possible (#1037)
1 parent 6e9da6d commit 059ca75

9 files changed

Lines changed: 47 additions & 41 deletions

File tree

boot/pb/scheme.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,22 @@ typedef unsigned char octet;
140140
#define Sstring_length(x) ((iptr)((uptr)(*((iptr *)TO_VOIDP((uptr)(x)+1)))>>4))
141141
#define Sstring_ref(x,i) Schar_value(((string_char *)TO_VOIDP((uptr)(x)+9))[i])
142142
#define Sunbox(x) (*((ptr *)TO_VOIDP((uptr)(x)+9)))
143+
static inline int Spopcount(uptr x) {
144+
#if defined(__clang__) || defined(__GNUC__)
145+
return __builtin_popcountll(x);
146+
#else
147+
/* count bits of each 2-bit chunk */
148+
x = x - ((x >> 1) & 0x5555555555555555ULL);
149+
/* count bits of each 4-bit chunk */
150+
x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL);
151+
/* count bits of each 8-bit chunk */
152+
x = x + (x >> 4);
153+
/* mask out junk */
154+
x &= 0x0F0F0F0F0F0F0F0FULL;
155+
/* add all 8-bit chunks */
156+
return (x * 0x0101010101010101ULL) >> 56;
157+
#endif
158+
}
143159
#define Sstencil_vector_length(x) Spopcount(((uptr)(*((iptr *)TO_VOIDP((uptr)(x)+1))))>>6)
144160
#define Sstencil_vector_ref(x,i) (((ptr *)TO_VOIDP((uptr)(x)+9))[i])
145161
EXPORT iptr Sinteger_value(ptr);

c/alloc.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616

1717
#include "system.h"
18-
#include "popcount.h"
1918

2019
/* locally defined functions */
2120
static void maybe_queue_fire_collector(thread_gc *tgc);

c/build.zuo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@
119119
(map at-source
120120
(list "system.h" "types.h" "version.h" "globals.h" "externs.h" "segment.h"
121121
"atomic.h" "thread.h" "sort.h" "compress-io.h"
122-
"nocurses.h" "popcount.h"))
122+
"nocurses.h"))
123123
(list c-config-file)
124124
(map at-mach
125125
(list "equates.h"

c/fasl.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,6 @@
195195

196196
#include "system.h"
197197
#include "zlib.h"
198-
#include "popcount.h"
199198

200199
#ifdef WIN32
201200
#include <io.h>

c/gc.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#ifndef WIN32
1919
#include <sys/wait.h>
2020
#endif /* WIN32 */
21-
#include "popcount.h"
2221
#include <assert.h>
2322

2423
/*

c/gcwrapper.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616

1717
#include "system.h"
18-
#include "popcount.h"
1918

2019
/* locally defined functions */
2120
static void segment_tell(uptr seg);

c/popcount.h

Lines changed: 0 additions & 35 deletions
This file was deleted.

release_notes/release_notes.stex

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2991,6 +2991,12 @@ in fasl files does not generally make sense.
29912991
%-----------------------------------------------------------------------------
29922992
\section{Bug Fixes}\label{section:bugfixes}
29932993

2994+
2995+
\subsection{Declare \scheme{Spopcount} in scheme.h (10.4.0)}
2996+
2997+
A bug where the header file scheme.h refers to an undeclared \scheme{Spopcount} function
2998+
has been fixed.
2999+
29943000
\subsection{Eager port closing on error in \scheme{open-source-file} (10.4.0)}
29953001

29963002
When \scheme{open-source-file} fails on a non-seekable device, the file descriptor port

s/mkheader.ss

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,30 @@
339339
(format "Schar_value~a" (access "x" "i" string data)))
340340

341341
(defref Sunbox box ref)
342-
342+
343+
(let-values
344+
([(suffix fives threes junk-mask ones shift)
345+
(constant-case ptr-bits
346+
[(32) (values "l" "0x55555555" "0x33333333" "0xF0F0F0F" "0x01010101" 24)]
347+
[(64) (values "ll" "0x5555555555555555ULL" "0x3333333333333333ULL"
348+
"0x0F0F0F0F0F0F0F0FULL" "0x0101010101010101ULL" 56)])])
349+
(pr "static inline int Spopcount(uptr x) {\n")
350+
(pr "#if defined(__clang__) || defined(__GNUC__)\n")
351+
(pr " return __builtin_popcount~a(x);\n" suffix)
352+
(pr "#else\n")
353+
(pr " /* count bits of each 2-bit chunk */\n")
354+
(pr " x = x - ((x >> 1) & ~a);\n" fives)
355+
(pr " /* count bits of each 4-bit chunk */\n")
356+
(pr " x = (x & ~a) + ((x >> 2) & ~a);\n" threes threes)
357+
(pr " /* count bits of each 8-bit chunk */\n")
358+
(pr " x = x + (x >> 4);\n")
359+
(pr " /* mask out junk */\n")
360+
(pr " x &= ~a;\n" junk-mask)
361+
(pr " /* add all 8-bit chunks */\n")
362+
(pr " return (x * ~a) >> ~d;\n" ones shift)
363+
(pr "#endif\n")
364+
(pr "}\n"))
365+
343366
(def "Sstencil_vector_length(x)"
344367
(format "Spopcount(((uptr)~a)>>~d)"
345368
(access "x" stencil-vector type)

0 commit comments

Comments
 (0)