X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fir1opt.lisp;h=d091f381e4353a5d08f0cd787f297184ccc502c0;hb=95591ed483dbb8c0846c129953acac1554f28809;hp=c22c25ceda55f4a508dc2415e3dcd0a60737f560;hpb=4af56c115ef7ec63e06be677f9dfbf8116882e4c;p=sbcl.git diff --git a/src/compiler/ir1opt.lisp b/src/compiler/ir1opt.lisp index c22c25c..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 @@ -510,20 +523,8 @@ (delete-ref node) (unlink-node node)) (combination - (let ((kind (combination-kind node)) - (info (combination-fun-info node))) - (when (and (eq kind :known) (fun-info-p info)) - (let ((attr (fun-info-attributes info))) - (when (and (not (ir1-attributep attr call)) - ;; ### For now, don't delete potentially - ;; flushable calls when they have the CALL - ;; attribute. Someday we should look at the - ;; functional args to determine if they have - ;; any side effects. - (if (policy node (= safety 3)) - (ir1-attributep attr flushable) - (ir1-attributep attr unsafely-flushable))) - (flush-combination node)))))) + (when (flushable-combination-p node) + (flush-combination node))) (mv-combination (when (eq (basic-combination-kind node) :local) (let ((fun (combination-lambda node))) @@ -1560,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