1.0.42: will be tagged as sbcl_1_0_42
[sbcl.git] / src / compiler / ir1opt.lisp
index 8604960..d091f38 100644 (file)
 (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)))))
 \f
 ;;;; interface for obtaining results of type inference
 
          (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)))
             (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))
 
   (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