0.8.0.3:
[sbcl.git] / src / compiler / locall.lisp
index 620d285..3e4ceaf 100644 (file)
 ;;;
 ;;; If there is a &MORE arg, then there are a couple of optimizations
 ;;; that we make (more for space than anything else):
-;;; -- If MIN-ARGS is 0, then we make the more entry a T clause, since 
+;;; -- If MIN-ARGS is 0, then we make the more entry a T clause, since
 ;;;    no argument count error is possible.
-;;; -- We can omit the = clause for the last entry-point, allowing the 
+;;; -- We can omit the = clause for the last entry-point, allowing the
 ;;;    case of 0 more args to fall through to the more entry.
 ;;;
 ;;; We don't bother to policy conditionalize wrong arg errors in
           (temps (make-gensym-list (length (lambda-vars fun)))))
        `(lambda (,n-supplied ,@temps)
          (declare (type index ,n-supplied))
-         ,(if (policy *lexenv* (zerop safety))
+         ,(if (policy *lexenv* (zerop verify-arg-count))
               `(declare (ignore ,n-supplied))
               `(%verify-arg-count ,n-supplied ,nargs))
          (locally
-           ;; KLUDGE: The intent here is to enable tail recursion
-           ;; optimization, since leaving frames for wrapper
-           ;; functions like this on the stack is actually more
-           ;; annoying than helpful for debugging. Unfortunately
-           ;; trying to express this by messing with the
-           ;; ANSI-standard declarations is a little awkward, since
-           ;; no matter how we do it we'll tend to have side-effects
-           ;; on things like SPEED-vs.-SAFETY comparisons. Perhaps
-           ;; it'd be better to define a new SB-EXT:TAIL-RECURSIVELY
-           ;; declaration and use that? -- WHN 2002-07-08
-           (declare (optimize (speed 2) (debug 1)))
+           (declare (optimize (merge-tail-calls 3)))
            (%funcall ,fun ,@temps)))))
     (optional-dispatch
      (let* ((min (optional-dispatch-min-args fun))
                       `(multiple-value-bind (,n-context ,n-count)
                            (%more-arg-context ,n-supplied ,max)
                          (locally
-                           ;; KLUDGE: As above, we're trying to
-                           ;; enable tail recursion optimization and
-                           ;; any other effects of this declaration
-                           ;; are accidental. -- WHN 2002-07-08
-                           (declare (optimize (speed 2) (debug 1)))
+                           (declare (optimize (merge-tail-calls 3)))
                            (%funcall ,more ,@temps ,n-context ,n-count)))))))
             (t
              (%arg-count-error ,n-supplied)))))))))
 
       (assert-continuation-type
        (first (basic-combination-args call))
-       (make-values-type :optional (mapcar #'leaf-type (lambda-vars ep))
-                        :rest *universal-type*)
+       (make-short-values-type (mapcar #'leaf-type (lambda-vars ep)))
        (lexenv-policy (node-lexenv call)))))
   (values))
 
         (with-ir1-environment-from-node call
           (ir1-convert-lambda
            `(lambda ,vars
-              (declare (ignorable . ,ignores))
-              (%funcall ,entry . ,args))
+              (declare (ignorable ,@ignores))
+              (%funcall ,entry ,@args))
            :debug-name (debug-namify "hairy function entry ~S"
                                      (continuation-fun-name
                                       (basic-combination-fun call)))))))
       (collect ((call-args))
        (do ((var arglist (cdr var))
             (temp temps (cdr temp)))
-           (())
+           ((null var))
          (let ((info (lambda-var-arg-info (car var))))
            (if info
                (ecase (arg-info-kind info)
        (join-components component clambda-component)))
     (let ((*current-component* component))
       (node-ends-block call))
-    ;; FIXME: Use DESTRUCTURING-BIND here, and grep for other 
+    ;; FIXME: Use DESTRUCTURING-BIND here, and grep for other
     ;; uses of '=.*length' which could also be converted to use
     ;; DESTRUCTURING-BIND or PROPER-LIST-OF-LENGTH-P.
     (aver (= (length (block-succ call-block)) 1))
 ;;; node, and change the control flow to transfer to NEXT-BLOCK
 ;;; instead. Move all the uses of the result continuation to CALL's
 ;;; CONT.
-;;;
-;;; If the actual continuation is only used by the LET call, then we
-;;; intersect the type assertion on the dummy continuation with the
-;;; assertion for the actual continuation; in all other cases
-;;; assertions on the dummy continuation are lost.
-;;;
-;;; We also intersect the derived type of the CALL with the derived
-;;; type of all the dummy continuation's uses. This serves mainly to
-;;; propagate TRULY-THE through LETs.
 (defun move-return-uses (fun call next-block)
   (declare (type clambda fun) (type basic-combination call)
           (type cblock next-block))
     (let ((result (return-result return))
          (cont (node-cont call))
          (call-type (node-derived-type call)))
-      (when (eq (continuation-use cont) call)
-        (set-continuation-type-assertion
-         cont
-         (continuation-asserted-type result)
-         (continuation-type-to-check result)))
       (unless (eq call-type *wild-type*)
-       (do-uses (use result)
+        ;; FIXME: Replace the call with unsafe CAST. -- APD, 2002-01-26
+        (do-uses (use result)
          (derive-node-type use call-type)))
       (substitute-continuation-uses cont result)))
   (values))
     (cond ((not return))
          ((or next-block call-return)
           (unless (block-delete-p (node-block return))
+             (when (and (node-tail-p call)
+                        call-return
+                        (not (eq (node-cont call)
+                                 (return-result call-return))))
+               ;; We do not care to give a meaningful continuation to
+               ;; a tail combination, but here we need it.
+               (delete-continuation-use call)
+               (add-continuation-use call (return-result call-return)))
             (move-return-uses fun call
-                              (or next-block (node-block call-return)))))
+                              (or next-block
+                                   (let ((block (node-block call-return)))
+                                     (when (block-delete-p block)
+                                       (setf (block-delete-p block) nil))
+                                     block)))))
          (t
           (aver (node-tail-p call))
           (setf (lambda-return call-fun) return)
-          (setf (return-lambda return) call-fun))))
+          (setf (return-lambda return) call-fun)
+           (setf (lambda-return fun) nil))))
   (move-let-call-cont fun)
   (values))
 
   (when (leaf-has-source-name-p clambda)
     ;; ANSI requires that explicit NOTINLINE be respected.
     (or (eq (lambda-inlinep clambda) :notinline)
-       ;; If (> DEBUG SPEED) we can guess that inlining generally
-       ;; won't be appreciated, but if the user specifically requests
-       ;; inlining, that takes precedence over our general guess.
-       (and (policy clambda (> debug speed))
+       ;; If (= LET-CONVERTION 0) we can guess that inlining
+       ;; generally won't be appreciated, but if the user
+       ;; specifically requests inlining, that takes precedence over
+       ;; our general guess.
+       (and (policy clambda (= let-convertion 0))
             (not (eq (lambda-inlinep clambda) :inline))))))
 
 ;;; We also don't convert calls to named functions which appear in the