0.pre7.86.flaky7.5:
authorWilliam Harold Newman <william.newman@airmail.net>
Mon, 12 Nov 2001 23:40:25 +0000 (23:40 +0000)
committerWilliam Harold Newman <william.newman@airmail.net>
Mon, 12 Nov 2001 23:40:25 +0000 (23:40 +0000)
(gets through the typep.lisp problem of flaky7.4, now dies
in xc of srctran, apparently because the LABELS code
is still broken)
s/find-lambda-vars/make-lambda-vars/
s/compute-closure/add-lambda-vars-and-let-vars-to-closures/
The old logic in CLOSE-OVER implicitly relied on LEAF-REFS
being completely set up before any CLOSE-OVERs were
called, else CLOSE-OVER could terminate prematurely
in the (MEMBER THING (PHYSENV-CLOSURE)) clause.
It looks as though it might even be the cause of the
failure in xc of typep.lisp. Since I'm finding it
difficult to grok, must less debug the order in which
the compiler initializes and mutates things, any order
dependency is the enemy, so rewrite it so that
it floods more systematically.

src/code/seq.lisp
src/compiler/constraint.lisp
src/compiler/ir1tran.lisp
src/compiler/physenvanal.lisp
version.lisp-expr

index 472b41b..90639c2 100644 (file)
                ;; obviously correct solution is to make Python smart
                ;; enough that we can use an inline function instead
                ;; of a compiler macro (as above). -- WHN 20000410
+               ;;
+               ;; FIXME: The DEFINE-COMPILER-MACRO here can be
+               ;; important for performance, and it'd be good to have
+               ;; it be visible throughout the compilation of all the
+               ;; target SBCL code. That could be done by defining
+               ;; SB-XC:DEFINE-COMPILER-MACRO and using it here,
+               ;; moving this DEFQUANTIFIER stuff (and perhaps other
+               ;; inline definitions in seq.lisp as well) into a new
+               ;; seq.lisp, and moving remaining target-only stuff
+               ;; from the old seq.lisp into target-seq.lisp.
                (define-compiler-macro ,name (pred first-seq &rest more-seqs)
                  (let ((elements (make-gensym-list (1+ (length more-seqs))))
                        (blockname (gensym "BLOCK")))
index c8b5715..6362e4d 100644 (file)
 ;;; Our OUT is:
 ;;;     out U (in - kill)
 ;;;
-;;; BLOCK-KILL-LIST is just a list of the lambda-vars killed, so we must
+;;; BLOCK-KILL-LIST is just a list of the LAMBDA-VARs killed, so we must
 ;;; compute the kill set when there are any vars killed. We bum this a
 ;;; bit by special-casing when only one var is killed, and just using
 ;;; that var's constraints as the kill set. This set could possibly be
index fc7078e..36cfd94 100644 (file)
 ;;; the continuation has no block, then we make it be in the block
 ;;; that the node is in. If the continuation heads its block, we end
 ;;; our block and link it to that block. If the continuation is not
-;;; currently used, then we set the derived-type for the continuation
+;;; currently used, then we set the DERIVED-TYPE for the continuation
 ;;; to that of the node, so that a little type propagation gets done.
 ;;;
 ;;; We also deal with a bit of THE's semantics here: we weaken the
 ;;; otherwise NIL is returned.
 ;;;
 ;;; This function may have arbitrary effects on the global environment
-;;; due to processing of PROCLAIMs and EVAL-WHENs. All syntax error
-;;; checking is done, with erroneous forms being replaced by a proxy
-;;; which signals an error if it is evaluated. Warnings about possibly
-;;; inconsistent or illegal changes to the global environment will
-;;; also be given.
+;;; due to processing of EVAL-WHENs. All syntax error checking is
+;;; done, with erroneous forms being replaced by a proxy which signals
+;;; an error if it is evaluated. Warnings about possibly inconsistent
+;;; or illegal changes to the global environment will also be given.
 ;;;
 ;;; We make the initial component and convert the form in a PROGN (and
 ;;; an optional NIL tacked on the end.) We then return the lambda. We
 ;;; Convert a reference to a symbolic constant or variable. If the
 ;;; symbol is entered in the LEXENV-VARIABLES we use that definition,
 ;;; otherwise we find the current global definition. This is also
-;;; where we pick off symbol macro and Alien variable references.
+;;; where we pick off symbol macro and alien variable references.
 (defun ir1-convert-variable (start cont name)
   (declare (type continuation start cont) (symbol name))
   (let ((var (or (lexenv-find name variables) (find-free-variable name))))
           key))))
     key))
 
