add SSE instructions with two opcode bytes
[sbcl.git] / src / compiler / entry.lisp
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.
4
5 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; more information.
7 ;;;;
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.
13
14 (in-package "SB!C")
15
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))
26       (when (xep-p fun)
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)
32   (values))
33
34 ;;; Initialize INFO structure to correspond to the XEP LAMBDA FUN.
35 (defun compute-entry-info (fun info)
36   (declare (type clambda fun) (type entry-info info))
37   (let ((bind (lambda-bind fun))
38         (internal-fun (functional-entry-fun fun)))
39     (setf (entry-info-closure-tn info)
40           (if (physenv-closure (lambda-physenv fun))
41               (make-normal-tn *backend-t-primitive-type*)
42               nil))
43     (setf (entry-info-offset info) (gen-label))
44     (setf (entry-info-name info)
45           (leaf-debug-name internal-fun))
46     (let ((doc (functional-documentation internal-fun))
47           (xrefs (pack-xref-data (functional-xref internal-fun))))
48       (setf (entry-info-info info) (if (and doc xrefs)
49                                        (cons doc xrefs)
50                                        (or doc xrefs))))
51     (when (policy bind (>= debug 1))
52       (let ((args (functional-arg-documentation internal-fun)))
53         (aver (not (eq args :unspecified)))
54         ;; When the component is dumped, the arglists of the entry
55         ;; points will be dumped.  If they contain values that need
56         ;; make-load-form processing then we need to do it now (bug
57         ;; 310132).
58         (setf (entry-info-arguments info)
59               (constant-value (find-constant args))))
60       (setf (entry-info-type info) (type-specifier (leaf-type internal-fun)))))
61   (values))
62
63 ;;; Replace all references to COMPONENT's non-closure XEPs that appear
64 ;;; in top level or externally-referenced components, changing to
65 ;;; :TOPLEVEL-XEP FUNCTIONALs. If the cross-component ref is not in a
66 ;;; :TOPLEVEL/externally-referenced component, or is to a closure,
67 ;;; then substitution is suppressed.
68 ;;;
69 ;;; When a cross-component ref is not substituted, we return T to
70 ;;; indicate that early deletion of this component's IR1 should not be
71 ;;; done. We also return T if this component contains
72 ;;; :TOPLEVEL/externally-referenced lambdas (though it is not a
73 ;;; :TOPLEVEL component.)
74 ;;;
75 ;;; We deliberately don't use the normal reference deletion, since we
76 ;;; don't want to trigger deletion of the XEP (although it shouldn't
77 ;;; hurt, since this is called after COMPONENT is compiled.) Instead,
78 ;;; we just clobber the REF-LEAF.
79 (defun replace-toplevel-xeps (component)
80   (let ((res nil))
81     (dolist (lambda (component-lambdas component))
82       (case (functional-kind lambda)
83         (:external
84          (unless (lambda-has-external-references-p lambda)
85            (let* ((ef (functional-entry-fun lambda))
86                   (new (make-functional
87                         :kind :toplevel-xep
88                         :info (leaf-info lambda)
89                         :%source-name (functional-%source-name ef)
90                         :%debug-name (functional-%debug-name ef)
91                         :lexenv (make-null-lexenv)))
92                   (closure (physenv-closure
93                             (lambda-physenv (main-entry ef)))))
94              (dolist (ref (leaf-refs lambda))
95                (let ((ref-component (node-component ref)))
96                  (cond ((eq ref-component component))
97                        ((or (not (component-toplevelish-p ref-component))
98                             closure)
99                         (setq res t))
100                        (t
101                         (setf (ref-leaf ref) new)
102                         (push ref (leaf-refs new))
103                         (setf (leaf-refs lambda)
104                               (delq ref (leaf-refs lambda))))))))))
105         (:toplevel
106          (setq res t))))
107     res))