X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fnode.lisp;h=a3c62d9060cba8bc2fc89102857834cf451786c7;hb=947522ee16a30d43466c8f86efacee7003e5d85f;hp=b6e34c86bed9210795ee4fd1b17135a902920abd;hpb=cfb9e3640e34706acdfccd26236024de259f3b4f;p=sbcl.git diff --git a/src/compiler/node.lisp b/src/compiler/node.lisp index b6e34c8..a3c62d9 100644 --- a/src/compiler/node.lisp +++ b/src/compiler/node.lisp @@ -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, @@ -142,7 +142,8 @@ (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) @@ -172,7 +173,7 @@ ;; 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. ;; @@ -182,7 +183,7 @@ ;; ;; 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 @@ -296,7 +297,8 @@ ;;; 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 @@ -309,7 +311,7 @@ ;;; 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 @@ -383,7 +385,7 @@ 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 @@ -395,7 +397,7 @@ ;;; 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)) @@ -412,7 +414,7 @@ (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 @@ -443,7 +445,7 @@ ;;; 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. @@ -512,7 +514,10 @@ ;; :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) @@ -571,7 +576,7 @@ ;;; 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))) @@ -774,8 +779,8 @@ (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. @@ -828,17 +833,18 @@ ;; 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 @@ -888,7 +894,8 @@ ;;; 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) @@ -933,7 +940,8 @@ ;;; 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 @@ -957,7 +965,8 @@ ;;; 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) @@ -970,23 +979,25 @@ ;;; 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-) @@ -1015,7 +1026,8 @@ ;;; 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. @@ -1028,7 +1040,8 @@ ;;; 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 @@ -1047,18 +1060,35 @@ #-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)) +;;; 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)) + ;;;; Freeze some structure types to speed type testing. #!-sb-fluid