Disallow both a :translator and :expander for any type name.
[sbcl.git] / src / compiler / generic / vm-type.lisp
blob2164d84101dcdf8f769786243816d2eedef852ae
1 ;;;; This file contains implementation-dependent parts of the type
2 ;;;; support code. This is stuff which deals with the mapping from
3 ;;;; types defined in Common Lisp to types actually supported by an
4 ;;;; implementation.
6 ;;;; This software is part of the SBCL system. See the README file for
7 ;;;; more information.
8 ;;;;
9 ;;;; This software is derived from the CMU CL system, which was
10 ;;;; written at Carnegie Mellon University and released into the
11 ;;;; public domain. The software is in the public domain and is
12 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
13 ;;;; files for more information.
15 (in-package "SB!KERNEL")
17 ;;;; implementation-dependent DEFTYPEs
19 ;;; Make DOUBLE-FLOAT a synonym for LONG-FLOAT, SINGLE-FLOAT for
20 ;;; SHORT-FLOAT. This is done by way of an "expander", not a "translator".
21 ;;; !PRECOMPUTE-TYPES will turn their :TYPE :KIND into :PRIMITIVE
22 ;;; in the target image so that they become not redefinable.
23 (sb!xc:deftype long-float (&optional low high) `(double-float ,low ,high))
24 (sb!xc:deftype short-float (&optional low high) `(single-float ,low ,high))
26 ;;; worst-case values for float attributes
27 (sb!xc:deftype float-exponent ()
28 #!-long-float 'double-float-exponent
29 #!+long-float 'long-float-exponent)
30 (sb!xc:deftype float-digits ()
31 #!-long-float `(integer 0 ,sb!vm:double-float-digits)
32 #!+long-float `(integer 0 ,sb!vm:long-float-digits))
33 (sb!xc:deftype float-radix () '(integer 2 2))
34 (sb!xc:deftype float-int-exponent ()
35 #!-long-float 'double-float-int-exponent
36 #!+long-float 'long-float-int-exponent)
38 ;;; a code for BOOLE
39 (sb!xc:deftype boole-code () '(unsigned-byte 4))
41 ;;; a byte specifier (as generated by BYTE)
42 (sb!xc:deftype byte-specifier () 'cons)
44 ;;; result of CHAR-INT
45 (sb!xc:deftype char-int () 'char-code)
47 ;;; PATHNAME pieces, as returned by the PATHNAME-xxx functions
48 (sb!xc:deftype pathname-host () '(or sb!impl::host null))
49 (sb!xc:deftype pathname-device ()
50 '(or simple-string (member nil :unspecific :unc)))
51 (sb!xc:deftype pathname-directory () 'list)
52 (sb!xc:deftype pathname-name ()
53 '(or simple-string sb!impl::pattern (member nil :unspecific :wild)))
54 (sb!xc:deftype pathname-type ()
55 '(or simple-string sb!impl::pattern (member nil :unspecific :wild)))
56 (sb!xc:deftype pathname-version ()
57 '(or integer (member nil :newest :wild :unspecific)))
59 ;;; internal time format. (Note: not a FIXNUM, ouch..)
60 (sb!xc:deftype internal-time () 'unsigned-byte)
62 (sb!xc:deftype bignum-element-type () `(unsigned-byte ,sb!vm:n-word-bits))
63 (sb!xc:deftype bignum-type () 'bignum)
64 ;;; FIXME: see also DEFCONSTANT MAXIMUM-BIGNUM-LENGTH in
65 ;;; src/code/bignum.lisp. -- CSR, 2004-07-19
66 (sb!xc:deftype bignum-index ()
67 '(mod #.(1- (ash 1 (- sb!vm:n-word-bits sb!vm:n-widetag-bits)))))
68 (sb!xc:deftype bignum-length ()
69 '(unsigned-byte #.(- sb!vm:n-word-bits sb!vm:n-widetag-bits)))
71 ;;; an index into an integer
72 (sb!xc:deftype bit-index ()
73 `(integer 0 #.(* (1- (ash 1 (- sb!vm:n-word-bits sb!vm:n-widetag-bits)))
74 sb!vm:n-word-bits)))
77 ;;;; hooks into the type system
79 (sb!xc:deftype unboxed-array (&optional dims)
80 (collect ((types (list 'or)))
81 (dolist (type *specialized-array-element-types*)
82 (when (subtypep type '(or integer character float (complex float)))
83 (types `(array ,type ,dims))))
84 (types)))
86 (sb!xc:deftype simple-unboxed-array (&optional dims)
87 (collect ((types (list 'or)))
88 (dolist (type *specialized-array-element-types*)
89 (when (subtypep type '(or integer character float (complex float)))
90 (types `(simple-array ,type ,dims))))
91 (types)))
93 (sb!xc:deftype complex-vector (&optional element-type length)
94 `(and (vector ,element-type ,length) (not simple-array)))
96 ;;; Return the symbol that describes the format of FLOAT.
97 (declaim (ftype (function (float) symbol) float-format-name))
98 (defun float-format-name (x)
99 (etypecase x
100 (single-float 'single-float)
101 (double-float 'double-float)
102 #!+long-float (long-float 'long-float)))
104 (declaim (ftype (sfunction (ctype) ctype) %upgraded-array-element-type))
105 (defun %upgraded-array-element-type (eltype)
106 (if (or (eq eltype *wild-type*)
107 ;; This is slightly dubious, but not as dubious as
108 ;; assuming that the upgraded-element-type should be
109 ;; equal to T, given the way that the AREF
110 ;; DERIVE-TYPE optimizer works. -- CSR, 2002-08-19
111 (contains-unknown-type-p eltype))
112 *wild-type*
113 (dolist (stype-name *specialized-array-element-types*
114 *universal-type*)
115 ;; FIXME: Mightn't it be better to have
116 ;; *SPECIALIZED-ARRAY-ELEMENT-TYPES* be stored as precalculated
117 ;; SPECIFIER-TYPE results, instead of having to calculate
118 ;; them on the fly this way? (Call the new array
119 ;; *SPECIALIZED-ARRAY-ELEMENT-SPECIFIER-TYPES* or something..)
120 (let ((stype (specifier-type stype-name)))
121 (aver (not (unknown-type-p stype)))
122 (when (csubtypep eltype stype)
123 (return stype))))))
125 (defun sb!xc:upgraded-array-element-type (spec &optional environment)
126 #!+sb-doc
127 "Return the element type that will actually be used to implement an array
128 with the specifier :ELEMENT-TYPE Spec."
129 (declare (ignore environment))
130 (handler-case
131 ;; Can't rely on SPECIFIER-TYPE to signal PARSE-UNKNOWN-TYPE in
132 ;; the case of (AND KNOWN UNKNOWN), since the result of the
133 ;; outter call to SPECIFIER-TYPE can be cached by the code that
134 ;; doesn't catch PARSE-UNKNOWN-TYPE signal.
135 (let ((type (specifier-type spec)))
136 (if (contains-unknown-type-p type)
137 (error "Undefined type: ~S" spec)
138 (type-specifier (%upgraded-array-element-type type))))
139 (parse-unknown-type (c)
140 (error "Undefined type: ~S" (parse-unknown-type-specifier c)))))
142 (defun sb!xc:upgraded-complex-part-type (spec &optional environment)
143 #!+sb-doc
144 "Return the element type of the most specialized COMPLEX number type that
145 can hold parts of type SPEC."
146 (declare (ignore environment))
147 (let ((type (specifier-type spec)))
148 (cond
149 ((eq type *empty-type*) nil)
150 ((unknown-type-p type) (error "undefined type: ~S" spec))
152 (let ((ctype (specifier-type `(complex ,spec))))
153 (cond
154 ((eq ctype *empty-type*) '(eql 0))
155 ((csubtypep ctype (specifier-type '(complex single-float)))
156 'single-float)
157 ((csubtypep ctype (specifier-type '(complex double-float)))
158 'double-float)
159 #!+long-float
160 ((csubtypep ctype (specifier-type '(complex long-float)))
161 'long-float)
162 ((csubtypep ctype (specifier-type '(complex rational)))
163 'rational)
164 (t 'real)))))))
166 ;;; Return the most specific integer type that can be quickly checked that
167 ;;; includes the given type.
168 (defun containing-integer-type (subtype)
169 (dolist (type `(fixnum
170 (signed-byte ,sb!vm:n-word-bits)
171 (unsigned-byte ,sb!vm:n-word-bits)
172 integer)
173 (error "~S isn't an integer type?" subtype))
174 (when (csubtypep subtype (specifier-type type))
175 (return type))))
177 ;;; If TYPE has a CHECK-xxx template, but doesn't have a corresponding
178 ;;; PRIMITIVE-TYPE, then return the template's name. Otherwise, return NIL.
179 (defun hairy-type-check-template-name (type)
180 (declare (type ctype type))
181 (typecase type
182 (cons-type
183 (if (type= type (specifier-type 'cons))
184 'sb!c:check-cons
185 nil))
186 (built-in-classoid
187 (if (type= type (specifier-type 'symbol))
188 'sb!c:check-symbol
189 nil))
190 (numeric-type
191 (cond ((type= type (specifier-type 'fixnum))
192 'sb!c:check-fixnum)
193 #!+#.(cl:if (cl:= 32 sb!vm:n-word-bits) '(and) '(or))
194 ((type= type (specifier-type '(signed-byte 32)))
195 'sb!c:check-signed-byte-32)
196 #!+#.(cl:if (cl:= 32 sb!vm:n-word-bits) '(and) '(or))
197 ((type= type (specifier-type '(unsigned-byte 32)))
198 'sb!c:check-unsigned-byte-32)
199 #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
200 ((type= type (specifier-type '(signed-byte 64)))
201 'sb!c:check-signed-byte-64)
202 #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
203 ((type= type (specifier-type '(unsigned-byte 64)))
204 'sb!c:check-unsigned-byte-64)
205 (t nil)))
206 (fun-type
207 'sb!c:check-fun)
209 nil)))
211 ;; Given a union type INPUT, see if it fully covers an ARRAY-* type,
212 ;; and unite into that when possible, taking care to handle more
213 ;; than one dimensionality/complexity of array, and non-array types.
214 ;; If FOR-TYPEP is true, then:
215 ;; - The input and result are lists of the component types.
216 ;; - We allow "almost coverings" of ARRAY-* to produce an answer
217 ;; that results in a quicker test.
218 ;; e.g. unboxed-array = (and array (not (array t)))
219 ;; Otherwise, if not FOR-TYPEP, the input/result are CTYPES,
220 ;; and we don't introduce negations into the union.
222 ;; Note that in FOR-TYPEP usage, this function should get a chance to see
223 ;; the whole union before WIDETAGS-FROM-UNION-TYPE has removed any types that
224 ;; are testable by their widetag. Otherwise (TYPEP X '(UNBOXED-ARRAY 1))
225 ;; becomes suboptimal. WIDETAGS-FROM-UNION-TYPE knows that strings/bit-vectors,
226 ;; either simple or hairy, all have distinguishing widetags, so if it sees
227 ;; them, reducing to (OR (%OTHER-POINTER-SUBTYPE-P ...) <more-array-types>),
228 ;; the other array-types will not comprise an "almost covering" of ARRAY-*
229 ;; and this code will not do what you want.
230 ;; Additionally, as part of the contract, we don't create a type-difference
231 ;; for a union all of whose types are testable by widetags.
232 ;; e.g. it would be suboptimal to rewrite
233 ;; (SIMPLE-UNBOXED-ARRAY (*)) -> (AND (SIMPLE-ARRAY * (*)) (NOT (ARRAY T)))
234 ;; because it always better to use %OTHER-POINTER-SUBTYPE-P in that case.
236 (defun simplify-array-unions (input &optional for-typep)
237 (let* ((array-props sb!vm:*specialized-array-element-type-properties*)
238 (types (if (listp input) input (union-type-types input)))
239 (full-mask (1- (ash 1 (length array-props))))
240 buckets output)
241 ;; KLUDGE: counting the input types is a fine preliminary check
242 ;; to avoid extra work, but importantly it (magically) bypasses all
243 ;; this logic during cold-init when CTYPE slots of all SAETPs are nil.
244 ;; SBCL sources mostly don't contain type expressions that benefit
245 ;; from this transform.
246 ;; If, in the not-for-typep case, there aren't at least as many
247 ;; array types as SAETPs, there can't be a covering.
248 ;; In the for-typep case, if there aren't at least half as many,
249 ;; then it couldn't be rewritten as negation.
250 ;; Uber-KLUDGE: using (length types) isn't enough to make the
251 ;; not-for-typep case make it all the way through cold-init.
252 (when (if for-typep
253 (< (length types) (floor (length array-props) 2))
254 (< (count-if #'array-type-p types) (length array-props)))
255 (return-from simplify-array-unions input))
256 (flet ((bucket-match-p (a b)
257 (and (eq (array-type-complexp a) (array-type-complexp b))
258 (equal (array-type-dimensions a) (array-type-dimensions b))))
259 (saetp-index (type)
260 (and (array-type-p type)
261 (neq (array-type-specialized-element-type type) *wild-type*)
262 (position (array-type-specialized-element-type type) array-props
263 :key #'sb!vm:saetp-ctype :test #'type=)))
264 (wild (type)
265 (make-array-type (array-type-dimensions type)
266 :element-type *wild-type*
267 :complexp (array-type-complexp type))))
268 ;; Bucket the array types by <dimensions,complexp> where each bucket
269 ;; tracks which SAETPs were seen.
270 ;; Search actual element types by TYPE=, not upgraded types, so that the
271 ;; transform into (ARRAY *) is not lossy. However, if uniting does occur
272 ;; and the resultant OR still contains any array type that upgrades to T,
273 ;; we might want to do yet another reduction because:
274 ;; (SPECIFIER-TYPE '(OR (VECTOR *) (VECTOR BAD))) => #<ARRAY-TYPE VECTOR>
275 (dolist (type types)
276 (binding* ((bit (saetp-index type) :exit-if-null)
277 (bucket (assoc type buckets :test #'bucket-match-p)))
278 (unless bucket
279 (push (setq bucket (cons type full-mask)) buckets))
280 ;; Each _missing_ type is represented by a '1' bit so that
281 ;; a final mask of 0 indicates an exhaustive partitioning.
282 ;; (SETF LOGBITP) would work for us, but CLHS doesn't require it.
283 (setf (cdr bucket) (logandc2 (cdr bucket) (ash 1 bit)))))
284 (cond
285 (for-typep
286 ;; Maybe compute the complement with respect to (ARRAY *)
287 ;; but never express unions of simple-rank-1 as a type-difference,
288 ;; because widetag testing of those is better.
289 (dolist (type types (nreverse output))
290 (let* ((bucket
291 (and (saetp-index type)
292 (or (array-type-complexp type)
293 (not (equal (array-type-dimensions type) '(*))))
294 (assoc type buckets :test #'bucket-match-p)))
295 (disjunct
296 (cond ((and bucket
297 (plusp (cdr bucket))
298 (< (logcount (cdr bucket))
299 (floor (length array-props) 2)))
300 (let (exclude)
301 (dotimes (i (length array-props))
302 (when (logbitp i (cdr bucket)) ; exclude it
303 (push (sb!vm:saetp-specifier
304 (svref array-props i)) exclude)))
305 (setf (cdr bucket) -1) ; mark as generated
306 (specifier-type
307 `(and ,(type-specifier (wild type))
308 ,@(mapcar (lambda (x) `(not (array ,x)))
309 exclude)))))
310 ((not (eql (cdr bucket) -1))
311 ;; noncanonical input is a bug,
312 ;; so assert that bucket is not full.
313 (aver (not (eql (cdr bucket) 0)))
314 type)))) ; keep
315 (when disjunct
316 (push disjunct output)))))
317 ((rassoc 0 buckets) ; at least one full bucket
318 ;; For each input type subsumed by a full bucket,
319 ;; insert the wild array type for that bucket.
320 (dolist (type types (apply #'type-union (nreverse output)))
321 (let* ((bucket (and (saetp-index type)
322 (assoc type buckets :test #'bucket-match-p)))
323 (disjunct (cond ((eql (cdr bucket) 0) ; bucket is full
324 (setf (cdr bucket) -1) ; mark as generated
325 (wild type))
326 ((not (eql (cdr bucket) -1))
327 type)))) ; keep
328 (when disjunct
329 (push disjunct output)))))
330 (t input))))) ; no change
332 ;; Given TYPES which is a list of types from a union type, decompose into
333 ;; two unions, one being an OR over types representable as widetags
334 ;; with other-pointer-lowtag, and the other being the difference
335 ;; between the input TYPES and the widetags.
336 ;; This is architecture-independent, but unfortunately the needed VOP can't
337 ;; be defined using DEFINE-TYPE-VOPS, so return (VALUES NIL TYPES) for
338 ;; unsupported backends which can't generate an arbitrary call to %TEST-HEADERS.
339 (defun widetags-from-union-type (types)
340 (setq types (simplify-array-unions types t))
341 ;; This seems preferable to a reader-conditional in generic code.
342 ;; There is a unit test that the supported architectures don't generate
343 ;; excessively large code, so hopefully it'll not get broken.
344 (let ((info (info :function :info '%other-pointer-subtype-p)))
345 (unless (and info (sb!c::fun-info-templates info))
346 (return-from widetags-from-union-type (values nil types))))
347 (let (widetags remainder)
348 (dolist (x types)
349 (let ((adjunct
350 (cond
351 ((and (array-type-p x)
352 (equal (array-type-dimensions x) '(*))
353 (type= (array-type-specialized-element-type x)
354 (array-type-element-type x)))
355 (if (eq (array-type-specialized-element-type x) *wild-type*)
356 ;; could be done, but probably no merit to implementing
357 ;; maybe/definitely-complex wild-type.
358 (unless (array-type-complexp x)
359 (map 'list #'sb!vm::saetp-typecode
360 sb!vm:*specialized-array-element-type-properties*))
361 (let ((saetp
362 (find
363 (array-type-element-type x)
364 sb!vm:*specialized-array-element-type-properties*
365 :key #'sb!vm:saetp-ctype :test #'type=)))
366 (cond ((not (array-type-complexp x))
367 (sb!vm:saetp-typecode saetp))
368 ((sb!vm:saetp-complex-typecode saetp)
369 (list* (sb!vm:saetp-complex-typecode saetp)
370 (when (eq (array-type-complexp x) :maybe)
371 (list (sb!vm:saetp-typecode saetp)))))))))
372 ((classoid-p x)
373 (case (classoid-name x)
374 (symbol sb!vm:symbol-header-widetag) ; plus a hack for nil
375 (system-area-pointer sb!vm:sap-widetag))))))
376 (cond ((not adjunct) (push x remainder))
377 ((listp adjunct) (setq widetags (nconc adjunct widetags)))
378 (t (push adjunct widetags)))))
379 (let ((remainder (nreverse remainder)))
380 (when (member sb!vm:symbol-header-widetag widetags)
381 ;; If symbol is the only widetag-testable type, it's better
382 ;; to just use symbolp. e.g. (OR SYMBOL CHARACTER) should not
383 ;; become (OR (%OTHER-POINTER-SUBTYPE-P ...)
384 (when (null (rest widetags))
385 (return-from widetags-from-union-type (values nil types)))
386 ;; Manipulate 'remainder' to include NULL since NIL's lowtag
387 ;; isn't other-pointer.
388 (let ((null-type (specifier-type 'null)))
389 (unless (member null-type remainder :test #'csubtypep)
390 (push null-type remainder))))
391 (values widetags remainder))))