ir1final.lisp 5.12 KB
Newer Older
wlott's avatar
wlott committed
1
2
3
;;; -*- Package: C; Log: C.Log -*-
;;;
;;; **********************************************************************
ram's avatar
ram committed
4
5
6
7
8
9
;;; This code was written as part of the CMU Common Lisp project at
;;; Carnegie Mellon University, and has been placed in the public domain.
;;; If you want to use this code or any part of CMU Common Lisp, please contact
;;; Scott Fahlman or slisp-group@cs.cmu.edu.
;;;
(ext:file-comment
10
  "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/ir1final.lisp,v 1.19 1993/08/17 16:23:35 ram Exp $")
ram's avatar
ram committed
11
;;;
wlott's avatar
wlott committed
12
13
14
15
16
17
18
;;; **********************************************************************
;;;
;;;    This file implements the IR1 finalize phase, which checks for various
;;; semantic errors.
;;;
;;; Written by Rob MacLachlan
;;;
19
(in-package "C")
wlott's avatar
wlott committed
20
21


22
;;; Note-Failed-Optimization  --  Internal
wlott's avatar
wlott committed
23
24
25
26
27
28
;;;
;;;    Give the user grief about optimizations that we weren't able to do.  It
;;; is assumed that they want to hear, or there wouldn't be any entries in the
;;; table.  If the node has been deleted or is no longer a known call, then do
;;; nothing; some other optimization must have gotten to it.
;;;
29
30
(defun note-failed-optimization (node failures)
  (declare (type combination node) (list failures))
wlott's avatar
wlott committed
31
32
33
  (unless (or (node-deleted node)
	      (not (function-info-p (combination-kind node))))
    (let ((*compiler-error-context* node))
34
      (dolist (failure failures)
35
36
	(let ((what (cdr failure))
	      (note (transform-note (car failure))))
37
38
	  (cond
	   ((consp what)
39
40
	    (compiler-note "Unable to ~A because:~%~6T~?"
			   note (first what) (rest what)))
41
42
43
44
45
46
47
48
49
50
51
	   ((valid-function-use node what
				:argument-test #'types-intersect
				:result-test #'values-types-intersect)
	    (collect ((messages))
	      (flet ((frob (string &rest stuff)
		       (messages string)
		       (messages stuff)))
		(valid-function-use node what
				    :warning-function #'frob
				    :error-function #'frob))
	      
52
	      (compiler-note "Unable to ~A due to type uncertainty:~@
53
	                      ~{~6T~?~^~&~}"
54
			     note (messages))))))))))
wlott's avatar
wlott committed
55

56

57
58
59
60
61
62
63
64
65
66
;;; FINALIZE-XEP-DEFINITION  --  Internal
;;;
;;; For each named function with an XEP, note the definition of that name, and
;;; add derived type information to the info environment.  We also delete the
;;; FUNCTIONAL from *FREE-FUNCTIONS* to eliminate the possibility that new
;;; references might be converted to it.
;;;
(defun finalize-xep-definition (fun)
  (let* ((leaf (functional-entry-function fun))
	 (name (leaf-name leaf))
67
	 (dtype (definition-type leaf)))
68
    (setf (leaf-type leaf) dtype)
69
70
    (when (or (and name (symbolp name))
	      (and (consp name) (eq (car name) 'setf)))
71
72
73
74
75
76
      (let* ((where (info function where-from name))
	     (*compiler-error-context* (lambda-bind (main-entry leaf)))
	     (global-def (gethash name *free-functions*))
	     (global-p
	      (and (defined-function-p global-def)
		   (eq (defined-function-functional global-def) leaf))))
77
78
79
80
81
82
83
84
85
86
87
88
89
	(note-name-defined name :function)
	(when global-p
	  (remhash name *free-functions*))
	(ecase where
	  (:assumed
	   (let ((approx-type (info function assumed-type name)))
	     (when (and approx-type (function-type-p dtype))
	       (valid-approximate-type approx-type dtype))
	     (setf (info function type name) dtype)
	     (setf (info function assumed-type name) nil))
	   (setf (info function where-from name) :defined))
	  (:declared); Just keep declared type.
	  (:defined
90
91
	   (when global-p
	     (setf (info function type name) dtype)))))))
92
  (undefined-value))
93
94
95
96
97
98
99
100
101


;;; NOTE-ASSUMED-TYPES  --  Internal
;;;
;;;    Find all calls in Component to assumed functions and update the assumed
;;; type information.  This is delayed until now so that we have the best
;;; possible information about the actual argument types.
;;;
(defun note-assumed-types (component name var)
102
103
  (when (and (eq (leaf-where-from var) :assumed)
	     (not (and (defined-function-p var)
104
105
106
		       (eq (defined-function-inlinep var) :notinline)))
	     (eq (info function where-from name) :assumed)
	     (eq (info function kind name) :function))
107
108
109
110
111
112
113
114
115
    (let ((atype (info function assumed-type name)))
      (dolist (ref (leaf-refs var))
	(let ((dest (continuation-dest (node-cont ref))))
	  (when (and (eq (block-component (node-block ref)) component)
		     (combination-p dest)
		     (eq (continuation-use (basic-combination-fun dest)) ref))
	    (setq atype (note-function-use dest atype)))))
      (setf (info function assumed-type name) atype))))

116

117
;;; IR1-FINALIZE  --  Interface
wlott's avatar
wlott committed
118
;;;
119
120
121
122
;;;    Do miscellaneous things that we want to do once all optimization has
;;; been done:
;;;  -- Record the derived result type before the back-end trashes the
;;;     flow graph.
123
;;;  -- Note definition of any entry points.
124
125
126
127
128
129
130
;;;  -- Note any failed optimizations.
;;; 
(defun ir1-finalize (component)
  (declare (type component component))
  (dolist (fun (component-lambdas component))
    (case (functional-kind fun)
      (:external
131
       (finalize-xep-definition fun))
132
133
      ((nil)
       (setf (leaf-type fun) (definition-type fun)))))
134
135
136
137
138
139
140
  
  (maphash #'note-failed-optimization
	   (component-failed-optimizations component))
  
  (maphash #'(lambda (k v)
	       (note-assumed-types component k v))
	   *free-functions*)
141
  (undefined-value))