1 ;;;; Code in this file handles VM-independent details of run-time
2 ;;;; function representation that primarily concern IR2 conversion and
3 ;;;; the dumper/loader.
5 ;;;; This software is part of the SBCL system. See the README file for
8 ;;;; This software is derived from the CMU CL system, which was
9 ;;;; written at Carnegie Mellon University and released into the
10 ;;;; public domain. The software is in the public domain and is
11 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
12 ;;;; files for more information.
16 ;;; This phase runs before IR2 conversion, initializing each XEP's
17 ;;; ENTRY-INFO structure. We call the VM-supplied
18 ;;; SELECT-COMPONENT-FORMAT function to make VM-dependent
19 ;;; initializations in the IR2-COMPONENT. This includes setting the
20 ;;; IR2-COMPONENT-KIND and allocating fixed implementation overhead in
21 ;;; the constant pool. If there was a forward reference to a function,
22 ;;; then the ENTRY-INFO will already exist, but will be uninitialized.
23 (defun entry-analyze (component)
24 (let ((2comp (component-info component)))
25 (dolist (fun (component-lambdas component))
27 (let ((info (or (leaf-info fun)
28 (setf (leaf-info fun) (make-entry-info)))))
29 (compute-entry-info fun info)
30 (push info (ir2-component-entries 2comp))))))
31 (select-component-format component)
34 ;;; Takes the list representation of the debug arglist and turns it
37 ;;; FIXME: Why don't we just save this as a list instead of converting
39 (defun make-arg-names (x)
40 (declare (type functional x))
41 (let ((args (functional-arg-documentation x)))
42 (aver (not (eq args :unspecified)))
45 (let ((*print-pretty* t)
49 (*print-case* :downcase))
50 (write-to-string args)))))
52 ;;; Initialize INFO structure to correspond to the XEP LAMBDA FUN.
53 (defun compute-entry-info (fun info)
54 (declare (type clambda fun) (type entry-info info))
55 (let ((bind (lambda-bind fun))
56 (internal-fun (functional-entry-fun fun)))
57 (setf (entry-info-closure-p info)
58 (not (null (physenv-closure (lambda-physenv fun)))))
59 (setf (entry-info-offset info) (gen-label))
60 (setf (entry-info-name info)
61 (leaf-debug-name internal-fun))
62 (when (policy bind (>= debug 1))
63 (setf (entry-info-arguments info) (make-arg-names internal-fun))
64 (setf (entry-info-type info) (type-specifier (leaf-type internal-fun)))))
67 ;;; Replace all references to COMPONENT's non-closure XEPs that appear
68 ;;; in top level or externally-referenced components, changing to
69 ;;; :TOPLEVEL-XEP FUNCTIONALs. If the cross-component ref is not in a
70 ;;; :TOPLEVEL/externally-referenced component, or is to a closure,
71 ;;; then substitution is suppressed.
73 ;;; When a cross-component ref is not substituted, we return T to
74 ;;; indicate that early deletion of this component's IR1 should not be
75 ;;; done. We also return T if this component contains
76 ;;; :TOPLEVEL/externally-referenced lambdas (though it is not a
77 ;;; :TOPLEVEL component.)
79 ;;; We deliberately don't use the normal reference deletion, since we
80 ;;; don't want to trigger deletion of the XEP (although it shouldn't
81 ;;; hurt, since this is called after COMPONENT is compiled.) Instead,
82 ;;; we just clobber the REF-LEAF.
83 (defun replace-toplevel-xeps (component)
85 (dolist (lambda (component-lambdas component))
86 (case (functional-kind lambda)
88 (unless (lambda-has-external-references-p lambda)
89 (let* ((ef (functional-entry-fun lambda))
92 :info (leaf-info lambda)
93 :%source-name (functional-%source-name ef)
94 :%debug-name (functional-%debug-name ef)
95 :lexenv (make-null-lexenv)))
96 (closure (physenv-closure
97 (lambda-physenv (main-entry ef)))))
98 (dolist (ref (leaf-refs lambda))
99 (let ((ref-component (node-component ref)))
100 (cond ((eq ref-component component))
101 ((or (not (component-toplevelish-p ref-component))
105 (setf (ref-leaf ref) new)
106 (push ref (leaf-refs new)))))))))