-;;; Parse a lambda-list into a list of VAR structures, stripping off
-;;; any aux bindings. Each arg name is checked for legality, and
+;;; Parse a lambda list into a list of VAR structures, stripping off
+;;; any &AUX bindings. Each arg name is checked for legality, and
 ;;; duplicate names are checked for. If an arg is globally special,
 ;;; the var is marked as :SPECIAL instead of :LEXICAL. &KEY,
 ;;; &OPTIONAL and &REST args are annotated with an ARG-INFO structure
 ;;;  4. a list of the &AUX variables; and
 ;;;  5. a list of the &AUX values.
 (declaim (ftype (function (list) (values list boolean boolean list list))
-               find-lambda-vars))
-(defun find-lambda-vars (list)
+               make-lambda-vars))
+(defun make-lambda-vars (list)
   (multiple-value-bind (required optional restp rest keyp keys allowp aux
                        morep more-context more-count)
       (parse-lambda-list list)
                    form))
   (unless (and (consp (cdr form)) (listp (cadr form)))
     (compiler-error
-     "The lambda expression has a missing or non-list lambda-list:~%  ~S"
+     "The lambda expression has a missing or non-list lambda list:~%  ~S"
      form))
 
   (multiple-value-bind (vars keyp allow-other-keys aux-vars aux-vals)
-      (find-lambda-vars (cadr form))
+      (make-lambda-vars (cadr form))
     (multiple-value-bind (forms decls) (sb!sys:parse-body (cddr form))
-      (let* ((cont (make-continuation))
+      (let* ((result-cont (make-continuation))
             (*lexenv* (process-decls decls
                                      (append aux-vars vars)
-                                     nil cont))
+                                     nil result-cont))
             (res (if (or (find-if #'lambda-var-arg-info vars) keyp)
                      (ir1-convert-hairy-lambda forms vars keyp
                                                allow-other-keys
-                                               aux-vars aux-vals cont
+                                               aux-vars aux-vals result-cont
                                                :source-name source-name
                                                :debug-name debug-name)
                      (ir1-convert-lambda-body forms vars
                                               :aux-vars aux-vars
                                               :aux-vals aux-vals
-                                              :result cont
+                                              :result result-cont
                                               :source-name source-name
                                               :debug-name debug-name))))
        (setf (functional-inline-expansion res) form)
index 4afe914..e319ef8 100644 (file)
@@ -34,7 +34,8 @@
   (setf (component-new-funs component) ())
   (dolist (fun (component-lambdas component))
     (reinit-lambda-physenv fun))
-  (mapc #'compute-closure (component-lambdas component))
+  (mapc #'add-lambda-vars-and-let-vars-to-closures
+       (component-lambdas component))
 
   (find-non-local-exits component)
   (find-cleanup-points component)
@@ -62,7 +63,7 @@
   (declare (type component component))
   (let ((found-it nil))
     (dolist (lambda (component-lambdas component))
-      (when (compute-closure lambda)
+      (when (add-lambda-vars-and-let-vars-to-closures lambda)
        (setq found-it t)))
     found-it))
 
@@ -98,7 +99,7 @@
 (defun preallocate-physenvs-for-toplevelish-lambdas (component)
   (dolist (clambda (component-lambdas component))
     (when (lambda-toplevelish-p clambda)
-      (compute-closure clambda)))
+      (add-lambda-vars-and-let-vars-to-closures clambda)))
   (values))
 
 ;;; If CLAMBDA has a PHYSENV, return it, otherwise assign an empty one
   (declare (type node node))
   (get-lambda-physenv (node-home-lambda node)))
 
+;;; private guts of ADD-LAMBDA-VARS-AND-LET-VARS-TO-CLOSURES
+;;;
+;;; This is the old CMU CL COMPUTE-CLOSURE, which only works on
+;;; LAMBDA-VARS directly, not on the LAMBDA-VARS of LAMBDA-LETS. It
+;;; seems never to be valid to use this operation alone, so in SBCL,
+;;; it's private, and the public interface,
+;;; ADD-LAMBDA-VARS-AND-LET-VARS-TO-CLOSURES, always runs over all the
+;;; variables, not only the LAMBDA-VARS of CLAMBDA itself but also
+;;; the LAMBDA-VARS of CLAMBDA's LAMBDA-LETS.
+(defun %add-lambda-vars-to-closures (clambda)
+  (let ((physenv (get-lambda-physenv clambda))
+       (did-something nil))
+    (note-unreferenced-vars clambda)
+    (dolist (var (lambda-vars clambda))
+      (dolist (ref (leaf-refs var))
+       (let ((ref-physenv (get-node-physenv ref)))
+         (unless (eq ref-physenv physenv)
+           (when (lambda-var-sets var)
+             (setf (lambda-var-indirect var) t))
+           (setq did-something t)
+           (close-over var ref-physenv physenv))))
+      (dolist (set (basic-var-sets var))
+       (let ((set-physenv (get-node-physenv set)))
+         (unless (eq set-physenv physenv)
+           (setq did-something t)
+           (setf (lambda-var-indirect var) t)
+           (close-over var set-physenv physenv)))))
+    did-something))
+
 ;;; Find any variables in CLAMBDA -- either directly in LAMBDA-VARS or
 ;;; in the LAMBDA-VARS of elements of LAMBDA-LETS -- with references
 ;;; outside of the home environment and close over them. If a
 ;;; value cell. We also warn about unreferenced variables here, just
 ;;; because it's a convenient place to do it. We return true if we
 ;;; close over anything.
-(defun compute-closure (clambda)
+(defun add-lambda-vars-and-let-vars-to-closures (clambda)
   (declare (type clambda clambda))
-  (flet (;; This is the old CMU CL COMPUTE-CLOSURE, which only works
-        ;; on LAMBDA-VARS directly, not on the LAMBDA-VARS of
-        ;; LAMBDA-LETS. It seems never to be valid to use this
-        ;; operation alone, so in SBCL, it's private, and the public
-        ;; interface always runs over all the variables, both the
-        ;; LAMBDA-VARS of CLAMBDA itself and the LAMBDA-VARS of
-        ;; CLAMBDA's LAMBDA-LETS.
-        ;;
-        ;; Note that we don't need to make a distinction between the
-        ;; outer CLAMBDA argument and the inner one, or refer to the
-        ;; outer CLAMBDA argument at all, because the LET-conversion
-        ;; process carefully modifies all the necessary CLAMBDA slots
-        ;; (e.g. LAMBDA-PHYSENV) of a LET-converted CLAMBDA to refer
-        ;; to the new home.
-        (%compute-closure (clambda)
-          (let ((physenv (get-lambda-physenv clambda))
-                (did-something nil))
-            (note-unreferenced-vars clambda)
-            (dolist (var (lambda-vars clambda))
-              (dolist (ref (leaf-refs var))
-                (let ((ref-physenv (get-node-physenv ref)))
-                  (unless (eq ref-physenv physenv)
-                    (when (lambda-var-sets var)
-                      (setf (lambda-var-indirect var) t))
-                    (setq did-something t)
-                    (close-over var ref-physenv physenv))))
-              (dolist (set (basic-var-sets var))
-                (let ((set-physenv (get-node-physenv set)))
-                  (unless (eq set-physenv physenv)
-                    (setq did-something t)
-                    (setf (lambda-var-indirect var) t)
-                    (close-over var set-physenv physenv)))))
-            did-something)))
-    (let ((did-something nil))
-      (when (%compute-closure clambda)
-       (setf did-something t))
-      (dolist (lambda-let (lambda-lets clambda))
-       ;; There's no need to recurse through full COMPUTE-CLOSURE
-       ;; here, since LETS only go one layer deep.
-       (aver (null (lambda-lets lambda-let)))
-       (when (%compute-closure lambda-let)
-         (setf did-something t)))
-      did-something)))
+  (let ((did-something nil))
+    (when (%add-lambda-vars-to-closures clambda)
+      (setf did-something t))
+    (dolist (lambda-let (lambda-lets clambda))
+      ;; There's no need to recurse through full COMPUTE-CLOSURE
+      ;; here, since LETS only go one layer deep.
+      (aver (null (lambda-lets lambda-let)))
+      (when (%add-lambda-vars-to-closures lambda-let)
+       (setf did-something t)))
+    did-something))
 
 ;;; Make sure that THING is closed over in REF-PHYSENV and in all
 ;;; PHYSENVs for the functions that reference REF-PHYSENV's function
 ;;; reach the home environment, we stop propagating the closure.
 (defun close-over (thing ref-physenv home-physenv)
   (declare (type physenv ref-physenv home-physenv))
-  (cond ((eq ref-physenv home-physenv))
-       ((member thing (physenv-closure ref-physenv)))
-       (t
-        (push thing (physenv-closure ref-physenv))
-        (dolist (call (leaf-refs (physenv-lambda ref-physenv)))
-          (close-over thing (get-node-physenv call) home-physenv))))
+  (let ((flooded-physenvs nil))
+    (named-let flood ((flooded-physenv ref-physenv))
+      (unless (or (eql flooded-physenv home-physenv)
+                 (member flooded-physenv flooded-physenvs))
+       (push flooded-physenv flooded-physenvs)
+       (pushnew thing (physenv-closure flooded-physenv))
+       (dolist (ref (leaf-refs (physenv-lambda flooded-physenv)))
+         (flood (get-node-physenv ref))))))
   (values))
 \f
 ;;;; non-local exit
index 935bd47..97c29b0 100644 (file)
@@ -18,4 +18,4 @@
 ;;; for internal versions, especially for internal versions off the
 ;;; main CVS branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
 
-"0.pre7.86.flaky7.4"
+"0.pre7.86.flaky7.5"