X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fir1opt.lisp;h=d091f381e4353a5d08f0cd787f297184ccc502c0;hb=95591ed483dbb8c0846c129953acac1554f28809;hp=b26cb6513f8e7bda2c70ad2db351f3106cb5d766;hpb=09ba205d5ff72b9f4b1ffcf8743809c01a9c69e5;p=sbcl.git diff --git a/src/compiler/ir1opt.lisp b/src/compiler/ir1opt.lisp index b26cb65..d091f38 100644 --- a/src/compiler/ir1opt.lisp +++ b/src/compiler/ir1opt.lisp @@ -23,15 +23,28 @@ (defun constant-lvar-p (thing) (declare (type (or lvar null) thing)) (and (lvar-p thing) - (let ((use (principal-lvar-use thing))) - (and (ref-p use) (constant-p (ref-leaf use)))))) + (or (let ((use (principal-lvar-use thing))) + (and (ref-p use) (constant-p (ref-leaf use)))) + ;; check for EQL types (but not singleton numeric types) + (let ((type (lvar-type thing))) + (and (member-type-p type) + (eql 1 (member-type-size type))))))) ;;; Return the constant value for an LVAR whose only use is a constant ;;; node. (declaim (ftype (function (lvar) t) lvar-value)) (defun lvar-value (lvar) - (let ((use (principal-lvar-use lvar))) - (constant-value (ref-leaf use)))) + (let ((use (principal-lvar-use lvar)) + (type (lvar-type lvar)) + leaf) + (cond ((and (ref-p use) + (constant-p (setf leaf (ref-leaf use)))) + (constant-value leaf)) + ((and (member-type-p type) + (eql 1 (member-type-size type))) + (first (member-type-members type))) + (t + (error "~S used on non-constant LVAR ~S" 'lvar-value lvar))))) ;;;; interface for obtaining results of type inference @@ -1277,7 +1290,6 @@ (ref (lvar-use (combination-fun call)))) (change-ref-leaf ref new-fun) (setf (combination-kind call) :full) - (maybe-propagate-dynamic-extent call new-fun) (locall-analyze-component *current-component*)))) (values)) @@ -1549,13 +1561,19 @@ (declare (type lvar arg) (type lambda-var var)) (binding* ((ref (first (leaf-refs var))) (lvar (node-lvar ref) :exit-if-null) - (dest (lvar-dest lvar))) + (dest (lvar-dest lvar)) + (dest-lvar (when (valued-node-p dest) (node-lvar dest)))) (when (and ;; Think about (LET ((A ...)) (IF ... A ...)): two ;; LVAR-USEs should not be met on one path. Another problem ;; is with dynamic-extent. (eq (lvar-uses lvar) ref) (not (block-delete-p (node-block ref))) + ;; If the destinatation is dynamic extent, don't substitute unless + ;; the source is as well. + (or (not dest-lvar) + (not (lvar-dynamic-extent dest-lvar)) + (lvar-dynamic-extent lvar)) (typecase dest ;; we should not change lifetime of unknown values lvars (cast