master: Restore the ability to use SSETs as CONSETs
snuglas via Sbcl-commits <[email protected]> Sat, 18 Jul 2026 21:25:47 +0000
| Newsgroups | gmane.lisp.steel-bank.cvs |
|---|---|
| Message-ID | <[email protected]> |
The branch "master" has been updated in SBCL:
via 3751ecd35626f8ca2dd5e74bb086b687c36a757a (commit)
from 3b5740a2970f71a30587b01917f24b452e75eeec (commit)
- Log -----------------------------------------------------------------
commit 3751ecd35626f8ca2dd5e74bb086b687c36a757a
Author: Douglas Katzman <[email protected]>
Date: Sat Jul 18 17:10:26 2026 -0400
Restore the ability to use SSETs as CONSETs
The bit-vector choice is still the default, however now we can run experiments
to see if an adaptive approach would make sense. First of all most consets are
small (< 64 bits) so they really could use just 1 word in the CONSET struct
instead of a separately allocated bit-vector. Over 64 bits the bit-vector is ok
but only up to a certain size. Eventually the vector waste so much more space
compared to an SSET because most CONSETs in large universes are not dense.
---
src/compiler/constraint.lisp | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/src/compiler/constraint.lisp b/src/compiler/constraint.lisp
index 5b8307287..6e04e95bc 100644
--- a/src/compiler/constraint.lisp
+++ b/src/compiler/constraint.lisp
@@ -133,6 +133,8 @@
;;; really lose compared to SSETs, here's the conset API as a wrapper
;;; around SSETs:
#+nil
+(eval-when (:compile-toplevel :execute) (push :conset-is-sset sb-xc:*features*))
+#+conset-is-sset
(progn
(deftype conset () 'sset)
(declaim (ftype (sfunction (conset) boolean) conset-empty))
@@ -146,15 +148,11 @@
(defun make-conset () (make-sset))
(defmacro do-conset-elements ((constraint conset &optional result) &body body)
`(do-sset-elements (,constraint ,conset ,result) ,@body))
- (defmacro do-conset-intersection
- ((constraint conset1 conset2 &optional result) &body body)
- `(do-conset-elements (,constraint ,conset1 ,result)
- (when (conset-member ,constraint ,conset2)
- ,@body)))
(defun conset-empty (conset) (sset-empty conset))
(defun copy-conset (conset) (copy-sset conset))
(defun conset-member (constraint conset) (sset-member constraint conset))
(defun conset-adjoin (constraint conset) (sset-adjoin constraint conset))
+ (defun conset-delete (constraint conset) (sset-delete constraint conset))
(defun conset= (conset1 conset2) (sset= conset1 conset2))
;; Note: CP doesn't ever care whether union, intersection, and
;; difference change the first set. (This is an important degree of
@@ -183,6 +181,7 @@
;;; 9 66 1.4 210 4.4 3857 81.0 - (FLET SB-C::BODY-FUN :IN SB-C::TYPE-FROM-CONSTRAINTS)
;;; 10 58 1.2 123 2.6 3915 82.2 - SB-KERNEL::%TYPE-INTERSECTION
+#-conset-is-sset
(locally
;; This is performance critical for the compiler, and benefits
;; from the following declarations. Probably you'll want to
@@ -501,6 +500,7 @@
;;; equality or emptiness testing. There's also union, but that's only an
;;; optimisation to avoid useless copies in ADD-TEST-CONSTRAINTS and
;;; FIND-BLOCK-TYPE-CONSTRAINTS.
+#-conset-is-sset
(defmacro do-conset-elements ((constraint conset &optional result) &body body)
(let ((index '#:index) ; gensym considered harmful
(conset-vector '#:conset-vector)
@@ -557,25 +557,28 @@
&body body)
(let ((min (gensym "MIN"))
(max (gensym "MAX")))
+ (declare (ignorable min max))
(once-only ((conset conset)
(constraints constraints))
`(flet ((body (,symbol)
(declare (type constraint ,symbol))
,@body))
(when ,constraints
- (let ((,min (conset-min ,conset))
- (,max (conset-max ,conset))
+ (let (#-conset-is-sset (,min (conset-min ,conset))
+ #-conset-is-sset (,max (conset-max ,conset))
(vector #-sb-xc-host (truly-the simple-vector (%array-data ,constraints))
- #+sb-xc-host ,constraints))
- #-sb-xc-host
- (declare (optimize (insert-array-bounds-checks 0)))
+ #+sb-xc-host ,constraints))
+ #-sb-xc-host (declare (optimize (insert-array-bounds-checks 0)))
(loop for i below (length ,constraints)
for constraint = (aref vector i)
- do (let ((number (truly-the index (constraint-number (truly-the constraint constraint)))))
- (when (and (<= ,min number)
- (< number ,max)
- (conset-member constraint ,conset))
- (body constraint))))))
+ when #-conset-is-sset
+ (let ((number (truly-the index (constraint-number
+ (truly-the constraint constraint)))))
+ (and (<= ,min number)
+ (< number ,max)
+ (conset-member constraint ,conset)))
+ #+conset-is-sset (conset-member constraint ,conset)
+ do (body constraint))))
,result))))
(defmacro do-eql-vars ((symbol (var constraints) &optional result) &body body)
-----------------------------------------------------------------------
hooks/post-receive
--
SBCL