X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fgeneric%2Fvm-tran.lisp;h=7031de38919acc1fcc89d5b09132181525f0ec7c;hb=f294da03824843f07d781e655d5a5e70c2c4851e;hp=8b24413c345a1a68a3136d18db40cbb8d2e40986;hpb=0c7ffa8fb85a94482814835c9f28abfd0400ab99;p=sbcl.git diff --git a/src/compiler/generic/vm-tran.lisp b/src/compiler/generic/vm-tran.lisp index 8b24413..7031de3 100644 --- a/src/compiler/generic/vm-tran.lisp +++ b/src/compiler/generic/vm-tran.lisp @@ -11,13 +11,6 @@ (in-package "SB!C") -;;; FIXME: It would be good to implement SB!XC:DEFCONSTANT, and use -;;; use that here, so that the compiler is born knowing this value. -;;; FIXME: Add a comment telling whether this holds for all vectors -;;; or only for vectors based on simple arrays (non-adjustable, etc.). -(defconstant vector-data-bit-offset - (* sb!vm:vector-data-offset sb!vm:n-word-bits)) - ;;; We need to define these predicates, since the TYPEP source ;;; transform picks whichever predicate was defined last when there ;;; are multiple predicates for equivalent types. @@ -61,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))))) @@ -86,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)))) @@ -107,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))))) @@ -134,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)))) @@ -144,6 +112,29 @@ 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) + + ;; 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 @@ -203,18 +194,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) @@ -237,17 +242,28 @@ (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)))))))) ;;;; %BYTE-BLT