1 ;;;; This file implements the IR1 finalize phase, which checks for
2 ;;;; various semantic errors.
4 ;;;; This software is part of the SBCL system. See the README file for
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.
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))))
30 ;; FIXME: This sometimes gets too long for a single line, e.g.
31 ;; "note: unable to optimize away possible call to FDEFINITION at runtime due to type uncertainty:"
32 ;; It would be nice to pretty-print it somehow, but how?
33 ;; ~@<..~:@> adds ~_ directives to the spaces which are in
34 ;; the format string, but a lot of the spaces where we'd want
35 ;; to break are in the included ~A string instead.
36 (compiler-note "unable to ~A because:~%~6T~?"
37 note (first what) (rest what)))
38 ((valid-function-use node what
39 :argument-test #'types-intersect
40 :result-test #'values-types-intersect)
42 (flet ((frob (string &rest stuff)
45 (valid-function-use node what
46 :warning-function #'frob
47 :error-function #'frob))
49 (compiler-note "unable to ~A due to type uncertainty:~@
51 note (messages))))))))))
53 ;;; For each named function with an XEP, note the definition of that
54 ;;; name, and add derived type information to the info environment. We
55 ;;; also delete the FUNCTIONAL from *FREE-FUNCTIONS* to eliminate the
56 ;;; possibility that new references might be converted to it.
57 (defun finalize-xep-definition (fun)
58 (let* ((leaf (functional-entry-function fun))
59 (name (leaf-name leaf))
60 (dtype (definition-type leaf)))
61 (setf (leaf-type leaf) dtype)
62 (when (or (and name (symbolp name))
63 (and (consp name) (eq (car name) 'setf)))
64 (let* ((where (info :function :where-from name))
65 (*compiler-error-context* (lambda-bind (main-entry leaf)))
66 (global-def (gethash name *free-functions*))
68 (and (defined-function-p global-def)
69 (eq (defined-function-functional global-def) leaf))))
70 (note-name-defined name :function)
72 (remhash name *free-functions*))
75 (let ((approx-type (info :function :assumed-type name)))
76 (when (and approx-type (function-type-p dtype))
77 (valid-approximate-type approx-type dtype))
78 (setf (info :function :type name) dtype)
79 (setf (info :function :assumed-type name) nil))
80 (setf (info :function :where-from name) :defined))
81 (:declared); Just keep declared type.
84 (setf (info :function :type name) dtype)))))))
87 ;;; Find all calls in Component to assumed functions and update the assumed
88 ;;; type information. This is delayed until now so that we have the best
89 ;;; possible information about the actual argument types.
90 (defun note-assumed-types (component name var)
91 (when (and (eq (leaf-where-from var) :assumed)
92 (not (and (defined-function-p var)
93 (eq (defined-function-inlinep var) :notinline)))
94 (eq (info :function :where-from name) :assumed)
95 (eq (info :function :kind name) :function))
96 (let ((atype (info :function :assumed-type name)))
97 (dolist (ref (leaf-refs var))
98 (let ((dest (continuation-dest (node-cont ref))))
99 (when (and (eq (block-component (node-block ref)) component)
101 (eq (continuation-use (basic-combination-fun dest)) ref))
102 (setq atype (note-function-use dest atype)))))
103 (setf (info :function :assumed-type name) atype))))
105 ;;; Do miscellaneous things that we want to do once all optimization has
107 ;;; -- Record the derived result type before the back-end trashes the
109 ;;; -- Note definition of any entry points.
110 ;;; -- Note any failed optimizations.
111 (defun ir1-finalize (component)
112 (declare (type component component))
113 (dolist (fun (component-lambdas component))
114 (case (functional-kind fun)
116 (finalize-xep-definition fun))
118 (setf (leaf-type fun) (definition-type fun)))))
120 (maphash #'note-failed-optimization
121 (component-failed-optimizations component))
123 (maphash #'(lambda (k v)
124 (note-assumed-types component k v))