;; 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)))))
"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)))))
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