DEFSTRUCT-SLOT-DESCRIPTION structure.
changes in sbcl-0.7.14 relative to sbcl-0.7.13:
- * a better implementation of SXHASH on bit vectors, measured both in
- execution speed and in distribution of results over the positive
- fixnums, has been installed.
+ * a better implementation of SXHASH on (simple) bit vectors,
+ measured both in execution speed and in distribution of results
+ over the positive fixnums, has been installed. Likewise, a better
+ implementation of EQUAL for simple bit vectors is now available.
* fixed CEILING optimization for a divisor of form 2^k.
* fixed bug 240 (emitting extra style warnings "using the lexical
binding of the symbol *XXX*" for &OPTIONAL arguments). (reported
"%BREAK"
"NTH-BUT-WITH-SANE-ARG-ORDER"
"DEPRECATION-WARNING"
+ "BIT-VECTOR-="
;; ..and macros..
"COLLECT"
"Return T if OBJ1 and OBJ2 are the same object, otherwise NIL."
(eq obj1 obj2))
+(defun bit-vector-= (x y)
+ (declare (type bit-vector x y))
+ (if (and (simple-bit-vector-p x)
+ (simple-bit-vector-p y))
+ (bit-vector-= x y) ; DEFTRANSFORM
+ (and (= (length x) (length y))
+ (do ((i 0 (1+ i))
+ (length (length x)))
+ ((= i length) t)
+ (declare (fixnum i))
+ (unless (= (bit x i) (bit y i))
+ (return nil))))))
+
(defun equal (x y)
#!+sb-doc
"Return T if X and Y are EQL or if they are structured components
(and (pathnamep y) (pathname= x y)))
((bit-vector-p x)
(and (bit-vector-p y)
- (= (the fixnum (length x))
- (the fixnum (length y)))
- (do ((i 0 (1+ i))
- (length (length x)))
- ((= i length) t)
- (declare (fixnum i))
- (or (= (the fixnum (bit x i))
- (the fixnum (bit y i)))
- (return nil)))))
+ (bit-vector-= x y)))
(t nil)))
;;; EQUALP comparison of HASH-TABLE values
(deftransform sxhash ((x) (simple-bit-vector))
`(let ((result 410823708))
(declare (type fixnum result))
- (mixf result (sxhash (length x)))
- (do* ((i sb!vm:vector-data-offset (+ i 1))
- ;; FIXME: should we respect DEPTHOID? SXHASH on strings
- ;; doesn't seem to...
- (end (+ sb!vm:vector-data-offset
- (ceiling (length x) sb!vm:n-word-bits))))
- ((= i end) result)
- (declare (type index i end))
- (let ((num
- (if (= i (1- end))
- (logand
- (ash (1- (ash 1 (mod (length x) sb!vm:n-word-bits)))
- ,(ecase sb!c:*backend-byte-order*
- (:little-endian 0)
- (:big-endian
- '(- sb!vm:n-word-bits
- (mod (length x) sb!vm:n-word-bits)))))
- (%raw-bits x i))
- (%raw-bits x i))))
- (declare (type (unsigned-byte 32) num))
- (mixf result ,(ecase sb!c:*backend-byte-order*
- (:little-endian '(logand num most-positive-fixnum))
- ;; FIXME: I'm not certain that N-LOWTAG-BITS
- ;; is the clearest way of expressing this:
- ;; it's essentially the difference between
- ;; `(UNSIGNED-BYTE ,SB!VM:N-WORD-BITS) and
- ;; (AND FIXNUM UNSIGNED-BYTE).
- (:big-endian '(ash num (- sb!vm:n-lowtag-bits)))))))))
+ (let ((length (length x)))
+ (cond
+ ((= length 0) (mix result (sxhash 0)))
+ (t
+ (mixf result (sxhash (length x)))
+ (do* ((i sb!vm:vector-data-offset (+ i 1))
+ ;; FIXME: should we respect DEPTHOID? SXHASH on
+ ;; strings doesn't seem to...
+ (end-1 (+ sb!vm:vector-data-offset
+ (floor (1- length) sb!vm:n-word-bits))))
+ ((= i end-1)
+ (let ((num
+ (logand
+ (ash (1- (ash 1 (mod length sb!vm:n-word-bits)))
+ ,(ecase sb!c:*backend-byte-order*
+ (:little-endian 0)
+ (:big-endian
+ '(- sb!vm:n-word-bits
+ (mod length sb!vm:n-word-bits)))))
+ (%raw-bits x i))))
+ (declare (type (unsigned-byte 32) num))
+ (mix result ,(ecase sb!c:*backend-byte-order*
+ (:little-endian
+ '(logand num most-positive-fixnum))
+ (:big-endian
+ '(ash num (- sb!vm:n-lowtag-bits)))))))
+ (declare (type index i end-1))
+ (let ((num (%raw-bits x i)))
+ (declare (type (unsigned-byte 32) num))
+ (mixf result ,(ecase sb!c:*backend-byte-order*
+ (:little-endian
+ '(logand num most-positive-fixnum))
+ ;; FIXME: I'm not certain that
+ ;; N-LOWTAG-BITS is the clearest way of
+ ;; expressing this: it's essentially the
+ ;; difference between `(UNSIGNED-BYTE
+ ;; ,SB!VM:N-WORD-BITS) and (AND FIXNUM
+ ;; UNSIGNED-BYTE).
+ (:big-endian
+ '(ash num (- sb!vm:n-lowtag-bits))))))))))))
;;; Some other common SXHASH cases are defined as DEFTRANSFORMs in
;;; order to avoid having to do TYPECASE at runtime.
(foldable)
#|:derive-type #'result-type-last-arg|#)
+(defknown bit-vector-= (bit-vector bit-vector) boolean
+ (movable foldable flushable))
+
(defknown array-has-fill-pointer-p (array) boolean
(movable foldable flushable))
(defknown fill-pointer (vector) index (foldable unsafely-flushable))
(type index index end-1))
(setf (%raw-bits result-bit-array index)
(32bit-logical-not (%raw-bits bit-array index))))))))
+
+(deftransform bit-vector-= ((x y) (simple-bit-vector simple-bit-vector))
+ `(and (= (length x) (length y))
+ (let ((length (length x)))
+ (or (= length 0)
+ (do* ((i sb!vm:vector-data-offset (+ i 1))
+ (end-1 (+ sb!vm:vector-data-offset
+ (floor (1- length) sb!vm:n-word-bits))))
+ ((= i end-1)
+ (let* ((extra (mod length sb!vm:n-word-bits))
+ (mask (1- (ash 1 extra)))
+ (numx
+ (logand
+ (ash mask
+ ,(ecase sb!c:*backend-byte-order*
+ (:little-endian 0)
+ (:big-endian
+ '(- sb!vm:n-word-bits extra))))
+ (%raw-bits x i)))
+ (numy
+ (logand
+ (ash mask
+ ,(ecase sb!c:*backend-byte-order*
+ (:little-endian 0)
+ (:big-endian
+ '(- sb!vm:n-word-bits extra))))
+ (%raw-bits y i))))
+ (declare (type (integer 0 31) extra)
+ (type (unsigned-byte 32) mask numx numy))
+ (= numx numy)))
+ (declare (type index i end-1))
+ (let ((numx (%raw-bits x i))
+ (numy (%raw-bits y i)))
+ (declare (type (unsigned-byte 32) numx numy))
+ (unless (= numx numy)
+ (return nil))))))))
\f
;;;; %BYTE-BLT
) ; PROGN
-
-;;; KLUDGE: All this ASH optimization is suppressed under CMU CL
-;;; because as of version 2.4.6 for Debian, CMU CL blows up on (ASH
-;;; 1000000000 -100000000000) (i.e. ASH of two bignums yielding zero)
-;;; and it's hard to avoid that calculation in here.
-#-(and cmu sb-xc-host)
-(progn
-
(defun ash-derive-type-aux (n-type shift same-arg)
(declare (ignore same-arg))
+ ;; KLUDGE: All this ASH optimization is suppressed under CMU CL for
+ ;; some bignum cases because as of version 2.4.6 for Debian and 18d,
+ ;; CMU CL blows up on (ASH 1000000000 -100000000000) (i.e. ASH of
+ ;; two bignums yielding zero) and it's hard to avoid that
+ ;; calculation in here.
+ #+(and cmu sb-xc-host)
+ (when (and (or (typep (numeric-type-low n-type) 'bignum)
+ (typep (numeric-type-high n-type) 'bignum))
+ (or (typep (numeric-type-low shift) 'bignum)
+ (typep (numeric-type-high shift) 'bignum)))
+ (return-from ash-derive-type-aux *universal-type*))
(flet ((ash-outer (n s)
(when (and (fixnump s)
(<= s 64)
(defoptimizer (ash derive-type) ((n shift))
(two-arg-derive-type n shift #'ash-derive-type-aux #'ash))
-) ; PROGN
#+sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
(macrolet ((frob (fun)
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.7.13.29"
+"0.7.13.30"