1.0.11.33: Oops, restore REPLACE deftransforms that got dropped in refactoring
[sbcl.git] / src / compiler / array-tran.lisp
index 0d47738..3579975 100644 (file)
                                 :node node
                                 :policy (> speed space))
   "inline non-SIMPLE-vector-handling logic"
-  (let ((element-type (upgraded-element-type-specifier-or-give-up array)))
-    `(%with-array-data-macro array start end
-                             :unsafe? ,(policy node (= safety 0))
-                             :element-type ,element-type)))
+  (let ((element-type (upgraded-element-type-specifier-or-give-up array))
+        (type (lvar-type array)))
+    (if (and (array-type-p type)
+             (listp (array-type-dimensions type))
+             (not (null (cdr (array-type-dimensions type)))))
+        ;; If it's a simple multidimensional array, then just return its
+        ;; data vector directly rather than going through
+        ;; %WITH-ARRAY-DATA-MACRO.  SBCL doesn't generally generate code
+        ;; that would use this currently, but we have encouraged users
+        ;; to use WITH-ARRAY-DATA and we may use it ourselves at some
+        ;; point in the future for optimized libraries or similar.
+        `(let ((data (truly-the (simple-array ,element-type (*))
+                                (%array-data-vector array))))
+           (values data 0 (length data) 0))
+        `(%with-array-data-macro array start end
+                                 :unsafe? ,(policy node (= safety 0))
+                                 :element-type ,element-type))))
 \f
 ;;;; array accessors
 
 
 ;; For AREF of vectors we do the bounds checking in the callee. This
 ;; lets us do a significantly more efficient check for simple-arrays
-;; without bloating the code.
+;; without bloating the code. If we already know the type of the array
+;; with sufficient precision, skip directly to DATA-VECTOR-REF.
 (deftransform aref ((array index) (t t) * :node node)
-  (if (policy node (zerop insert-array-bounds-checks))
-      `(hairy-data-vector-ref array index)
-      `(hairy-data-vector-ref/check-bounds array index)))
+  (let ((type (lvar-type array)))
+    (cond ((and (array-type-p type)
+                (null (array-type-complexp type))
+                (not (eql (extract-upgraded-element-type array)
+                          *wild-type*))
+                (eql (length (array-type-dimensions type)) 1))
+           `(data-vector-ref array (%check-bound array
+                                                 (array-dimension array 0)
+                                                 index)))
+          ((policy node (zerop insert-array-bounds-checks))
+           `(hairy-data-vector-ref array index))
+          (t
+           `(hairy-data-vector-ref/check-bounds array index)))))
 
 (deftransform %aset ((array index new-value) (t t t) * :node node)
   (if (policy node (zerop insert-array-bounds-checks))
   (define hairy-data-vector-set/check-bounds
       hairy-data-vector-set (new-value) (*)))
 
-(deftransform aref ((array index) ((or simple-vector
-                                       (simple-unboxed-array 1))
-                                   index))
-  (let ((type (lvar-type array)))
-    (unless (array-type-p type)
-      ;; Not an exactly specified one-dimensional simple array -> punt
-      ;; to the complex version.
-      (give-up-ir1-transform)))
-  `(data-vector-ref array (%check-bound array
-                                        (array-dimension array 0)
-                                        index)))
-
 ;;; Just convert into a HAIRY-DATA-VECTOR-REF (or
 ;;; HAIRY-DATA-VECTOR-SET) after checking that the index is inside the
 ;;; array total size.