0.8.0.35:
[sbcl/lichteblau.git] / src / compiler / ir1final.lisp
blob8802d7edb036522afd1e0f5e26b7d3204eb1af64
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
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.
13 (in-package "SB!C")
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 (fun-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-fun-use node what
33 :argument-test #'types-equal-or-intersect
34 :result-test #'values-types-equal-or-intersect)
35 (collect ((messages))
36 (flet ((give-grief (string &rest stuff)
37 (messages string)
38 (messages stuff)))
39 (valid-fun-use node what
40 :unwinnage-fun #'give-grief
41 :lossage-fun #'give-grief))
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 ))))))
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-FUNS* to eliminate the
57 ;;; possibility that new references might be converted to it.
58 (defun finalize-xep-definition (fun)
59 (let* ((leaf (functional-entry-fun fun))
60 (defined-ftype (definition-type leaf)))
61 (setf (leaf-type leaf) defined-ftype)
62 (when (leaf-has-source-name-p leaf)
63 (let ((source-name (leaf-source-name leaf)))
64 (let* ((where (info :function :where-from source-name))
65 (*compiler-error-context* (lambda-bind (main-entry leaf)))
66 (global-def (gethash source-name *free-funs*))
67 (global-p (defined-fun-p global-def)))
68 (note-name-defined source-name :function)
69 (when global-p
70 (remhash source-name *free-funs*))
71 (ecase where
72 (:assumed
73 (let ((approx-type (info :function :assumed-type source-name)))
74 (when (and approx-type (fun-type-p defined-ftype))
75 (valid-approximate-type approx-type defined-ftype))
76 (setf (info :function :type source-name) defined-ftype)
77 (setf (info :function :assumed-type source-name) nil))
78 (setf (info :function :where-from source-name) :defined))
79 (:declared
80 (let ((declared-ftype (info :function :type source-name)))
81 (unless (defined-ftype-matches-declared-ftype-p
82 defined-ftype declared-ftype)
83 (compiler-style-warn
84 "~@<The previously declared FTYPE~2I ~_~S~I ~_~
85 conflicts with the definition type ~2I~_~S~:>"
86 (type-specifier declared-ftype)
87 (type-specifier defined-ftype)))))
88 (:defined
89 (setf (info :function :type source-name) defined-ftype)))))))
90 (values))
92 ;;; Find all calls in COMPONENT to assumed functions and update the
93 ;;; assumed type information. This is delayed until now so that we
94 ;;; have the best possible information about the actual argument
95 ;;; types.
96 (defun note-assumed-types (component name var)
97 (when (and (eq (leaf-where-from var) :assumed)
98 (not (and (defined-fun-p var)
99 (eq (defined-fun-inlinep var) :notinline)))
100 (eq (info :function :where-from name) :assumed)
101 (eq (info :function :kind name) :function))
102 (let ((atype (info :function :assumed-type name)))
103 (dolist (ref (leaf-refs var))
104 (let ((dest (continuation-dest (node-cont ref))))
105 (when (and (eq (node-component ref) component)
106 (combination-p dest)
107 (eq (continuation-use (basic-combination-fun dest)) ref))
108 (setq atype (note-fun-use dest atype)))))
109 (setf (info :function :assumed-type name) atype))))
111 ;;; Do miscellaneous things that we want to do once all optimization
112 ;;; has been done:
113 ;;; -- Record the derived result type before the back-end trashes the
114 ;;; flow graph.
115 ;;; -- Note definition of any entry points.
116 ;;; -- Note any failed optimizations.
117 (defun ir1-finalize (component)
118 (declare (type component component))
119 (dolist (fun (component-lambdas component))
120 (case (functional-kind fun)
121 (:external
122 (finalize-xep-definition fun))
123 ((nil)
124 (setf (leaf-type fun) (definition-type fun)))))
126 (maphash #'note-failed-optimization
127 (component-failed-optimizations component))
129 (maphash (lambda (k v)
130 (note-assumed-types component k v))
131 *free-funs*)
132 (values))