;;; Prevent open coding DIMENSION and :INITIAL-CONTENTS arguments,
;;; so that we can pick them apart.
-(define-source-transform make-array (&whole form &rest args)
- (declare (ignore args))
+(define-source-transform make-array (&whole form dimensions &rest keyargs
+ &environment env)
(if (and (fun-lexically-notinline-p 'list)
(fun-lexically-notinline-p 'vector))
(values nil t)
`(locally (declare (notinline list vector))
- ,form)))
+ ;; Transform '(3) style dimensions to integer args directly.
+ ,(if (sb!xc:constantp dimensions env)
+ (let ((dims (constant-form-value dimensions env)))
+ (if (and (listp dims) (= 1 (length dims)))
+ `(make-array ',(car dims) ,@keyargs)
+ form))
+ form))))
;;; This baby is a bit of a monster, but it takes care of any MAKE-ARRAY
;;; call which creates a vector with a known element type -- and tries
(setf *mystery* :mystery)
(assert (eq :ok (test-mystery (make-thing :slot :mystery))))
+;;; optimizing make-array
+(defun count-code-callees (f)
+ (let ((code (sb-kernel:fun-code-header f))
+ (n 0))
+ (loop for i from sb-vm::code-constants-offset below (sb-kernel:get-header-data code)
+ for c = (sb-kernel:code-header-ref code i)
+ do (when (typep c 'fdefn)
+ (print c)
+ (incf n)))
+ n))
+(assert (zerop (count-code-callees
+ (compile nil
+ `(lambda (x y z)
+ (make-array '(3) :initial-contents (list x y z)))))))
+(assert (zerop (count-code-callees
+ (compile nil
+ `(lambda (x y z)
+ (make-array '3 :initial-contents (vector x y z)))))))
+(assert (zerop (count-code-callees
+ (compile nil
+ `(lambda (x y z)
+ (make-array '3 :initial-contents `(,x ,y ,z)))))))
+
;;; success
;;; 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.28.57"
+"1.0.28.58"