0.6.7.22: removed CVS dollar-Header-dollar tags from sources
[sbcl.git] / src / compiler / ir1final.lisp
1 ;;;; This file implements the IR1 finalize phase, which checks for
2 ;;;; various semantic errors.
3
4 ;;;; This software is part of the SBCL system. See the README file for
5 ;;;; more information.
6 ;;;;
7 ;;;; This software is derived from the CMU CL system, which was
8 ;;;; written at Carnegie Mellon University and released into the
9 ;;;; public domain. The software is in the public domain and is
10 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
11 ;;;; files for more information.
12
13 (in-package "SB!C")
14
15 ;;; Give the user grief about optimizations that we weren't able to do. It
16 ;;; is assumed that they want to hear, or there wouldn't be any entries in the
17 ;;; table. If the node has been deleted or is no longer a known call, then do
18 ;;; nothing; some other optimization must have gotten to it.
19 (defun note-failed-optimization (node failures)
20   (declare (type combination node) (list failures))
21   (unless (or (node-deleted node)
22               (not (function-info-p (combination-kind node))))
23     (let ((*compiler-error-context* node))
24       (dolist (failure failures)
25         (let ((what (cdr failure))
26               (note (transform-note (car failure))))
27           (cond
28            ((consp what)
29             (compiler-note "unable to ~A because:~%~6T~?"
30                            note (first what) (rest what)))
31            ((valid-function-use node what
32                                 :argument-test #'types-intersect
33                                 :result-test #'values-types-intersect)
34             (collect ((messages))
35               (flet ((frob (string &rest stuff)
36                        (messages string)
37                        (messages stuff)))
38                 (valid-function-use node what
39                                     :warning-function #'frob
40                                     :error-function #'frob))
41
42               (compiler-note "unable to ~A due to type uncertainty:~@
43                               ~{~6T~?~^~&~}"
44                              note (messages))))))))))
45
46 ;;; For each named function with an XEP, note the definition of that
47 ;;; name, and add derived type information to the info environment. We
48 ;;; also delete the FUNCTIONAL from *FREE-FUNCTIONS* to eliminate the
49 ;;; possibility that new references might be converted to it.
50 (defun finalize-xep-definition (fun)
51   (let* ((leaf (functional-entry-function fun))
52          (name (leaf-name leaf))
53          (dtype (definition-type leaf)))
54     (setf (leaf-type leaf) dtype)
55     (when (or (and name (symbolp name))
56               (and (consp name) (eq (car name) 'setf)))
57       (let* ((where (info :function :where-from name))
58              (*compiler-error-context* (lambda-bind (main-entry leaf)))
59              (global-def (gethash name *free-functions*))
60              (global-p
61               (and (defined-function-p global-def)
62                    (eq (defined-function-functional global-def) leaf))))
63         (note-name-defined name :function)
64         (when global-p
65           (remhash name *free-functions*))
66         (ecase where
67           (:assumed
68            (let ((approx-type (info :function :assumed-type name)))
69              (when (and approx-type (function-type-p dtype))
70                (valid-approximate-type approx-type dtype))
71              (setf (info :function :type name) dtype)
72              (setf (info :function :assumed-type name) nil))
73            (setf (info :function :where-from name) :defined))
74           (:declared); Just keep declared type.
75           (:defined
76            (when global-p
77              (setf (info :function :type name) dtype)))))))
78   (values))
79
80 ;;; Find all calls in Component to assumed functions and update the assumed
81 ;;; type information. This is delayed until now so that we have the best
82 ;;; possible information about the actual argument types.
83 (defun note-assumed-types (component name var)
84   (when (and (eq (leaf-where-from var) :assumed)
85              (not (and (defined-function-p var)
86                        (eq (defined-function-inlinep var) :notinline)))
87              (eq (info :function :where-from name) :assumed)
88              (eq (info :function :kind name) :function))
89     (let ((atype (info :function :assumed-type name)))
90       (dolist (ref (leaf-refs var))
91         (let ((dest (continuation-dest (node-cont ref))))
92           (when (and (eq (block-component (node-block ref)) component)
93                      (combination-p dest)
94                      (eq (continuation-use (basic-combination-fun dest)) ref))
95             (setq atype (note-function-use dest atype)))))
96       (setf (info :function :assumed-type name) atype))))
97
98 ;;; Do miscellaneous things that we want to do once all optimization has
99 ;;; been done:
100 ;;;  -- Record the derived result type before the back-end trashes the
101 ;;;     flow graph.
102 ;;;  -- Note definition of any entry points.
103 ;;;  -- Note any failed optimizations.
104 (defun ir1-finalize (component)
105   (declare (type component component))
106   (dolist (fun (component-lambdas component))
107     (case (functional-kind fun)
108       (:external
109        (finalize-xep-definition fun))
110       ((nil)
111        (setf (leaf-type fun) (definition-type fun)))))
112
113   (maphash #'note-failed-optimization
114            (component-failed-optimizations component))
115
116   (maphash #'(lambda (k v)
117                (note-assumed-types component k v))
118            *free-functions*)
119   (values))