1.0.30.16: faster COERCE for various (SIMPLE-ARRAY * (*)) subtypes
authorNikodemus Siivola <nikodemus@random-state.net>
Wed, 29 Jul 2009 19:14:46 +0000 (19:14 +0000)
committerNikodemus Siivola <nikodemus@random-state.net>
Wed, 29 Jul 2009 19:14:46 +0000 (19:14 +0000)
 * Optimize for all regonizable subtypes.

 * Also optimize for SIMPLE-STRING.

NEWS
src/compiler/typetran.lisp
version.lisp-expr

diff --git a/NEWS b/NEWS
index 7852683..d65d68b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,9 @@ changes relative to sbcl-1.0.30:
   * new feature: experimental :EMIT-CFASL parameter to COMPILE-FILE can
     be used to output toplevel compile-time effects into a separate .CFASL
     file.
+  * optimization: COERCE to SIMPLE-STRING and recognizable one-dimenstional
+    subtypes of SIMPLE-ARRAY is upto 70% faster when the coercion is actually
+    needed.
   * optimization: division of floating point numbers by constants uses
     multiplication by reciprocal when an exact reciprocal exists.
   * optimization: multiplication of single- and double-floats floats by
index bada4f6..b9106f4 100644 (file)
              ;; FIXME: #!+long-float (t ,(error "LONG-FLOAT case needed"))
              ((csubtypep tspec (specifier-type 'float))
               '(%single-float x))
-             ((and (csubtypep tspec (specifier-type 'simple-vector))
-                   ;; Can we avoid checking for dimension issues like
-                   ;; (COERCE FOO '(SIMPLE-VECTOR 5)) returning a
-                   ;; vector of length 6?
-                   (or (policy node (< safety 3)) ; no need in unsafe code
-                       (and (array-type-p tspec) ; no need when no dimensions
-                            (equal (array-type-dimensions tspec) '(*)))))
-              `(if (simple-vector-p x)
+             ;; Special case this one: SIMPLE-STRING is a union-type.
+             ((type= tspec (specifier-type 'simple-string))
+              `(if (typep x 'simple-string)
                    x
-                   (replace (make-array (length x)) x)))
-             ;; FIXME: other VECTOR types?
+                   (replace (make-array (length x) :element-type 'character) x)))
+             ;; Handle specialized element types.
+             ((csubtypep tspec (specifier-type '(simple-array * (*))))
+              (dolist (etype sb!kernel::*specialized-array-element-types*
+                       (give-up-ir1-transform))
+                (when etype
+                  (let ((spec `(simple-array ,etype (*))))
+                    (when (and (csubtypep tspec (specifier-type spec))
+                               ;; Can we avoid checking for dimension issues like (COERCE FOO
+                               ;; '(SIMPLE-VECTOR 5)) returning a vector of length 6?
+                               (or (policy node (< safety 3)) ; no need in unsafe code
+                                   (and (array-type-p tspec) ; no need when no dimensions
+                                        (equal (array-type-dimensions tspec) '(*)))))
+                      (return
+                        `(if (typep x ',spec)
+                             x
+                             (replace (make-array (length x) :element-type ',etype) x))))
+                    (give-up-ir1-transform)))))
              (t
               (give-up-ir1-transform)))))))
 
index 9d41cd9..ad8a46e 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.30.15"
+"1.0.30.16"