From: Nikodemus Siivola Date: Wed, 29 Jul 2009 19:14:46 +0000 (+0000) Subject: 1.0.30.16: faster COERCE for various (SIMPLE-ARRAY * (*)) subtypes X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=9d58d34a720c08b3c79f699222d9928e539c8471;p=sbcl.git 1.0.30.16: faster COERCE for various (SIMPLE-ARRAY * (*)) subtypes * Optimize for all regonizable subtypes. * Also optimize for SIMPLE-STRING. --- diff --git a/NEWS b/NEWS index 7852683..d65d68b 100644 --- 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 diff --git a/src/compiler/typetran.lisp b/src/compiler/typetran.lisp index bada4f6..b9106f4 100644 --- a/src/compiler/typetran.lisp +++ b/src/compiler/typetran.lisp @@ -614,17 +614,28 @@ ;; 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))))))) diff --git a/version.lisp-expr b/version.lisp-expr index 9d41cd9..ad8a46e 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -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"