0.pre7.14.flaky4.11:
[sbcl.git] / src / compiler / node.lisp
index 0c4b05c..a3c62d9 100644 (file)
@@ -70,9 +70,9 @@
   ;;   A continuation that is the CONT of some node in BLOCK.
   (kind :unused :type (member :unused :deleted :inside-block :block-start
                              :deleted-block-start))
-  ;; The node which receives this value, if any. In a deleted continuation,
-  ;; this is null even though the node that receives this continuation may not
-  ;; yet be deleted.
+  ;; The node which receives this value, if any. In a deleted
+  ;; continuation, this is null even though the node that receives
+  ;; this continuation may not yet be deleted.
   (dest nil :type (or node null))
   ;; If this is a NODE, then it is the node which is to be evaluated
   ;; next. This is always null in :DELETED and :UNUSED continuations,
   ;;    called for, but it believes it has proven that the check won't
   ;;    be done for policy reasons or because a safe implementation
   ;;    will be used. In the latter case, LTN must ensure that a safe
-  ;;    implementation *is* be used.
+  ;;    implementation *is* used.
   ;;
   ;; :ERROR
   ;;    There is a compile-time type error in some use of this
 (def!method print-object ((x continuation) stream)
   (print-unreadable-object (x stream :type t :identity t)))
 
