8f8cb1611eee5cb1cc3a943bc3088a4e70572620
[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
16 ;;; do. It is assumed that the user wants to hear about this, or there
17 ;;; wouldn't be any entries in the table. If the node has been deleted
18 ;;; or is no longer a known call, then do nothing; some other
19 ;;; optimization must have gotten to it.
20 (defun note-failed-optimization (node failures)
21   (declare (type combination node) (list failures))
22   (unless (or (node-deleted node)
23               (not (function-info-p (combination-kind node))))
24     (let ((*compiler-error-context* node))
25       (dolist (failure failures)
26         (let ((what (cdr failure))
27               (note (transform-note (car failure))))
28           (cond
29            ((consp what)
30             (compiler-note "~@<unable to ~2I~_~A ~I~_because: ~2I~_~?~:>"
31                            note (first what) (rest what)))
32            ((valid-function-use node what
33                                 :argument-test #'types-equal-or-intersect
34                                 :result-test #'values-types-equal-or-intersect)
35             (collect ((messages))
36               (flet ((frob (string &rest stuff)
37                        (messages string)
38                        (messages stuff)))
39                 (valid-function-use node what
40                                     :warning-function #'frob
41                                     :error-function #'frob))
42               (compiler-note "~@<unable to ~
43                               ~2I~_~A ~
44                               ~I~_due to type uncertainty: ~
45                               ~2I~_~{~?~^~@:_~}~:>"
46                              note (messages))))
47            ;; As best I can guess, it's OK to fall off the end here
48            ;; because if it's not a VALID-FUNCTION-USE, the user
49            ;; doesn't want to hear about it. The things I caught when
50            ;; I put ERROR "internal error: unexpected FAILURE=~S" here
51            ;; didn't look like things we need to report. -- WHN 2001-02-07
52            ))))))
53
54 ;;; For each named function with an XEP, note the definition of that
55 ;;; name, and add derived type information to the info environment. We
56 ;;; also delete the FUNCTIONAL from *FREE-FUNCTIONS* to eliminate the
57 ;;; possibility that new references might be converted to it.
58 (defun finalize-xep-definition (fun)
59   (let* ((leaf (functional-entry-function fun))
60          (name (leaf-name leaf))
61          (dtype (definition-type leaf)))
62     (setf (leaf-type leaf) dtype)
63     (when (or (and name (symbolp name))
64               (and (consp name) (eq (car name) 'setf)))
65       (let* ((where (info :function :where-from name))
66              (*compiler-error-context* (lambda-bind (main-entry leaf)))
67              (global-def (gethash name *free-functions*))
68              (global-p (defined-function-p global-def)))
69         (note-name-defined name :function)
70         (when global-p
71           (remhash name *free-functions*))
72         (ecase where
73           (:assumed
74            (let ((approx-type (info :function :assumed-type name)))
75              (when (and approx-type (function-type-p dtype))
76                (valid-approximate-type approx-type dtype))
77              (setf (info :function :type name) dtype)
78              (setf (info :function :assumed-type name) nil))
79            (setf (info :function :where-from name) :defined))
80           (:declared
81            ;; Check that derived type matches declared type.
82            (let ((type (info :function :type name)))
83              (when (and type (function-type-p dtype))
84                (let ((type-returns (function-type-returns type))
85                      (dtype-returns (function-type-returns dtype))
86                      (*error-function* #'compiler-warning))
87                  (unless (values-types-equal-or-intersect type-returns
88                                                           dtype-returns)
89                    (note-lossage "The result type from previous declaration:~%  ~S~@
90                                   conflicts with the result type:~%  ~S"
91                                  (type-specifier type-returns)
92                                  (type-specifier dtype-returns))))))
93            ;; (Regardless of what happens, we keep the declared type.)
94            )
95           (:defined
96            (when global-p
97              (setf (info :function :type name) dtype)))))))
98   (values))
99
100 ;;; Find all calls in Component to assumed functions and update the assumed
101 ;;; type information. This is delayed until now so that we have the best
102 ;;; possible information about the actual argument types.
103 (defun note-assumed-types (component name var)
104   (when (and (eq (leaf-where-from var) :assumed)
105              (not (and (defined-function-p var)
106                        (eq (defined-function-inlinep var) :notinline)))
107              (eq (info :function :where-from name) :assumed)
108              (eq (info :function :kind name) :function))
109     (let ((atype (info :function :assumed-type name)))
110       (dolist (ref (leaf-refs var))
111         (let ((dest (continuation-dest (node-cont ref))))
112           (when (and (eq (block-component (node-block ref)) component)
113                      (combination-p dest)
114                      (eq (continuation-use (basic-combination-fun dest)) ref))
115             (setq atype (note-function-use dest atype)))))
116       (setf (info :function :assumed-type name) atype))))
117
118 ;;; Do miscellaneous things that we want to do once all optimization has
119 ;;; been done:
120 ;;;  -- Record the derived result type before the back-end trashes the
121 ;;;     flow graph.
122 ;;;  -- Note definition of any entry points.
123 ;;;  -- Note any failed optimizations.
124 (defun ir1-finalize (component)
125   (declare (type component component))
126   (dolist (fun (component-lambdas component))
127     (case (functional-kind fun)
128       (:external
129        (finalize-xep-definition fun))
130       ((nil)
131        (setf (leaf-type fun) (definition-type fun)))))
132
133   (maphash #'note-failed-optimization
134            (component-failed-optimizations component))
135
136   (maphash #'(lambda (k v)
137                (note-assumed-types component k v))
138            *free-functions*)
139   (values))