X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Floop.lisp;h=6b9a43aaaac49e4abef570e68dcff6c0b7f567ed;hb=fb76e3acd8b8a53cdadaa65bce1d090d99e004a0;hp=101a8df8978d9bd1f5cefb10c8f9ab37ad2bc401;hpb=5369caf4d418065012b96af0d29c74d7851c04ff;p=sbcl.git diff --git a/src/code/loop.lisp b/src/code/loop.lisp index 101a8df..6b9a43a 100644 --- a/src/code/loop.lisp +++ b/src/code/loop.lisp @@ -503,27 +503,21 @@ code to be loaded. ;;;; code analysis stuff (defun loop-constant-fold-if-possible (form &optional expected-type) - (let ((new-form form) (constantp nil) (constant-value nil)) - (when (setq constantp (constantp new-form)) - (setq constant-value (eval new-form))) + (let* ((constantp (sb!xc:constantp form)) + (value (and constantp (sb!int:constant-form-value form)))) (when (and constantp expected-type) - (unless (sb!xc:typep constant-value expected-type) + (unless (sb!xc:typep value expected-type) (loop-warn "~@" - form constant-value expected-type) - (setq constantp nil constant-value nil))) - (values new-form constantp constant-value))) - -(defun loop-constantp (form) - (constantp form)) + form value expected-type) + (setq constantp nil value nil))) + (values form constantp value))) ;;;; LOOP iteration optimization -(defvar *loop-duplicate-code* - nil) +(defvar *loop-duplicate-code* nil) -(defvar *loop-iteration-flag-var* - (make-symbol "LOOP-NOT-FIRST-TIME")) +(defvar *loop-iteration-flag-var* (make-symbol "LOOP-NOT-FIRST-TIME")) (defun loop-code-duplication-threshold (env) (declare (ignore env)) @@ -923,10 +917,22 @@ code to be loaded. (defun loop-typed-init (data-type &optional step-var-p) (when (and data-type (sb!xc:subtypep data-type 'number)) - (if (or (sb!xc:subtypep data-type 'float) - (sb!xc:subtypep data-type '(complex float))) - (coerce (if step-var-p 1 0) data-type) - (if step-var-p 1 0)))) + (let ((init (if step-var-p 1 0))) + (flet ((like (&rest types) + (coerce init (find-if (lambda (type) + (sb!xc:subtypep data-type type)) + types)))) + (cond ((sb!xc:subtypep data-type 'float) + (like 'single-float 'double-float + 'short-float 'long-float 'float)) + ((sb!xc:subtypep data-type '(complex float)) + (like '(complex single-float) + '(complex double-float) + '(complex short-float) + '(complex long-float) + '(complex float))) + (t + init)))))) (defun loop-optional-type (&optional variable) ;; No variable specified implies that no destructuring is permissible. @@ -1052,7 +1058,9 @@ code to be loaded. (defun loop-declare-var (name dtype &optional step-var-p) (cond ((or (null name) (null dtype) (eq dtype t)) nil) ((symbolp name) - (unless (sb!xc:subtypep t dtype) + (unless (or (sb!xc:subtypep t dtype) + (and (eq (find-package :cl) (symbol-package name)) + (eq :special (sb!int:info :variable :kind name)))) (let ((dtype (let ((init (loop-typed-init dtype step-var-p))) (if (sb!xc:typep init dtype) dtype @@ -1067,7 +1075,7 @@ code to be loaded. (t (error "invalid LOOP variable passed in: ~S" name)))) (defun loop-maybe-bind-form (form data-type) - (if (loop-constantp form) + (if (constantp form) form (loop-make-var (gensym "LOOP-BIND-") form data-type))) @@ -1726,7 +1734,8 @@ code to be loaded. `(and ,indexv-type real))))) (:by (multiple-value-setq (form stepby-constantp stepby) - (loop-constant-fold-if-possible form `(and ,indexv-type (real (0))))) + (loop-constant-fold-if-possible form + `(and ,indexv-type (real (0))))) (unless stepby-constantp (loop-make-var (setq stepby (gensym "LOOP-STEP-BY-")) form @@ -1737,7 +1746,8 @@ code to be loaded. maybe invalid prepositions were specified in iteration path descriptor?" prep))) (when (and odir dir (not (eq dir odir))) - (loop-error "conflicting stepping directions in LOOP sequencing path")) + (loop-error + "conflicting stepping directions in LOOP sequencing path")) (setq odir dir)) (when (and sequence-variable (not sequencep)) (loop-error "missing OF or IN phrase in sequence path")) @@ -1755,8 +1765,9 @@ code to be loaded. :key #'type-declaration-of :from-end t))) (sb!int:aver (eq decl %decl)) - (setf (cadr decl) - `(and real ,(cadr decl)))))) + (when decl + (setf (cadr decl) + `(and real ,(cadr decl))))))) ;; default start ;; DUPLICATE KLUDGE: loop-make-var generates a temporary ;; symbol for indexv if it is NIL. See also the comment in