-(defstruct (node (:constructor nil))
+(defstruct (node (:constructor nil)
+                (:copier nil))
   ;; the bottom-up derived type for this node. This does not take into
   ;; consideration output type assertions on this node (actually on its CONT).
   (derived-type *wild-type* :type ctype)
   ;; Following the introduced forms is a representation of the
   ;; location of the enclosing original source form. This transition
   ;; is indicated by the magic ORIGINAL-SOURCE-START marker. The first
-  ;; element of the orignal source is the "form number", which is the
+  ;; element of the original source is the "form number", which is the
   ;; ordinal number of this form in a depth-first, left-to-right walk
   ;; of the truly top-level form in which this appears.
   ;;
   ;;
   ;; The last element in the list is the top-level form number, which
   ;; is the ordinal number (in this call to the compiler) of the truly
-  ;; top-level form containing the orignal source.
+  ;; top-level form containing the original source.
   (source-path *current-path* :type list)
   ;; If this node is in a tail-recursive position, then this is set to
   ;; T. At the end of IR1 (in environment analysis) this is computed
 ;;; The Block-Annotation structure is shared (via :INCLUDE) by
 ;;; different block-info annotation structures so that code
 ;;; (specifically control analysis) can be shared.
-(defstruct (block-annotation (:constructor nil))
+(defstruct (block-annotation (:constructor nil)
+                            (:copier nil))
   ;; The IR1 block that this block is in the INFO for.
   (block (required-argument) :type cblock)
   ;; the next and previous block in emission order (not DFO). This
 ;;; The Component structure provides a handle on a connected piece of
 ;;; the flow graph. Most of the passes in the compiler operate on
 ;;; components rather than on the entire flow graph.
-(defstruct component
+(defstruct (component (:copier nil))
   ;; The kind of component:
   ;;
   ;; NIL
   name
   (reanalyze :test reanalyze))
 
-;;; The Cleanup structure represents some dynamic binding action.
+;;; The CLEANUP structure represents some dynamic binding action.
 ;;; Blocks are annotated with the current cleanup so that dynamic
 ;;; bindings can be removed when control is transferred out of the
 ;;; binding environment. We arrange for changes in dynamic bindings to
 ;;; by requiring that the exit continuations initially head their
 ;;; blocks, and then by not merging blocks when there is a cleanup
 ;;; change.
-(defstruct cleanup
+(defstruct (cleanup (:copier nil))
   ;; The kind of thing that has to be cleaned up.
   (kind (required-argument)
        :type (member :special-bind :catch :unwind-protect :block :tagbody))
   (nlx-info :test nlx-info))
 
 ;;; The ENVIRONMENT structure represents the result of environment analysis.
-(defstruct environment
+(defstruct (environment (:copier nil))
   ;; the function that allocates this environment
   (function (required-argument) :type clambda)
   ;; a list of all the lambdas that allocate variables in this environment
 ;;; The tail set is somewhat approximate, because it is too early to
 ;;; be sure which calls will be TR. Any call that *might* end up TR
 ;;; causes tail-set merging.
-(defstruct tail-set
+(defstruct (tail-set (:copier nil))
   ;; a list of all the lambdas in this tail set
   (functions nil :type list)
   ;; our current best guess of the type returned by these functions.
   ;;  :DECLARED, from a declaration.
   ;;  :ASSUMED, from uses of the object.
   ;;  :DEFINED, from examination of the definition.
-  ;; FIXME: This should be a named type. (LEAF-WHERE-FROM?)
+  ;; FIXME: This should be a named type. (LEAF-WHERE-FROM? Or
+  ;; perhaps just WHERE-FROM, since it's not just used in LEAF,
+  ;; but also in various DEFINE-INFO-TYPEs in globaldb.lisp,
+  ;; and very likely elsewhere too.)
   (where-from :assumed :type (member :declared :assumed :defined))
   ;; list of the REF nodes for this leaf
   (refs () :type list)
 ;;; defined in the same compilation block, or that have inline
 ;;; expansions, or have a non-NIL INLINEP value. Whenever we change
 ;;; the INLINEP state (i.e. an inline proclamation) we copy the
-;;; structure so that former inlinep values are preserved.
+;;; structure so that former INLINEP values are preserved.
 (def!struct (defined-function (:include global-var
                                        (where-from :defined)
                                        (kind :global-function)))
   (arglist nil :type list)
   ;; true if &ALLOW-OTHER-KEYS was supplied
   (allowp nil :type boolean)
-  ;; true if &KEY was specified (doesn't necessarily mean that there
-  ;; are any keyword arguments...)
+  ;; true if &KEY was specified (which doesn't necessarily mean that
+  ;; there are any &KEY arguments..)
   (keyp nil :type boolean)
   ;; the number of required arguments. This is the smallest legal
   ;; number of arguments.
   ;; defaults even when there is no user-specified supplied-p var.
   (supplied-p nil :type (or lambda-var null))
   ;; the default for a keyword or optional, represented as the
-  ;; original Lisp code. This is set to NIL in keyword arguments that
-  ;; are defaulted using the SUPPLIED-P arg.
+  ;; original Lisp code. This is set to NIL in &KEY arguments that are
+  ;; defaulted using the SUPPLIED-P arg.
   (default nil :type t)
-  ;; the actual keyword for a keyword argument
-  (keyword nil :type (or keyword null)))
+  ;; the actual key for a &KEY argument. Note that in ANSI CL this is not
+  ;; necessarily a keyword: (DEFUN FOO (&KEY ((BAR BAR))) ..).
+  (key nil :type symbol))
 (defprinter (arg-info)
   (specialp :test specialp)
   kind
   (supplied-p :test supplied-p)
   (default :test default)
-  (keyword :test keyword))
+  (key :test key))
 
 ;;; The LAMBDA-VAR structure represents a lexical lambda variable.
 ;;; This structure is also used during IR1 conversion to describe
 ;;; initially (and forever) NIL, since REFs don't receive any values
 ;;; and don't have any IR1 optimizer.
 (defstruct (ref (:include node (:reoptimize nil))
-               (:constructor make-ref (derived-type leaf)))
+               (:constructor make-ref (derived-type leaf))
+               (:copier nil))
   ;; The leaf referenced.
   (leaf nil :type leaf))
 (defprinter (ref)
 ;;; function appears as the successor. The NODE-CONT remains the
 ;;; continuation which receives the value of the call.
 (defstruct (basic-combination (:include node)
-                             (:constructor nil))
+                             (:constructor nil)
+                             (:copier nil))
   ;; continuation for the function
   (fun (required-argument) :type continuation)
   ;; list of CONTINUATIONs for the args. In a local call, an argument
 ;;; including FUNCALL. This is distinct from BASIC-COMBINATION so that
 ;;; an MV-COMBINATION isn't COMBINATION-P.
 (defstruct (combination (:include basic-combination)
-                       (:constructor make-combination (fun))))
+                       (:constructor make-combination (fun))
+                       (:copier nil)))
 (defprinter (combination)
   (fun :prin1 (continuation-use fun))
-  (args :prin1 (mapcar #'(lambda (x)
-                          (if x
-                              (continuation-use x)
-                              "<deleted>"))
+  (args :prin1 (mapcar (lambda (x)
+                        (if x
+                            (continuation-use x)
+                            "<deleted>"))
                       args)))
 
-;;; An MV-Combination is to Multiple-Value-Call as a Combination is to
-;;; Funcall. This is used to implement all the multiple-value
+;;; An MV-COMBINATION is to MULTIPLE-VALUE-CALL as a COMBINATION is to
+;;; FUNCALL. This is used to implement all the multiple-value
 ;;; receiving forms.
 (defstruct (mv-combination (:include basic-combination)
-                          (:constructor make-mv-combination (fun))))
+                          (:constructor make-mv-combination (fun))
+                          (:copier nil)))
 (defprinter (mv-combination)
   (fun :prin1 (continuation-use fun))
   (args :prin1 (mapcar #'continuation-use args)))
 
-;;; The Bind node marks the beginning of a lambda body and represents
+;;; The BIND node marks the beginning of a lambda body and represents
 ;;; the creation and initialization of the variables.
-(defstruct (bind (:include node))
+(defstruct (bind (:include node)
+                (:copier nil))
   ;; the lambda we are binding variables for. Null when we are
   ;; creating the LAMBDA during IR1 translation.
   (lambda nil :type (or clambda null)))
 (defprinter (bind)
   lambda)
 
-;;; The Return node marks the end of a lambda body. It collects the
+;;; The RETURN node marks the end of a lambda body. It collects the
 ;;; return values and represents the control transfer on return. This
-;;; is also where we stick information used for Tail-Set type
+;;; is also where we stick information used for TAIL-SET type
 ;;; inference.
 (defstruct (creturn (:include node)
                    (:conc-name return-)
 ;;; The ENTRY node serves to mark the start of the dynamic extent of a
 ;;; lexical exit. It is the mess-up node for the corresponding :Entry
 ;;; cleanup.
-(defstruct (entry (:include node))
+(defstruct (entry (:include node)
+                 (:copier nil))
   ;; All of the Exit nodes for potential non-local exits to this point.
   (exits nil :type list)
   ;; The cleanup for this entry. NULL only temporarily.
 ;;; the returned value being delivered directly to the exit
 ;;; continuation, it is delivered to our VALUE continuation. The
 ;;; original exit continuation is the exit node's CONT.
-(defstruct (exit (:include node))
+(defstruct (exit (:include node)
+                (:copier nil))
   ;; The Entry node that this is an exit for. If null, this is a
   ;; degenerate exit. A degenerate exit is used to "fill" an empty
   ;; block (which isn't allowed in IR1.) In a degenerate exit, Value
            #-no-ansi-print-object
            (:print-object (lambda (x s)
                             (print-unreadable-object (x s :type t)
-                              (prin1 (undefined-warning-name x) s)))))
-  ;; The name of the unknown thing.
+                              (prin1 (undefined-warning-name x) s))))
+           (:copier nil))
+  ;; the name of the unknown thing
   (name nil :type (or symbol list))
-  ;; The kind of reference to Name.
+  ;; the kind of reference to NAME
   (kind (required-argument) :type (member :function :type :variable))
-  ;; The number of times this thing was used.
+  ;; the number of times this thing was used
   (count 0 :type unsigned-byte)
-  ;; A list of COMPILER-ERROR-CONTEXT structures describing places
+  ;; a list of COMPILER-ERROR-CONTEXT structures describing places
   ;; where this thing was used. Note that we only record the first
   ;; *UNDEFINED-WARNING-LIMIT* calls.
   (warnings () :type list))
 \f
+;;; a helper for the POLICY macro, defined late here so that the
+;;; various type tests can be inlined
+(declaim (ftype (function ((or list lexenv node functional)) list)
+               %coerce-to-policy))
+(defun %coerce-to-policy (thing)
+  (let ((result (etypecase thing
+                 (list thing)
+                 (lexenv (lexenv-policy thing))
+                 (node (lexenv-policy (node-lexenv thing)))
+                 (functional (lexenv-policy (functional-lexenv thing))))))
+    ;; Test the first element of the list as a rudimentary sanity
+    ;; that it really does look like a valid policy.
+    (aver (or (null result) (policy-quality-name-p (caar result))))
+    ;; Voila.
+    result))
+\f
 ;;;; Freeze some structure types to speed type testing.
 
 #!-sb-fluid