X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fnode.lisp;h=73b38cdb941c209599d98d12a9f4dbdbe7f2bd3e;hb=17794352c2ef078a1fc3cdd306f17f7328edf40b;hp=44f0bfe4ef8a585d0592b3433c3c696a2ed35937;hpb=78a057624fecd10d0fb2ead4ef02ffc361b1ee22;p=sbcl.git diff --git a/src/compiler/node.lisp b/src/compiler/node.lisp index 44f0bfe..73b38cd 100644 --- a/src/compiler/node.lisp +++ b/src/compiler/node.lisp @@ -37,7 +37,7 @@ ;; until it is assigned a block, and may be also be temporarily ;; unused during later manipulations of IR1. In a consistent ;; state there should never be any mention of :UNUSED - ;; continuations. Next can have a non-null value if the next node + ;; continuations. NEXT can have a non-null value if the next node ;; has already been determined. ;; ;; :DELETED @@ -79,15 +79,13 @@ ;; and will be null in a :INSIDE-BLOCK continuation when this is the ;; CONT of the LAST. (next nil :type (or node null)) - ;; an assertion on the type of this continuation's value - (asserted-type *wild-type* :type ctype) ;; cached type of this continuation's value. If NIL, then this must ;; be recomputed: see CONTINUATION-DERIVED-TYPE. (%derived-type nil :type (or ctype null)) ;; the node where this continuation is used, if unique. This is always ;; null in :DELETED and :UNUSED continuations, and is never null in ;; :INSIDE-BLOCK continuations. In a :BLOCK-START continuation, the - ;; Block's START-USES indicate whether NIL means no uses or more + ;; BLOCK's START-USES indicate whether NIL means no uses or more ;; than one use. (use nil :type (or node null)) ;; the basic block this continuation is in. This is null only in @@ -102,36 +100,9 @@ ;; the optimizer for this node type doesn't care, it can elect not ;; to clear this flag. (reoptimize t :type boolean) - ;; an indication of what we have proven about how this contination's - ;; type assertion is satisfied: - ;; - ;; NIL - ;; No type check is necessary (proven type is a subtype of the assertion.) - ;; - ;; T - ;; A type check is needed. - ;; - ;; :DELETED - ;; Don't do a type check, but believe (intersect) the assertion. - ;; A T check can be changed to :DELETED if we somehow prove the - ;; check is unnecessary, or if we eliminate it through a policy - ;; decision. - ;; - ;; :NO-CHECK - ;; Type check generation sets the slot to this if a check is - ;; 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* used. - ;; - ;; :ERROR - ;; There is a compile-time type error in some use of this - ;; continuation. A type check should still be generated, but be - ;; careful. - ;; - ;; This is computed lazily by CONTINUATION-DERIVED-TYPE, so use - ;; CONTINUATION-TYPE-CHECK instead of the %'ed slot accessor. - (%type-check t :type (member t nil :deleted :no-check :error)) + ;; Cached type which is checked by DEST. If NIL, then this must be + ;; recomputed: see CONTINUATION-EXTERNALLY-CHECKABLE-TYPE. + (%externally-checkable-type nil :type (or null ctype)) ;; something or other that the back end annotates this continuation with (info nil) ;; uses of this continuation in the lexical environment. They are @@ -140,14 +111,14 @@ (lexenv-uses nil :type list)) (def!method print-object ((x continuation) stream) - (print-unreadable-object (x stream :type t :identity t))) + (print-unreadable-object (x stream :type t :identity t) + (format stream " #~D" (cont-num x)))) (defstruct (node (:constructor nil) (:copier nil)) ;; unique ID for debugging #!+sb-show (id (new-object-id) :read-only t) - ;; the bottom-up derived type for this node. This does not take into - ;; consideration output type assertions on this node (actually on its CONT). + ;; the bottom-up derived type for this node. (derived-type *wild-type* :type ctype) ;; True if this node needs to be optimized. This is set to true ;; whenever something changes about the value of a continuation @@ -157,7 +128,7 @@ ;; indicates what we do controlwise after evaluating this node. This ;; may be null during IR1 conversion. (cont nil :type (or continuation null)) - ;; the continuation that this node is the next of. This is null + ;; the continuation that this node is the NEXT of. This is null ;; during IR1 conversion when we haven't linked the node in yet or ;; in nodes that have been deleted from the IR1 by UNLINK-NODE. (prev nil :type (or continuation null)) @@ -221,7 +192,7 @@ ;;; is set when a continuation type assertion is strengthened. ;;; TEST-MODIFIED is set whenever the test for the ending IF has ;;; changed (may be true when there is no IF.) -(def-boolean-attribute block +(!def-boolean-attribute block reoptimize flush-p type-check delete-p type-asserted test-modified) ;;; FIXME: Tweak so that definitions of e.g. BLOCK-DELETE-P is @@ -276,19 +247,9 @@ (flags (block-attributes reoptimize flush-p type-check type-asserted test-modified) :type attributes) - ;; CMU CL had a KILL slot here, documented as "set used by - ;; constraint propagation", which was used in constraint propagation - ;; as a list of LAMBDA-VARs killed, and in copy propagation as an - ;; SSET, representing I dunno what. I (WHN) found this confusing, - ;; and furthermore it caused type errors when I was trying to make - ;; the compiler produce fully general LAMBDA functions directly - ;; (instead of doing as CMU CL always did, producing extra little - ;; functions which return the LAMDBA you need) and therefore taking - ;; a new path through the compiler. So I split this into two: - ;; KILL-LIST = list of LAMBDA-VARs killed, used in constraint propagation - ;; KILL-SSET = an SSET value, used in copy propagation - (kill-list nil :type list) - (kill-sset nil :type (or sset null)) + ;; in constraint propagation: list of LAMBDA-VARs killed in this block + ;; in copy propagation: list of killed TNs + (kill nil) ;; other sets used in constraint propagation and/or copy propagation (gen nil) (in nil) @@ -306,12 +267,14 @@ (flag nil) ;; some kind of info used by the back end (info nil) - ;; If true, then constraints that hold in this block and its - ;; successors by merit of being tested by its IF predecessor. + ;; constraints that hold in this block and its successors by merit + ;; of being tested by its IF predecessors. (test-constraint nil :type (or sset null))) (def!method print-object ((cblock cblock) stream) (print-unreadable-object (cblock stream :type t :identity t) - (format stream ":START c~W" (cont-num (block-start cblock))))) + (format stream "~W :START c~W" + (block-number cblock) + (cont-num (block-start cblock))))) ;;; The BLOCK-ANNOTATION class is inherited (via :INCLUDE) by ;;; different BLOCK-INFO annotation structures so that code @@ -338,7 +301,9 @@ ;;; size of flow analysis problems, this allows back-end data ;;; structures to be reclaimed after the compilation of each ;;; component. -(defstruct (component (:copier nil)) +(defstruct (component (:copier nil) + (:constructor + make-component (head tail &aux (last-block tail)))) ;; unique ID for debugging #!+sb-show (id (new-object-id) :read-only t) ;; the kind of component @@ -372,13 +337,15 @@ ;; the blocks that are the dummy head and tail of the DFO ;; ;; Entry/exit points have these blocks as their - ;; predecessors/successors. Null temporarily. The start and return - ;; from each non-deleted function is linked to the component head - ;; and tail. Until physical environment analysis links NLX entry - ;; stubs to the component head, every successor of the head is a - ;; function start (i.e. begins with a BIND node.) - (head nil :type (or null cblock)) - (tail nil :type (or null cblock)) + ;; predecessors/successors. The start and return from each + ;; non-deleted function is linked to the component head and + ;; tail. Until physical environment analysis links NLX entry stubs + ;; to the component head, every successor of the head is a function + ;; start (i.e. begins with a BIND node.) + (head (missing-arg) :type cblock) + (tail (missing-arg) :type cblock) + ;; New blocks are inserted before this. + (last-block (missing-arg) :type cblock) ;; This becomes a list of the CLAMBDA structures for all functions ;; in this component. OPTIONAL-DISPATCHes are represented only by ;; their XEP and other associated lambdas. This doesn't contain any @@ -700,8 +667,7 @@ (sets () :type list)) ;;; The GLOBAL-VAR structure represents a value hung off of the symbol -;;; NAME. We use a :CONSTANT VAR when we know that the thing is a -;;; constant, but don't know what the value is at compile time. +;;; NAME. (def!struct (global-var (:include basic-var)) ;; kind of variable described (kind (missing-arg) @@ -753,6 +719,12 @@ ;; Unlike the SOURCE-NAME slot, this slot's value should never ;; affect ordinary code behavior, only debugging/diagnostic behavior. ;; + ;; Ha. Ah, the starry-eyed idealism of the writer of the above + ;; paragraph. FUNCTION-LAMBDA-EXPRESSION's behaviour, as of + ;; sbcl-0.7.11.x, differs if the name of the a function is a string + ;; or not, as if it is a valid function name then it can look for an + ;; inline expansion. + ;; ;; The value of this slot can be anything, except that it shouldn't ;; be a legal function name, since otherwise debugging gets ;; confusing. (If a legal function name is a good name for the @@ -853,7 +825,7 @@ ;; KIND was :TOPLEVEL. Now it must be set explicitly, both for ;; :TOPLEVEL functions and for any other kind of functions that we ;; want to dump or return from #'CL:COMPILE or whatever. - (has-external-references-p nil) + (has-external-references-p nil) ;; In a normal function, this is the external entry point (XEP) ;; lambda for this function, if any. Each function that is used ;; other than in a local call has an XEP, and all of the @@ -912,7 +884,7 @@ ;; anonymous. In SBCL (as opposed to CMU CL) we make all ;; FUNCTIONALs have debug names. The CMU CL code didn't bother ;; in many FUNCTIONALs, especially those which were likely to be - ;; optimized away before the user saw them. However, getting + ;; optimized away before the user saw them. However, getting ;; that right requires a global understanding of the code, ;; which seems bad, so we just require names for everything. (leaf-source-name functional))) @@ -1023,10 +995,10 @@ ;; the total number of required and optional arguments. Args at ;; positions >= to this are &REST, &KEY or illegal args. (max-args 0 :type unsigned-byte) - ;; list of the LAMBDAs which are the entry points for non-rest, - ;; non-key calls. The entry for MIN-ARGS is first, MIN-ARGS+1 - ;; second, ... MAX-ARGS last. The last entry-point always calls the - ;; main entry; in simple cases it may be the main entry. + ;; list of the (maybe delayed) LAMBDAs which are the entry points + ;; for non-rest, non-key calls. The entry for MIN-ARGS is first, + ;; MIN-ARGS+1 second, ... MAX-ARGS last. The last entry-point always + ;; calls the main entry; in simple cases it may be the main entry. (entry-points nil :type list) ;; an entry point which takes MAX-ARGS fixed arguments followed by ;; an argument context pointer and an argument count. This entry @@ -1133,7 +1105,11 @@ ;;; 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 + (leaf + &aux (leaf-type (leaf-type leaf)) + (derived-type + (make-single-value-type leaf-type)))) (:copier nil)) ;; The leaf referenced. (leaf nil :type leaf)) @@ -1161,7 +1137,8 @@ alternative) (defstruct (cset (:include node - (derived-type *universal-type*)) + (derived-type (make-single-value-type + *universal-type*))) (:conc-name set-) (:predicate set-p) (:constructor make-set) @@ -1258,6 +1235,30 @@ (defprinter (creturn :conc-name return- :identity t) lambda result-type) + +;;; The CAST node represents type assertions. The check for +;;; TYPE-TO-CHECK is performed and then the VALUE is declared to be of +;;; type ASSERTED-TYPE. +(defstruct (cast (:include node) + (:constructor %make-cast)) + (asserted-type (missing-arg) :type ctype) + (type-to-check (missing-arg) :type ctype) + ;; an indication of what we have proven about how this type + ;; assertion is satisfied: + ;; + ;; NIL + ;; No type check is necessary (VALUE type is a subtype of the TYPE-TO-CHECK.) + ;; + ;; T + ;; A type check is needed. + (%type-check t :type (member t nil)) + ;; the continuations which is checked + (value (missing-arg) :type continuation)) +(defprinter (cast :identity t) + %type-check + value + asserted-type + type-to-check) ;;;; non-local exit support ;;;;