1.0.16.32: revert ANY-REG from registers for primitive type T on x86oids
[sbcl.git] / src / compiler / generic / primtype.lisp
index 1232ca1..2ee50b0 100644 (file)
 (!def-vm-support-routine primitive-type-of (object)
   (let ((type (ctype-of object)))
     (cond ((not (member-type-p type)) (primitive-type type))
-          ((equal (member-type-members type) '(nil))
+          ((and (eql 1 (member-type-size type))
+                (equal (member-type-members type) '(nil)))
            (primitive-type-or-lose 'list))
           (t
            *backend-t-primitive-type*))))
                              (return (any)))))))))))
         (intersection-type
          (let ((types (intersection-type-types type))
-               (res (any))
-               (exact nil))
-           (dolist (type types (values res exact))
-             (multiple-value-bind (ptype ptype-exact)
+               (res (any)))
+           ;; why NIL for the exact?  Well, we assume that the
+           ;; intersection type is in fact doing something for us:
+           ;; that is, that each of the types in the intersection is
+           ;; in fact cutting off some of the type lattice.  Since no
+           ;; intersection type is represented by a primitive type and
+           ;; primitive types are mutually exclusive, it follows that
+           ;; no intersection type can represent the entirety of the
+           ;; primitive type.  (And NIL is the conservative answer,
+           ;; anyway).  -- CSR, 2006-09-14
+           (dolist (type types (values res nil))
+             (multiple-value-bind (ptype)
                  (primitive-type type)
-               (when ptype-exact
-                 (aver (or (not exact) (eq ptype res)))
-                 (setq exact t))
-               (when (or ptype-exact (and (not exact) (eq res (any))))
-                 ;; Try to find a narrower representation then
-                 ;; (any). Takes care of undecidable types in
-                 ;; intersections with decidable ones.
-                 (setq res ptype))))))
+               (cond
+                 ;; if the result so far is (any), any improvement on
+                 ;; the specificity of the primitive type is valid.
+                 ((eq res (any))
+                  (setq res ptype))
+                 ;; if the primitive type returned is (any), the
+                 ;; result so far is valid.  Likewise, if the
+                 ;; primitive type is the same as the result so far,
+                 ;; everything is fine.
+                 ((or (eq ptype (any)) (eq ptype res)))
+                 ;; otherwise, we have something hairy and confusing,
+                 ;; such as (and condition funcallable-instance).
+                 ;; Punt.
+                 (t (return (any))))))))
         (member-type
-         (let* ((members (member-type-members type))
-                (res (primitive-type-of (first members))))
-           (dolist (mem (rest members) (values res nil))
-             (let ((ptype (primitive-type-of mem)))
-               (unless (eq ptype res)
-                 (let ((new-ptype (or (maybe-numeric-type-union res ptype)
-                                      (maybe-numeric-type-union ptype res))))
-                   (if new-ptype
-                       (setq res new-ptype)
-                       (return (any)))))))))
+         (let (res)
+           (block nil
+             (mapc-member-type-members
+              (lambda (member)
+                (let ((ptype (primitive-type-of member)))
+                  (if res
+                      (unless (eq ptype res)
+                        (let ((new-ptype (or (maybe-numeric-type-union res ptype)
+                                             (maybe-numeric-type-union ptype res))))
+                          (if new-ptype
+                              (setq res new-ptype)
+                              (return (any)))))
+                      (setf res ptype))))
+              type))
+           res))
         (named-type
          (ecase (named-type-name type)
            ((t *) (values *backend-t-primitive-type* t))
            ((instance) (exactly instance))
            ((funcallable-instance) (part-of function))
+           ((extended-sequence) (any))
            ((nil) (any))))
         (character-set-type
          (let ((pairs (character-set-type-pairs type)))