X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fvop.lisp;h=5395e236321966721b4f262fc7acf0e19cd2b63b;hb=b63c4fb9b98fa8188e17ba926e150ba417a74635;hp=605bb4a4379d511a707ccb332a649c23d4f69e65;hpb=e47ffa8855d4139f88f5982fe4b82a05c3498ed3;p=sbcl.git diff --git a/src/compiler/vop.lisp b/src/compiler/vop.lisp index 605bb4a..5395e23 100644 --- a/src/compiler/vop.lisp +++ b/src/compiler/vop.lisp @@ -47,7 +47,7 @@ (scs nil :type list) ;; the Lisp type equivalent to this type. If this type could never be ;; returned by PRIMITIVE-TYPE, then this is the NIL (or empty) type - (type (missing-arg) :type ctype) + (specifier (missing-arg) :type type-specifier) ;; the template used to check that an object is of this type. This is a ;; template of one argument and one result, both of primitive-type T. If ;; the argument is of the correct type, then it is delivered into the @@ -68,9 +68,9 @@ ;;; COMPONENT-INFO ;;; Holds the IR2-COMPONENT structure. ;;; -;;; CONTINUATION-INFO -;;; Holds the IR2-CONTINUATION structure. Continuations whose -;;; values aren't used won't have any. +;;; LVAR-INFO +;;; Holds the IR2-LVAR structure. LVARs whose values aren't used +;;; won't have any. XXX ;;; ;;; CLEANUP-INFO ;;; If non-null, then a TN in which the affected dynamic @@ -111,22 +111,21 @@ ;; the IR2-BLOCK's number, which differs from BLOCK's BLOCK-NUMBER ;; if any blocks are split. This is assigned by lifetime analysis. (number nil :type (or index null)) - ;; information about unknown-values continuations that is used by - ;; stack analysis to do stack simulation. An UNKNOWN-VALUES - ;; continuation is PUSHED if its DEST is in another block. - ;; Similarly, a continuation is POPPED if its DEST is in this block - ;; but has its uses elsewhere. The continuations are in the order - ;; that are pushed/popped in the block. Note that the args to a - ;; single MV-COMBINATION appear reversed in POPPED, since we must - ;; effectively pop the last argument first. All pops must come - ;; before all pushes (although internal MV uses may be interleaved.) - ;; POPPED is computed by LTN, and PUSHED is computed by stack - ;; analysis. + ;; information about unknown-values LVARs that is used by stack + ;; analysis to do stack simulation. An UNKNOWN-VALUES LVAR is PUSHED + ;; if its DEST is in another block. Similarly, a LVAR is POPPED if + ;; its DEST is in this block but has its uses elsewhere. The LVARs + ;; are in the order that are pushed/popped in the block. Note that + ;; the args to a single MV-COMBINATION appear reversed in POPPED, + ;; since we must effectively pop the last argument first. All pops + ;; must come before all pushes (although internal MV uses may be + ;; interleaved.) POPPED is computed by LTN, and PUSHED is computed + ;; by stack analysis. (pushed () :type list) (popped () :type list) ;; the result of stack analysis: lists of all the unknown-values - ;; continuations on the stack at the block start and end, topmost - ;; continuation first. + ;; LVARs on the stack at the block start and end, topmost LVAR + ;; first. (start-stack () :type list) (end-stack () :type list) ;; the first and last VOP in this block. If there are none, both @@ -180,45 +179,51 @@ (local-tn-count :test (not (zerop local-tn-count))) (%label :test %label)) -;;; An IR2-CONTINUATION structure is used to annotate continuations -;;; that are used as a function result continuation or that receive MVs. -(defstruct (ir2-continuation - (:constructor make-ir2-continuation (primitive-type)) +;;; An IR2-LVAR structure is used to annotate LVARs that are used as a +;;; function result LVARs or that receive MVs. +(defstruct (ir2-lvar + (:constructor make-ir2-lvar (primitive-type)) (:copier nil)) - ;; If this is :DELAYED, then this is a single value continuation for - ;; which the evaluation of the use is to be postponed until the - ;; evaluation of destination. This can be done for ref nodes or - ;; predicates whose destination is an IF. + ;; If this is :DELAYED, then this is a single value LVAR for which + ;; the evaluation of the use is to be postponed until the evaluation + ;; of destination. This can be done for ref nodes or predicates + ;; whose destination is an IF. ;; - ;; If this is :FIXED, then this continuation has a fixed number of - ;; values, with the TNs in LOCS. + ;; If this is :FIXED, then this LVAR has a fixed number of values, + ;; with the TNs in LOCS. ;; - ;; If this is :UNKNOWN, then this is an unknown-values continuation, - ;; using the passing locations in LOCS. + ;; If this is :UNKNOWN, then this is an unknown-values LVAR, using + ;; the passing locations in LOCS. ;; - ;; If this is :UNUSED, then this continuation should never actually - ;; be used as the destination of a value: it is only used - ;; tail-recursively. + ;; If this is :UNUSED, then this LVAR should never actually be used + ;; as the destination of a value: it is only used tail-recursively. (kind :fixed :type (member :delayed :fixed :unknown :unused)) - ;; The primitive-type of the first value of this continuation. This - ;; is primarily for internal use during LTN, but it also records the + ;; The primitive-type of the first value of this LVAR. This is + ;; primarily for internal use during LTN, but it also records the ;; type restriction on delayed references. In multiple-value ;; contexts, this is null to indicate that it is meaningless. This - ;; is always (primitive-type (continuation-type cont)), which may be - ;; more restrictive than the tn-primitive-type of the value TN. This - ;; is becase the value TN must hold any possible type that could be - ;; computed (before type checking.) + ;; is always (primitive-type (lvar-type cont)), which may be more + ;; restrictive than the tn-primitive-type of the value TN. This is + ;; becase the value TN must hold any possible type that could be + ;; computed (before type checking.) XXX (primitive-type nil :type (or primitive-type null)) - ;; Locations used to hold the values of the continuation. If the - ;; number of values if fixed, then there is one TN per value. If the - ;; number of values is unknown, then this is a two-list of TNs - ;; holding the start of the values glob and the number of values. - ;; Note that since type checking is the responsibility of the values - ;; receiver, these TNs primitive type is only based on the proven - ;; type information. - (locs nil :type list)) + ;; Locations used to hold the values of the LVAR. If the number of + ;; values if fixed, then there is one TN per value. If the number of + ;; values is unknown, then this is a two-list of TNs holding the + ;; start of the values glob and the number of values. Note that + ;; since type checking is the responsibility of the values receiver, + ;; these TNs primitive type is only based on the proven type + ;; information. + (locs nil :type list) + #!+stack-grows-downward-not-upward + (stack-pointer nil :type (or tn null))) +;; For upward growing stack start of stack block and start of object +;; differ only by lowtag. +#!-stack-grows-downward-not-upward +(defmacro ir2-lvar-stack-pointer (2lvar) + `(first (ir2-lvar-locs ,2lvar))) -(defprinter (ir2-continuation) +(defprinter (ir2-lvar) kind primitive-type locs) @@ -309,12 +314,14 @@ ;;; An ENTRY-INFO condenses all the information that the dumper needs ;;; to create each XEP's function entry data structure. ENTRY-INFO -;;; structures are somtimes created before they are initialized, since -;;; IR2 conversion may need to compile a forward reference. In this -;;; case the slots aren't actually initialized until entry analysis runs. +;;; structures are sometimes created before they are initialized, +;;; since IR2 conversion may need to compile a forward reference. In +;;; this case the slots aren't actually initialized until entry +;;; analysis runs. (defstruct (entry-info (:copier nil)) - ;; Does this function have a non-null closure environment? - (closure-p nil :type boolean) + ;; TN, containing closure (if needed) for this function in the home + ;; environment. + (closure-tn nil :type (or null tn)) ;; a label pointing to the entry vector for this function, or NIL ;; before ENTRY-ANALYZE runs (offset nil :type (or label null)) @@ -415,13 +422,53 @@ home save-sp dynamic-state) + +(defstruct (cloop (:conc-name loop-) + (:predicate loop-p) + (:constructor make-loop) + (:copier copy-loop)) + ;; The kind of loop that this is. These values are legal: + ;; + ;; :OUTER + ;; This is the outermost loop structure, and represents all the + ;; code in a component. + ;; + ;; :NATURAL + ;; A normal loop with only one entry. + ;; + ;; :STRANGE + ;; A segment of a "strange loop" in a non-reducible flow graph. + (kind (required-argument) :type (member :outer :natural :strange)) + ;; The first and last blocks in the loop. There may be more than one tail, + ;; since there may be multiple back branches to the same head. + (head nil :type (or cblock null)) + (tail nil :type list) + ;; A list of all the blocks in this loop or its inferiors that have a + ;; successor outside of the loop. + (exits nil :type list) + ;; The loop that this loop is nested within. This is null in the outermost + ;; loop structure. + (superior nil :type (or cloop null)) + ;; A list of the loops nested directly within this one. + (inferiors nil :type list) + (depth 0 :type fixnum) + ;; The head of the list of blocks directly within this loop. We must recurse + ;; on INFERIORS to find all the blocks. + (blocks nil :type (or null cblock))) + +(defprinter (cloop :conc-name LOOP-) + kind + head + tail + exits + depth) ;;;; VOPs and templates ;;; A VOP is a Virtual Operation. It represents an operation and the ;;; operands to the operation. -(defstruct (vop (:constructor make-vop (block node info args results)) - (:copier nil)) +(def!struct (vop (:constructor make-vop (block node info args results)) + (:copier nil)) ;; VOP-INFO structure containing static info about the operation (info nil :type (or vop-info null)) ;; the IR2-BLOCK this VOP is in @@ -460,8 +507,8 @@ ;;; A TN-REF object contains information about a particular reference ;;; to a TN. The information in TN-REFs largely determines how TNs are ;;; packed. -(defstruct (tn-ref (:constructor make-tn-ref (tn write-p)) - (:copier nil)) +(def!struct (tn-ref (:constructor make-tn-ref (tn write-p)) + (:copier nil)) ;; the TN referenced (tn (missing-arg) :type tn) ;; Is this is a write reference? (as opposed to a read reference) @@ -500,7 +547,7 @@ ;; the arg/result type restrictions. We compute this from the ;; PRIMITIVE-TYPE restrictions to make life easier for IR1 phases ;; that need to anticipate LTN's template selection. - (type (missing-arg) :type fun-type) + (type (missing-arg) :type ctype) ;; lists of restrictions on the argument and result types. A ;; restriction may take several forms: ;; -- The restriction * is no restriction at all. @@ -732,6 +779,7 @@ ;; is set, then the location is in use somewhere in the block, and ;; thus has a conflict for always-live TNs. (always-live '#() :type simple-vector) + (always-live-count '#() :type simple-vector) ;; a vector containing the TN currently live in each location in the ;; SB, or NIL if the location is unused. This is used during load-tn pack. (live-tns '#() :type simple-vector) @@ -743,7 +791,7 @@ ;;; the SC structure holds the storage base that storage is allocated ;;; in and information used to select locations within the SB -(defstruct (sc (:copier nil)) +(def!struct (sc (:copier nil)) ;; name, for printing and reference (name nil :type symbol) ;; the number used to index SC cost vectors @@ -815,7 +863,7 @@ ;;;; TNs -(defstruct (tn (:include sset-element) +(def!struct (tn (:include sset-element) (:constructor make-random-tn) (:constructor make-tn (number kind primitive-type sc)) (:copier nil)) @@ -897,7 +945,7 @@ ;; If a local TN, the block relative number for this TN. Global TNs ;; whose liveness changes within a block are also assigned a local ;; number during the conflicts analysis of that block. If the TN has - ;; no local number within the block, then this is Nil. + ;; no local number within the block, then this is NIL. (local-number nil :type (or local-tn-number null)) ;; If this object is a local TN, this slot is a bit-vector with 1 ;; for the local-number of every TN that we conflict with. @@ -927,7 +975,9 @@ (cost 0 :type fixnum) ;; If a :ENVIRONMENT or :DEBUG-ENVIRONMENT TN, this is the ;; physical environment that the TN is live throughout. - (physenv nil :type (or physenv null))) + (physenv nil :type (or physenv null)) + ;; The depth of the deepest loop that this TN is used in. + (loop-depth 0 :type fixnum)) (def!method print-object ((tn tn) stream) (print-unreadable-object (tn stream :type t) ;; KLUDGE: The distinction between PRINT-TN and PRINT-OBJECT on TN is