From 82e3ca5623c21612d0d833d48d462b7b9ad69bcf Mon Sep 17 00:00:00 2001 From: ram <ram> Date: Mon, 7 Sep 1992 15:26:39 +0000 Subject: [PATCH] Changes to handling of inline expansion/inlinep information. LEXENV-INLINES is gone. Instead, :NOTINLINE references are changed to refer to :NOTINLINE DEFINED-FUNCTION leafs. The previous use in e.g. locall where we set LEAF-INLINEP to NIL to inhibit further optimization in the case of an error is now handed by the :ERROR combination-kind. Moved *failed-optimizations* to COMPONENT-FAILED-OPTIMIZATIONS. Added COMPONENT-INLINE-EXPANSIONS which stops infinite (or very frequent) inline expansions. Added :COMPLEX-TOP-LEVEL functional kind used to represent components with mixed top-level and run-time code. The DEFINED-FUNCTION leaf stores information about functions where we either know the actual definition, inline expansion, or have a non-default inlinep. This allows us to clean up the semantics of block compilation and inline expansion a bit, since we can keep track of both the GLOBAL-VAR and FUNCTIONAL versions of a function. --- compiler/node.lisp | 88 +++++++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 25 deletions(-) diff --git a/compiler/node.lisp b/compiler/node.lisp index 4ff1dfbe5..c5d2e04e6 100644 --- a/compiler/node.lisp +++ b/compiler/node.lisp @@ -7,7 +7,7 @@ ;;; Scott Fahlman or slisp-group@cs.cmu.edu. ;;; (ext:file-comment - "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/node.lisp,v 1.24 1992/04/21 04:15:00 wlott Exp $") + "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/node.lisp,v 1.25 1992/09/07 15:26:39 ram Exp $") ;;; ;;; ********************************************************************** ;;; @@ -16,7 +16,7 @@ ;;; ;;; Written by Rob MacLachlan ;;; -(in-package 'c) +(in-package "C") (export '(component component-info)) @@ -33,7 +33,7 @@ (:constructor make-null-environment ()) (:constructor internal-make-lexenv (functions variables blocks tags type-restrictions - inlines lambda cleanup cookie + lambda cleanup cookie interface-cookie options))) ;; ;; Alist (name . what), where What is either a Functional (a local function) @@ -67,9 +67,6 @@ ;; to track the innermost THE type declaration. (type-restrictions nil :type list) ;; - ;; An alist (Leaf . Inlinep) describing local inline declarations. - (inlines nil :type list) - ;; ;; The lexically enclosing lambda, if any. (lambda nil :type (or clambda null)) ;; @@ -415,11 +412,14 @@ ;; The kind of component: ;; ;; NIL - ;; An ordinary component, containing arbitrary code. + ;; An ordinary component, containing non-top-level code. ;; ;; :Top-Level ;; A component containing only load-time code. ;; + ;; :Complex-Top-Level + ;; A component containing both top-level and run-time code. + ;; ;; :Initial ;; The result of initial IR1 conversion, on which component analysis has ;; not been done. @@ -427,7 +427,7 @@ ;; :Deleted ;; Debris left over from component analysis. ;; - (kind nil :type (member nil :top-level :initial :deleted)) + (kind nil :type (member nil :top-level :complex-top-level :initial :deleted)) ;; ;; The blocks that are the dummy head and tail of the DFO. Entry/exit points ;; have these blocks as their predecessors/successors. Null temporarily. @@ -465,7 +465,19 @@ ;; ;; The Source-Info structure describing where this component was compiled ;; from. - (source-info *source-info* :type source-info)) + (source-info *source-info* :type source-info) + ;; + ;; Count of the number of inline expansions we have done while compiling this + ;; component, to detect infinite or exponential blowups. + (inline-expansions 0 :type index) + ;; + ;; A hashtable from combination nodes to things describing how an + ;; optimization of the node failed. The value is an alist + ;; (Transform . Args), where Transform is the structure describing the + ;; transform that failed, and Args is either a list of format arguments for + ;; the note, or the FUNCTION-TYPE that would have enabled the transformation + ;; but failed to match. + (failed-optimizations (make-hash-table :test #'eq) :type hash-table)) (defprinter component name @@ -701,6 +713,32 @@ for slot) +;;; The Defined-Function structure represents functions that are 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. +;;; +(defstruct (defined-function (:include global-var + (where-from :defined) + (kind :global-function)) + (:print-function %print-defined-function)) + ;; + ;; The values of INLINEP and INLINE-EXPANSION initialized from the global + ;; environment. + (inlinep nil :type inlinep) + (inline-expansion nil :type (or cons null)) + ;; + ;; The block-local definition of this function (either because it was + ;; semi-inline, or because it was defined in this block.) If this function + ;; is not an entry point, then this may be deleted or let-converted. Null if + ;; we haven't converted the expansion yet. + (functional nil :type (or functional null))) + +(defprinter defined-function + name + inlinep + (functional :test functional)) ;;;; Function stuff: @@ -790,9 +828,13 @@ ;; With all other kinds, this is null. (entry-function nil :type (or functional null)) ;; + ;; The value of any inline/notinline declaration for a local function. + (inlinep nil :type inlinep) + ;; ;; If we have a lambda that can be used as in inline expansion for this ;; function, then this is it. If there is no source-level lambda - ;; corresponding to this function then this is Null. + ;; corresponding to this function then this is Null (but then INLINEP will + ;; always be NIL as well.) (inline-expansion nil :type list) ;; ;; The lexical environment that the inline-expansion should be converted in. @@ -1041,19 +1083,14 @@ ;;; (defstruct (ref (:include node (:reoptimize nil)) - (:constructor really-make-ref (derived-type leaf inlinep)) + (:constructor really-make-ref (derived-type leaf)) (:print-function %print-ref)) ;; ;; The leaf referenced. - (leaf nil :type leaf) - ;; - ;; For a function variable, indicates the legality of coding inline. Nil, - ;; means that there is no relevent declaration so we can do whatever we want. - (inlinep nil :type inlinep)) + (leaf nil :type leaf)) (defprinter ref - leaf - (inlinep :test inlinep)) + leaf) ;;; Naturally, the IF node always appears at the end of a block. Node-Cont is @@ -1115,13 +1152,14 @@ ;; variable is unreferenced, and thus no argument value need be passed. (args nil :type list) ;; - ;; The kind of function call being made. :Full is a standard call, with the - ;; function being determined at run time. :Local is used when we are calling - ;; a function known at compile time. The IR1 for the called function is - ;; spliced into the flow graph for the caller. Calls to known global - ;; functions are represented by storing the Function-Info for the function in - ;; this slot. - (kind :full :type (or (member :full :local) function-info)) + ;; The kind of function call being made. :LOCAL means that this is a local + ;; call to a function in the same component, and that argument syntax + ;; checking has been done, etc. Calls to known global functions are + ;; represented by storing the FUNCTION-INFO for the function in this slot. + ;; :FULL is a call to an (as yet) unknown function. :ERROR is like :FULL, + ;; but means that we have discovered that the call contains an error, and + ;; should not be reconsidered for optimization. + (kind :full :type (or (member :local :full :error) function-info)) ;; ;; Some kind of information attached to this node by the back end. (info nil)) -- GitLab