X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fgeneric%2Fvm-tran.lisp;h=7c4cc00da832822b447fa959637e725d2d98e50d;hb=5930ee54090c03d242c70716683b12b95d74a089;hp=e28bc1328f9305dd2e76638f4fead1d5992c2d59;hpb=86210c4e406c1b2ff10cc3bac0e71435867db48b;p=sbcl.git diff --git a/src/compiler/generic/vm-tran.lisp b/src/compiler/generic/vm-tran.lisp index e28bc13..7c4cc00 100644 --- a/src/compiler/generic/vm-tran.lisp +++ b/src/compiler/generic/vm-tran.lisp @@ -54,20 +54,7 @@ ;; to hand-expand it ourselves.) (let ((element-type-specifier (type-specifier element-ctype))) `(multiple-value-bind (array index) - ;; FIXME: All this noise should move into a - ;; %DATA-VECTOR-AND-INDEX function, and there should be - ;; DEFTRANSFORMs for %DATA-VECTOR-AND-INDEX to optimize the - ;; function call away when the array is known to be simple, - ;; and to specialize to - ;; %DATA-VECTOR-AND-INDEX-IN-VECTOR-CASE when the array is - ;; known to have only one dimension. - (if (array-header-p array) - (%with-array-data array index nil) - (let ((array array)) - (declare (type (simple-array ,element-type-specifier 1) - array)) - (%check-bound array 0 index) - (values array index))) + (%data-vector-and-index array index) (declare (type (simple-array ,element-type-specifier 1) array)) (data-vector-ref array index))))) @@ -79,7 +66,7 @@ (let ((dims (array-type-dimensions array-type))) (when (or (atom dims) (= (length dims) 1)) (give-up-ir1-transform)) - (let ((el-type (array-type-element-type array-type)) + (let ((el-type (array-type-specialized-element-type array-type)) (total-size (if (member '* dims) '* (reduce #'* dims)))) @@ -100,22 +87,10 @@ "Upgraded element type of array is not known at compile time.")) (let ((element-type-specifier (type-specifier element-ctype))) `(multiple-value-bind (array index) - ;; FIXME: All this noise should move into a - ;; %DATA-VECTOR-AND-INDEX function, and there should be - ;; DEFTRANSFORMs for %DATA-VECTOR-AND-INDEX to optimize the - ;; function call away when the array is known to be simple, - ;; and to specialize to - ;; %DATA-VECTOR-AND-INDEX-IN-VECTOR-CASE when the array is - ;; known to have only one dimension. - (if (array-header-p array) - (%with-array-data array index nil) - (let ((array array)) - (declare (type (simple-array ,element-type-specifier 1) - array)) - (%check-bound array 0 index) - (values array index))) - (data-vector-set (truly-the (simple-array ,element-type-specifier 1) - array) + (%data-vector-and-index array index) + (declare (type (simple-array ,element-type-specifier 1) array) + (type ,element-type-specifier new-value)) + (data-vector-set array index new-value))))) @@ -127,7 +102,7 @@ (let ((dims (array-type-dimensions array-type))) (when (or (atom dims) (= (length dims) 1)) (give-up-ir1-transform)) - (let ((el-type (array-type-element-type array-type)) + (let ((el-type (array-type-specialized-element-type array-type)) (total-size (if (member '* dims) '* (reduce #'* dims)))) @@ -137,6 +112,39 @@ index new-value))))) +(defoptimizer (%data-vector-and-index derive-type) ((array index)) + (let ((atype (continuation-type array))) + (when (array-type-p atype) + (values-specifier-type + `(values (simple-array ,(type-specifier + (array-type-specialized-element-type atype)) + (*)) + index))))) + +(deftransform %data-vector-and-index ((%array %index) + (simple-array t) + * + :important t) + ;; KLUDGE: why the percent signs? Well, ARRAY and INDEX are + ;; respectively exported from the CL and SB!INT packages, which + ;; means that they're visible to all sorts of things. If the + ;; compiler can prove that the call to ARRAY-HEADER-P, below, either + ;; returns T or NIL, it will delete the irrelevant branch. However, + ;; user code might have got here with a variable named CL:ARRAY, and + ;; quite often compiler code with a variable named SB!INT:INDEX, so + ;; this can generate code deletion notes for innocuous user code: + ;; (DEFUN F (ARRAY I) (DECLARE (SIMPLE-VECTOR ARRAY)) (AREF ARRAY I)) + ;; -- CSR, 2003-04-01 + + ;; We do this solely for the -OR-GIVE-UP side effect, since we want + ;; to know that the type can be figured out in the end before we + ;; proceed, but we don't care yet what the type will turn out to be. + (upgraded-element-type-specifier-or-give-up %array) + + '(if (array-header-p %array) + (values (%array-data-vector %array) %index) + (values %array %index))) + ;;; transforms for getting at simple arrays of (UNSIGNED-BYTE N) when (< N 8) ;;; ;;; FIXME: In CMU CL, these were commented out with #+NIL. Why? Should @@ -196,18 +204,32 @@ bit-array-1 bit-array-2 result-bit-array)))) - (do ((index sb!vm:vector-data-offset (1+ index)) - (end (+ sb!vm:vector-data-offset - (truncate (the index - (+ (length bit-array-1) - sb!vm:n-word-bits -1)) - sb!vm:n-word-bits)))) - ((= index end) result-bit-array) - (declare (optimize (speed 3) (safety 0)) - (type index index end)) - (setf (%raw-bits result-bit-array index) - (,',wordfun (%raw-bits bit-array-1 index) - (%raw-bits bit-array-2 index)))))))) + (let ((length (length result-bit-array))) + (if (= length 0) + ;; We avoid doing anything to 0-length + ;; bit-vectors, or rather, the memory that + ;; follows them. Other divisible-by-32 cases + ;; are handled by the (1- length), below. + ;; CSR, 2002-04-24 + result-bit-array + (do ((index sb!vm:vector-data-offset (1+ index)) + (end-1 (+ sb!vm:vector-data-offset + ;; bit-vectors of length 1-32 + ;; need precisely one (SETF + ;; %RAW-BITS), done here in the + ;; epilogue. - CSR, 2002-04-24 + (truncate (truly-the index (1- length)) + sb!vm:n-word-bits)))) + ((= index end-1) + (setf (%raw-bits result-bit-array index) + (,',wordfun (%raw-bits bit-array-1 index) + (%raw-bits bit-array-2 index))) + result-bit-array) + (declare (optimize (speed 3) (safety 0)) + (type index index end-1)) + (setf (%raw-bits result-bit-array index) + (,',wordfun (%raw-bits bit-array-1 index) + (%raw-bits bit-array-2 index)))))))))) (def bit-and 32bit-logical-and) (def bit-ior 32bit-logical-or) (def bit-xor 32bit-logical-xor) @@ -230,17 +252,64 @@ (error "Argument and result bit arrays are not the same length:~ ~% ~S~% ~S" bit-array result-bit-array)))) - (do ((index sb!vm:vector-data-offset (1+ index)) - (end (+ sb!vm:vector-data-offset - (truncate (the index - (+ (length bit-array) - (1- sb!vm:n-word-bits))) - sb!vm:n-word-bits)))) - ((= index end) result-bit-array) - (declare (optimize (speed 3) (safety 0)) - (type index index end)) - (setf (%raw-bits result-bit-array index) - (32bit-logical-not (%raw-bits bit-array index)))))) + (let ((length (length result-bit-array))) + (if (= length 0) + ;; We avoid doing anything to 0-length bit-vectors, or + ;; rather, the memory that follows them. Other + ;; divisible-by-32 cases are handled by the (1- length), + ;; below. CSR, 2002-04-24 + result-bit-array + (do ((index sb!vm:vector-data-offset (1+ index)) + (end-1 (+ sb!vm:vector-data-offset + ;; bit-vectors of length 1-32 need precisely + ;; one (SETF %RAW-BITS), done here in the + ;; epilogue. - CSR, 2002-04-24 + (truncate (truly-the index (1- length)) + sb!vm:n-word-bits)))) + ((= index end-1) + (setf (%raw-bits result-bit-array index) + (32bit-logical-not (%raw-bits bit-array index))) + result-bit-array) + (declare (optimize (speed 3) (safety 0)) + (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)))))))) ;;;; %BYTE-BLT