(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