"VALUES-SPECIFIER-TYPE-CACHE-CLEAR" "VALUES-SUBTYPEP"
"VALUES-TYPE"
"VALUES-TYPE-ERROR"
+ "VALUES-TYPE-IN"
"VALUES-TYPE-INTERSECTION"
"VALUES-TYPE-OPTIONAL"
+ "VALUES-TYPE-OUT"
"VALUES-TYPE-P" "VALUES-TYPE-REQUIRED"
"VALUES-TYPE-REST" "VALUES-TYPE-UNION"
"VALUES-TYPE-TYPES" "VALUES-TYPES"
- "VALUES-TYPE-START"
"VALUES-TYPES-EQUAL-OR-INTERSECT" "VECTOR-T-P"
"VECTOR-TO-VECTOR*"
"VECTOR-OF-CHECKED-LENGTH-GIVEN-LENGTH"
(cond ((args-type-rest type))
(t default-type)))))
-;;; If COUNT values are supplied, which types should they have?
-(defun values-type-start (type count)
+;;; types of values in (the <type> (values o_1 ... o_n))
+(defun values-type-out (type count)
(declare (type ctype type) (type unsigned-byte count))
(if (eq type *wild-type*)
(make-list count :initial-element *universal-type*)
do (res rest))))
(res))))
+;;; types of variable in (m-v-bind (v_1 ... v_n) (the <type> ...
+(defun values-type-in (type count)
+ (declare (type ctype type) (type unsigned-byte count))
+ (if (eq type *wild-type*)
+ (make-list count :initial-element *universal-type*)
+ (collect ((res))
+ (let ((null-type (specifier-type 'null)))
+ (loop for type in (values-type-required type)
+ while (plusp count)
+ do (decf count)
+ do (res type))
+ (loop for type in (values-type-optional type)
+ while (plusp count)
+ do (decf count)
+ do (res (type-union type null-type)))
+ (when (plusp count)
+ (loop with rest = (acond ((values-type-rest type)
+ (type-union it null-type))
+ (t null-type))
+ repeat count
+ do (res rest))))
+ (res))))
+
;;; Return a list of OPERATION applied to the types in TYPES1 and
;;; TYPES2, padding with REST2 as needed. TYPES1 must not be shorter
;;; than TYPES2. The second value is T if OPERATION always returned a
force-hairy)))
((not (eq vcount :unknown))
(maybe-negate-check value
- (values-type-start ctype vcount)
- (values-type-start atype vcount)
+ (values-type-out ctype vcount)
+ (values-type-out atype vcount)
t))
(t
(values :too-hairy nil))))))))
((= length 1)
(single-value-type atype))
(t
- (make-values-type :required
- (values-type-start atype length)))))
+ (make-values-type
+ :required (values-type-out atype length)))))
(dtype (node-derived-type cast))
- (dtype (make-values-type :required
- (values-type-start dtype length))))
+ (dtype (make-values-type
+ :required (values-type-out dtype length))))
(setf (cast-asserted-type cast) atype)
(setf (node-derived-type cast) dtype)))
;;; vars.
(defun ir1-optimize-mv-bind (node)
(declare (type mv-combination node))
- (let ((arg (first (basic-combination-args node)))
- (vars (lambda-vars (combination-lambda node))))
- (multiple-value-bind (types nvals)
- (values-types (continuation-derived-type arg))
- (unless (eq nvals :unknown)
- (mapc (lambda (var type)
- (if (basic-var-sets var)
- (propagate-from-sets var type)
- (propagate-to-refs var type)))
- vars
- (adjust-list types
- (length vars)
- (specifier-type 'null)))))
+ (let* ((arg (first (basic-combination-args node)))
+ (vars (lambda-vars (combination-lambda node)))
+ (n-vars (length vars))
+ (types (values-type-in (continuation-derived-type arg)
+ n-vars)))
+ (loop for var in vars
+ and type in types
+ do (if (basic-var-sets var)
+ (propagate-from-sets var type)
+ (propagate-to-refs var type)))
(setf (continuation-reoptimize arg) nil))
(values))
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.8.1.26"
+"0.8.1.27"