1.0.47.27: limit open coding from MEMBER, ASSOC, &co
[sbcl.git] / src / compiler / constraint.lisp
index df2f3b9..812976e 100644 (file)
                           (var2
                            (add 'eql var1 var2 nil))
                           ((constant-lvar-p arg2)
-                           (add 'eql var1 (ref-leaf (principal-lvar-use arg2))
+                           (add 'eql var1
+                                (let ((use (principal-lvar-use arg2)))
+                                  (if (ref-p use)
+                                      (ref-leaf use)
+                                      (find-constant (lvar-value arg2))))
                                 nil))
                           (t
                            (add-test-constraint 'typep var1 (lvar-type arg2)
                       (add (if (eq name '<) '> '<) var2 (lvar-type arg1) nil))))
                  (t
                   (let ((ptype (gethash name *backend-predicate-types*)))
-                    (if ptype
-                        (add 'typep (ok-lvar-lambda-var (first args) constraints)
-                             ptype nil)
-                        (with-open-file (f "/tmp/unknown.txt"
-                                           :if-exists :append
-                                           :if-does-not-exist :create
-                                           :direction :output)
-                          (let ((*package* (find-package :keyword)))
-                            (format f "~S~%" name))))))))))))
+                    (when ptype
+                      (add 'typep (ok-lvar-lambda-var (first args) constraints)
+                           ptype nil))))))))))
       (values consequent-constraints alternative-constraints))))
 
 ;;;; Applying constraints
           (modified-numeric-type x :low new-bound)
           (modified-numeric-type x :high new-bound)))))
 
+;;; Return true if LEAF is "visible" from NODE.
+(defun leaf-visible-from-node-p (leaf node)
+  (cond
+   ((lambda-var-p leaf)
+    ;; A LAMBDA-VAR is visible iif it is homed in a CLAMBDA that is an
+    ;; ancestor for NODE.
+    (let ((leaf-lambda (lambda-var-home leaf)))
+      (loop for lambda = (node-home-lambda node)
+            then (lambda-parent lambda)
+            while lambda
+            when (eq lambda leaf-lambda)
+            return t)))
+   ;; FIXME: Check on FUNCTIONALs (CLAMBDAs and OPTIONAL-DISPATCHes),
+   ;; not just LAMBDA-VARs.
+   (t
+    ;; Assume everything else is globally visible.
+    t)))
+
 ;;; Given the set of CONSTRAINTS for a variable and the current set of
 ;;; restrictions from flow analysis IN, set the type for REF
 ;;; accordingly.
                               (and (leaf-refs other) ; protect from
                                         ; deleted vars
                                    (csubtypep other-type leaf-type)
-                                   (not (type= other-type leaf-type))))
+                                   (not (type= other-type leaf-type))
+                                   ;; Don't change to a LEAF not visible here.
+                                   (leaf-visible-from-node-p other ref)))
                           (change-ref-leaf ref other)
                           (when (constant-p other) (return)))
                          (t
                  for var in (lambda-vars fun)
                  and val in (combination-args call)
                  when (and val (lambda-var-constraints var))
-                 do (let* ((type (lvar-type val))
-                           (con (find-or-create-constraint 'typep var type
-                                                           nil)))
-                      (conset-adjoin con gen))
-                 (maybe-add-eql-var-var-constraint var val gen)))))
+                 do (let ((type (lvar-type val)))
+                      (unless (eq type *universal-type*)
+                        (let ((con (find-or-create-constraint 'typep var type nil)))
+                          (conset-adjoin con gen))))
+                    (maybe-add-eql-var-var-constraint var val gen)))))
       (ref
        (when (ok-ref-lambda-var node)
          (maybe-add-eql-var-lvar-constraint node gen)
          (let ((var (ok-lvar-lambda-var lvar gen)))
            (when var
              (let ((atype (single-value-type (cast-derived-type node)))) ;FIXME
-               (do-eql-vars (var (var gen))
-                 (let ((con (find-or-create-constraint 'typep var atype nil)))
-                   (conset-adjoin con gen))))))))
+               (unless (eq atype *universal-type*)
+                 (do-eql-vars (var (var gen))
+                   (let ((con (find-or-create-constraint 'typep var atype nil)))
+                     (conset-adjoin con gen)))))))))
       (cset
        (binding* ((var (set-var node))
                   (nil (lambda-var-p var) :exit-if-null)
                   (cons (lambda-var-constraints var) :exit-if-null))
          (conset-difference gen cons)
-         (let* ((type (single-value-type (node-derived-type node)))
-                (con (find-or-create-constraint 'typep var type nil)))
-           (conset-adjoin con gen))
+         (let ((type (single-value-type (node-derived-type node))))
+           (unless (eq type *universal-type*)
+             (let ((con (find-or-create-constraint 'typep var type nil)))
+               (conset-adjoin con gen))))
          (maybe-add-eql-var-var-constraint var (set-value node) gen)))))
   gen)