Tolerate non-simple strings when checking arguments to CERROR.
[sbcl.git] / src / compiler / srctran.lisp
blob7ac54a2f0d36fb18df0fb08542a13c99875833fa
1 ;;;; This file contains macro-like source transformations which
2 ;;;; convert uses of certain functions into the canonical form desired
3 ;;;; within the compiler. FIXME: and other IR1 transforms and stuff.
5 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; more information.
7 ;;;;
8 ;;;; This software is derived from the CMU CL system, which was
9 ;;;; written at Carnegie Mellon University and released into the
10 ;;;; public domain. The software is in the public domain and is
11 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
12 ;;;; files for more information.
14 (in-package "SB!C")
16 ;;; We turn IDENTITY into PROG1 so that it is obvious that it just
17 ;;; returns the first value of its argument. Ditto for VALUES with one
18 ;;; arg.
19 (define-source-transform identity (x) `(prog1 ,x))
20 (define-source-transform values (x) `(prog1 ,x))
22 ;;; CONSTANTLY is pretty much never worth transforming, but it's good to get the type.
23 (defoptimizer (constantly derive-type) ((value))
24 (specifier-type
25 `(function (&rest t) (values ,(type-specifier (lvar-type value)) &optional))))
27 (defoptimizer (complement derive-type) ((fun))
28 (let ((type (lvar-fun-type fun)))
29 (when (fun-type-p type)
30 (specifier-type
31 (append (butlast (type-specifier type))
32 '(boolean))))))
34 ;;; If the function has a known number of arguments, then return a
35 ;;; lambda with the appropriate fixed number of args. If the
36 ;;; destination is a FUNCALL, then do the &REST APPLY thing, and let
37 ;;; MV optimization figure things out.
38 (deftransform complement ((fun) * * :node node)
39 "open code"
40 (multiple-value-bind (min max)
41 (fun-type-nargs (lvar-type fun))
42 (cond
43 ((and min (eql min max))
44 (let ((dums (make-gensym-list min)))
45 `#'(lambda ,dums (not (funcall fun ,@dums)))))
46 ((awhen (node-lvar node)
47 (let ((dest (lvar-dest it)))
48 (and (combination-p dest)
49 (eq (combination-fun dest) it))))
50 '#'(lambda (&rest args)
51 (not (apply fun args))))
53 (give-up-ir1-transform
54 "The function doesn't have a fixed argument count.")))))
56 ;;;; list hackery
58 ;;; Translate CxR into CAR/CDR combos.
59 (defun source-transform-cxr (form env)
60 (declare (ignore env))
61 (if (not (singleton-p (cdr form)))
62 (values nil t)
63 (let* ((name (car form))
64 (string (symbol-name
65 (etypecase name
66 (symbol name)
67 (leaf (leaf-source-name name))))))
68 (do ((i (- (length string) 2) (1- i))
69 (res (cadr form)
70 `(,(ecase (char string i)
71 (#\A 'car)
72 (#\D 'cdr))
73 ,res)))
74 ((zerop i) res)))))
76 ;;; Make source transforms to turn CxR forms into combinations of CAR
77 ;;; and CDR. ANSI specifies that everything up to 4 A/D operations is
78 ;;; defined.
79 ;;; Don't transform CAD*R, they are treated specially for &more args
80 ;;; optimizations
82 (loop for i of-type index from 2 upto 4 do
83 ;; Iterate over BUF = all names CxR where x = an I-element
84 ;; string of #\A or #\D characters.
85 (let ((buf (make-string (+ 2 i))))
86 (setf (aref buf 0) #\C
87 (aref buf (1+ i)) #\R)
88 (dotimes (j (ash 2 i))
89 (declare (type index j))
90 (dotimes (k i)
91 (declare (type index k))
92 (setf (aref buf (1+ k))
93 (if (logbitp k j) #\A #\D)))
94 (unless (member buf '("CADR" "CADDR" "CADDDR")
95 :test #'equal)
96 (setf (info :function :source-transform (intern buf))
97 #'source-transform-cxr)))))
99 ;;; Turn FIRST..FOURTH and REST into the obvious synonym, assuming
100 ;;; whatever is right for them is right for us. FIFTH..TENTH turn into
101 ;;; Nth, which can be expanded into a CAR/CDR later on if policy
102 ;;; favors it.
103 (define-source-transform rest (x) `(cdr ,x))
104 (define-source-transform first (x) `(car ,x))
105 (define-source-transform second (x) `(cadr ,x))
106 (define-source-transform third (x) `(caddr ,x))
107 (define-source-transform fourth (x) `(cadddr ,x))
108 (define-source-transform fifth (x) `(nth 4 ,x))
109 (define-source-transform sixth (x) `(nth 5 ,x))
110 (define-source-transform seventh (x) `(nth 6 ,x))
111 (define-source-transform eighth (x) `(nth 7 ,x))
112 (define-source-transform ninth (x) `(nth 8 ,x))
113 (define-source-transform tenth (x) `(nth 9 ,x))
115 ;;; LIST with one arg is an extremely common operation (at least inside
116 ;;; SBCL itself); translate it to CONS to take advantage of common
117 ;;; allocation routines.
118 (define-source-transform list (&rest args)
119 (case (length args)
120 (1 `(cons ,(first args) nil))
121 (t (values nil t))))
123 (defoptimizer (list derive-type) ((&rest args))
124 (if args
125 (specifier-type 'cons)
126 (specifier-type 'null)))
128 ;;; And similarly for LIST*.
129 (define-source-transform list* (arg &rest others)
130 (cond ((not others) arg)
131 ((not (cdr others)) `(cons ,arg ,(car others)))
132 (t (values nil t))))
134 (defoptimizer (list* derive-type) ((arg &rest args))
135 (if args
136 (specifier-type 'cons)
137 (lvar-type arg)))
139 (define-source-transform make-list (length &rest rest)
140 (if (or (null rest)
141 ;; Use of &KEY in source xforms doesn't have all the usual semantics.
142 ;; It's better to hand-roll it - cf. transforms for WRITE[-TO-STRING].
143 (typep rest '(cons (eql :initial-element) (cons t null))))
144 ;; Something fishy here- If THE is removed, OPERAND-RESTRICTION-OK
145 ;; returns NIL because type inference on MAKE-LIST never happens.
146 ;; But the fndb entry for %MAKE-LIST is right, so I'm slightly bewildered.
147 `(%make-list (the (integer 0 (,(1- sb!xc:array-dimension-limit))) ,length)
148 ,(second rest))
149 (values nil t))) ; give up
151 (deftransform %make-list ((length item) ((constant-arg (eql 0)) t)) nil)
153 (define-source-transform append (&rest lists)
154 (case (length lists)
155 (0 nil)
156 (1 (car lists))
157 (2 `(sb!impl::append2 ,@lists))
158 (t (values nil t))))
160 (define-source-transform nconc (&rest lists)
161 (case (length lists)
162 (0 ())
163 (1 (car lists))
164 (t (values nil t))))
166 ;;; (append nil nil nil fixnum) => fixnum
167 ;;; (append x x cons x x) => cons
168 ;;; (append x x x x list) => list
169 ;;; (append x x x x sequence) => sequence
170 ;;; (append fixnum x ...) => nil
171 (defun derive-append-type (args)
172 (when (null args)
173 (return-from derive-append-type (specifier-type 'null)))
174 (let* ((cons-type (specifier-type 'cons))
175 (null-type (specifier-type 'null))
176 (list-type (specifier-type 'list))
177 (last (lvar-type (car (last args)))))
178 ;; Derive the actual return type, assuming that all but the last
179 ;; arguments are LISTs (otherwise, APPEND/NCONC doesn't return).
180 (loop with all-nil = t ; all but the last args are NIL?
181 with some-cons = nil ; some args are conses?
182 for (arg next) on args
183 for lvar-type = (type-approx-intersection2 (lvar-type arg)
184 list-type)
185 while next
186 do (multiple-value-bind (typep definitely)
187 (ctypep nil lvar-type)
188 (cond ((type= lvar-type *empty-type*)
189 ;; type mismatch! insert an inline check that'll cause
190 ;; compile-time warnings.
191 (assert-lvar-type arg list-type
192 (lexenv-policy *lexenv*)))
193 (some-cons) ; we know result's a cons -- nothing to do
194 ((and (not typep) definitely) ; can't be NIL
195 (setf some-cons t)) ; must be a CONS
196 (all-nil
197 (setf all-nil (csubtypep lvar-type null-type)))))
198 finally
199 ;; if some of the previous arguments are CONSes so is the result;
200 ;; if all the previous values are NIL, we're a fancy identity;
201 ;; otherwise, could be either
202 (return (cond (some-cons cons-type)
203 (all-nil last)
204 (t (type-union last cons-type)))))))
206 (defoptimizer (append derive-type) ((&rest args))
207 (derive-append-type args))
209 (defoptimizer (sb!impl::append2 derive-type) ((&rest args))
210 (derive-append-type args))
212 (defoptimizer (nconc derive-type) ((&rest args))
213 (derive-append-type args))
215 ;;; Translate RPLACx to LET and SETF.
216 (define-source-transform rplaca (x y)
217 (once-only ((n-x x))
218 `(progn
219 (setf (car ,n-x) ,y)
220 ,n-x)))
221 (define-source-transform rplacd (x y)
222 (once-only ((n-x x))
223 `(progn
224 (setf (cdr ,n-x) ,y)
225 ,n-x)))
227 (deftransform last ((list &optional n) (t &optional t))
228 (let ((c (constant-lvar-p n)))
229 (cond ((or (not n)
230 (and c (eql 1 (lvar-value n))))
231 '(%last1 list))
232 ((and c (eql 0 (lvar-value n)))
233 '(%last0 list))
235 (let ((type (lvar-type n)))
236 (cond ((csubtypep type (specifier-type 'fixnum))
237 '(%lastn/fixnum list n))
238 ((csubtypep type (specifier-type 'bignum))
239 '(%lastn/bignum list n))
241 (give-up-ir1-transform "second argument type too vague"))))))))
243 (define-source-transform gethash (&rest args)
244 (case (length args)
245 (2 `(sb!impl::gethash3 ,@args nil))
246 (3 `(sb!impl::gethash3 ,@args))
247 (t (values nil t))))
248 (define-source-transform get (&rest args)
249 (case (length args)
250 (2 `(sb!impl::get3 ,@args nil))
251 (3 `(sb!impl::get3 ,@args))
252 (t (values nil t))))
254 (defvar *default-nthcdr-open-code-limit* 6)
255 (defvar *extreme-nthcdr-open-code-limit* 20)
257 (deftransform nthcdr ((n l) (unsigned-byte t) * :node node)
258 "convert NTHCDR to CAxxR"
259 (unless (constant-lvar-p n)
260 (give-up-ir1-transform))
261 (let ((n (lvar-value n)))
262 (when (> n
263 (if (policy node (and (= speed 3) (= space 0)))
264 *extreme-nthcdr-open-code-limit*
265 *default-nthcdr-open-code-limit*))
266 (give-up-ir1-transform))
268 (labels ((frob (n)
269 (if (zerop n)
271 `(cdr ,(frob (1- n))))))
272 (frob n))))
274 ;;;; arithmetic and numerology
276 (define-source-transform plusp (x) `(> ,x 0))
277 (define-source-transform minusp (x) `(< ,x 0))
278 (define-source-transform zerop (x) `(= ,x 0))
280 (define-source-transform 1+ (x) `(+ ,x 1))
281 (define-source-transform 1- (x) `(- ,x 1))
283 (define-source-transform oddp (x) `(logtest ,x 1))
284 (define-source-transform evenp (x) `(not (logtest ,x 1)))
286 ;;; Note that all the integer division functions are available for
287 ;;; inline expansion.
289 (macrolet ((deffrob (fun)
290 `(define-source-transform ,fun (x &optional (y nil y-p))
291 (declare (ignore y))
292 (if y-p
293 (values nil t)
294 `(,',fun ,x 1)))))
295 (deffrob truncate)
296 (deffrob round)
297 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
298 (deffrob floor)
299 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
300 (deffrob ceiling))
302 ;;; This used to be a source transform (hence the lack of restrictions
303 ;;; on the argument types), but we make it a regular transform so that
304 ;;; the VM has a chance to see the bare LOGTEST and potentiall choose
305 ;;; to implement it differently. --njf, 06-02-2006
307 ;;; Other transforms may be useful even with direct LOGTEST VOPs; let
308 ;;; them fire (including the type-directed constant folding below), but
309 ;;; disable the inlining rewrite in such cases. -- PK, 2013-05-20
310 (deftransform logtest ((x y) * * :node node)
311 (let ((type (two-arg-derive-type x y
312 #'logand-derive-type-aux
313 #'logand)))
314 (multiple-value-bind (typep definitely)
315 (ctypep 0 type)
316 (cond ((and (not typep) definitely)
318 ((type= type (specifier-type '(eql 0)))
319 nil)
320 ((neq :default (combination-implementation-style node))
321 (give-up-ir1-transform))
323 `(not (zerop (logand x y))))))))
325 (deftransform logbitp ((index integer))
326 (let ((integer-type (lvar-type integer))
327 (integer-value (and (constant-lvar-p integer)
328 (lvar-value integer))))
329 (cond ((eql integer-value 0)
330 nil)
331 ((eql integer-value -1)
333 ((csubtypep integer-type (specifier-type '(or word
334 sb!vm:signed-word)))
335 `(if (>= index #.sb!vm:n-word-bits)
336 (minusp integer)
337 (not (zerop (logand integer (ash 1 index))))))
338 ((csubtypep integer-type (specifier-type 'bignum))
339 (if (csubtypep (lvar-type index)
340 (specifier-type '(mod #.sb!vm:n-word-bits))) ; word-index
341 `(logbitp index (%bignum-ref integer 0))
342 `(bignum-logbitp index integer)))
344 (give-up-ir1-transform)))))
346 (define-source-transform byte (size position)
347 `(cons ,size ,position))
348 (define-source-transform byte-size (spec) `(car ,spec))
349 (define-source-transform byte-position (spec) `(cdr ,spec))
350 (define-source-transform ldb-test (bytespec integer)
351 `(not (zerop (mask-field ,bytespec ,integer))))
353 ;;; With the ratio and complex accessors, we pick off the "identity"
354 ;;; case, and use a primitive to handle the cell access case.
355 (define-source-transform numerator (num)
356 (once-only ((n-num `(the rational ,num)))
357 `(if (ratiop ,n-num)
358 (%numerator ,n-num)
359 ,n-num)))
360 (define-source-transform denominator (num)
361 (once-only ((n-num `(the rational ,num)))
362 `(if (ratiop ,n-num)
363 (%denominator ,n-num)
364 1)))
366 ;;;; interval arithmetic for computing bounds
367 ;;;;
368 ;;;; This is a set of routines for operating on intervals. It
369 ;;;; implements a simple interval arithmetic package. Although SBCL
370 ;;;; has an interval type in NUMERIC-TYPE, we choose to use our own
371 ;;;; for two reasons:
372 ;;;;
373 ;;;; 1. This package is simpler than NUMERIC-TYPE.
374 ;;;;
375 ;;;; 2. It makes debugging much easier because you can just strip
376 ;;;; out these routines and test them independently of SBCL. (This is a
377 ;;;; big win!)
378 ;;;;
379 ;;;; One disadvantage is a probable increase in consing because we
380 ;;;; have to create these new interval structures even though
381 ;;;; numeric-type has everything we want to know. Reason 2 wins for
382 ;;;; now.
384 ;;; Support operations that mimic real arithmetic comparison
385 ;;; operators, but imposing a total order on the floating points such
386 ;;; that negative zeros are strictly less than positive zeros.
387 (macrolet ((def (name op)
388 `(defun ,name (x y)
389 (declare (real x y))
390 (if (and (floatp x) (floatp y) (zerop x) (zerop y))
391 (,op (float-sign x) (float-sign y))
392 (,op x y)))))
393 (def signed-zero->= >=)
394 (def signed-zero-> >)
395 (def signed-zero-= =)
396 (def signed-zero-< <)
397 (def signed-zero-<= <=))
399 (defun make-interval (&key low high)
400 (labels ((normalize-bound (val)
401 (cond #-sb-xc-host
402 ((and (floatp val)
403 (float-infinity-p val))
404 ;; Handle infinities.
405 nil)
406 ((or (numberp val)
407 (eq val nil))
408 ;; Handle any closed bounds.
409 val)
410 ((listp val)
411 ;; We have an open bound. Normalize the numeric
412 ;; bound. If the normalized bound is still a number
413 ;; (not nil), keep the bound open. Otherwise, the
414 ;; bound is really unbounded, so drop the openness.
415 (let ((new-val (normalize-bound (first val))))
416 (when new-val
417 ;; The bound exists, so keep it open still.
418 (list new-val))))
420 (error "unknown bound type in MAKE-INTERVAL")))))
421 (%make-interval (normalize-bound low)
422 (normalize-bound high))))
424 ;;; Apply the function F to a bound X. If X is an open bound and the
425 ;;; function is declared strictly monotonic, then the result will be
426 ;;; open. IF X is NIL, the result is NIL.
427 (defun bound-func (f x strict)
428 (declare (type function f))
429 (and x
430 (handler-case
431 (with-float-traps-masked (:underflow :overflow :inexact :divide-by-zero)
432 ;; With these traps masked, we might get things like infinity
433 ;; or negative infinity returned. Check for this and return
434 ;; NIL to indicate unbounded.
435 (let ((y (funcall f (type-bound-number x))))
436 (if (and (floatp y)
437 (float-infinity-p y))
439 (set-bound y (and strict (consp x))))))
440 ;; Some numerical operations will signal SIMPLE-TYPE-ERROR, e.g.
441 ;; in the course of converting a bignum to a float. Default to
442 ;; NIL in that case.
443 (simple-type-error ()))))
445 (defun safe-double-coercion-p (x)
446 (or (typep x 'double-float)
447 (<= most-negative-double-float x most-positive-double-float)))
449 (defun safe-single-coercion-p (x)
450 (or (typep x 'single-float)
451 (and
452 ;; Fix for bug 420, and related issues: during type derivation we often
453 ;; end up deriving types for both
455 ;; (some-op <int> <single>)
456 ;; and
457 ;; (some-op (coerce <int> 'single-float) <single>)
459 ;; or other equivalent transformed forms. The problem with this
460 ;; is that on x86 (+ <int> <single>) is on the machine level
461 ;; equivalent of
463 ;; (coerce (+ (coerce <int> 'double-float)
464 ;; (coerce <single> 'double-float))
465 ;; 'single-float)
467 ;; so if the result of (coerce <int> 'single-float) is not exact, the
468 ;; derived types for the transformed forms will have an empty
469 ;; intersection -- which in turn means that the compiler will conclude
470 ;; that the call never returns, and all hell breaks lose when it *does*
471 ;; return at runtime. (This affects not just +, but other operators are
472 ;; well.)
474 ;; See also: SAFE-CTYPE-FOR-SINGLE-COERCION-P
476 ;; FIXME: If we ever add SSE-support for x86, this conditional needs to
477 ;; change.
478 #!+x86
479 (not (typep x `(or (integer * (,most-negative-exactly-single-float-fixnum))
480 (integer (,most-positive-exactly-single-float-fixnum) *))))
481 (<= most-negative-single-float x most-positive-single-float))))
483 ;;; Apply a binary operator OP to two bounds X and Y. The result is
484 ;;; NIL if either is NIL. Otherwise bound is computed and the result
485 ;;; is open if either X or Y is open.
487 ;;; FIXME: only used in this file, not needed in target runtime
489 ;;; ANSI contaigon specifies coercion to floating point if one of the
490 ;;; arguments is floating point. Here we should check to be sure that
491 ;;; the other argument is within the bounds of that floating point
492 ;;; type.
494 (defmacro safely-binop (op x y)
495 `(cond
496 ((typep ,x 'double-float)
497 (when (safe-double-coercion-p ,y)
498 (,op ,x ,y)))
499 ((typep ,y 'double-float)
500 (when (safe-double-coercion-p ,x)
501 (,op ,x ,y)))
502 ((typep ,x 'single-float)
503 (when (safe-single-coercion-p ,y)
504 (,op ,x ,y)))
505 ((typep ,y 'single-float)
506 (when (safe-single-coercion-p ,x)
507 (,op ,x ,y)))
508 (t (,op ,x ,y))))
510 (defmacro bound-binop (op x y)
511 (with-unique-names (xb yb res)
512 `(and ,x ,y
513 (with-float-traps-masked (:underflow :overflow :inexact :divide-by-zero)
514 (let* ((,xb (type-bound-number ,x))
515 (,yb (type-bound-number ,y))
516 (,res (safely-binop ,op ,xb ,yb)))
517 (set-bound ,res
518 (and (or (consp ,x) (consp ,y))
519 ;; Open bounds can very easily be messed up
520 ;; by FP rounding, so take care here.
521 ,(case op
523 ;; Multiplying a greater-than-zero with
524 ;; less than one can round to zero.
525 `(or (not (fp-zero-p ,res))
526 (cond ((and (consp ,x) (fp-zero-p ,xb))
527 (>= (abs ,yb) 1))
528 ((and (consp ,y) (fp-zero-p ,yb))
529 (>= (abs ,xb) 1)))))
531 ;; Dividing a greater-than-zero with
532 ;; greater than one can round to zero.
533 `(or (not (fp-zero-p ,res))
534 (cond ((and (consp ,x) (fp-zero-p ,xb))
535 (<= (abs ,yb) 1))
536 ((and (consp ,y) (fp-zero-p ,yb))
537 (<= (abs ,xb) 1)))))
538 ((+ -)
539 ;; Adding or subtracting greater-than-zero
540 ;; can end up with identity.
541 `(and (not (fp-zero-p ,xb))
542 (not (fp-zero-p ,yb))))))))))))
544 (defun coercion-loses-precision-p (val type)
545 (typecase val
546 (single-float)
547 (double-float (subtypep type 'single-float))
548 (rational (subtypep type 'float))
549 (t (bug "Unexpected arguments to bounds coercion: ~S ~S" val type))))
551 (defun coerce-for-bound (val type)
552 (cond
553 ((or (null val)
554 (null type))
555 val)
556 ((consp val)
557 (let ((xbound (coerce-for-bound (car val) type)))
558 (if (coercion-loses-precision-p (car val) type)
559 xbound
560 (list xbound))))
561 ((subtypep type 'double-float)
562 (if (<= most-negative-double-float val most-positive-double-float)
563 (coerce val type)))
564 ((or (subtypep type 'single-float) (subtypep type 'float))
565 ;; coerce to float returns a single-float
566 (if (<= most-negative-single-float val most-positive-single-float)
567 (coerce val type)))
568 (t (coerce val type))))
570 (defun coerce-and-truncate-floats (val type)
571 (when val
572 (if (consp val)
573 (let ((xbound (coerce-for-bound (car val) type)))
574 (if (coercion-loses-precision-p (car val) type)
575 xbound
576 (list xbound)))
577 (cond
578 ((subtypep type 'double-float)
579 (if (<= most-negative-double-float val most-positive-double-float)
580 (coerce val type)
581 (if (< val most-negative-double-float)
582 most-negative-double-float most-positive-double-float)))
583 ((or (subtypep type 'single-float) (subtypep type 'float))
584 ;; coerce to float returns a single-float
585 (if (<= most-negative-single-float val most-positive-single-float)
586 (coerce val type)
587 (if (< val most-negative-single-float)
588 most-negative-single-float most-positive-single-float)))
589 (t (coerce val type))))))
591 ;;; Convert a numeric-type object to an interval object.
592 (defun numeric-type->interval (x)
593 (declare (type numeric-type x))
594 (make-interval :low (numeric-type-low x)
595 :high (numeric-type-high x)))
597 (defun type-approximate-interval (type)
598 (declare (type ctype type))
599 (let ((types (prepare-arg-for-derive-type type))
600 (result nil))
601 (dolist (type types)
602 (let ((type (if (member-type-p type)
603 (convert-member-type type)
604 type)))
605 (unless (numeric-type-p type)
606 (return-from type-approximate-interval nil))
607 (let ((interval (numeric-type->interval type)))
608 (setq result
609 (if result
610 (interval-approximate-union result interval)
611 interval)))))
612 result))
614 (defun copy-interval-limit (limit)
615 (if (numberp limit)
616 limit
617 (copy-list limit)))
619 (defun copy-interval (x)
620 (declare (type interval x))
621 (make-interval :low (copy-interval-limit (interval-low x))
622 :high (copy-interval-limit (interval-high x))))
624 ;;; Given a point P contained in the interval X, split X into two
625 ;;; intervals at the point P. If CLOSE-LOWER is T, then the left
626 ;;; interval contains P. If CLOSE-UPPER is T, the right interval
627 ;;; contains P. You can specify both to be T or NIL.
628 (defun interval-split (p x &optional close-lower close-upper)
629 (declare (type number p)
630 (type interval x))
631 (list (make-interval :low (copy-interval-limit (interval-low x))
632 :high (if close-lower p (list p)))
633 (make-interval :low (if close-upper (list p) p)
634 :high (copy-interval-limit (interval-high x)))))
636 ;;; Return the closure of the interval. That is, convert open bounds
637 ;;; to closed bounds.
638 (defun interval-closure (x)
639 (declare (type interval x))
640 (make-interval :low (type-bound-number (interval-low x))
641 :high (type-bound-number (interval-high x))))
643 ;;; For an interval X, if X >= POINT, return '+. If X <= POINT, return
644 ;;; '-. Otherwise return NIL.
645 (defun interval-range-info (x &optional (point 0))
646 (declare (type interval x))
647 (let ((lo (interval-low x))
648 (hi (interval-high x)))
649 (cond ((and lo (signed-zero->= (type-bound-number lo) point))
651 ((and hi (signed-zero->= point (type-bound-number hi)))
654 nil))))
656 ;;; Test to see whether the interval X is bounded. HOW determines the
657 ;;; test, and should be either ABOVE, BELOW, or BOTH.
658 (defun interval-bounded-p (x how)
659 (declare (type interval x))
660 (ecase how
661 (above
662 (interval-high x))
663 (below
664 (interval-low x))
665 (both
666 (and (interval-low x) (interval-high x)))))
668 ;;; See whether the interval X contains the number P, taking into
669 ;;; account that the interval might not be closed.
670 (defun interval-contains-p (p x)
671 (declare (type number p)
672 (type interval x))
673 ;; Does the interval X contain the number P? This would be a lot
674 ;; easier if all intervals were closed!
675 (let ((lo (interval-low x))
676 (hi (interval-high x)))
677 (cond ((and lo hi)
678 ;; The interval is bounded
679 (if (and (signed-zero-<= (type-bound-number lo) p)
680 (signed-zero-<= p (type-bound-number hi)))
681 ;; P is definitely in the closure of the interval.
682 ;; We just need to check the end points now.
683 (cond ((signed-zero-= p (type-bound-number lo))
684 (numberp lo))
685 ((signed-zero-= p (type-bound-number hi))
686 (numberp hi))
687 (t t))
688 nil))
690 ;; Interval with upper bound
691 (if (signed-zero-< p (type-bound-number hi))
693 (and (numberp hi) (signed-zero-= p hi))))
695 ;; Interval with lower bound
696 (if (signed-zero-> p (type-bound-number lo))
698 (and (numberp lo) (signed-zero-= p lo))))
700 ;; Interval with no bounds
701 t))))
703 ;;; Determine whether two intervals X and Y intersect. Return T if so.
704 ;;; If CLOSED-INTERVALS-P is T, the treat the intervals as if they
705 ;;; were closed. Otherwise the intervals are treated as they are.
707 ;;; Thus if X = [0, 1) and Y = (1, 2), then they do not intersect
708 ;;; because no element in X is in Y. However, if CLOSED-INTERVALS-P
709 ;;; is T, then they do intersect because we use the closure of X = [0,
710 ;;; 1] and Y = [1, 2] to determine intersection.
711 (defun interval-intersect-p (x y &optional closed-intervals-p)
712 (declare (type interval x y))
713 (and (interval-intersection/difference (if closed-intervals-p
714 (interval-closure x)
716 (if closed-intervals-p
717 (interval-closure y)
721 ;;; Are the two intervals adjacent? That is, is there a number
722 ;;; between the two intervals that is not an element of either
723 ;;; interval? If so, they are not adjacent. For example [0, 1) and
724 ;;; [1, 2] are adjacent but [0, 1) and (1, 2] are not because 1 lies
725 ;;; between both intervals.
726 (defun interval-adjacent-p (x y)
727 (declare (type interval x y))
728 (flet ((adjacent (lo hi)
729 ;; Check to see whether lo and hi are adjacent. If either is
730 ;; nil, they can't be adjacent.
731 (when (and lo hi (= (type-bound-number lo) (type-bound-number hi)))
732 ;; The bounds are equal. They are adjacent if one of
733 ;; them is closed (a number). If both are open (consp),
734 ;; then there is a number that lies between them.
735 (or (numberp lo) (numberp hi)))))
736 (or (adjacent (interval-low y) (interval-high x))
737 (adjacent (interval-low x) (interval-high y)))))
739 ;;; Compute the intersection and difference between two intervals.
740 ;;; Two values are returned: the intersection and the difference.
742 ;;; Let the two intervals be X and Y, and let I and D be the two
743 ;;; values returned by this function. Then I = X intersect Y. If I
744 ;;; is NIL (the empty set), then D is X union Y, represented as the
745 ;;; list of X and Y. If I is not the empty set, then D is (X union Y)
746 ;;; - I, which is a list of two intervals.
748 ;;; For example, let X = [1,5] and Y = [-1,3). Then I = [1,3) and D =
749 ;;; [-1,1) union [3,5], which is returned as a list of two intervals.
750 (defun interval-intersection/difference (x y)
751 (declare (type interval x y))
752 (let ((x-lo (interval-low x))
753 (x-hi (interval-high x))
754 (y-lo (interval-low y))
755 (y-hi (interval-high y)))
756 (labels
757 ((opposite-bound (p)
758 ;; If p is an open bound, make it closed. If p is a closed
759 ;; bound, make it open.
760 (if (listp p)
761 (first p)
762 (list p)))
763 (test-number (p int bound)
764 ;; Test whether P is in the interval.
765 (let ((pn (type-bound-number p)))
766 (when (interval-contains-p pn (interval-closure int))
767 ;; Check for endpoints.
768 (let* ((lo (interval-low int))
769 (hi (interval-high int))
770 (lon (type-bound-number lo))
771 (hin (type-bound-number hi)))
772 (cond
773 ;; Interval may be a point.
774 ((and lon hin (= lon hin pn))
775 (and (numberp p) (numberp lo) (numberp hi)))
776 ;; Point matches the low end.
777 ;; [P] [P,?} => TRUE [P] (P,?} => FALSE
778 ;; (P [P,?} => TRUE P) [P,?} => FALSE
779 ;; (P (P,?} => TRUE P) (P,?} => FALSE
780 ((and lon (= pn lon))
781 (or (and (numberp p) (numberp lo))
782 (and (consp p) (eq :low bound))))
783 ;; [P] {?,P] => TRUE [P] {?,P) => FALSE
784 ;; P) {?,P] => TRUE (P {?,P] => FALSE
785 ;; P) {?,P) => TRUE (P {?,P) => FALSE
786 ((and hin (= pn hin))
787 (or (and (numberp p) (numberp hi))
788 (and (consp p) (eq :high bound))))
789 ;; Not an endpoint, all is well.
791 t))))))
792 (test-lower-bound (p int)
793 ;; P is a lower bound of an interval.
794 (if p
795 (test-number p int :low)
796 (not (interval-bounded-p int 'below))))
797 (test-upper-bound (p int)
798 ;; P is an upper bound of an interval.
799 (if p
800 (test-number p int :high)
801 (not (interval-bounded-p int 'above)))))
802 (let ((x-lo-in-y (test-lower-bound x-lo y))
803 (x-hi-in-y (test-upper-bound x-hi y))
804 (y-lo-in-x (test-lower-bound y-lo x))
805 (y-hi-in-x (test-upper-bound y-hi x)))
806 (cond ((or x-lo-in-y x-hi-in-y y-lo-in-x y-hi-in-x)
807 ;; Intervals intersect. Let's compute the intersection
808 ;; and the difference.
809 (multiple-value-bind (lo left-lo left-hi)
810 (cond (x-lo-in-y (values x-lo y-lo (opposite-bound x-lo)))
811 (y-lo-in-x (values y-lo x-lo (opposite-bound y-lo))))
812 (multiple-value-bind (hi right-lo right-hi)
813 (cond (x-hi-in-y
814 (values x-hi (opposite-bound x-hi) y-hi))
815 (y-hi-in-x
816 (values y-hi (opposite-bound y-hi) x-hi)))
817 (values (make-interval :low lo :high hi)
818 (list (make-interval :low left-lo
819 :high left-hi)
820 (make-interval :low right-lo
821 :high right-hi))))))
823 (values nil (list x y))))))))
825 ;;; If intervals X and Y intersect, return a new interval that is the
826 ;;; union of the two. If they do not intersect, return NIL.
827 (defun interval-merge-pair (x y)
828 (declare (type interval x y))
829 ;; If x and y intersect or are adjacent, create the union.
830 ;; Otherwise return nil
831 (when (or (interval-intersect-p x y)
832 (interval-adjacent-p x y))
833 (flet ((select-bound (x1 x2 min-op max-op)
834 (let ((x1-val (type-bound-number x1))
835 (x2-val (type-bound-number x2)))
836 (cond ((and x1 x2)
837 ;; Both bounds are finite. Select the right one.
838 (cond ((funcall min-op x1-val x2-val)
839 ;; x1 is definitely better.
841 ((funcall max-op x1-val x2-val)
842 ;; x2 is definitely better.
845 ;; Bounds are equal. Select either
846 ;; value and make it open only if
847 ;; both were open.
848 (set-bound x1-val (and (consp x1) (consp x2))))))
850 ;; At least one bound is not finite. The
851 ;; non-finite bound always wins.
852 nil)))))
853 (let* ((x-lo (copy-interval-limit (interval-low x)))
854 (x-hi (copy-interval-limit (interval-high x)))
855 (y-lo (copy-interval-limit (interval-low y)))
856 (y-hi (copy-interval-limit (interval-high y))))
857 (make-interval :low (select-bound x-lo y-lo #'< #'>)
858 :high (select-bound x-hi y-hi #'> #'<))))))
860 ;;; return the minimal interval, containing X and Y
861 (defun interval-approximate-union (x y)
862 (cond ((interval-merge-pair x y))
863 ((interval-< x y)
864 (make-interval :low (copy-interval-limit (interval-low x))
865 :high (copy-interval-limit (interval-high y))))
867 (make-interval :low (copy-interval-limit (interval-low y))
868 :high (copy-interval-limit (interval-high x))))))
870 ;;; basic arithmetic operations on intervals. We probably should do
871 ;;; true interval arithmetic here, but it's complicated because we
872 ;;; have float and integer types and bounds can be open or closed.
874 ;;; the negative of an interval
875 (defun interval-neg (x)
876 (declare (type interval x))
877 (make-interval :low (bound-func #'- (interval-high x) t)
878 :high (bound-func #'- (interval-low x) t)))
880 ;;; Add two intervals.
881 (defun interval-add (x y)
882 (declare (type interval x y))
883 (make-interval :low (bound-binop + (interval-low x) (interval-low y))
884 :high (bound-binop + (interval-high x) (interval-high y))))
886 ;;; Subtract two intervals.
887 (defun interval-sub (x y)
888 (declare (type interval x y))
889 (make-interval :low (bound-binop - (interval-low x) (interval-high y))
890 :high (bound-binop - (interval-high x) (interval-low y))))
892 ;;; Multiply two intervals.
893 (defun interval-mul (x y)
894 (declare (type interval x y))
895 (flet ((bound-mul (x y)
896 (cond ((or (null x) (null y))
897 ;; Multiply by infinity is infinity
898 nil)
899 ((or (and (numberp x) (zerop x))
900 (and (numberp y) (zerop y)))
901 ;; Multiply by closed zero is special. The result
902 ;; is always a closed bound. But don't replace this
903 ;; with zero; we want the multiplication to produce
904 ;; the correct signed zero, if needed. Use SIGNUM
905 ;; to avoid trying to multiply huge bignums with 0.0.
906 (* (signum (type-bound-number x)) (signum (type-bound-number y))))
907 ((or (and (floatp x) (float-infinity-p x))
908 (and (floatp y) (float-infinity-p y)))
909 ;; Infinity times anything is infinity
910 nil)
912 ;; General multiply. The result is open if either is open.
913 (bound-binop * x y)))))
914 (let ((x-range (interval-range-info x))
915 (y-range (interval-range-info y)))
916 (cond ((null x-range)
917 ;; Split x into two and multiply each separately
918 (destructuring-bind (x- x+) (interval-split 0 x t t)
919 (interval-merge-pair (interval-mul x- y)
920 (interval-mul x+ y))))
921 ((null y-range)
922 ;; Split y into two and multiply each separately
923 (destructuring-bind (y- y+) (interval-split 0 y t t)
924 (interval-merge-pair (interval-mul x y-)
925 (interval-mul x y+))))
926 ((eq x-range '-)
927 (interval-neg (interval-mul (interval-neg x) y)))
928 ((eq y-range '-)
929 (interval-neg (interval-mul x (interval-neg y))))
930 ((and (eq x-range '+) (eq y-range '+))
931 ;; If we are here, X and Y are both positive.
932 (make-interval
933 :low (bound-mul (interval-low x) (interval-low y))
934 :high (bound-mul (interval-high x) (interval-high y))))
936 (bug "excluded case in INTERVAL-MUL"))))))
938 ;;; Divide two intervals.
939 (defun interval-div (top bot)
940 (declare (type interval top bot))
941 (flet ((bound-div (x y y-low-p)
942 ;; Compute x/y
943 (cond ((null y)
944 ;; Divide by infinity means result is 0. However,
945 ;; we need to watch out for the sign of the result,
946 ;; to correctly handle signed zeros. We also need
947 ;; to watch out for positive or negative infinity.
948 (if (floatp (type-bound-number x))
949 (if y-low-p
950 (- (float-sign (type-bound-number x) 0.0))
951 (float-sign (type-bound-number x) 0.0))
953 ((zerop (type-bound-number y))
954 ;; Divide by zero means result is infinity
955 nil)
956 ((and (numberp x) (zerop x))
957 ;; Zero divided by anything is zero, but don't lose the sign
958 (/ x (signum (type-bound-number y))))
960 (bound-binop / x y)))))
961 (let ((top-range (interval-range-info top))
962 (bot-range (interval-range-info bot)))
963 (cond ((null bot-range)
964 ;; The denominator contains zero, so anything goes!
965 (make-interval))
966 ((eq bot-range '-)
967 ;; Denominator is negative so flip the sign, compute the
968 ;; result, and flip it back.
969 (interval-neg (interval-div top (interval-neg bot))))
970 ((null top-range)
971 ;; Split top into two positive and negative parts, and
972 ;; divide each separately
973 (destructuring-bind (top- top+) (interval-split 0 top t t)
974 (or (interval-merge-pair (interval-div top- bot)
975 (interval-div top+ bot))
976 (make-interval))))
977 ((eq top-range '-)
978 ;; Top is negative so flip the sign, divide, and flip the
979 ;; sign of the result.
980 (interval-neg (interval-div (interval-neg top) bot)))
981 ((and (eq top-range '+) (eq bot-range '+))
982 ;; the easy case
983 (make-interval
984 :low (bound-div (interval-low top) (interval-high bot) t)
985 :high (bound-div (interval-high top) (interval-low bot) nil)))
987 (bug "excluded case in INTERVAL-DIV"))))))
989 ;;; Apply the function F to the interval X. If X = [a, b], then the
990 ;;; result is [f(a), f(b)]. It is up to the user to make sure the
991 ;;; result makes sense. It will if F is monotonic increasing (or, if
992 ;;; the interval is closed, non-decreasing).
994 ;;; (Actually most uses of INTERVAL-FUNC are coercions to float types,
995 ;;; which are not monotonic increasing, so default to calling
996 ;;; BOUND-FUNC with a non-strict argument).
997 (defun interval-func (f x &optional increasing)
998 (declare (type function f)
999 (type interval x))
1000 (let ((lo (bound-func f (interval-low x) increasing))
1001 (hi (bound-func f (interval-high x) increasing)))
1002 (make-interval :low lo :high hi)))
1004 ;;; Return T if X < Y. That is every number in the interval X is
1005 ;;; always less than any number in the interval Y.
1006 (defun interval-< (x y)
1007 (declare (type interval x y))
1008 ;; X < Y only if X is bounded above, Y is bounded below, and they
1009 ;; don't overlap.
1010 (when (and (interval-bounded-p x 'above)
1011 (interval-bounded-p y 'below))
1012 ;; Intervals are bounded in the appropriate way. Make sure they
1013 ;; don't overlap.
1014 (let ((left (interval-high x))
1015 (right (interval-low y)))
1016 (cond ((> (type-bound-number left)
1017 (type-bound-number right))
1018 ;; The intervals definitely overlap, so result is NIL.
1019 nil)
1020 ((< (type-bound-number left)
1021 (type-bound-number right))
1022 ;; The intervals definitely don't touch, so result is T.
1025 ;; Limits are equal. Check for open or closed bounds.
1026 ;; Don't overlap if one or the other are open.
1027 (or (consp left) (consp right)))))))
1029 ;;; Return T if X >= Y. That is, every number in the interval X is
1030 ;;; always greater than any number in the interval Y.
1031 (defun interval->= (x y)
1032 (declare (type interval x y))
1033 ;; X >= Y if lower bound of X >= upper bound of Y
1034 (when (and (interval-bounded-p x 'below)
1035 (interval-bounded-p y 'above))
1036 (>= (type-bound-number (interval-low x))
1037 (type-bound-number (interval-high y)))))
1039 ;;; Return T if X = Y.
1040 (defun interval-= (x y)
1041 (declare (type interval x y))
1042 (and (interval-bounded-p x 'both)
1043 (interval-bounded-p y 'both)
1044 (flet ((bound (v)
1045 (if (numberp v)
1047 ;; Open intervals cannot be =
1048 (return-from interval-= nil))))
1049 ;; Both intervals refer to the same point
1050 (= (bound (interval-high x)) (bound (interval-low x))
1051 (bound (interval-high y)) (bound (interval-low y))))))
1053 ;;; Return T if X /= Y
1054 (defun interval-/= (x y)
1055 (not (interval-intersect-p x y)))
1057 ;;; Return an interval that is the absolute value of X. Thus, if
1058 ;;; X = [-1 10], the result is [0, 10].
1059 (defun interval-abs (x)
1060 (declare (type interval x))
1061 (case (interval-range-info x)
1063 (copy-interval x))
1065 (interval-neg x))
1067 (destructuring-bind (x- x+) (interval-split 0 x t t)
1068 (interval-merge-pair (interval-neg x-) x+)))))
1070 ;;; Compute the square of an interval.
1071 (defun interval-sqr (x)
1072 (declare (type interval x))
1073 (interval-func (lambda (x) (* x x)) (interval-abs x)))
1075 ;;;; numeric DERIVE-TYPE methods
1077 ;;; a utility for defining derive-type methods of integer operations. If
1078 ;;; the types of both X and Y are integer types, then we compute a new
1079 ;;; integer type with bounds determined by FUN when applied to X and Y.
1080 ;;; Otherwise, we use NUMERIC-CONTAGION.
1081 (defun derive-integer-type-aux (x y fun)
1082 (declare (type function fun))
1083 (if (and (numeric-type-p x) (numeric-type-p y)
1084 (eq (numeric-type-class x) 'integer)
1085 (eq (numeric-type-class y) 'integer)
1086 (eq (numeric-type-complexp x) :real)
1087 (eq (numeric-type-complexp y) :real))
1088 (multiple-value-bind (low high) (funcall fun x y)
1089 (make-numeric-type :class 'integer
1090 :complexp :real
1091 :low low
1092 :high high))
1093 (numeric-contagion x y)))
1095 (defun derive-integer-type (x y fun)
1096 (declare (type lvar x y) (type function fun))
1097 (let ((x (lvar-type x))
1098 (y (lvar-type y)))
1099 (derive-integer-type-aux x y fun)))
1101 ;;; simple utility to flatten a list
1102 (defun flatten-list (x)
1103 (labels ((flatten-and-append (tree list)
1104 (cond ((null tree) list)
1105 ((atom tree) (cons tree list))
1106 (t (flatten-and-append
1107 (car tree) (flatten-and-append (cdr tree) list))))))
1108 (flatten-and-append x nil)))
1110 ;;; Take some type of lvar and massage it so that we get a list of the
1111 ;;; constituent types. If ARG is *EMPTY-TYPE*, return NIL to indicate
1112 ;;; failure.
1113 (defun prepare-arg-for-derive-type (arg)
1114 (flet ((listify (arg)
1115 (typecase arg
1116 (numeric-type
1117 (list arg))
1118 (union-type
1119 (union-type-types arg))
1121 (list arg)))))
1122 (unless (eq arg *empty-type*)
1123 ;; Make sure all args are some type of numeric-type. For member
1124 ;; types, convert the list of members into a union of equivalent
1125 ;; single-element member-type's.
1126 (let ((new-args nil))
1127 (dolist (arg (listify arg))
1128 (if (member-type-p arg)
1129 ;; Run down the list of members and convert to a list of
1130 ;; member types.
1131 (mapc-member-type-members
1132 (lambda (member)
1133 (push (if (numberp member) (make-eql-type member) *empty-type*)
1134 new-args))
1135 arg)
1136 (push arg new-args)))
1137 (unless (member *empty-type* new-args)
1138 new-args)))))
1140 ;;; Take a list of types and return a canonical type specifier,
1141 ;;; combining any MEMBER types together. If both positive and negative
1142 ;;; MEMBER types are present they are converted to a float type.
1143 ;;; XXX This would be far simpler if the type-union methods could handle
1144 ;;; member/number unions.
1146 ;;; If we're about to generate an overly complex union of numeric types, start
1147 ;;; collapse the ranges together.
1149 ;;; FIXME: The MEMBER canonicalization parts of MAKE-DERIVED-UNION-TYPE and
1150 ;;; entire CONVERT-MEMBER-TYPE probably belong in the kernel's type logic,
1151 ;;; invoked always, instead of in the compiler, invoked only during some type
1152 ;;; optimizations.
1153 (defvar *derived-numeric-union-complexity-limit* 6)
1155 (defun make-derived-union-type (type-list)
1156 (let ((xset (alloc-xset))
1157 (fp-zeroes '())
1158 (misc-types '())
1159 (numeric-type *empty-type*))
1160 (dolist (type type-list)
1161 (cond ((member-type-p type)
1162 (mapc-member-type-members
1163 (lambda (member)
1164 (if (fp-zero-p member)
1165 (unless (member member fp-zeroes)
1166 (pushnew member fp-zeroes))
1167 (add-to-xset member xset)))
1168 type))
1169 ((numeric-type-p type)
1170 (let ((*approximate-numeric-unions*
1171 (when (and (union-type-p numeric-type)
1172 (nthcdr *derived-numeric-union-complexity-limit*
1173 (union-type-types numeric-type)))
1174 t)))
1175 (setf numeric-type (type-union type numeric-type))))
1177 (push type misc-types))))
1178 (if (and (xset-empty-p xset) (not fp-zeroes))
1179 (apply #'type-union numeric-type misc-types)
1180 (apply #'type-union (make-member-type xset fp-zeroes)
1181 numeric-type misc-types))))
1183 ;;; Convert a member type with a single member to a numeric type.
1184 (defun convert-member-type (arg)
1185 (let* ((members (member-type-members arg))
1186 (member (first members))
1187 (member-type (type-of member)))
1188 (aver (not (rest members)))
1189 (specifier-type (cond ((typep member 'integer)
1190 `(integer ,member ,member))
1191 ((memq member-type '(short-float single-float
1192 double-float long-float))
1193 `(,member-type ,member ,member))
1195 member-type)))))
1197 ;;; This is used in defoptimizers for computing the resulting type of
1198 ;;; a function.
1200 ;;; Given the lvar ARG, derive the resulting type using the
1201 ;;; DERIVE-FUN. DERIVE-FUN takes exactly one argument which is some
1202 ;;; "atomic" lvar type like numeric-type or member-type (containing
1203 ;;; just one element). It should return the resulting type, which can
1204 ;;; be a list of types.
1206 ;;; For the case of member types, if a MEMBER-FUN is given it is
1207 ;;; called to compute the result otherwise the member type is first
1208 ;;; converted to a numeric type and the DERIVE-FUN is called.
1209 (defun one-arg-derive-type (arg derive-fun member-fun)
1210 (declare (type function derive-fun)
1211 (type (or null function) member-fun))
1212 (let ((arg-list (prepare-arg-for-derive-type (lvar-type arg))))
1213 (when arg-list
1214 (flet ((deriver (x)
1215 (typecase x
1216 (member-type
1217 (if member-fun
1218 (with-float-traps-masked
1219 (:underflow :overflow :divide-by-zero)
1220 (specifier-type
1221 `(eql ,(funcall member-fun
1222 (first (member-type-members x))))))
1223 ;; Otherwise convert to a numeric type.
1224 (funcall derive-fun (convert-member-type x))))
1225 (numeric-type
1226 (funcall derive-fun x))
1228 *universal-type*))))
1229 ;; Run down the list of args and derive the type of each one,
1230 ;; saving all of the results in a list.
1231 (let ((results nil))
1232 (dolist (arg arg-list)
1233 (let ((result (deriver arg)))
1234 (if (listp result)
1235 (setf results (append results result))
1236 (push result results))))
1237 (if (rest results)
1238 (make-derived-union-type results)
1239 (first results)))))))
1241 ;;; Same as ONE-ARG-DERIVE-TYPE, except we assume the function takes
1242 ;;; two arguments. DERIVE-FUN takes 3 args in this case: the two
1243 ;;; original args and a third which is T to indicate if the two args
1244 ;;; really represent the same lvar. This is useful for deriving the
1245 ;;; type of things like (* x x), which should always be positive. If
1246 ;;; we didn't do this, we wouldn't be able to tell.
1247 (defun two-arg-derive-type (arg1 arg2 derive-fun fun)
1248 (declare (type function derive-fun fun))
1249 (flet ((deriver (x y same-arg)
1250 (cond ((and (member-type-p x) (member-type-p y))
1251 (let* ((x (first (member-type-members x)))
1252 (y (first (member-type-members y)))
1253 (result (ignore-errors
1254 (with-float-traps-masked
1255 (:underflow :overflow :divide-by-zero
1256 :invalid)
1257 (funcall fun x y)))))
1258 (cond ((null result) *empty-type*)
1259 ((and (floatp result) (float-nan-p result))
1260 (make-numeric-type :class 'float
1261 :format (type-of result)
1262 :complexp :real))
1264 (specifier-type `(eql ,result))))))
1265 ((and (member-type-p x) (numeric-type-p y))
1266 (funcall derive-fun (convert-member-type x) y same-arg))
1267 ((and (numeric-type-p x) (member-type-p y))
1268 (funcall derive-fun x (convert-member-type y) same-arg))
1269 ((and (numeric-type-p x) (numeric-type-p y))
1270 (funcall derive-fun x y same-arg))
1272 *universal-type*))))
1273 (let ((same-arg (same-leaf-ref-p arg1 arg2))
1274 (a1 (prepare-arg-for-derive-type (lvar-type arg1)))
1275 (a2 (prepare-arg-for-derive-type (lvar-type arg2))))
1276 (when (and a1 a2)
1277 (let ((results nil))
1278 (if same-arg
1279 ;; Since the args are the same LVARs, just run down the
1280 ;; lists.
1281 (dolist (x a1)
1282 (let ((result (deriver x x same-arg)))
1283 (if (listp result)
1284 (setf results (append results result))
1285 (push result results))))
1286 ;; Try all pairwise combinations.
1287 (dolist (x a1)
1288 (dolist (y a2)
1289 (let ((result (or (deriver x y same-arg)
1290 (numeric-contagion x y))))
1291 (if (listp result)
1292 (setf results (append results result))
1293 (push result results))))))
1294 (if (rest results)
1295 (make-derived-union-type results)
1296 (first results)))))))
1298 #+sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1299 (progn
1300 (defoptimizer (+ derive-type) ((x y))
1301 (derive-integer-type
1303 #'(lambda (x y)
1304 (flet ((frob (x y)
1305 (if (and x y)
1306 (+ x y)
1307 nil)))
1308 (values (frob (numeric-type-low x) (numeric-type-low y))
1309 (frob (numeric-type-high x) (numeric-type-high y)))))))
1311 (defoptimizer (- derive-type) ((x y))
1312 (derive-integer-type
1314 #'(lambda (x y)
1315 (flet ((frob (x y)
1316 (if (and x y)
1317 (- x y)
1318 nil)))
1319 (values (frob (numeric-type-low x) (numeric-type-high y))
1320 (frob (numeric-type-high x) (numeric-type-low y)))))))
1322 (defoptimizer (* derive-type) ((x y))
1323 (derive-integer-type
1325 #'(lambda (x y)
1326 (let ((x-low (numeric-type-low x))
1327 (x-high (numeric-type-high x))
1328 (y-low (numeric-type-low y))
1329 (y-high (numeric-type-high y)))
1330 (cond ((not (and x-low y-low))
1331 (values nil nil))
1332 ((or (minusp x-low) (minusp y-low))
1333 (if (and x-high y-high)
1334 (let ((max (* (max (abs x-low) (abs x-high))
1335 (max (abs y-low) (abs y-high)))))
1336 (values (- max) max))
1337 (values nil nil)))
1339 (values (* x-low y-low)
1340 (if (and x-high y-high)
1341 (* x-high y-high)
1342 nil))))))))
1344 (defoptimizer (/ derive-type) ((x y))
1345 (numeric-contagion (lvar-type x) (lvar-type y)))
1347 ) ; PROGN
1349 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1350 (progn
1351 (defun +-derive-type-aux (x y same-arg)
1352 (if (and (numeric-type-real-p x)
1353 (numeric-type-real-p y))
1354 (let ((result
1355 (if same-arg
1356 (let ((x-int (numeric-type->interval x)))
1357 (interval-add x-int x-int))
1358 (interval-add (numeric-type->interval x)
1359 (numeric-type->interval y))))
1360 (result-type (numeric-contagion x y)))
1361 ;; If the result type is a float, we need to be sure to coerce
1362 ;; the bounds into the correct type.
1363 (when (eq (numeric-type-class result-type) 'float)
1364 (setf result (interval-func
1365 #'(lambda (x)
1366 (coerce-for-bound x (or (numeric-type-format result-type)
1367 'float)))
1368 result)))
1369 (make-numeric-type
1370 :class (if (and (eq (numeric-type-class x) 'integer)
1371 (eq (numeric-type-class y) 'integer))
1372 ;; The sum of integers is always an integer.
1373 'integer
1374 (numeric-type-class result-type))
1375 :format (numeric-type-format result-type)
1376 :low (interval-low result)
1377 :high (interval-high result)))
1378 ;; general contagion
1379 (numeric-contagion x y)))
1381 (defoptimizer (+ derive-type) ((x y))
1382 (two-arg-derive-type x y #'+-derive-type-aux #'+))
1384 (defun --derive-type-aux (x y same-arg)
1385 (if (and (numeric-type-real-p x)
1386 (numeric-type-real-p y))
1387 (let ((result
1388 ;; (- X X) is always 0.
1389 (if same-arg
1390 (make-interval :low 0 :high 0)
1391 (interval-sub (numeric-type->interval x)
1392 (numeric-type->interval y))))
1393 (result-type (numeric-contagion x y)))
1394 ;; If the result type is a float, we need to be sure to coerce
1395 ;; the bounds into the correct type.
1396 (when (eq (numeric-type-class result-type) 'float)
1397 (setf result (interval-func
1398 #'(lambda (x)
1399 (coerce-for-bound x (or (numeric-type-format result-type)
1400 'float)))
1401 result)))
1402 (make-numeric-type
1403 :class (if (and (eq (numeric-type-class x) 'integer)
1404 (eq (numeric-type-class y) 'integer))
1405 ;; The difference of integers is always an integer.
1406 'integer
1407 (numeric-type-class result-type))
1408 :format (numeric-type-format result-type)
1409 :low (interval-low result)
1410 :high (interval-high result)))
1411 ;; general contagion
1412 (numeric-contagion x y)))
1414 (defoptimizer (- derive-type) ((x y))
1415 (two-arg-derive-type x y #'--derive-type-aux #'-))
1417 (defun *-derive-type-aux (x y same-arg)
1418 (if (and (numeric-type-real-p x)
1419 (numeric-type-real-p y))
1420 (let ((result
1421 ;; (* X X) is always positive, so take care to do it right.
1422 (if same-arg
1423 (interval-sqr (numeric-type->interval x))
1424 (interval-mul (numeric-type->interval x)
1425 (numeric-type->interval y))))
1426 (result-type (numeric-contagion x y)))
1427 ;; If the result type is a float, we need to be sure to coerce
1428 ;; the bounds into the correct type.
1429 (when (eq (numeric-type-class result-type) 'float)
1430 (setf result (interval-func
1431 #'(lambda (x)
1432 (coerce-for-bound x (or (numeric-type-format result-type)
1433 'float)))
1434 result)))
1435 (make-numeric-type
1436 :class (if (and (eq (numeric-type-class x) 'integer)
1437 (eq (numeric-type-class y) 'integer))
1438 ;; The product of integers is always an integer.
1439 'integer
1440 (numeric-type-class result-type))
1441 :format (numeric-type-format result-type)
1442 :low (interval-low result)
1443 :high (interval-high result)))
1444 (numeric-contagion x y)))
1446 (defoptimizer (* derive-type) ((x y))
1447 (two-arg-derive-type x y #'*-derive-type-aux #'*))
1449 (defun /-derive-type-aux (x y same-arg)
1450 (if (and (numeric-type-real-p x)
1451 (numeric-type-real-p y))
1452 (let ((result
1453 ;; (/ X X) is always 1, except if X can contain 0. In
1454 ;; that case, we shouldn't optimize the division away
1455 ;; because we want 0/0 to signal an error.
1456 (if (and same-arg
1457 (not (interval-contains-p
1458 0 (interval-closure (numeric-type->interval y)))))
1459 (make-interval :low 1 :high 1)
1460 (interval-div (numeric-type->interval x)
1461 (numeric-type->interval y))))
1462 (result-type (numeric-contagion x y)))
1463 ;; If the result type is a float, we need to be sure to coerce
1464 ;; the bounds into the correct type.
1465 (when (eq (numeric-type-class result-type) 'float)
1466 (setf result (interval-func
1467 #'(lambda (x)
1468 (coerce-for-bound x (or (numeric-type-format result-type)
1469 'float)))
1470 result)))
1471 (make-numeric-type :class (numeric-type-class result-type)
1472 :format (numeric-type-format result-type)
1473 :low (interval-low result)
1474 :high (interval-high result)))
1475 (numeric-contagion x y)))
1477 (defoptimizer (/ derive-type) ((x y))
1478 (two-arg-derive-type x y #'/-derive-type-aux #'/))
1480 ) ; PROGN
1482 (defun ash-derive-type-aux (n-type shift same-arg)
1483 (declare (ignore same-arg))
1484 ;; KLUDGE: All this ASH optimization is suppressed under CMU CL for
1485 ;; some bignum cases because as of version 2.4.6 for Debian and 18d,
1486 ;; CMU CL blows up on (ASH 1000000000 -100000000000) (i.e. ASH of
1487 ;; two bignums yielding zero) and it's hard to avoid that
1488 ;; calculation in here.
1489 #+(and cmu sb-xc-host)
1490 (when (and (or (typep (numeric-type-low n-type) 'bignum)
1491 (typep (numeric-type-high n-type) 'bignum))
1492 (or (typep (numeric-type-low shift) 'bignum)
1493 (typep (numeric-type-high shift) 'bignum)))
1494 (return-from ash-derive-type-aux *universal-type*))
1495 (flet ((ash-outer (n s)
1496 (when (and (fixnump s)
1497 (<= s 64)
1498 (> s sb!xc:most-negative-fixnum))
1499 (ash n s)))
1500 ;; KLUDGE: The bare 64's here should be related to
1501 ;; symbolic machine word size values somehow.
1503 (ash-inner (n s)
1504 (if (and (fixnump s)
1505 (> s sb!xc:most-negative-fixnum))
1506 (ash n (min s 64))
1507 (if (minusp n) -1 0))))
1508 (or (and (csubtypep n-type (specifier-type 'integer))
1509 (csubtypep shift (specifier-type 'integer))
1510 (let ((n-low (numeric-type-low n-type))
1511 (n-high (numeric-type-high n-type))
1512 (s-low (numeric-type-low shift))
1513 (s-high (numeric-type-high shift)))
1514 (make-numeric-type :class 'integer :complexp :real
1515 :low (when n-low
1516 (if (minusp n-low)
1517 (ash-outer n-low s-high)
1518 (ash-inner n-low s-low)))
1519 :high (when n-high
1520 (if (minusp n-high)
1521 (ash-inner n-high s-low)
1522 (ash-outer n-high s-high))))))
1523 *universal-type*)))
1525 (defoptimizer (ash derive-type) ((n shift))
1526 (two-arg-derive-type n shift #'ash-derive-type-aux #'ash))
1528 #+sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1529 (macrolet ((frob (fun)
1530 `#'(lambda (type type2)
1531 (declare (ignore type2))
1532 (let ((lo (numeric-type-low type))
1533 (hi (numeric-type-high type)))
1534 (values (if hi (,fun hi) nil) (if lo (,fun lo) nil))))))
1536 (defoptimizer (%negate derive-type) ((num))
1537 (derive-integer-type num num (frob -))))
1539 (defun lognot-derive-type-aux (int)
1540 (derive-integer-type-aux int int
1541 (lambda (type type2)
1542 (declare (ignore type2))
1543 (let ((lo (numeric-type-low type))
1544 (hi (numeric-type-high type)))
1545 (values (if hi (lognot hi) nil)
1546 (if lo (lognot lo) nil)
1547 (numeric-type-class type)
1548 (numeric-type-format type))))))
1550 (defoptimizer (lognot derive-type) ((int))
1551 (lognot-derive-type-aux (lvar-type int)))
1553 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1554 (defoptimizer (%negate derive-type) ((num))
1555 (flet ((negate-bound (b)
1556 (and b
1557 (set-bound (- (type-bound-number b))
1558 (consp b)))))
1559 (one-arg-derive-type num
1560 (lambda (type)
1561 (modified-numeric-type
1562 type
1563 :low (negate-bound (numeric-type-high type))
1564 :high (negate-bound (numeric-type-low type))))
1565 #'-)))
1567 #+sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1568 (defoptimizer (abs derive-type) ((num))
1569 (let ((type (lvar-type num)))
1570 (if (and (numeric-type-p type)
1571 (eq (numeric-type-class type) 'integer)
1572 (eq (numeric-type-complexp type) :real))
1573 (let ((lo (numeric-type-low type))
1574 (hi (numeric-type-high type)))
1575 (make-numeric-type :class 'integer :complexp :real
1576 :low (cond ((and hi (minusp hi))
1577 (abs hi))
1579 (max 0 lo))
1582 :high (if (and hi lo)
1583 (max (abs hi) (abs lo))
1584 nil)))
1585 (numeric-contagion type type))))
1587 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1588 (defun abs-derive-type-aux (type)
1589 (cond ((eq (numeric-type-complexp type) :complex)
1590 ;; The absolute value of a complex number is always a
1591 ;; non-negative float.
1592 (let* ((format (case (numeric-type-class type)
1593 ((integer rational) 'single-float)
1594 (t (numeric-type-format type))))
1595 (bound-format (or format 'float)))
1596 (make-numeric-type :class 'float
1597 :format format
1598 :complexp :real
1599 :low (coerce 0 bound-format)
1600 :high nil)))
1602 ;; The absolute value of a real number is a non-negative real
1603 ;; of the same type.
1604 (let* ((abs-bnd (interval-abs (numeric-type->interval type)))
1605 (class (numeric-type-class type))
1606 (format (numeric-type-format type))
1607 (bound-type (or format class 'real)))
1608 (make-numeric-type
1609 :class class
1610 :format format
1611 :complexp :real
1612 :low (coerce-and-truncate-floats (interval-low abs-bnd) bound-type)
1613 :high (coerce-and-truncate-floats
1614 (interval-high abs-bnd) bound-type))))))
1616 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1617 (defoptimizer (abs derive-type) ((num))
1618 (one-arg-derive-type num #'abs-derive-type-aux #'abs))
1620 #+sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1621 (defoptimizer (truncate derive-type) ((number divisor))
1622 (let ((number-type (lvar-type number))
1623 (divisor-type (lvar-type divisor))
1624 (integer-type (specifier-type 'integer)))
1625 (if (and (numeric-type-p number-type)
1626 (csubtypep number-type integer-type)
1627 (numeric-type-p divisor-type)
1628 (csubtypep divisor-type integer-type))
1629 (let ((number-low (numeric-type-low number-type))
1630 (number-high (numeric-type-high number-type))
1631 (divisor-low (numeric-type-low divisor-type))
1632 (divisor-high (numeric-type-high divisor-type)))
1633 (values-specifier-type
1634 `(values ,(integer-truncate-derive-type number-low number-high
1635 divisor-low divisor-high)
1636 ,(integer-rem-derive-type number-low number-high
1637 divisor-low divisor-high))))
1638 *universal-type*)))
1640 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
1641 (progn
1643 (defun rem-result-type (number-type divisor-type)
1644 ;; Figure out what the remainder type is. The remainder is an
1645 ;; integer if both args are integers; a rational if both args are
1646 ;; rational; and a float otherwise.
1647 (cond ((and (csubtypep number-type (specifier-type 'integer))
1648 (csubtypep divisor-type (specifier-type 'integer)))
1649 'integer)
1650 ((and (csubtypep number-type (specifier-type 'rational))
1651 (csubtypep divisor-type (specifier-type 'rational)))
1652 'rational)
1653 ((and (csubtypep number-type (specifier-type 'float))
1654 (csubtypep divisor-type (specifier-type 'float)))
1655 ;; Both are floats so the result is also a float, of
1656 ;; the largest type.
1657 (or (float-format-max (numeric-type-format number-type)
1658 (numeric-type-format divisor-type))
1659 'float))
1660 ((and (csubtypep number-type (specifier-type 'float))
1661 (csubtypep divisor-type (specifier-type 'rational)))
1662 ;; One of the arguments is a float and the other is a
1663 ;; rational. The remainder is a float of the same
1664 ;; type.
1665 (or (numeric-type-format number-type) 'float))
1666 ((and (csubtypep divisor-type (specifier-type 'float))
1667 (csubtypep number-type (specifier-type 'rational)))
1668 ;; One of the arguments is a float and the other is a
1669 ;; rational. The remainder is a float of the same
1670 ;; type.
1671 (or (numeric-type-format divisor-type) 'float))
1673 ;; Some unhandled combination. This usually means both args
1674 ;; are REAL so the result is a REAL.
1675 'real)))
1677 (defun truncate-derive-type-quot (number-type divisor-type)
1678 (let* ((rem-type (rem-result-type number-type divisor-type))
1679 (number-interval (numeric-type->interval number-type))
1680 (divisor-interval (numeric-type->interval divisor-type)))
1681 ;;(declare (type (member '(integer rational float)) rem-type))
1682 ;; We have real numbers now.
1683 (cond ((eq rem-type 'integer)
1684 ;; Since the remainder type is INTEGER, both args are
1685 ;; INTEGERs.
1686 (let* ((res (integer-truncate-derive-type
1687 (interval-low number-interval)
1688 (interval-high number-interval)
1689 (interval-low divisor-interval)
1690 (interval-high divisor-interval))))
1691 (specifier-type (if (listp res) res 'integer))))
1693 (let ((quot (truncate-quotient-bound
1694 (interval-div number-interval
1695 divisor-interval))))
1696 (specifier-type `(integer ,(or (interval-low quot) '*)
1697 ,(or (interval-high quot) '*))))))))
1699 (defun truncate-derive-type-rem (number-type divisor-type)
1700 (let* ((rem-type (rem-result-type number-type divisor-type))
1701 (number-interval (numeric-type->interval number-type))
1702 (divisor-interval (numeric-type->interval divisor-type))
1703 (rem (truncate-rem-bound number-interval divisor-interval)))
1704 ;;(declare (type (member '(integer rational float)) rem-type))
1705 ;; We have real numbers now.
1706 (cond ((eq rem-type 'integer)
1707 ;; Since the remainder type is INTEGER, both args are
1708 ;; INTEGERs.
1709 (specifier-type `(,rem-type ,(or (interval-low rem) '*)
1710 ,(or (interval-high rem) '*))))
1712 (multiple-value-bind (class format)
1713 (ecase rem-type
1714 (integer
1715 (values 'integer nil))
1716 (rational
1717 (values 'rational nil))
1718 ((or single-float double-float #!+long-float long-float)
1719 (values 'float rem-type))
1720 (float
1721 (values 'float nil))
1722 (real
1723 (values nil nil)))
1724 (when (member rem-type '(float single-float double-float
1725 #!+long-float long-float))
1726 (setf rem (interval-func #'(lambda (x)
1727 (coerce-for-bound x rem-type))
1728 rem)))
1729 (make-numeric-type :class class
1730 :format format
1731 :low (interval-low rem)
1732 :high (interval-high rem)))))))
1734 (defun truncate-derive-type-quot-aux (num div same-arg)
1735 (declare (ignore same-arg))
1736 (if (and (numeric-type-real-p num)
1737 (numeric-type-real-p div))
1738 (truncate-derive-type-quot num div)
1739 *empty-type*))
1741 (defun truncate-derive-type-rem-aux (num div same-arg)
1742 (declare (ignore same-arg))
1743 (cond ((not (and (numeric-type-real-p num)
1744 (numeric-type-real-p div)))
1745 *empty-type*)
1746 ;; Floats introduce rounding errors
1747 ((and (memq (numeric-type-class num) '(integer rational))
1748 (memq (numeric-type-class div) '(integer rational)))
1749 (truncate-derive-type-rem num div))
1751 (numeric-contagion num div))))
1753 (defoptimizer (truncate derive-type) ((number divisor))
1754 (let ((quot (two-arg-derive-type number divisor
1755 #'truncate-derive-type-quot-aux #'truncate))
1756 (rem (two-arg-derive-type number divisor
1757 #'truncate-derive-type-rem-aux #'rem)))
1758 (when (and quot rem)
1759 (make-values-type :required (list quot rem)))))
1761 (defun ftruncate-derive-type-quot (number-type divisor-type)
1762 ;; The bounds are the same as for truncate. However, the first
1763 ;; result is a float of some type. We need to determine what that
1764 ;; type is. Basically it's the more contagious of the two types.
1765 (let ((q-type (truncate-derive-type-quot number-type divisor-type))
1766 (format (numeric-type-format
1767 (numeric-contagion number-type divisor-type))))
1768 (make-numeric-type :class 'float
1769 :format format
1770 :low (coerce-for-bound (numeric-type-low q-type) format)
1771 :high (coerce-for-bound (numeric-type-high q-type) format))))
1773 (defun ftruncate-derive-type-quot-aux (n d same-arg)
1774 (declare (ignore same-arg))
1775 (if (and (numeric-type-real-p n)
1776 (numeric-type-real-p d))
1777 (ftruncate-derive-type-quot n d)
1778 *empty-type*))
1780 (defoptimizer (ftruncate derive-type) ((number divisor))
1781 (let ((quot
1782 (two-arg-derive-type number divisor
1783 #'ftruncate-derive-type-quot-aux #'ftruncate))
1784 (rem (two-arg-derive-type number divisor
1785 #'truncate-derive-type-rem-aux #'rem)))
1786 (when (and quot rem)
1787 (make-values-type :required (list quot rem)))))
1789 (defun %unary-truncate-derive-type-aux (number)
1790 (truncate-derive-type-quot number (specifier-type '(integer 1 1))))
1792 (defoptimizer (%unary-truncate derive-type) ((number))
1793 (one-arg-derive-type number
1794 #'%unary-truncate-derive-type-aux
1795 #'%unary-truncate))
1797 (defoptimizer (%unary-truncate/single-float derive-type) ((number))
1798 (one-arg-derive-type number
1799 #'%unary-truncate-derive-type-aux
1800 #'%unary-truncate))
1802 (defoptimizer (%unary-truncate/double-float derive-type) ((number))
1803 (one-arg-derive-type number
1804 #'%unary-truncate-derive-type-aux
1805 #'%unary-truncate))
1807 (defoptimizer (%unary-ftruncate derive-type) ((number))
1808 (let ((divisor (specifier-type '(integer 1 1))))
1809 (one-arg-derive-type number
1810 #'(lambda (n)
1811 (ftruncate-derive-type-quot-aux n divisor nil))
1812 #'%unary-ftruncate)))
1814 (defoptimizer (%unary-round derive-type) ((number))
1815 (one-arg-derive-type number
1816 (lambda (n)
1817 (block nil
1818 (unless (numeric-type-real-p n)
1819 (return *empty-type*))
1820 (let* ((interval (numeric-type->interval n))
1821 (low (interval-low interval))
1822 (high (interval-high interval)))
1823 (when (consp low)
1824 (setf low (car low)))
1825 (when (consp high)
1826 (setf high (car high)))
1827 (specifier-type
1828 `(integer ,(if low
1829 (round low)
1831 ,(if high
1832 (round high)
1833 '*))))))
1834 #'%unary-round))
1836 ;;; Define optimizers for FLOOR and CEILING.
1837 (macrolet
1838 ((def (name q-name r-name)
1839 (let ((q-aux (symbolicate q-name "-AUX"))
1840 (r-aux (symbolicate r-name "-AUX")))
1841 `(progn
1842 ;; Compute type of quotient (first) result.
1843 (defun ,q-aux (number-type divisor-type)
1844 (let* ((number-interval
1845 (numeric-type->interval number-type))
1846 (divisor-interval
1847 (numeric-type->interval divisor-type))
1848 (quot (,q-name (interval-div number-interval
1849 divisor-interval))))
1850 (specifier-type `(integer ,(or (interval-low quot) '*)
1851 ,(or (interval-high quot) '*)))))
1852 ;; Compute type of remainder.
1853 (defun ,r-aux (number-type divisor-type)
1854 (let* ((divisor-interval
1855 (numeric-type->interval divisor-type))
1856 (rem (,r-name divisor-interval))
1857 (result-type (rem-result-type number-type divisor-type)))
1858 (multiple-value-bind (class format)
1859 (ecase result-type
1860 (integer
1861 (values 'integer nil))
1862 (rational
1863 (values 'rational nil))
1864 ((or single-float double-float #!+long-float long-float)
1865 (values 'float result-type))
1866 (float
1867 (values 'float nil))
1868 (real
1869 (values nil nil)))
1870 (when (member result-type '(float single-float double-float
1871 #!+long-float long-float))
1872 ;; Make sure that the limits on the interval have
1873 ;; the right type.
1874 (setf rem (interval-func (lambda (x)
1875 (coerce-for-bound x result-type))
1876 rem)))
1877 (make-numeric-type :class class
1878 :format format
1879 :low (interval-low rem)
1880 :high (interval-high rem)))))
1881 ;; the optimizer itself
1882 (defoptimizer (,name derive-type) ((number divisor))
1883 (flet ((derive-q (n d same-arg)
1884 (declare (ignore same-arg))
1885 (if (and (numeric-type-real-p n)
1886 (numeric-type-real-p d))
1887 (,q-aux n d)
1888 *empty-type*))
1889 (derive-r (num div same-arg)
1890 (declare (ignore same-arg))
1891 (cond ((not (and (numeric-type-real-p num)
1892 (numeric-type-real-p div)))
1893 *empty-type*)
1894 ;; Floats introduce rounding errors
1895 ((and (memq (numeric-type-class num) '(integer rational))
1896 (memq (numeric-type-class div) '(integer rational)))
1897 (,r-aux num div))
1899 (numeric-contagion num div)))))
1900 (let ((quot (two-arg-derive-type
1901 number divisor #'derive-q #',name))
1902 (rem (two-arg-derive-type
1903 number divisor #'derive-r #'mod)))
1904 (when (and quot rem)
1905 (make-values-type :required (list quot rem))))))))))
1907 (def floor floor-quotient-bound floor-rem-bound)
1908 (def ceiling ceiling-quotient-bound ceiling-rem-bound))
1910 ;;; Define optimizers for FFLOOR and FCEILING
1911 (macrolet ((def (name q-name r-name)
1912 (let ((q-aux (symbolicate "F" q-name "-AUX"))
1913 (r-aux (symbolicate r-name "-AUX")))
1914 `(progn
1915 ;; Compute type of quotient (first) result.
1916 (defun ,q-aux (number-type divisor-type)
1917 (let* ((number-interval
1918 (numeric-type->interval number-type))
1919 (divisor-interval
1920 (numeric-type->interval divisor-type))
1921 (quot (,q-name (interval-div number-interval
1922 divisor-interval)))
1923 (res-type (numeric-contagion number-type
1924 divisor-type))
1925 (format (numeric-type-format res-type)))
1926 (make-numeric-type
1927 :class (numeric-type-class res-type)
1928 :format format
1929 :low (coerce-for-bound (interval-low quot) format)
1930 :high (coerce-for-bound (interval-high quot) format))))
1932 (defoptimizer (,name derive-type) ((number divisor))
1933 (flet ((derive-q (n d same-arg)
1934 (declare (ignore same-arg))
1935 (if (and (numeric-type-real-p n)
1936 (numeric-type-real-p d))
1937 (,q-aux n d)
1938 *empty-type*))
1939 (derive-r (num div same-arg)
1940 (declare (ignore same-arg))
1941 (cond ((not (and (numeric-type-real-p num)
1942 (numeric-type-real-p div)))
1943 *empty-type*)
1944 ;; Floats introduce rounding errors
1945 ((and (memq (numeric-type-class num) '(integer rational))
1946 (memq (numeric-type-class div) '(integer rational)))
1947 (,r-aux num div))
1949 (numeric-contagion num div)))))
1950 (let ((quot (two-arg-derive-type
1951 number divisor #'derive-q #',name))
1952 (rem (two-arg-derive-type
1953 number divisor #'derive-r #'mod)))
1954 (when (and quot rem)
1955 (make-values-type :required (list quot rem))))))))))
1957 (def ffloor floor-quotient-bound floor-rem-bound)
1958 (def fceiling ceiling-quotient-bound ceiling-rem-bound))
1960 ;;; functions to compute the bounds on the quotient and remainder for
1961 ;;; the FLOOR function
1962 (defun floor-quotient-bound (quot)
1963 ;; Take the floor of the quotient and then massage it into what we
1964 ;; need.
1965 (let ((lo (interval-low quot))
1966 (hi (interval-high quot)))
1967 ;; Take the floor of the lower bound. The result is always a
1968 ;; closed lower bound.
1969 (when lo
1970 (setf lo (- (floor (type-bound-number lo))
1971 ;; FLOOR on floats depends on the divisor,
1972 ;; make it conservative
1973 (if (floatp (type-bound-number lo))
1975 0))))
1976 ;; For the upper bound, we need to be careful.
1977 (setf hi
1978 (cond ((consp hi)
1979 ;; An open bound. We need to be careful here because
1980 ;; the floor of '(10.0) is 9, but the floor of
1981 ;; 10.0 is 10.
1982 (multiple-value-bind (q r) (floor (first hi))
1983 (if (zerop r)
1984 (1- q)
1985 q)))
1987 ;; A closed bound, so the answer is obvious.
1988 (floor hi))
1990 hi)))
1991 (make-interval :low lo :high hi)))
1992 (defun floor-rem-bound (div)
1993 ;; The remainder depends only on the divisor. Try to get the
1994 ;; correct sign for the remainder if we can.
1995 (case (interval-range-info div)
1997 ;; The divisor is always positive.
1998 (let ((rem (interval-abs div)))
1999 (setf (interval-low rem) 0)
2000 (when (and (numberp (interval-high rem))
2001 (not (zerop (interval-high rem))))
2002 ;; The remainder never contains the upper bound. However,
2003 ;; watch out for the case where the high limit is zero!
2004 (setf (interval-high rem) (list (interval-high rem))))
2005 rem))
2007 ;; The divisor is always negative.
2008 (let ((rem (interval-neg (interval-abs div))))
2009 (setf (interval-high rem) 0)
2010 (when (numberp (interval-low rem))
2011 ;; The remainder never contains the lower bound.
2012 (setf (interval-low rem) (list (interval-low rem))))
2013 rem))
2014 (otherwise
2015 ;; The divisor can be positive or negative. All bets off. The
2016 ;; magnitude of remainder is the maximum value of the divisor.
2017 (let ((limit (type-bound-number (interval-high (interval-abs div)))))
2018 ;; The bound never reaches the limit, so make the interval open.
2019 (make-interval :low (if limit
2020 (list (- limit))
2021 limit)
2022 :high (list limit))))))
2023 #| Test cases
2024 (floor-quotient-bound (make-interval :low 0.3 :high 10.3))
2025 => #S(INTERVAL :LOW 0 :HIGH 10)
2026 (floor-quotient-bound (make-interval :low 0.3 :high '(10.3)))
2027 => #S(INTERVAL :LOW 0 :HIGH 10)
2028 (floor-quotient-bound (make-interval :low 0.3 :high 10))
2029 => #S(INTERVAL :LOW 0 :HIGH 10)
2030 (floor-quotient-bound (make-interval :low 0.3 :high '(10)))
2031 => #S(INTERVAL :LOW 0 :HIGH 9)
2032 (floor-quotient-bound (make-interval :low '(0.3) :high 10.3))
2033 => #S(INTERVAL :LOW 0 :HIGH 10)
2034 (floor-quotient-bound (make-interval :low '(0.0) :high 10.3))
2035 => #S(INTERVAL :LOW 0 :HIGH 10)
2036 (floor-quotient-bound (make-interval :low '(-1.3) :high 10.3))
2037 => #S(INTERVAL :LOW -2 :HIGH 10)
2038 (floor-quotient-bound (make-interval :low '(-1.0) :high 10.3))
2039 => #S(INTERVAL :LOW -1 :HIGH 10)
2040 (floor-quotient-bound (make-interval :low -1.0 :high 10.3))
2041 => #S(INTERVAL :LOW -1 :HIGH 10)
2043 (floor-rem-bound (make-interval :low 0.3 :high 10.3))
2044 => #S(INTERVAL :LOW 0 :HIGH '(10.3))
2045 (floor-rem-bound (make-interval :low 0.3 :high '(10.3)))
2046 => #S(INTERVAL :LOW 0 :HIGH '(10.3))
2047 (floor-rem-bound (make-interval :low -10 :high -2.3))
2048 #S(INTERVAL :LOW (-10) :HIGH 0)
2049 (floor-rem-bound (make-interval :low 0.3 :high 10))
2050 => #S(INTERVAL :LOW 0 :HIGH '(10))
2051 (floor-rem-bound (make-interval :low '(-1.3) :high 10.3))
2052 => #S(INTERVAL :LOW '(-10.3) :HIGH '(10.3))
2053 (floor-rem-bound (make-interval :low '(-20.3) :high 10.3))
2054 => #S(INTERVAL :LOW (-20.3) :HIGH (20.3))
2057 ;;; same functions for CEILING
2058 (defun ceiling-quotient-bound (quot)
2059 ;; Take the ceiling of the quotient and then massage it into what we
2060 ;; need.
2061 (let ((lo (interval-low quot))
2062 (hi (interval-high quot)))
2063 ;; Take the ceiling of the upper bound. The result is always a
2064 ;; closed upper bound.
2065 (when hi
2066 (setf hi (+ (floor (type-bound-number hi))
2067 ;; CEILING on floats depends on the divisor,
2068 ;; make it conservative
2069 (if (ceiling (type-bound-number hi))
2071 0))))
2072 ;; For the lower bound, we need to be careful.
2073 (setf lo
2074 (cond ((consp lo)
2075 ;; An open bound. We need to be careful here because
2076 ;; the ceiling of '(10.0) is 11, but the ceiling of
2077 ;; 10.0 is 10.
2078 (multiple-value-bind (q r) (ceiling (first lo))
2079 (if (zerop r)
2080 (1+ q)
2081 q)))
2083 ;; A closed bound, so the answer is obvious.
2084 (ceiling lo))
2086 lo)))
2087 (make-interval :low lo :high hi)))
2088 (defun ceiling-rem-bound (div)
2089 ;; The remainder depends only on the divisor. Try to get the
2090 ;; correct sign for the remainder if we can.
2091 (case (interval-range-info div)
2093 ;; Divisor is always positive. The remainder is negative.
2094 (let ((rem (interval-neg (interval-abs div))))
2095 (setf (interval-high rem) 0)
2096 (when (and (numberp (interval-low rem))
2097 (not (zerop (interval-low rem))))
2098 ;; The remainder never contains the upper bound. However,
2099 ;; watch out for the case when the upper bound is zero!
2100 (setf (interval-low rem) (list (interval-low rem))))
2101 rem))
2103 ;; Divisor is always negative. The remainder is positive
2104 (let ((rem (interval-abs div)))
2105 (setf (interval-low rem) 0)
2106 (when (numberp (interval-high rem))
2107 ;; The remainder never contains the lower bound.
2108 (setf (interval-high rem) (list (interval-high rem))))
2109 rem))
2110 (otherwise
2111 ;; The divisor can be positive or negative. All bets off. The
2112 ;; magnitude of remainder is the maximum value of the divisor.
2113 (let ((limit (type-bound-number (interval-high (interval-abs div)))))
2114 ;; The bound never reaches the limit, so make the interval open.
2115 (make-interval :low (if limit
2116 (list (- limit))
2117 limit)
2118 :high (list limit))))))
2120 #| Test cases
2121 (ceiling-quotient-bound (make-interval :low 0.3 :high 10.3))
2122 => #S(INTERVAL :LOW 1 :HIGH 11)
2123 (ceiling-quotient-bound (make-interval :low 0.3 :high '(10.3)))
2124 => #S(INTERVAL :LOW 1 :HIGH 11)
2125 (ceiling-quotient-bound (make-interval :low 0.3 :high 10))
2126 => #S(INTERVAL :LOW 1 :HIGH 10)
2127 (ceiling-quotient-bound (make-interval :low 0.3 :high '(10)))
2128 => #S(INTERVAL :LOW 1 :HIGH 10)
2129 (ceiling-quotient-bound (make-interval :low '(0.3) :high 10.3))
2130 => #S(INTERVAL :LOW 1 :HIGH 11)
2131 (ceiling-quotient-bound (make-interval :low '(0.0) :high 10.3))
2132 => #S(INTERVAL :LOW 1 :HIGH 11)
2133 (ceiling-quotient-bound (make-interval :low '(-1.3) :high 10.3))
2134 => #S(INTERVAL :LOW -1 :HIGH 11)
2135 (ceiling-quotient-bound (make-interval :low '(-1.0) :high 10.3))
2136 => #S(INTERVAL :LOW 0 :HIGH 11)
2137 (ceiling-quotient-bound (make-interval :low -1.0 :high 10.3))
2138 => #S(INTERVAL :LOW -1 :HIGH 11)
2140 (ceiling-rem-bound (make-interval :low 0.3 :high 10.3))
2141 => #S(INTERVAL :LOW (-10.3) :HIGH 0)
2142 (ceiling-rem-bound (make-interval :low 0.3 :high '(10.3)))
2143 => #S(INTERVAL :LOW 0 :HIGH '(10.3))
2144 (ceiling-rem-bound (make-interval :low -10 :high -2.3))
2145 => #S(INTERVAL :LOW 0 :HIGH (10))
2146 (ceiling-rem-bound (make-interval :low 0.3 :high 10))
2147 => #S(INTERVAL :LOW (-10) :HIGH 0)
2148 (ceiling-rem-bound (make-interval :low '(-1.3) :high 10.3))
2149 => #S(INTERVAL :LOW (-10.3) :HIGH (10.3))
2150 (ceiling-rem-bound (make-interval :low '(-20.3) :high 10.3))
2151 => #S(INTERVAL :LOW (-20.3) :HIGH (20.3))
2154 (defun truncate-quotient-bound (quot)
2155 ;; For positive quotients, truncate is exactly like floor. For
2156 ;; negative quotients, truncate is exactly like ceiling. Otherwise,
2157 ;; it's the union of the two pieces.
2158 (case (interval-range-info quot)
2160 ;; just like FLOOR
2161 (floor-quotient-bound quot))
2163 ;; just like CEILING
2164 (ceiling-quotient-bound quot))
2165 (otherwise
2166 ;; Split the interval into positive and negative pieces, compute
2167 ;; the result for each piece and put them back together.
2168 (destructuring-bind (neg pos) (interval-split 0 quot t t)
2169 (interval-merge-pair (ceiling-quotient-bound neg)
2170 (floor-quotient-bound pos))))))
2172 (defun truncate-rem-bound (num div)
2173 ;; This is significantly more complicated than FLOOR or CEILING. We
2174 ;; need both the number and the divisor to determine the range. The
2175 ;; basic idea is to split the ranges of NUM and DEN into positive
2176 ;; and negative pieces and deal with each of the four possibilities
2177 ;; in turn.
2178 (case (interval-range-info num)
2180 (case (interval-range-info div)
2182 (floor-rem-bound div))
2184 (ceiling-rem-bound div))
2185 (otherwise
2186 (destructuring-bind (neg pos) (interval-split 0 div t t)
2187 (interval-merge-pair (truncate-rem-bound num neg)
2188 (truncate-rem-bound num pos))))))
2190 (case (interval-range-info div)
2192 (ceiling-rem-bound div))
2194 (floor-rem-bound div))
2195 (otherwise
2196 (destructuring-bind (neg pos) (interval-split 0 div t t)
2197 (interval-merge-pair (truncate-rem-bound num neg)
2198 (truncate-rem-bound num pos))))))
2199 (otherwise
2200 (destructuring-bind (neg pos) (interval-split 0 num t t)
2201 (interval-merge-pair (truncate-rem-bound neg div)
2202 (truncate-rem-bound pos div))))))
2203 ) ; PROGN
2205 ;;; Derive useful information about the range. Returns three values:
2206 ;;; - '+ if its positive, '- negative, or nil if it overlaps 0.
2207 ;;; - The abs of the minimal value (i.e. closest to 0) in the range.
2208 ;;; - The abs of the maximal value if there is one, or nil if it is
2209 ;;; unbounded.
2210 (defun numeric-range-info (low high)
2211 (cond ((and low (not (minusp low)))
2212 (values '+ low high))
2213 ((and high (not (plusp high)))
2214 (values '- (- high) (if low (- low) nil)))
2216 (values nil 0 (and low high (max (- low) high))))))
2218 (defun integer-truncate-derive-type
2219 (number-low number-high divisor-low divisor-high)
2220 ;; The result cannot be larger in magnitude than the number, but the
2221 ;; sign might change. If we can determine the sign of either the
2222 ;; number or the divisor, we can eliminate some of the cases.
2223 (multiple-value-bind (number-sign number-min number-max)
2224 (numeric-range-info number-low number-high)
2225 (multiple-value-bind (divisor-sign divisor-min divisor-max)
2226 (numeric-range-info divisor-low divisor-high)
2227 (when (and divisor-max (zerop divisor-max))
2228 ;; We've got a problem: guaranteed division by zero.
2229 (return-from integer-truncate-derive-type t))
2230 (when (zerop divisor-min)
2231 ;; We'll assume that they aren't going to divide by zero.
2232 (incf divisor-min))
2233 (cond ((and number-sign divisor-sign)
2234 ;; We know the sign of both.
2235 (if (eq number-sign divisor-sign)
2236 ;; Same sign, so the result will be positive.
2237 `(integer ,(if divisor-max
2238 (truncate number-min divisor-max)
2240 ,(if number-max
2241 (truncate number-max divisor-min)
2242 '*))
2243 ;; Different signs, the result will be negative.
2244 `(integer ,(if number-max
2245 (- (truncate number-max divisor-min))
2247 ,(if divisor-max
2248 (- (truncate number-min divisor-max))
2249 0))))
2250 ((eq divisor-sign '+)
2251 ;; The divisor is positive. Therefore, the number will just
2252 ;; become closer to zero.
2253 `(integer ,(if number-low
2254 (truncate number-low divisor-min)
2256 ,(if number-high
2257 (truncate number-high divisor-min)
2258 '*)))
2259 ((eq divisor-sign '-)
2260 ;; The divisor is negative. Therefore, the absolute value of
2261 ;; the number will become closer to zero, but the sign will also
2262 ;; change.
2263 `(integer ,(if number-high
2264 (- (truncate number-high divisor-min))
2266 ,(if number-low
2267 (- (truncate number-low divisor-min))
2268 '*)))
2269 ;; The divisor could be either positive or negative.
2270 (number-max
2271 ;; The number we are dividing has a bound. Divide that by the
2272 ;; smallest posible divisor.
2273 (let ((bound (truncate number-max divisor-min)))
2274 `(integer ,(- bound) ,bound)))
2276 ;; The number we are dividing is unbounded, so we can't tell
2277 ;; anything about the result.
2278 `integer)))))
2280 #+sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
2281 (defun integer-rem-derive-type
2282 (number-low number-high divisor-low divisor-high)
2283 (if (and divisor-low divisor-high)
2284 ;; We know the range of the divisor, and the remainder must be
2285 ;; smaller than the divisor. We can tell the sign of the
2286 ;; remainder if we know the sign of the number.
2287 (let ((divisor-max (1- (max (abs divisor-low) (abs divisor-high)))))
2288 `(integer ,(if (or (null number-low)
2289 (minusp number-low))
2290 (- divisor-max)
2292 ,(if (or (null number-high)
2293 (plusp number-high))
2294 divisor-max
2295 0)))
2296 ;; The divisor is potentially either very positive or very
2297 ;; negative. Therefore, the remainder is unbounded, but we might
2298 ;; be able to tell something about the sign from the number.
2299 `(integer ,(if (and number-low (not (minusp number-low)))
2300 ;; The number we are dividing is positive.
2301 ;; Therefore, the remainder must be positive.
2304 ,(if (and number-high (not (plusp number-high)))
2305 ;; The number we are dividing is negative.
2306 ;; Therefore, the remainder must be negative.
2308 '*))))
2310 #+sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
2311 (defoptimizer (random derive-type) ((bound &optional state))
2312 (declare (ignore state))
2313 (let ((type (lvar-type bound)))
2314 (when (numeric-type-p type)
2315 (let ((class (numeric-type-class type))
2316 (high (numeric-type-high type))
2317 (format (numeric-type-format type)))
2318 (make-numeric-type
2319 :class class
2320 :format format
2321 :low (coerce 0 (or format class 'real))
2322 :high (cond ((not high) nil)
2323 ((eq class 'integer) (max (1- high) 0))
2324 ((or (consp high) (zerop high)) high)
2325 (t `(,high))))))))
2327 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
2328 (defun random-derive-type-aux (type)
2329 (let ((class (numeric-type-class type))
2330 (high (numeric-type-high type))
2331 (format (numeric-type-format type)))
2332 (make-numeric-type
2333 :class class
2334 :format format
2335 :low (coerce 0 (or format class 'real))
2336 :high (cond ((not high) nil)
2337 ((eq class 'integer) (max (1- high) 0))
2338 ((or (consp high) (zerop high)) high)
2339 (t `(,high))))))
2341 #-sb-xc-host ; (See CROSS-FLOAT-INFINITY-KLUDGE.)
2342 (defoptimizer (random derive-type) ((bound &optional state))
2343 (declare (ignore state))
2344 (one-arg-derive-type bound #'random-derive-type-aux nil))
2346 ;;;; miscellaneous derive-type methods
2348 (defoptimizer (integer-length derive-type) ((x))
2349 (let ((x-type (lvar-type x)))
2350 (when (numeric-type-p x-type)
2351 ;; If the X is of type (INTEGER LO HI), then the INTEGER-LENGTH
2352 ;; of X is (INTEGER (MIN lo hi) (MAX lo hi), basically. Be
2353 ;; careful about LO or HI being NIL, though. Also, if 0 is
2354 ;; contained in X, the lower bound is obviously 0.
2355 (flet ((null-or-min (a b)
2356 (and a b (min (integer-length a)
2357 (integer-length b))))
2358 (null-or-max (a b)
2359 (and a b (max (integer-length a)
2360 (integer-length b)))))
2361 (let* ((min (numeric-type-low x-type))
2362 (max (numeric-type-high x-type))
2363 (min-len (null-or-min min max))
2364 (max-len (null-or-max min max)))
2365 (when (ctypep 0 x-type)
2366 (setf min-len 0))
2367 (specifier-type `(integer ,(or min-len '*) ,(or max-len '*))))))))
2369 (defoptimizer (logcount derive-type) ((x))
2370 (let ((x-type (lvar-type x)))
2371 (when (numeric-type-p x-type)
2372 (let ((min (numeric-type-low x-type))
2373 (max (numeric-type-high x-type)))
2374 (when (and min max)
2375 (specifier-type
2376 `(integer ,(if (or (> min 0)
2377 (< max -1))
2380 ,(max (integer-length min)
2381 (integer-length max)))))))))
2383 (defoptimizer (isqrt derive-type) ((x))
2384 (let ((x-type (lvar-type x)))
2385 (when (numeric-type-p x-type)
2386 (let* ((lo (numeric-type-low x-type))
2387 (hi (numeric-type-high x-type))
2388 (lo-res (if (typep lo 'unsigned-byte)
2389 (isqrt lo)
2391 (hi-res (if (typep hi 'unsigned-byte)
2392 (isqrt hi)
2393 '*)))
2394 (specifier-type `(integer ,lo-res ,hi-res))))))
2396 (defoptimizer (char-code derive-type) ((char))
2397 (let ((type (type-intersection (lvar-type char) (specifier-type 'character))))
2398 (cond ((member-type-p type)
2399 (specifier-type
2400 `(member
2401 ,@(loop for member in (member-type-members type)
2402 when (characterp member)
2403 collect (char-code member)))))
2404 ((sb!kernel::character-set-type-p type)
2405 (specifier-type
2406 `(or
2407 ,@(loop for (low . high)
2408 in (character-set-type-pairs type)
2409 collect `(integer ,low ,high)))))
2410 ((csubtypep type (specifier-type 'base-char))
2411 (specifier-type
2412 `(mod ,base-char-code-limit)))
2414 (specifier-type
2415 `(mod ,sb!xc:char-code-limit))))))
2417 (defoptimizer (code-char derive-type) ((code))
2418 (let ((type (lvar-type code)))
2419 ;; FIXME: unions of integral ranges? It ought to be easier to do
2420 ;; this, given that CHARACTER-SET is basically an integral range
2421 ;; type. -- CSR, 2004-10-04
2422 (when (numeric-type-p type)
2423 (let* ((lo (numeric-type-low type))
2424 (hi (numeric-type-high type))
2425 (type (specifier-type `(character-set ((,lo . ,hi))))))
2426 (cond
2427 ;; KLUDGE: when running on the host, we lose a slight amount
2428 ;; of precision so that we don't have to "unparse" types
2429 ;; that formally we can't, such as (CHARACTER-SET ((0
2430 ;; . 0))). -- CSR, 2004-10-06
2431 #+sb-xc-host
2432 ((csubtypep type (specifier-type 'standard-char)) type)
2433 #+sb-xc-host
2434 ((csubtypep type (specifier-type 'base-char))
2435 (specifier-type 'base-char))
2436 #+sb-xc-host
2437 ((csubtypep type (specifier-type 'extended-char))
2438 (specifier-type 'extended-char))
2439 (t #+sb-xc-host (specifier-type 'character)
2440 #-sb-xc-host type))))))
2442 (defoptimizer (values derive-type) ((&rest values))
2443 (make-values-type :required (mapcar #'lvar-type values)))
2445 (defun signum-derive-type-aux (type)
2446 (if (eq (numeric-type-complexp type) :complex)
2447 (let* ((format (case (numeric-type-class type)
2448 ((integer rational) 'single-float)
2449 (t (numeric-type-format type))))
2450 (bound-format (or format 'float)))
2451 (make-numeric-type :class 'float
2452 :format format
2453 :complexp :complex
2454 :low (coerce -1 bound-format)
2455 :high (coerce 1 bound-format)))
2456 (let* ((interval (numeric-type->interval type))
2457 (range-info (interval-range-info interval))
2458 (contains-0-p (interval-contains-p 0 interval))
2459 (class (numeric-type-class type))
2460 (format (numeric-type-format type))
2461 (one (coerce 1 (or format class 'real)))
2462 (zero (coerce 0 (or format class 'real)))
2463 (minus-one (coerce -1 (or format class 'real)))
2464 (plus (make-numeric-type :class class :format format
2465 :low one :high one))
2466 (minus (make-numeric-type :class class :format format
2467 :low minus-one :high minus-one))
2468 ;; KLUDGE: here we have a fairly horrible hack to deal
2469 ;; with the schizophrenia in the type derivation engine.
2470 ;; The problem is that the type derivers reinterpret
2471 ;; numeric types as being exact; so (DOUBLE-FLOAT 0d0
2472 ;; 0d0) within the derivation mechanism doesn't include
2473 ;; -0d0. Ugh. So force it in here, instead.
2474 (zero (make-numeric-type :class class :format format
2475 :low (- zero) :high zero)))
2476 (case range-info
2477 (+ (if contains-0-p (type-union plus zero) plus))
2478 (- (if contains-0-p (type-union minus zero) minus))
2479 (t (type-union minus zero plus))))))
2481 (defoptimizer (signum derive-type) ((num))
2482 (one-arg-derive-type num #'signum-derive-type-aux nil))
2484 ;;;; byte operations
2485 ;;;;
2486 ;;;; We try to turn byte operations into simple logical operations.
2487 ;;;; First, we convert byte specifiers into separate size and position
2488 ;;;; arguments passed to internal %FOO functions. We then attempt to
2489 ;;;; transform the %FOO functions into boolean operations when the
2490 ;;;; size and position are constant and the operands are fixnums.
2491 ;;;; The goal of the source-transform is to avoid consing a byte specifier
2492 ;;;; to immediately throw away. A more powerful framework could recognize
2493 ;;;; in IR1 when a constructor call flows to one or more accessors for the
2494 ;;;; constructed object and nowhere else (no mutators). If so, forwarding
2495 ;;;; the constructor arguments to their reads would generally solve this.
2496 ;;;; A transform approximates that, but fails when BYTE is produced by an
2497 ;;;; inline function and not a macro.
2498 (flet ((xform (bytespec-form env int fun &optional (new nil setter-p))
2499 (let ((spec (handler-case (%macroexpand bytespec-form env)
2500 (error ()
2501 (return-from xform (values nil t))))))
2502 (if (and (consp spec) (eq (car spec) 'byte))
2503 (if (proper-list-of-length-p (cdr spec) 2)
2504 (values `(,fun ,@(if setter-p (list new))
2505 ,(second spec) ,(third spec) ,int) nil)
2506 ;; No point in compiling calls to BYTE-{SIZE,POSITION}
2507 (values nil t)) ; T => "pass" (meaning "fail")
2508 (let ((new-temp (if setter-p (copy-symbol 'new)))
2509 (byte (copy-symbol 'byte)))
2510 (values `(let (,@(if new-temp `((,new-temp ,new)))
2511 (,byte ,spec))
2512 (,fun ,@(if setter-p (list new-temp))
2513 (byte-size ,byte) (byte-position ,byte) ,int))
2514 nil))))))
2516 ;; DEFINE-SOURCE-TRANSFORM has no compile-time effect, so it's fine that
2517 ;; these 4 things are non-toplevel. (xform does not need to be a macro)
2518 (define-source-transform ldb (spec int &environment env)
2519 (xform spec env int '%ldb))
2521 (define-source-transform dpb (newbyte spec int &environment env)
2522 (xform spec env int '%dpb newbyte))
2524 (define-source-transform mask-field (spec int &environment env)
2525 (xform spec env int '%mask-field))
2527 (define-source-transform deposit-field (newbyte spec int &environment env)
2528 (xform spec env int '%deposit-field newbyte)))
2530 (defoptimizer (%ldb derive-type) ((size posn num))
2531 (declare (ignore posn num))
2532 (let ((size (lvar-type size)))
2533 (if (and (numeric-type-p size)
2534 (csubtypep size (specifier-type 'integer)))
2535 (let ((size-high (numeric-type-high size)))
2536 (if (and size-high (<= size-high sb!vm:n-word-bits))
2537 (specifier-type `(unsigned-byte* ,size-high))
2538 (specifier-type 'unsigned-byte)))
2539 *universal-type*)))
2541 (defoptimizer (%mask-field derive-type) ((size posn num))
2542 (declare (ignore num))
2543 (let ((size (lvar-type size))
2544 (posn (lvar-type posn)))
2545 (if (and (numeric-type-p size)
2546 (csubtypep size (specifier-type 'integer))
2547 (numeric-type-p posn)
2548 (csubtypep posn (specifier-type 'integer)))
2549 (let ((size-high (numeric-type-high size))
2550 (posn-high (numeric-type-high posn)))
2551 (if (and size-high posn-high
2552 (<= (+ size-high posn-high) sb!vm:n-word-bits))
2553 (specifier-type `(unsigned-byte* ,(+ size-high posn-high)))
2554 (specifier-type 'unsigned-byte)))
2555 *universal-type*)))
2557 (defun %deposit-field-derive-type-aux (size posn int)
2558 (let ((size (lvar-type size))
2559 (posn (lvar-type posn))
2560 (int (lvar-type int)))
2561 (when (and (numeric-type-p size)
2562 (numeric-type-p posn)
2563 (numeric-type-p int))
2564 (let ((size-high (numeric-type-high size))
2565 (posn-high (numeric-type-high posn))
2566 (high (numeric-type-high int))
2567 (low (numeric-type-low int)))
2568 (when (and size-high posn-high high low
2569 ;; KLUDGE: we need this cutoff here, otherwise we
2570 ;; will merrily derive the type of %DPB as
2571 ;; (UNSIGNED-BYTE 1073741822), and then attempt to
2572 ;; canonicalize this type to (INTEGER 0 (1- (ASH 1
2573 ;; 1073741822))), with hilarious consequences. We
2574 ;; cutoff at 4*SB!VM:N-WORD-BITS to allow inference
2575 ;; over a reasonable amount of shifting, even on
2576 ;; the alpha/32 port, where N-WORD-BITS is 32 but
2577 ;; machine integers are 64-bits. -- CSR,
2578 ;; 2003-09-12
2579 (<= (+ size-high posn-high) (* 4 sb!vm:n-word-bits)))
2580 (let ((raw-bit-count (max (integer-length high)
2581 (integer-length low)
2582 (+ size-high posn-high))))
2583 (specifier-type
2584 (if (minusp low)
2585 `(signed-byte ,(1+ raw-bit-count))
2586 `(unsigned-byte* ,raw-bit-count)))))))))
2588 (defoptimizer (%dpb derive-type) ((newbyte size posn int))
2589 (declare (ignore newbyte))
2590 (%deposit-field-derive-type-aux size posn int))
2592 (defoptimizer (%deposit-field derive-type) ((newbyte size posn int))
2593 (declare (ignore newbyte))
2594 (%deposit-field-derive-type-aux size posn int))
2596 (deftransform %ldb ((size posn int)
2597 (fixnum fixnum integer)
2598 (unsigned-byte #.sb!vm:n-word-bits))
2599 "convert to inline logical operations"
2600 (if (and (constant-lvar-p size)
2601 (constant-lvar-p posn)
2602 (<= (+ (lvar-value size) (lvar-value posn)) sb!vm:n-fixnum-bits))
2603 (let ((size (lvar-value size))
2604 (posn (lvar-value posn)))
2605 `(logand (ash (mask-signed-field sb!vm:n-fixnum-bits int) ,(- posn))
2606 ,(ash (1- (ash 1 sb!vm:n-word-bits))
2607 (- size sb!vm:n-word-bits))))
2608 `(logand (ash int (- posn))
2609 (ash ,(1- (ash 1 sb!vm:n-word-bits))
2610 (- size ,sb!vm:n-word-bits)))))
2612 (deftransform %mask-field ((size posn int)
2613 (fixnum fixnum integer)
2614 (unsigned-byte #.sb!vm:n-word-bits))
2615 "convert to inline logical operations"
2616 `(logand int
2617 (ash (ash ,(1- (ash 1 sb!vm:n-word-bits))
2618 (- size ,sb!vm:n-word-bits))
2619 posn)))
2621 ;;; Note: for %DPB and %DEPOSIT-FIELD, we can't use
2622 ;;; (OR (SIGNED-BYTE N) (UNSIGNED-BYTE N))
2623 ;;; as the result type, as that would allow result types that cover
2624 ;;; the range -2^(n-1) .. 1-2^n, instead of allowing result types of
2625 ;;; (UNSIGNED-BYTE N) and result types of (SIGNED-BYTE N).
2627 (deftransform %dpb ((new size posn int)
2629 (unsigned-byte #.sb!vm:n-word-bits))
2630 "convert to inline logical operations"
2631 `(let ((mask (ldb (byte size 0) -1)))
2632 (logior (ash (logand new mask) posn)
2633 (logand int (lognot (ash mask posn))))))
2635 (deftransform %dpb ((new size posn int)
2637 (signed-byte #.sb!vm:n-word-bits))
2638 "convert to inline logical operations"
2639 `(let ((mask (ldb (byte size 0) -1)))
2640 (logior (ash (logand new mask) posn)
2641 (logand int (lognot (ash mask posn))))))
2643 (deftransform %deposit-field ((new size posn int)
2645 (unsigned-byte #.sb!vm:n-word-bits))
2646 "convert to inline logical operations"
2647 `(let ((mask (ash (ldb (byte size 0) -1) posn)))
2648 (logior (logand new mask)
2649 (logand int (lognot mask)))))
2651 (deftransform %deposit-field ((new size posn int)
2653 (signed-byte #.sb!vm:n-word-bits))
2654 "convert to inline logical operations"
2655 `(let ((mask (ash (ldb (byte size 0) -1) posn)))
2656 (logior (logand new mask)
2657 (logand int (lognot mask)))))
2659 (defoptimizer (mask-signed-field derive-type) ((size x))
2660 (declare (ignore x))
2661 (let ((size (lvar-type size)))
2662 (if (numeric-type-p size)
2663 (let ((size-high (numeric-type-high size)))
2664 (if (and size-high (<= 1 size-high sb!vm:n-word-bits))
2665 (specifier-type `(signed-byte ,size-high))
2666 *universal-type*))
2667 *universal-type*)))
2669 ;;; Rightward ASH
2670 #!+ash-right-vops
2671 (progn
2672 (defun %ash/right (integer amount)
2673 (ash integer (- amount)))
2675 (deftransform ash ((integer amount) (sb!vm:signed-word (integer * 0)) *
2676 :important nil)
2677 "Convert ASH of signed word to %ASH/RIGHT"
2678 (when (constant-lvar-p amount)
2679 (give-up-ir1-transform))
2680 (let ((use (lvar-uses amount)))
2681 (cond ((and (combination-p use)
2682 (eql '%negate (lvar-fun-name (combination-fun use))))
2683 (splice-fun-args amount '%negate 1)
2684 `(lambda (integer amount)
2685 (declare (type unsigned-byte amount))
2686 (%ash/right integer (if (>= amount ,sb!vm:n-word-bits)
2687 ,(1- sb!vm:n-word-bits)
2688 amount))))
2690 `(%ash/right integer (if (<= amount ,(- sb!vm:n-word-bits))
2691 ,(1- sb!vm:n-word-bits)
2692 (- amount)))))))
2694 (deftransform ash ((integer amount) (word (integer * 0)) *
2695 :important nil)
2696 "Convert ASH of word to %ASH/RIGHT"
2697 (when (constant-lvar-p amount)
2698 (give-up-ir1-transform))
2699 (let ((use (lvar-uses amount)))
2700 (cond ((and (combination-p use)
2701 (eql '%negate (lvar-fun-name (combination-fun use))))
2702 (splice-fun-args amount '%negate 1)
2703 `(lambda (integer amount)
2704 (declare (type unsigned-byte amount))
2705 (if (>= amount ,sb!vm:n-word-bits)
2707 (%ash/right integer amount))))
2709 `(if (<= amount ,(- sb!vm:n-word-bits))
2711 (%ash/right integer (- amount)))))))
2713 (deftransform %ash/right ((integer amount) (integer (constant-arg unsigned-byte)))
2714 "Convert %ASH/RIGHT by constant back to ASH"
2715 `(ash integer ,(- (lvar-value amount))))
2717 (deftransform %ash/right ((integer amount) * * :node node)
2718 "strength reduce large variable right shift"
2719 (let ((return-type (single-value-type (node-derived-type node))))
2720 (cond ((type= return-type (specifier-type '(eql 0)))
2722 ((type= return-type (specifier-type '(eql -1)))
2724 ((csubtypep return-type (specifier-type '(member -1 0)))
2725 `(ash integer ,(- sb!vm:n-word-bits)))
2727 (give-up-ir1-transform)))))
2729 (defun %ash/right-derive-type-aux (n-type shift same-arg)
2730 (declare (ignore same-arg))
2731 (or (and (or (csubtypep n-type (specifier-type 'sb!vm:signed-word))
2732 (csubtypep n-type (specifier-type 'word)))
2733 (csubtypep shift (specifier-type `(mod ,sb!vm:n-word-bits)))
2734 (let ((n-low (numeric-type-low n-type))
2735 (n-high (numeric-type-high n-type))
2736 (s-low (numeric-type-low shift))
2737 (s-high (numeric-type-high shift)))
2738 (make-numeric-type :class 'integer :complexp :real
2739 :low (when n-low
2740 (if (minusp n-low)
2741 (ash n-low (- s-low))
2742 (ash n-low (- s-high))))
2743 :high (when n-high
2744 (if (minusp n-high)
2745 (ash n-high (- s-high))
2746 (ash n-high (- s-low)))))))
2747 *universal-type*))
2749 (defoptimizer (%ash/right derive-type) ((n shift))
2750 (two-arg-derive-type n shift #'%ash/right-derive-type-aux #'%ash/right))
2753 ;;; Not declaring it as actually being RATIO becuase it is used as one
2754 ;;; of the legs in the EXPT transform below and that may result in
2755 ;;; some unwanted type conflicts, e.g. (random (expt 2 (the integer y)))
2756 (declaim (type (sfunction (integer) rational) reciprocate))
2757 (defun reciprocate (x)
2758 (declare (optimize (safety 0)))
2759 #+sb-xc-host (error "Can't call reciprocate ~D" x)
2760 #-sb-xc-host (%make-ratio 1 x))
2762 (deftransform expt ((base power) ((constant-arg unsigned-byte) integer))
2763 (let ((base (lvar-value base)))
2764 (cond ((/= (logcount base) 1)
2765 (give-up-ir1-transform))
2766 ((= base 1)
2769 `(let ((%denominator (ash 1 ,(if (= base 2)
2770 `(abs power)
2771 `(* (abs power) ,(1- (integer-length base)))))))
2772 (if (minusp power)
2773 (reciprocate %denominator)
2774 %denominator))))))
2776 (deftransform expt ((base power) ((constant-arg unsigned-byte) unsigned-byte))
2777 (let ((base (lvar-value base)))
2778 (unless (= (logcount base) 1)
2779 (give-up-ir1-transform))
2780 `(ash 1 ,(if (= base 2)
2781 `power
2782 `(* power ,(1- (integer-length base)))))))
2784 ;;; Modular functions
2786 ;;; (ldb (byte s 0) (foo x y ...)) =
2787 ;;; (ldb (byte s 0) (foo (ldb (byte s 0) x) y ...))
2789 ;;; and similar for other arguments.
2791 (defun make-modular-fun-type-deriver (prototype kind width signedp)
2792 (declare (ignore kind))
2793 #!-sb-fluid
2794 (binding* ((info (info :function :info prototype) :exit-if-null)
2795 (fun (fun-info-derive-type info) :exit-if-null)
2796 (mask-type (specifier-type
2797 (ecase signedp
2798 ((nil) (let ((mask (1- (ash 1 width))))
2799 `(integer ,mask ,mask)))
2800 ((t) `(signed-byte ,width))))))
2801 (lambda (call)
2802 (let ((res (funcall fun call)))
2803 (when res
2804 (if (eq signedp nil)
2805 (logand-derive-type-aux res mask-type))))))
2806 #!+sb-fluid
2807 (lambda (call)
2808 (binding* ((info (info :function :info prototype) :exit-if-null)
2809 (fun (fun-info-derive-type info) :exit-if-null)
2810 (res (funcall fun call) :exit-if-null)
2811 (mask-type (specifier-type
2812 (ecase signedp
2813 ((nil) (let ((mask (1- (ash 1 width))))
2814 `(integer ,mask ,mask)))
2815 ((t) `(signed-byte ,width))))))
2816 (if (eq signedp nil)
2817 (logand-derive-type-aux res mask-type)))))
2819 ;;; Try to recursively cut all uses of LVAR to WIDTH bits.
2821 ;;; For good functions, we just recursively cut arguments; their
2822 ;;; "goodness" means that the result will not increase (in the
2823 ;;; (unsigned-byte +infinity) sense). An ordinary modular function is
2824 ;;; replaced with the version, cutting its result to WIDTH or more
2825 ;;; bits. For most functions (e.g. for +) we cut all arguments; for
2826 ;;; others (e.g. for ASH) we have "optimizers", cutting only necessary
2827 ;;; arguments (maybe to a different width) and returning the name of a
2828 ;;; modular version, if it exists, or NIL. If we have changed
2829 ;;; anything, we need to flush old derived types, because they have
2830 ;;; nothing in common with the new code.
2831 (defun cut-to-width (lvar kind width signedp)
2832 (declare (type lvar lvar) (type (integer 0) width))
2833 (let ((type (specifier-type (if (zerop width)
2834 '(eql 0)
2835 `(,(ecase signedp
2836 ((nil) 'unsigned-byte)
2837 ((t) 'signed-byte))
2838 ,width)))))
2839 (labels ((reoptimize-node (node name)
2840 (setf (node-derived-type node)
2841 (fun-type-returns
2842 (proclaimed-ftype name)))
2843 (setf (lvar-%derived-type (node-lvar node)) nil)
2844 (setf (node-reoptimize node) t)
2845 (setf (block-reoptimize (node-block node)) t)
2846 (reoptimize-component (node-component node) :maybe))
2847 (insert-lvar-cut (lvar)
2848 "Insert a LOGAND/MASK-SIGNED-FIELD to cut the value of LVAR
2849 to the required bit width. Returns T if any change was made.
2851 When the destination of LVAR will definitely cut LVAR's value
2852 to width (i.e. it's a logand or mask-signed-field with constant
2853 other argument), do nothing. Otherwise, splice LOGAND/M-S-F in."
2854 (binding* ((dest (lvar-dest lvar) :exit-if-null)
2855 (nil (combination-p dest) :exit-if-null)
2856 (name (lvar-fun-name (combination-fun dest) t))
2857 (args (combination-args dest)))
2858 (case name
2859 (logand
2860 (when (= 2 (length args))
2861 (let ((other (if (eql (first args) lvar)
2862 (second args)
2863 (first args))))
2864 (when (and (constant-lvar-p other)
2865 (ctypep (lvar-value other) type)
2866 (not signedp))
2867 (return-from insert-lvar-cut)))))
2868 (mask-signed-field
2869 (when (and signedp
2870 (eql lvar (second args))
2871 (constant-lvar-p (first args))
2872 (<= (lvar-value (first args)) width))
2873 (return-from insert-lvar-cut)))))
2874 (filter-lvar lvar
2875 (if signedp
2876 `(mask-signed-field ,width 'dummy)
2877 `(logand 'dummy ,(ldb (byte width 0) -1))))
2878 (do-uses (node lvar)
2879 (setf (block-reoptimize (node-block node)) t)
2880 (reoptimize-component (node-component node) :maybe))
2882 (cut-node (node)
2883 "Try to cut a node to width. The primary return value is
2884 whether we managed to cut (cleverly), and the second whether
2885 anything was changed. The third return value tells whether
2886 the cut value might be wider than expected."
2887 (when (block-delete-p (node-block node))
2888 (return-from cut-node (values t nil)))
2889 (typecase node
2890 (ref
2891 (typecase (ref-leaf node)
2892 (constant
2893 (let* ((constant-value (constant-value (ref-leaf node)))
2894 (new-value
2895 (cond ((not (integerp constant-value))
2896 (return-from cut-node (values t nil)))
2897 (signedp
2898 (mask-signed-field width constant-value))
2900 (ldb (byte width 0) constant-value)))))
2901 (cond ((= constant-value new-value)
2902 (values t nil)) ; we knew what to do and did nothing
2904 (change-ref-leaf node (make-constant new-value)
2905 :recklessly t)
2906 (let ((lvar (node-lvar node)))
2907 (setf (lvar-%derived-type lvar)
2908 (and (lvar-has-single-use-p lvar)
2909 (make-values-type :required (list (ctype-of new-value))))))
2910 (setf (block-reoptimize (node-block node)) t)
2911 (reoptimize-component (node-component node) :maybe)
2912 (values t t)))))))
2913 (combination
2914 (when (eq (basic-combination-kind node) :known)
2915 (let* ((fun-ref (lvar-use (combination-fun node)))
2916 (fun-name (lvar-fun-name (combination-fun node)))
2917 (modular-fun (find-modular-version fun-name kind
2918 signedp width)))
2919 (cond ((not modular-fun)
2920 ;; don't know what to do here
2921 (values nil nil))
2922 ((let ((dtype (single-value-type
2923 (node-derived-type node))))
2924 (and
2925 (case fun-name
2926 (logand
2927 (csubtypep dtype
2928 (specifier-type 'unsigned-byte)))
2929 (logior
2930 (csubtypep dtype
2931 (specifier-type '(integer * 0))))
2932 (mask-signed-field
2934 (t nil))
2935 (csubtypep dtype type)))
2936 ;; nothing to do
2937 (values t nil))
2939 (binding* ((name (etypecase modular-fun
2940 ((eql :good) fun-name)
2941 (modular-fun-info
2942 (modular-fun-info-name modular-fun))
2943 (function
2944 (funcall modular-fun node width)))
2945 :exit-if-null)
2946 (did-something nil)
2947 (over-wide nil))
2948 (unless (eql modular-fun :good)
2949 (setq did-something t
2950 over-wide t)
2951 (change-ref-leaf
2952 fun-ref
2953 (find-free-fun name "in a strange place"))
2954 (setf (combination-kind node) :full))
2955 (unless (functionp modular-fun)
2956 (dolist (arg (basic-combination-args node))
2957 (multiple-value-bind (change wide)
2958 (cut-lvar arg)
2959 (setf did-something (or did-something change)
2960 over-wide (or over-wide wide)))))
2961 (when did-something
2962 (reoptimize-node node name))
2963 (values t did-something over-wide)))))))))
2964 (cut-lvar (lvar &key head
2965 &aux did-something must-insert over-wide)
2966 "Cut all the LVAR's use nodes. If any of them wasn't handled
2967 and its type is too wide for the operation we wish to perform
2968 insert an explicit bit-width narrowing operation (LOGAND or
2969 MASK-SIGNED-FIELD) between the LVAR (*) and its destination.
2970 The narrowing operation might not be inserted if the LVAR's
2971 destination is already such an operation, to avoid endless
2972 recursion.
2974 If we're at the head, forcibly insert a cut operation if the
2975 result might be too wide.
2977 (*) We can't easily do that for each node, and doing so might
2978 result in code bloat, anyway. (I'm also not sure it would be
2979 correct for complicated C/D FG)"
2980 (do-uses (node lvar)
2981 (multiple-value-bind (handled any-change wide)
2982 (cut-node node)
2983 (setf did-something (or did-something any-change)
2984 must-insert (or must-insert
2985 (not (or handled
2986 (csubtypep (single-value-type
2987 (node-derived-type node))
2988 type))))
2989 over-wide (or over-wide wide))))
2990 (when (or must-insert
2991 (and head over-wide))
2992 (setf did-something (or (insert-lvar-cut lvar) did-something)
2993 ;; we're just the right width after an explicit cut.
2994 over-wide nil))
2995 (values did-something over-wide)))
2996 (cut-lvar lvar :head t))))
2998 (defun best-modular-version (width signedp)
2999 ;; 1. exact width-matched :untagged
3000 ;; 2. >/>= width-matched :tagged
3001 ;; 3. >/>= width-matched :untagged
3002 (let* ((uuwidths (modular-class-widths *untagged-unsigned-modular-class*))
3003 (uswidths (modular-class-widths *untagged-signed-modular-class*))
3004 (uwidths (if (and uuwidths uswidths)
3005 (merge 'list (copy-list uuwidths) (copy-list uswidths)
3006 #'< :key #'car)
3007 (or uuwidths uswidths)))
3008 (twidths (modular-class-widths *tagged-modular-class*)))
3009 (let ((exact (find (cons width signedp) uwidths :test #'equal)))
3010 (when exact
3011 (return-from best-modular-version (values width :untagged signedp))))
3012 (flet ((inexact-match (w)
3013 (cond
3014 ((eq signedp (cdr w)) (<= width (car w)))
3015 ((eq signedp nil) (< width (car w))))))
3016 (let ((tgt (find-if #'inexact-match twidths)))
3017 (when tgt
3018 (return-from best-modular-version
3019 (values (car tgt) :tagged (cdr tgt)))))
3020 (let ((ugt (find-if #'inexact-match uwidths)))
3021 (when ugt
3022 (return-from best-modular-version
3023 (values (car ugt) :untagged (cdr ugt))))))))
3025 (defun integer-type-numeric-bounds (type)
3026 (typecase type
3027 ;; KLUDGE: this is not INTEGER-type-numeric-bounds
3028 (numeric-type (values (numeric-type-low type)
3029 (numeric-type-high type)))
3030 (union-type
3031 (let ((low nil)
3032 (high nil))
3033 (dolist (type (union-type-types type) (values low high))
3034 (unless (and (numeric-type-p type)
3035 (eql (numeric-type-class type) 'integer))
3036 (return (values nil nil)))
3037 (let ((this-low (numeric-type-low type))
3038 (this-high (numeric-type-high type)))
3039 (unless (and this-low this-high)
3040 (return (values nil nil)))
3041 (setf low (min this-low (or low this-low))
3042 high (max this-high (or high this-high)))))))))
3044 (defoptimizer (logand optimizer) ((x y) node)
3045 (let ((result-type (single-value-type (node-derived-type node))))
3046 (multiple-value-bind (low high)
3047 (integer-type-numeric-bounds result-type)
3048 (when (and (numberp low)
3049 (numberp high)
3050 (>= low 0))
3051 (let ((width (integer-length high)))
3052 (multiple-value-bind (w kind signedp)
3053 (best-modular-version width nil)
3054 (when w
3055 ;; FIXME: This should be (CUT-TO-WIDTH NODE KIND WIDTH SIGNEDP).
3057 ;; FIXME: I think the FIXME (which is from APD) above
3058 ;; implies that CUT-TO-WIDTH should do /everything/
3059 ;; that's required, including reoptimizing things
3060 ;; itself that it knows are necessary. At the moment,
3061 ;; CUT-TO-WIDTH sets up some new calls with
3062 ;; combination-type :FULL, which later get noticed as
3063 ;; known functions and properly converted.
3065 ;; We cut to W not WIDTH if SIGNEDP is true, because
3066 ;; signed constant replacement needs to know which bit
3067 ;; in the field is the signed bit.
3068 (let ((xact (cut-to-width x kind (if signedp w width) signedp))
3069 (yact (cut-to-width y kind (if signedp w width) signedp)))
3070 (declare (ignore xact yact))
3071 nil) ; After fixing above, replace with T, meaning
3072 ; "don't reoptimize this (LOGAND) node any more".
3073 )))))))
3075 (defoptimizer (mask-signed-field optimizer) ((width x) node)
3076 (declare (ignore width))
3077 (let ((result-type (single-value-type (node-derived-type node))))
3078 (multiple-value-bind (low high)
3079 (integer-type-numeric-bounds result-type)
3080 (when (and (numberp low) (numberp high))
3081 (let ((width (max (integer-length high) (integer-length low))))
3082 (multiple-value-bind (w kind)
3083 (best-modular-version (1+ width) t)
3084 (when w
3085 ;; FIXME: This should be (CUT-TO-WIDTH NODE KIND W T).
3086 ;; [ see comment above in LOGAND optimizer ]
3087 (cut-to-width x kind w t)
3088 nil ; After fixing above, replace with T.
3089 )))))))
3091 (defoptimizer (logior optimizer) ((x y) node)
3092 (let ((result-type (single-value-type (node-derived-type node))))
3093 (multiple-value-bind (low high)
3094 (integer-type-numeric-bounds result-type)
3095 (when (and (numberp low)
3096 (numberp high)
3097 (<= high 0))
3098 (let ((width (integer-length low)))
3099 (multiple-value-bind (w kind)
3100 (best-modular-version (1+ width) t)
3101 (when w
3102 ;; FIXME: see comment in LOGAND optimizer
3103 (let ((xact (cut-to-width x kind w t))
3104 (yact (cut-to-width y kind w t)))
3105 (declare (ignore xact yact))
3106 nil) ; After fixing above, replace with T
3107 )))))))
3109 ;;; Handle the case of a constant BOOLE-CODE.
3110 (deftransform boole ((op x y) * *)
3111 "convert to inline logical operations"
3112 (unless (constant-lvar-p op)
3113 (give-up-ir1-transform "BOOLE code is not a constant."))
3114 (let ((control (lvar-value op)))
3115 (case control
3116 (#.sb!xc:boole-clr 0)
3117 (#.sb!xc:boole-set -1)
3118 (#.sb!xc:boole-1 'x)
3119 (#.sb!xc:boole-2 'y)
3120 (#.sb!xc:boole-c1 '(lognot x))
3121 (#.sb!xc:boole-c2 '(lognot y))
3122 (#.sb!xc:boole-and '(logand x y))
3123 (#.sb!xc:boole-ior '(logior x y))
3124 (#.sb!xc:boole-xor '(logxor x y))
3125 (#.sb!xc:boole-eqv '(logeqv x y))
3126 (#.sb!xc:boole-nand '(lognand x y))
3127 (#.sb!xc:boole-nor '(lognor x y))
3128 (#.sb!xc:boole-andc1 '(logandc1 x y))
3129 (#.sb!xc:boole-andc2 '(logandc2 x y))
3130 (#.sb!xc:boole-orc1 '(logorc1 x y))
3131 (#.sb!xc:boole-orc2 '(logorc2 x y))
3133 (abort-ir1-transform "~S is an illegal control arg to BOOLE."
3134 control)))))
3136 ;;;; converting special case multiply/divide to shifts
3138 ;;; If arg is a constant power of two, turn * into a shift.
3139 (deftransform * ((x y) (integer integer) *)
3140 "convert x*2^k to shift"
3141 (unless (constant-lvar-p y)
3142 (give-up-ir1-transform))
3143 (let* ((y (lvar-value y))
3144 (y-abs (abs y))
3145 (len (1- (integer-length y-abs))))
3146 (unless (and (> y-abs 0) (= y-abs (ash 1 len)))
3147 (give-up-ir1-transform))
3148 (if (minusp y)
3149 `(- (ash x ,len))
3150 `(ash x ,len))))
3152 ;;; These must come before the ones below, so that they are tried
3153 ;;; first.
3154 (deftransform floor ((number divisor))
3155 `(multiple-value-bind (tru rem) (truncate number divisor)
3156 (if (and (not (zerop rem))
3157 (if (minusp divisor)
3158 (plusp number)
3159 (minusp number)))
3160 (values (1- tru) (+ rem divisor))
3161 (values tru rem))))
3163 (deftransform ceiling ((number divisor))
3164 `(multiple-value-bind (tru rem) (truncate number divisor)
3165 (if (and (not (zerop rem))
3166 (if (minusp divisor)
3167 (minusp number)
3168 (plusp number)))
3169 (values (+ tru 1) (- rem divisor))
3170 (values tru rem))))
3172 (deftransform rem ((number divisor))
3173 `(nth-value 1 (truncate number divisor)))
3175 (deftransform mod ((number divisor))
3176 `(let ((rem (rem number divisor)))
3177 (if (and (not (zerop rem))
3178 (if (minusp divisor)
3179 (plusp number)
3180 (minusp number)))
3181 (+ rem divisor)
3182 rem)))
3184 ;;; If arg is a constant power of two, turn FLOOR into a shift and
3185 ;;; mask. If CEILING, add in (1- (ABS Y)), do FLOOR and correct a
3186 ;;; remainder.
3187 (flet ((frob (y ceil-p)
3188 (unless (constant-lvar-p y)
3189 (give-up-ir1-transform))
3190 (let* ((y (lvar-value y))
3191 (y-abs (abs y))
3192 (len (1- (integer-length y-abs))))
3193 (unless (and (> y-abs 0) (= y-abs (ash 1 len)))
3194 (give-up-ir1-transform))
3195 (let ((shift (- len))
3196 (mask (1- y-abs))
3197 (delta (if ceil-p (* (signum y) (1- y-abs)) 0)))
3198 `(let ((x (+ x ,delta)))
3199 ,(if (minusp y)
3200 `(values (ash (- x) ,shift)
3201 (- (- (logand (- x) ,mask)) ,delta))
3202 `(values (ash x ,shift)
3203 (- (logand x ,mask) ,delta))))))))
3204 (deftransform floor ((x y) (integer integer) *)
3205 "convert division by 2^k to shift"
3206 (frob y nil))
3207 (deftransform ceiling ((x y) (integer integer) *)
3208 "convert division by 2^k to shift"
3209 (frob y t)))
3211 ;;; Do the same for MOD.
3212 (deftransform mod ((x y) (integer (constant-arg integer)) *)
3213 "convert remainder mod 2^k to LOGAND"
3214 (let* ((y (lvar-value y))
3215 (y-abs (abs y))
3216 (len (1- (integer-length y-abs))))
3217 (unless (and (> y-abs 0) (= y-abs (ash 1 len)))
3218 (give-up-ir1-transform))
3219 (let ((mask (1- y-abs)))
3220 (if (minusp y)
3221 `(- (logand (- x) ,mask))
3222 `(logand x ,mask)))))
3224 ;;; If arg is a constant power of two, turn TRUNCATE into a shift and mask.
3225 (deftransform truncate ((x y) (integer (constant-arg integer)))
3226 "convert division by 2^k to shift"
3227 (let* ((y (lvar-value y))
3228 (y-abs (abs y))
3229 (len (1- (integer-length y-abs))))
3230 (unless (and (> y-abs 0) (= y-abs (ash 1 len)))
3231 (give-up-ir1-transform))
3232 (let ((shift (- len))
3233 (mask (1- y-abs)))
3234 `(if (minusp x)
3235 (values ,(if (minusp y)
3236 `(ash (- x) ,shift)
3237 `(- (ash (- x) ,shift)))
3238 (- (logand (- x) ,mask)))
3239 (values ,(if (minusp y)
3240 `(- (ash x ,shift))
3241 `(ash x ,shift))
3242 (logand x ,mask))))))
3244 ;;; And the same for REM.
3245 (deftransform rem ((x y) (integer (constant-arg integer)) *)
3246 "convert remainder mod 2^k to LOGAND"
3247 (let* ((y (lvar-value y))
3248 (y-abs (abs y))
3249 (len (1- (integer-length y-abs))))
3250 (unless (and (> y-abs 0) (= y-abs (ash 1 len)))
3251 (give-up-ir1-transform))
3252 (let ((mask (1- y-abs)))
3253 `(if (minusp x)
3254 (- (logand (- x) ,mask))
3255 (logand x ,mask)))))
3257 ;;; Return an expression to calculate the integer quotient of X and
3258 ;;; constant Y, using multiplication, shift and add/sub instead of
3259 ;;; division. Both arguments must be unsigned, fit in a machine word and
3260 ;;; Y must neither be zero nor a power of two. The quotient is rounded
3261 ;;; towards zero.
3262 ;;; The algorithm is taken from the paper "Division by Invariant
3263 ;;; Integers using Multiplication", 1994 by Torbj\"{o}rn Granlund and
3264 ;;; Peter L. Montgomery, Figures 4.2 and 6.2, modified to exclude the
3265 ;;; case of division by powers of two.
3266 ;;; The algorithm includes an adaptive precision argument. Use it, since
3267 ;;; we often have sub-word value ranges. Careful, in this case, we need
3268 ;;; p s.t 2^p > n, not the ceiling of the binary log.
3269 ;;; Also, for some reason, the paper prefers shifting to masking. Mask
3270 ;;; instead. Masking is equivalent to shifting right, then left again;
3271 ;;; all the intermediate values are still words, so we just have to shift
3272 ;;; right a bit more to compensate, at the end.
3274 ;;; The following two examples show an average case and the worst case
3275 ;;; with respect to the complexity of the generated expression, under
3276 ;;; a word size of 64 bits:
3278 ;;; (UNSIGNED-DIV-TRANSFORMER 10 MOST-POSITIVE-WORD) ->
3279 ;;; (ASH (%MULTIPLY (LOGANDC2 X 0) 14757395258967641293) -3)
3281 ;;; (UNSIGNED-DIV-TRANSFORMER 7 MOST-POSITIVE-WORD) ->
3282 ;;; (LET* ((NUM X)
3283 ;;; (T1 (%MULTIPLY NUM 2635249153387078803)))
3284 ;;; (ASH (LDB (BYTE 64 0)
3285 ;;; (+ T1 (ASH (LDB (BYTE 64 0)
3286 ;;; (- NUM T1))
3287 ;;; -1)))
3288 ;;; -2))
3290 (defun gen-unsigned-div-by-constant-expr (y max-x)
3291 (declare (type (integer 3 #.most-positive-word) y)
3292 (type word max-x))
3293 (aver (not (zerop (logand y (1- y)))))
3294 (labels ((ld (x)
3295 ;; the floor of the binary logarithm of (positive) X
3296 (integer-length (1- x)))
3297 (choose-multiplier (y precision)
3298 (do* ((l (ld y))
3299 (shift l (1- shift))
3300 (expt-2-n+l (expt 2 (+ sb!vm:n-word-bits l)))
3301 (m-low (truncate expt-2-n+l y) (ash m-low -1))
3302 (m-high (truncate (+ expt-2-n+l
3303 (ash expt-2-n+l (- precision)))
3305 (ash m-high -1)))
3306 ((not (and (< (ash m-low -1) (ash m-high -1))
3307 (> shift 0)))
3308 (values m-high shift)))))
3309 (let ((n (expt 2 sb!vm:n-word-bits))
3310 (precision (integer-length max-x))
3311 (shift1 0))
3312 (multiple-value-bind (m shift2)
3313 (choose-multiplier y precision)
3314 (when (and (>= m n) (evenp y))
3315 (setq shift1 (ld (logand y (- y))))
3316 (multiple-value-setq (m shift2)
3317 (choose-multiplier (/ y (ash 1 shift1))
3318 (- precision shift1))))
3319 (cond ((>= m n)
3320 (flet ((word (x)
3321 `(truly-the word ,x)))
3322 `(let* ((num x)
3323 (t1 (%multiply-high num ,(- m n))))
3324 (ash ,(word `(+ t1 (ash ,(word `(- num t1))
3325 -1)))
3326 ,(- 1 shift2)))))
3327 ((and (zerop shift1) (zerop shift2))
3328 (let ((max (truncate max-x y)))
3329 ;; Explicit TRULY-THE needed to get the FIXNUM=>FIXNUM
3330 ;; VOP.
3331 `(truly-the (integer 0 ,max)
3332 (%multiply-high x ,m))))
3334 `(ash (%multiply-high (logandc2 x ,(1- (ash 1 shift1))) ,m)
3335 ,(- (+ shift1 shift2)))))))))
3337 #!-multiply-high-vops
3338 (define-source-transform %multiply-high (x y)
3339 `(values (sb!bignum:%multiply ,x ,y)))
3341 ;;; If the divisor is constant and both args are positive and fit in a
3342 ;;; machine word, replace the division by a multiplication and possibly
3343 ;;; some shifts and an addition. Calculate the remainder by a second
3344 ;;; multiplication and a subtraction. Dead code elimination will
3345 ;;; suppress the latter part if only the quotient is needed. If the type
3346 ;;; of the dividend allows to derive that the quotient will always have
3347 ;;; the same value, emit much simpler code to handle that. (This case
3348 ;;; may be rare but it's easy to detect and the compiler doesn't find
3349 ;;; this optimization on its own.)
3350 (deftransform truncate ((x y) (word (constant-arg word))
3352 :policy (and (> speed compilation-speed)
3353 (> speed space)))
3354 "convert integer division to multiplication"
3355 (let* ((y (lvar-value y))
3356 (x-type (lvar-type x))
3357 (max-x (or (and (numeric-type-p x-type)
3358 (numeric-type-high x-type))
3359 most-positive-word)))
3360 ;; Division by zero, one or powers of two is handled elsewhere.
3361 (when (zerop (logand y (1- y)))
3362 (give-up-ir1-transform))
3363 `(let* ((quot ,(gen-unsigned-div-by-constant-expr y max-x))
3364 (rem (ldb (byte #.sb!vm:n-word-bits 0)
3365 (- x (* quot ,y)))))
3366 (values quot rem))))
3368 ;;;; arithmetic and logical identity operation elimination
3370 ;;; Flush calls to various arith functions that convert to the
3371 ;;; identity function or a constant.
3372 (macrolet ((def (name identity result)
3373 `(deftransform ,name ((x y) (* (constant-arg (member ,identity))) *)
3374 "fold identity operations"
3375 ',result)))
3376 (def ash 0 x)
3377 (def logand -1 x)
3378 (def logand 0 0)
3379 (def logior 0 x)
3380 (def logior -1 -1)
3381 (def logxor -1 (lognot x))
3382 (def logxor 0 x))
3384 (defun least-zero-bit (x)
3385 (and (/= x -1)
3386 (1- (integer-length (logxor x (1+ x))))))
3388 (deftransform logand ((x y) (* (constant-arg integer)) *)
3389 "fold identity operation"
3390 (let* ((y (lvar-value y))
3391 (width (or (least-zero-bit y) '*)))
3392 (unless (and (neq width 0) ; (logand x 0) handled elsewhere
3393 (csubtypep (lvar-type x)
3394 (specifier-type `(unsigned-byte ,width))))
3395 (give-up-ir1-transform))
3396 'x))
3398 (deftransform mask-signed-field ((size x) ((constant-arg t) *) *)
3399 "fold identity operation"
3400 (let ((size (lvar-value size)))
3401 (when (= size 0) (give-up-ir1-transform))
3402 (unless (csubtypep (lvar-type x) (specifier-type `(signed-byte ,size)))
3403 (give-up-ir1-transform))
3404 'x))
3406 (deftransform logior ((x y) (* (constant-arg integer)) *)
3407 "fold identity operation"
3408 (let* ((y (lvar-value y))
3409 (width (or (least-zero-bit (lognot y))
3410 (give-up-ir1-transform)))) ; (logior x 0) handled elsewhere
3411 (unless (csubtypep (lvar-type x)
3412 (specifier-type `(integer ,(- (ash 1 width)) -1)))
3413 (give-up-ir1-transform))
3414 'x))
3416 ;;; Pick off easy association opportunities for constant folding.
3417 ;;; More complicated stuff that also depends on commutativity
3418 ;;; (e.g. (f (f x k1) (f y k2)) => (f (f x y) (f k1 k2))) should
3419 ;;; probably be handled with a more general tree-rewriting pass.
3420 (macrolet ((def (operator &key (type 'integer) (folded (list operator)))
3421 `(deftransform ,operator ((x z) (,type (constant-arg ,type)))
3422 ,(format nil "associate ~A/~A of constants"
3423 operator folded)
3424 (binding* ((node (if (lvar-has-single-use-p x)
3425 (lvar-use x)
3426 (give-up-ir1-transform)))
3427 (folded (or (and (combination-p node)
3428 (car (memq (lvar-fun-name
3429 (combination-fun node))
3430 ',folded)))
3431 (give-up-ir1-transform)))
3432 (y (second (combination-args node)))
3433 (nil (or (constant-lvar-p y)
3434 (give-up-ir1-transform)))
3435 (y (lvar-value y)))
3436 (unless (typep y ',type)
3437 (give-up-ir1-transform))
3438 (splice-fun-args x folded 2)
3439 `(lambda (x y z)
3440 (declare (ignore y z))
3441 ;; (operator (folded x y) z)
3442 ;; == (operator x (folded z y))
3443 (,',operator x (,folded ,(lvar-value z) ,y)))))))
3444 (def logand)
3445 (def logior)
3446 (def logxor)
3447 (def logtest :folded (logand))
3448 (def + :type rational :folded (+ -))
3449 (def * :type rational :folded (* /)))
3451 (deftransform mask-signed-field ((width x) ((constant-arg unsigned-byte) *))
3452 "Fold mask-signed-field/mask-signed-field of constant width"
3453 (binding* ((node (if (lvar-has-single-use-p x)
3454 (lvar-use x)
3455 (give-up-ir1-transform)))
3456 (nil (or (combination-p node)
3457 (give-up-ir1-transform)))
3458 (nil (or (eq (lvar-fun-name (combination-fun node))
3459 'mask-signed-field)
3460 (give-up-ir1-transform)))
3461 (x-width (first (combination-args node)))
3462 (nil (or (constant-lvar-p x-width)
3463 (give-up-ir1-transform)))
3464 (x-width (lvar-value x-width)))
3465 (unless (typep x-width 'unsigned-byte)
3466 (give-up-ir1-transform))
3467 (splice-fun-args x 'mask-signed-field 2)
3468 `(lambda (width x-width x)
3469 (declare (ignore width x-width))
3470 (mask-signed-field ,(min (lvar-value width) x-width) x))))
3472 ;;; These are restricted to rationals, because (- 0 0.0) is 0.0, not -0.0, and
3473 ;;; (* 0 -4.0) is -0.0.
3474 (deftransform - ((x y) ((constant-arg (member 0)) rational) *)
3475 "convert (- 0 x) to negate"
3476 '(%negate y))
3477 (deftransform * ((x y) (rational (constant-arg (member 0))) *)
3478 "convert (* x 0) to 0"
3481 (deftransform %negate ((x) (rational))
3482 "Eliminate %negate/%negate of rationals"
3483 (splice-fun-args x '%negate 1)
3484 '(the rational x))
3486 (deftransform %negate ((x) (number))
3487 "Combine %negate/*"
3488 (let ((use (lvar-uses x))
3489 arg)
3490 (unless (and (combination-p use)
3491 (eql '* (lvar-fun-name (combination-fun use)))
3492 (constant-lvar-p (setf arg (second (combination-args use))))
3493 (numberp (setf arg (lvar-value arg))))
3494 (give-up-ir1-transform))
3495 (splice-fun-args x '* 2)
3496 `(lambda (x y)
3497 (declare (ignore y))
3498 (* x ,(- arg)))))
3500 ;;; Return T if in an arithmetic op including lvars X and Y, the
3501 ;;; result type is not affected by the type of X. That is, Y is at
3502 ;;; least as contagious as X.
3503 (defun not-more-contagious (x y)
3504 (let ((x (lvar-type x))
3505 (y (lvar-type y)))
3506 (cond
3507 ((csubtypep x (specifier-type 'rational)))
3508 ((csubtypep x (specifier-type 'single-float))
3509 (csubtypep y (specifier-type 'float)))
3510 ((csubtypep x (specifier-type 'double-float))
3511 (csubtypep y (specifier-type 'double-float))))))
3513 (def!type exact-number ()
3514 '(or rational (complex rational)))
3516 ;;; Fold (+ x 0).
3518 ;;; Only safely applicable for exact numbers. For floating-point
3519 ;;; x, one would have to first show that neither x or y are signed
3520 ;;; 0s, and that x isn't an SNaN.
3521 (deftransform + ((x y) (exact-number (constant-arg (eql 0))) *)
3522 "fold zero arg"
3525 ;;; Fold (- x 0).
3526 (deftransform - ((x y) (exact-number (constant-arg (eql 0))) *)
3527 "fold zero arg"
3530 ;;; Fold (OP x +/-1)
3532 ;;; %NEGATE might not always signal correctly.
3533 (macrolet
3534 ((def (name result minus-result)
3535 `(deftransform ,name ((x y)
3536 (exact-number (constant-arg (member 1 -1))))
3537 "fold identity operations"
3538 (if (minusp (lvar-value y)) ',minus-result ',result))))
3539 (def * x (%negate x))
3540 (def / x (%negate x))
3541 (def expt x (/ 1 x)))
3543 ;;; Fold (expt x n) into multiplications for small integral values of
3544 ;;; N; convert (expt x 1/2) to sqrt.
3545 (deftransform expt ((x y) (t (constant-arg real)) *)
3546 "recode as multiplication or sqrt"
3547 (let ((val (lvar-value y)))
3548 ;; If Y would cause the result to be promoted to the same type as
3549 ;; Y, we give up. If not, then the result will be the same type
3550 ;; as X, so we can replace the exponentiation with simple
3551 ;; multiplication and division for small integral powers.
3552 (unless (not-more-contagious y x)
3553 (give-up-ir1-transform))
3554 (cond ((zerop val)
3555 (let ((x-type (lvar-type x)))
3556 (cond ((csubtypep x-type (specifier-type '(or rational
3557 (complex rational))))
3559 ((csubtypep x-type (specifier-type 'real))
3560 `(if (rationalp x)
3562 (float 1 x)))
3563 ((csubtypep x-type (specifier-type 'complex))
3564 ;; both parts are float
3565 `(1+ (* x ,val)))
3566 (t (give-up-ir1-transform)))))
3567 ((= val 2) '(* x x))
3568 ((= val -2) '(/ (* x x)))
3569 ((= val 3) '(* x x x))
3570 ((= val -3) '(/ (* x x x)))
3571 ((= val 1/2) '(sqrt x))
3572 ((= val -1/2) '(/ (sqrt x)))
3573 (t (give-up-ir1-transform)))))
3575 (deftransform expt ((x y) ((constant-arg (member -1 -1.0 -1.0d0)) integer) *)
3576 "recode as an ODDP check"
3577 (let ((val (lvar-value x)))
3578 (if (eql -1 val)
3579 '(- 1 (* 2 (logand 1 y)))
3580 `(if (oddp y)
3581 ,val
3582 ,(abs val)))))
3584 ;;; KLUDGE: Shouldn't (/ 0.0 0.0), etc. cause exceptions in these
3585 ;;; transformations?
3586 ;;; Perhaps we should have to prove that the denominator is nonzero before
3587 ;;; doing them? -- WHN 19990917
3588 (macrolet ((def (name)
3589 `(deftransform ,name ((x y) ((constant-arg (integer 0 0)) integer)
3591 "fold zero arg"
3592 0)))
3593 (def ash)
3594 (def /))
3596 (macrolet ((def (name)
3597 `(deftransform ,name ((x y) ((constant-arg (integer 0 0)) integer)
3599 "fold zero arg"
3600 '(values 0 0))))
3601 (def truncate)
3602 (def round)
3603 (def floor)
3604 (def ceiling))
3606 (macrolet ((def (name &optional float)
3607 (let ((x (if float '(float x) 'x)))
3608 `(deftransform ,name ((x y) (integer (constant-arg (member 1 -1)))
3610 "fold division by 1"
3611 `(values ,(if (minusp (lvar-value y))
3612 '(%negate ,x)
3613 ',x) 0)))))
3614 (def truncate)
3615 (def round)
3616 (def floor)
3617 (def ceiling)
3618 (def ftruncate t)
3619 (def fround t)
3620 (def ffloor t)
3621 (def fceiling t))
3624 ;;;; character operations
3626 (deftransform two-arg-char-equal ((a b) (base-char base-char) *
3627 :policy (> speed space))
3628 "open code"
3629 '(let* ((ac (char-code a))
3630 (bc (char-code b))
3631 (sum (logxor ac bc)))
3632 (or (zerop sum)
3633 (when (eql sum #x20)
3634 (let ((sum (+ ac bc)))
3635 (or (and (> sum 161) (< sum 213))
3636 (and (> sum 415) (< sum 461))
3637 (and (> sum 463) (< sum 477))))))))
3639 (defun transform-constant-char-equal (a b &optional (op 'char=))
3640 (let ((char (lvar-value b)))
3641 (if (both-case-p char)
3642 (let ((reverse (if (upper-case-p char)
3643 (char-downcase char)
3644 (char-upcase char))))
3645 `(or (,op ,a ,char)
3646 (,op ,a ,reverse)))
3647 `(,op ,a ,char))))
3649 (deftransform two-arg-char-equal ((a b) (* (constant-arg character)) *
3650 :node node)
3651 (transform-constant-char-equal 'a b))
3653 (deftransform char-upcase ((x) (base-char))
3654 "open code"
3655 '(let ((n-code (char-code x)))
3656 (if (or (and (> n-code #o140) ; Octal 141 is #\a.
3657 (< n-code #o173)) ; Octal 172 is #\z.
3658 (and (> n-code #o337)
3659 (< n-code #o367))
3660 (and (> n-code #o367)
3661 (< n-code #o377)))
3662 (code-char (logxor #x20 n-code))
3663 x)))
3665 (deftransform char-downcase ((x) (base-char))
3666 "open code"
3667 '(let ((n-code (char-code x)))
3668 (if (or (and (> n-code 64) ; 65 is #\A.
3669 (< n-code 91)) ; 90 is #\Z.
3670 (and (> n-code 191)
3671 (< n-code 215))
3672 (and (> n-code 215)
3673 (< n-code 223)))
3674 (code-char (logxor #x20 n-code))
3675 x)))
3677 ;;;; equality predicate transforms
3679 ;;; Return true if X and Y are lvars whose only use is a
3680 ;;; reference to the same leaf, and the value of the leaf cannot
3681 ;;; change.
3682 (defun same-leaf-ref-p (x y)
3683 (declare (type lvar x y))
3684 (let ((x-use (principal-lvar-use x))
3685 (y-use (principal-lvar-use y)))
3686 (and (ref-p x-use)
3687 (ref-p y-use)
3688 (eq (ref-leaf x-use) (ref-leaf y-use))
3689 (constant-reference-p x-use))))
3691 ;;; If X and Y are the same leaf, then the result is true. Otherwise,
3692 ;;; if there is no intersection between the types of the arguments,
3693 ;;; then the result is definitely false.
3694 (deftransforms (eq char=) ((x y) * *)
3695 "Simple equality transform"
3696 (cond
3697 ((same-leaf-ref-p x y) t)
3698 ((not (types-equal-or-intersect (lvar-type x) (lvar-type y)))
3699 nil)
3700 (t (give-up-ir1-transform))))
3702 ;;; Can't use the above thing, since TYPES-EQUAL-OR-INTERSECT is case sensitive.
3703 (deftransform two-arg-char-equal ((x y) * *)
3704 (cond
3705 ((same-leaf-ref-p x y) t)
3706 (t (give-up-ir1-transform))))
3708 ;;; This is similar to SIMPLE-EQUALITY-TRANSFORM, except that we also
3709 ;;; try to convert to a type-specific predicate or EQ:
3710 ;;; -- If both args are characters, convert to CHAR=. This is better than
3711 ;;; just converting to EQ, since CHAR= may have special compilation
3712 ;;; strategies for non-standard representations, etc.
3713 ;;; -- If either arg is definitely a fixnum, we check to see if X is
3714 ;;; constant and if so, put X second. Doing this results in better
3715 ;;; code from the backend, since the backend assumes that any constant
3716 ;;; argument comes second.
3717 ;;; -- If either arg is definitely not a number or a fixnum, then we
3718 ;;; can compare with EQ.
3719 ;;; -- Otherwise, we try to put the arg we know more about second. If X
3720 ;;; is constant then we put it second. If X is a subtype of Y, we put
3721 ;;; it second. These rules make it easier for the back end to match
3722 ;;; these interesting cases.
3723 (deftransform eql ((x y) * * :node node)
3724 "convert to simpler equality predicate"
3725 (let ((x-type (lvar-type x))
3726 (y-type (lvar-type y))
3727 #!+integer-eql-vop (int-type (specifier-type 'integer))
3728 (char-type (specifier-type 'character)))
3729 (cond
3730 ((same-leaf-ref-p x y) t)
3731 ((not (types-equal-or-intersect x-type y-type))
3732 nil)
3733 ((and (csubtypep x-type char-type)
3734 (csubtypep y-type char-type))
3735 '(char= x y))
3736 ((or (eq-comparable-type-p x-type) (eq-comparable-type-p y-type))
3737 '(eq y x))
3738 #!+integer-eql-vop
3739 ((or (csubtypep x-type int-type) (csubtypep y-type int-type))
3740 '(%eql/integer x y))
3742 (give-up-ir1-transform)))))
3744 (defun array-type-dimensions-mismatch (x-type y-type)
3745 (let ((array-type (specifier-type 'array))
3746 (simple-array-type (specifier-type 'simple-array)))
3747 (and (csubtypep x-type array-type)
3748 (csubtypep y-type array-type)
3749 (let ((x-dims (ctype-array-dimensions x-type))
3750 (y-dims (ctype-array-dimensions y-type)))
3751 (and (consp x-dims)
3752 (consp y-dims)
3753 (or (/= (length x-dims)
3754 (length y-dims))
3755 ;; Can compare dimensions only for simple
3756 ;; arrays due to fill-pointer and
3757 ;; adjust-array.
3758 (and (csubtypep x-type simple-array-type)
3759 (csubtypep y-type simple-array-type)
3760 (loop for x-dim in x-dims
3761 for y-dim in y-dims
3762 thereis (and (integerp x-dim)
3763 (integerp y-dim)
3764 (not (= x-dim y-dim)))))))))))
3766 ;;; Only a simple array will always remain non-empty
3767 (defun array-type-non-empty-p (type)
3768 (and (csubtypep type (specifier-type 'simple-array))
3769 (let ((dimensions (ctype-array-dimensions type)))
3770 (and (consp dimensions)
3771 (every (lambda (dim)
3772 (typep dim '(integer 1)))
3773 dimensions)))))
3775 ;;; similarly to the EQL transform above, we attempt to constant-fold
3776 ;;; or convert to a simpler predicate: mostly we have to be careful
3777 ;;; with strings and bit-vectors.
3778 (deftransform equal ((x y) * *)
3779 "convert to simpler equality predicate"
3780 (let ((x-type (lvar-type x))
3781 (y-type (lvar-type y))
3782 (combination-type (specifier-type '(or bit-vector string
3783 cons pathname))))
3784 (flet ((both-csubtypep (type)
3785 (let ((ctype (specifier-type type)))
3786 (and (csubtypep x-type ctype)
3787 (csubtypep y-type ctype))))
3788 (some-csubtypep (type)
3789 (let ((ctype (specifier-type type)))
3790 (or (csubtypep x-type ctype)
3791 (csubtypep y-type ctype))))
3792 (some-csubtypep2 (type1 type2)
3793 (let ((ctype1 (specifier-type type1))
3794 (ctype2 (specifier-type type2)))
3795 (or (and (csubtypep x-type ctype1)
3796 (csubtypep y-type ctype2))
3797 (and (csubtypep y-type ctype1)
3798 (csubtypep x-type ctype2)))))
3799 (non-equal-array-p (type)
3800 (and (csubtypep type (specifier-type 'array))
3801 (let ((equal-types (specifier-type '(or bit character)))
3802 (element-types (ctype-array-specialized-element-types type)))
3803 (and (neq element-types *wild-type*)
3804 (notany (lambda (x)
3805 (csubtypep x equal-types))
3806 element-types))))))
3807 (cond
3808 ((same-leaf-ref-p x y) t)
3809 ((array-type-dimensions-mismatch x-type y-type)
3810 nil)
3811 ((and (constant-lvar-p x)
3812 (equal (lvar-value x) ""))
3813 `(and (stringp y)
3814 (zerop (length y))))
3815 ((and (constant-lvar-p y)
3816 (equal (lvar-value y) ""))
3817 `(and (stringp x)
3818 (zerop (length x))))
3819 ((or (some-csubtypep 'symbol)
3820 (some-csubtypep 'character))
3821 `(eq x y))
3822 ((both-csubtypep 'string)
3823 '(string= x y))
3824 ((both-csubtypep 'bit-vector)
3825 '(bit-vector-= x y))
3826 ((both-csubtypep 'pathname)
3827 '(pathname= x y))
3828 ((or (non-equal-array-p x-type)
3829 (non-equal-array-p y-type))
3830 '(eq x y))
3831 ((types-equal-or-intersect x-type y-type)
3832 (cond ((some-csubtypep 'number)
3833 '(eql x y))
3834 ((some-csubtypep '(and array (not vector)))
3835 '(eq x y))
3836 ((both-csubtypep 'simple-array)
3837 ;; Can only work on simple arrays due to fill-pointer
3838 (let ((x-dim (ctype-array-dimensions x-type))
3839 (y-dim (ctype-array-dimensions x-type)))
3840 (if (and (consp x-dim)
3841 (consp y-dim)
3842 (integerp (car x-dim))
3843 (integerp (car y-dim))
3844 (not (equal x-dim y-dim)))
3846 (give-up-ir1-transform))))
3847 ((or (types-equal-or-intersect x-type combination-type)
3848 (types-equal-or-intersect y-type combination-type))
3849 (give-up-ir1-transform))
3851 '(eql x y))))
3852 ((some-csubtypep2 '(and array (not vector))
3853 'vector)
3854 nil)
3855 (t (give-up-ir1-transform))))))
3857 (deftransform equalp ((x y) * *)
3858 "convert to simpler equality predicate"
3859 (let ((x-type (lvar-type x))
3860 (y-type (lvar-type y))
3861 (combination-type (specifier-type '(or number array
3862 character
3863 cons pathname
3864 instance hash-table))))
3865 (flet ((both-csubtypep (type)
3866 (let ((ctype (specifier-type type)))
3867 (and (csubtypep x-type ctype)
3868 (csubtypep y-type ctype))))
3869 (some-csubtypep (type)
3870 (let ((ctype (specifier-type type)))
3871 (or (csubtypep x-type ctype)
3872 (csubtypep y-type ctype))))
3873 (transform-char-equal (x y)
3874 (and (constant-lvar-p y)
3875 (characterp (lvar-value y))
3876 (transform-constant-char-equal x y 'eq))))
3877 (cond
3878 ((same-leaf-ref-p x y) t)
3879 ((array-type-dimensions-mismatch x-type y-type)
3880 nil)
3881 ((and (constant-lvar-p x)
3882 (typep (lvar-value x) '(simple-array * (0))))
3883 `(and (vectorp y)
3884 (zerop (length y))))
3885 ((and (constant-lvar-p y)
3886 (typep (lvar-value y) '(simple-array * (0))))
3887 `(and (vectorp x)
3888 (zerop (length x))))
3889 ((some-csubtypep 'symbol)
3890 `(eq x y))
3891 ((transform-char-equal 'x y))
3892 ((transform-char-equal 'y x))
3893 ((both-csubtypep 'string)
3894 '(string-equal x y))
3895 ((both-csubtypep 'bit-vector)
3896 '(bit-vector-= x y))
3897 ((both-csubtypep 'pathname)
3898 '(pathname= x y))
3899 ((both-csubtypep 'character)
3900 '(two-arg-char-equal x y))
3901 ((both-csubtypep 'number)
3902 '(= x y))
3903 ((both-csubtypep 'hash-table)
3904 '(hash-table-equalp x y))
3905 ((and (both-csubtypep 'array)
3906 ;; At least one array has to be longer than 0
3907 ;; and not adjustable, because #() and "" are equal.
3908 (or (array-type-non-empty-p x-type)
3909 (array-type-non-empty-p y-type))
3910 (flet ((upgraded-et (type)
3911 (multiple-value-bind (specialized supetype)
3912 (array-type-upgraded-element-type type)
3913 (or supetype specialized))))
3914 (let ((number-ctype (specifier-type 'number))
3915 (x-et (upgraded-et x-type))
3916 (y-et (upgraded-et y-type)))
3917 (and (neq x-et *wild-type*)
3918 (neq y-et *wild-type*)
3919 (cond ((types-equal-or-intersect x-et y-et)
3920 nil)
3921 ((csubtypep x-et number-ctype)
3922 (not (types-equal-or-intersect y-et number-ctype)))
3923 ((types-equal-or-intersect y-et number-ctype)
3924 (not (types-equal-or-intersect x-et number-ctype))))))))
3925 nil)
3926 ((types-equal-or-intersect x-type y-type)
3927 (if (or (types-equal-or-intersect x-type combination-type)
3928 (types-equal-or-intersect y-type combination-type))
3929 (give-up-ir1-transform)
3930 '(eq x y)))
3931 (t (give-up-ir1-transform))))))
3933 ;;; Convert to EQL if both args are rational and complexp is specified
3934 ;;; and the same for both.
3935 (deftransform = ((x y) (number number) *)
3936 "open code"
3937 (let ((x-type (lvar-type x))
3938 (y-type (lvar-type y)))
3939 (cond ((or (and (csubtypep x-type (specifier-type 'float))
3940 (csubtypep y-type (specifier-type 'float)))
3941 (and (csubtypep x-type (specifier-type '(complex float)))
3942 (csubtypep y-type (specifier-type '(complex float))))
3943 #!+complex-float-vops
3944 (and (csubtypep x-type (specifier-type '(or single-float (complex single-float))))
3945 (csubtypep y-type (specifier-type '(or single-float (complex single-float)))))
3946 #!+complex-float-vops
3947 (and (csubtypep x-type (specifier-type '(or double-float (complex double-float))))
3948 (csubtypep y-type (specifier-type '(or double-float (complex double-float))))))
3949 ;; They are both floats. Leave as = so that -0.0 is
3950 ;; handled correctly.
3951 (give-up-ir1-transform))
3952 ((or (and (csubtypep x-type (specifier-type 'rational))
3953 (csubtypep y-type (specifier-type 'rational)))
3954 (and (csubtypep x-type
3955 (specifier-type '(complex rational)))
3956 (csubtypep y-type
3957 (specifier-type '(complex rational)))))
3958 ;; They are both rationals and complexp is the same.
3959 ;; Convert to EQL.
3960 '(eql x y))
3961 ((or (and (csubtypep x-type (specifier-type 'real))
3962 (csubtypep y-type
3963 (specifier-type '(complex rational))))
3964 (and (csubtypep y-type (specifier-type 'real))
3965 (csubtypep x-type
3966 (specifier-type '(complex rational)))))
3967 ;; Can't be EQL since imagpart can't be 0.
3968 nil)
3970 (give-up-ir1-transform
3971 "The operands might not be the same type.")))))
3973 (defun maybe-float-lvar-p (lvar)
3974 (neq *empty-type* (type-intersection (specifier-type 'float)
3975 (lvar-type lvar))))
3977 (flet ((maybe-invert (node op inverted x y)
3978 (cond
3979 #!+(or x86-64 arm64) ;; have >=/<= VOPs
3980 ((and (csubtypep (lvar-type x) (specifier-type 'float))
3981 (csubtypep (lvar-type y) (specifier-type 'float)))
3982 (give-up-ir1-transform))
3983 ;; Don't invert if either argument can be a float (NaNs)
3984 ((or (maybe-float-lvar-p x) (maybe-float-lvar-p y))
3985 (delay-ir1-transform node :constraint)
3986 `(or (,op x y) (= x y)))
3988 `(if (,inverted x y) nil t)))))
3989 (deftransform >= ((x y) (number number) * :node node)
3990 "invert or open code"
3991 (maybe-invert node '> '< x y))
3992 (deftransform <= ((x y) (number number) * :node node)
3993 "invert or open code"
3994 (maybe-invert node '< '> x y)))
3996 ;;; See whether we can statically determine (< X Y) using type
3997 ;;; information. If X's high bound is < Y's low, then X < Y.
3998 ;;; Similarly, if X's low is >= to Y's high, the X >= Y (so return
3999 ;;; NIL). If not, at least make sure any constant arg is second.
4000 (macrolet ((def (name inverse reflexive-p surely-true surely-false)
4001 `(deftransform ,name ((x y))
4002 "optimize using intervals"
4003 (if (and (same-leaf-ref-p x y)
4004 ;; For non-reflexive functions we don't need
4005 ;; to worry about NaNs: (non-ref-op NaN NaN) => false,
4006 ;; but with reflexive ones we don't know...
4007 ,@(when reflexive-p
4008 '((and (not (maybe-float-lvar-p x))
4009 (not (maybe-float-lvar-p y))))))
4010 ,reflexive-p
4011 (let ((ix (or (type-approximate-interval (lvar-type x))
4012 (give-up-ir1-transform)))
4013 (iy (or (type-approximate-interval (lvar-type y))
4014 (give-up-ir1-transform))))
4015 (cond (,surely-true
4017 (,surely-false
4018 nil)
4019 ((and (constant-lvar-p x)
4020 (not (constant-lvar-p y)))
4021 `(,',inverse y x))
4023 (give-up-ir1-transform))))))))
4024 (def = = t (interval-= ix iy) (interval-/= ix iy))
4025 (def /= /= nil (interval-/= ix iy) (interval-= ix iy))
4026 (def < > nil (interval-< ix iy) (interval->= ix iy))
4027 (def > < nil (interval-< iy ix) (interval->= iy ix))
4028 (def <= >= t (interval->= iy ix) (interval-< iy ix))
4029 (def >= <= t (interval->= ix iy) (interval-< ix iy)))
4031 (defun ir1-transform-char< (x y first second inverse)
4032 (cond
4033 ((same-leaf-ref-p x y) nil)
4034 ;; If we had interval representation of character types, as we
4035 ;; might eventually have to to support 2^21 characters, then here
4036 ;; we could do some compile-time computation as in transforms for
4037 ;; < above. -- CSR, 2003-07-01
4038 ((and (constant-lvar-p first)
4039 (not (constant-lvar-p second)))
4040 `(,inverse y x))
4041 (t (give-up-ir1-transform))))
4043 (deftransform char< ((x y) (character character) *)
4044 (ir1-transform-char< x y x y 'char>))
4046 (deftransform char> ((x y) (character character) *)
4047 (ir1-transform-char< y x x y 'char<))
4049 ;;;; converting N-arg comparisons
4050 ;;;;
4051 ;;;; We convert calls to N-arg comparison functions such as < into
4052 ;;;; two-arg calls. This transformation is enabled for all such
4053 ;;;; comparisons in this file. If any of these predicates are not
4054 ;;;; open-coded, then the transformation should be removed at some
4055 ;;;; point to avoid pessimization.
4057 ;;; This function is used for source transformation of N-arg
4058 ;;; comparison functions other than inequality. We deal both with
4059 ;;; converting to two-arg calls and inverting the sense of the test,
4060 ;;; if necessary. If the call has two args, then we pass or return a
4061 ;;; negated test as appropriate. If it is a degenerate one-arg call,
4062 ;;; then we transform to code that returns true. Otherwise, we bind
4063 ;;; all the arguments and expand into a bunch of IFs.
4064 (defun multi-compare (predicate args not-p type &optional force-two-arg-p)
4065 (let ((nargs (length args)))
4066 (cond ((< nargs 1) (values nil t))
4067 ((= nargs 1) `(progn (the ,type ,@args) t))
4068 ((= nargs 2)
4069 (if not-p
4070 `(if (,predicate ,(first args) ,(second args)) nil t)
4071 (if force-two-arg-p
4072 `(,predicate ,(first args) ,(second args))
4073 (values nil t))))
4075 (do* ((i (1- nargs) (1- i))
4076 (last nil current)
4077 (current (gensym) (gensym))
4078 (vars (list current) (cons current vars))
4079 (result t (if not-p
4080 `(if (,predicate ,current ,last)
4081 nil ,result)
4082 `(if (,predicate ,current ,last)
4083 ,result nil))))
4084 ((zerop i)
4085 `((lambda ,vars (declare (type ,type ,@vars)) ,result)
4086 ,@args)))))))
4088 (define-source-transform = (&rest args) (multi-compare '= args nil 'number))
4089 (define-source-transform < (&rest args) (multi-compare '< args nil 'real))
4090 (define-source-transform > (&rest args) (multi-compare '> args nil 'real))
4091 ;;; We cannot do the inversion for >= and <= here, since both
4092 ;;; (< NaN X) and (> NaN X)
4093 ;;; are false, and we don't have type-information available yet. The
4094 ;;; deftransforms for two-argument versions of >= and <= takes care of
4095 ;;; the inversion to > and < when possible.
4096 (define-source-transform <= (&rest args) (multi-compare '<= args nil 'real))
4097 (define-source-transform >= (&rest args) (multi-compare '>= args nil 'real))
4099 (define-source-transform char= (&rest args) (multi-compare 'char= args nil
4100 'character))
4101 (define-source-transform char< (&rest args) (multi-compare 'char< args nil
4102 'character))
4103 (define-source-transform char> (&rest args) (multi-compare 'char> args nil
4104 'character))
4105 (define-source-transform char<= (&rest args) (multi-compare 'char> args t
4106 'character))
4107 (define-source-transform char>= (&rest args) (multi-compare 'char< args t
4108 'character))
4110 (define-source-transform char-equal (&rest args)
4111 (multi-compare 'two-arg-char-equal args nil 'character t))
4112 (define-source-transform char-lessp (&rest args)
4113 (multi-compare 'two-arg-char-lessp args nil 'character t))
4114 (define-source-transform char-greaterp (&rest args)
4115 (multi-compare 'two-arg-char-greaterp args nil 'character t))
4116 (define-source-transform char-not-greaterp (&rest args)
4117 (multi-compare 'two-arg-char-greaterp args t 'character t))
4118 (define-source-transform char-not-lessp (&rest args)
4119 (multi-compare 'two-arg-char-lessp args t 'character t))
4121 ;;; This function does source transformation of N-arg inequality
4122 ;;; functions such as /=. This is similar to MULTI-COMPARE in the <3
4123 ;;; arg cases. If there are more than two args, then we expand into
4124 ;;; the appropriate n^2 comparisons only when speed is important.
4125 (declaim (ftype (function (symbol list t) *) multi-not-equal))
4126 (defun multi-not-equal (predicate args type)
4127 (let ((nargs (length args)))
4128 (cond ((< nargs 1) (values nil t))
4129 ((= nargs 1) `(progn (the ,type ,@args) t))
4130 ((= nargs 2)
4131 `(if (,predicate ,(first args) ,(second args)) nil t))
4132 ((not (policy *lexenv*
4133 (and (>= speed space)
4134 (>= speed compilation-speed))))
4135 (values nil t))
4137 (let ((vars (make-gensym-list nargs)))
4138 (do ((var vars next)
4139 (next (cdr vars) (cdr next))
4140 (result t))
4141 ((null next)
4142 `((lambda ,vars (declare (type ,type ,@vars)) ,result)
4143 ,@args))
4144 (let ((v1 (first var)))
4145 (dolist (v2 next)
4146 (setq result `(if (,predicate ,v1 ,v2) nil ,result))))))))))
4148 (define-source-transform /= (&rest args)
4149 (multi-not-equal '= args 'number))
4150 (define-source-transform char/= (&rest args)
4151 (multi-not-equal 'char= args 'character))
4152 (define-source-transform char-not-equal (&rest args)
4153 (multi-not-equal 'char-equal args 'character))
4155 ;;; Expand MAX and MIN into the obvious comparisons.
4156 (define-source-transform max (arg0 &rest rest)
4157 (once-only ((arg0 arg0))
4158 (if (null rest)
4159 `(values (the real ,arg0))
4160 `(let ((maxrest (max ,@rest)))
4161 (if (>= ,arg0 maxrest) ,arg0 maxrest)))))
4162 (define-source-transform min (arg0 &rest rest)
4163 (once-only ((arg0 arg0))
4164 (if (null rest)
4165 `(values (the real ,arg0))
4166 `(let ((minrest (min ,@rest)))
4167 (if (<= ,arg0 minrest) ,arg0 minrest)))))
4169 ;;; Simplify some cross-type comparisons
4170 (macrolet ((def (comparator round)
4171 `(progn
4172 (deftransform ,comparator
4173 ((x y) (rational (constant-arg float)))
4174 "open-code RATIONAL to FLOAT comparison"
4175 (let ((y (lvar-value y)))
4176 #-sb-xc-host
4177 (when (or (float-nan-p y)
4178 (float-infinity-p y))
4179 (give-up-ir1-transform))
4180 (setf y (rational y))
4181 `(,',comparator
4182 x ,(if (csubtypep (lvar-type x)
4183 (specifier-type 'integer))
4184 (,round y)
4185 y))))
4186 (deftransform ,comparator
4187 ((x y) (integer (constant-arg ratio)))
4188 "open-code INTEGER to RATIO comparison"
4189 `(,',comparator x ,(,round (lvar-value y)))))))
4190 (def < ceiling)
4191 (def > floor))
4193 (deftransform = ((x y) (rational (constant-arg float)))
4194 "open-code RATIONAL to FLOAT comparison"
4195 (let ((y (lvar-value y)))
4196 #-sb-xc-host
4197 (when (or (float-nan-p y)
4198 (float-infinity-p y))
4199 (give-up-ir1-transform))
4200 (setf y (rational y))
4201 (if (and (csubtypep (lvar-type x)
4202 (specifier-type 'integer))
4203 (ratiop y))
4205 `(= x ,y))))
4207 (deftransform = ((x y) (integer (constant-arg ratio)))
4208 "constant-fold INTEGER to RATIO comparison"
4209 nil)
4211 ;;;; converting N-arg arithmetic functions
4212 ;;;;
4213 ;;;; N-arg arithmetic and logic functions are associated into two-arg
4214 ;;;; versions, and degenerate cases are flushed.
4216 ;;; Left-associate FIRST-ARG and MORE-ARGS using FUNCTION.
4217 (declaim (ftype (sfunction (symbol t list) list) associate-args))
4218 (defun associate-args (fun first-arg more-args)
4219 (aver more-args)
4220 (let ((next (rest more-args))
4221 (arg (first more-args)))
4222 (if (null next)
4223 `(,fun ,first-arg ,arg)
4224 (associate-args fun `(,fun ,first-arg ,arg) next))))
4226 ;;; Reduce constants in ARGS list.
4227 (declaim (ftype (sfunction (symbol list symbol) list) reduce-constants))
4228 (defun reduce-constants (fun args one-arg-result-type)
4229 (let ((one-arg-constant-p (ecase one-arg-result-type
4230 (number #'numberp)
4231 (integer #'integerp)))
4232 (reduced-value)
4233 (reduced-p nil))
4234 (collect ((not-constants))
4235 (dolist (arg args)
4236 (let ((value (if (constantp arg)
4237 (constant-form-value arg)
4238 arg)))
4239 (cond ((not (funcall one-arg-constant-p value))
4240 (not-constants arg))
4241 (reduced-value
4242 (handler-case (funcall fun reduced-value value)
4243 (arithmetic-error ()
4244 (not-constants arg))
4245 (:no-error (value)
4246 ;; Some backends have no float traps
4247 (cond #!+(and (or arm arm64)
4248 (not (host-feature sb-xc-host)))
4249 ((or (and (floatp value)
4250 (or (float-infinity-p value)
4251 (float-nan-p value)))
4252 (and (complex-float-p value)
4253 (or (float-infinity-p (imagpart value))
4254 (float-nan-p (imagpart value))
4255 (float-infinity-p (realpart value))
4256 (float-nan-p (realpart value)))))
4257 (not-constants arg))
4259 (setf reduced-value value
4260 reduced-p t))))))
4262 (setf reduced-value value)))))
4263 ;; It is tempting to drop constants reduced to identity here,
4264 ;; but if X is SNaN in (* X 1), we cannot drop the 1.
4265 (if (not-constants)
4266 (if reduced-p
4267 `(,reduced-value ,@(not-constants))
4268 args)
4269 `(,reduced-value)))))
4271 ;;; Do source transformations for transitive functions such as +.
4272 ;;; One-arg cases are replaced with the arg and zero arg cases with
4273 ;;; the identity. ONE-ARG-RESULT-TYPE is the type to ensure (with THE)
4274 ;;; that the argument in one-argument calls is.
4275 (declaim (ftype (function (symbol list t &optional symbol list)
4276 * ; KLUDGE: avoid "assertion too complex to check"
4277 #|(values t &optional (member nil t))|#)
4278 source-transform-transitive))
4279 (defun source-transform-transitive (fun args identity
4280 &optional (one-arg-result-type 'number)
4281 (one-arg-prefixes '(values)))
4282 (case (length args)
4283 (0 identity)
4284 (1 `(,@one-arg-prefixes (the ,one-arg-result-type ,(first args))))
4285 (2 (values nil t))
4287 (let* ((reduced-args (reduce-constants fun args one-arg-result-type))
4288 (first (first reduced-args))
4289 (rest (rest reduced-args)))
4290 (if rest
4291 (associate-args fun first rest)
4292 first)))))
4294 (define-source-transform + (&rest args)
4295 (source-transform-transitive '+ args 0))
4296 (define-source-transform * (&rest args)
4297 (source-transform-transitive '* args 1))
4298 (define-source-transform logior (&rest args)
4299 (source-transform-transitive 'logior args 0 'integer))
4300 (define-source-transform logxor (&rest args)
4301 (source-transform-transitive 'logxor args 0 'integer))
4302 (define-source-transform logand (&rest args)
4303 (source-transform-transitive 'logand args -1 'integer))
4304 (define-source-transform logeqv (&rest args)
4305 (source-transform-transitive 'logeqv args -1 'integer))
4306 (define-source-transform gcd (&rest args)
4307 (source-transform-transitive 'gcd args 0 'integer '(abs)))
4308 (define-source-transform lcm (&rest args)
4309 (source-transform-transitive 'lcm args 1 'integer '(abs)))
4311 ;;; Do source transformations for intransitive n-arg functions such as
4312 ;;; /. With one arg, we form the inverse. With two args we pass.
4313 ;;; Otherwise we associate into two-arg calls.
4314 (declaim (ftype (function (symbol symbol list list &optional symbol)
4315 * ; KLUDGE: avoid "assertion too complex to check"
4316 #|(values list &optional (member nil t))|#)
4317 source-transform-intransitive))
4318 (defun source-transform-intransitive (fun fun* args one-arg-prefixes
4319 &optional (one-arg-result-type 'number))
4320 (case (length args)
4321 ((0 2) (values nil t))
4322 (1 `(,@one-arg-prefixes (the ,one-arg-result-type ,(first args))))
4324 (let ((reduced-args
4325 (reduce-constants fun* (rest args) one-arg-result-type)))
4326 (associate-args fun (first args) reduced-args)))))
4328 (define-source-transform - (&rest args)
4329 (source-transform-intransitive '- '+ args '(%negate)))
4330 (define-source-transform / (&rest args)
4331 (source-transform-intransitive '/ '* args '(/ 1)))
4333 ;;;; transforming APPLY
4335 ;;; We convert APPLY into MULTIPLE-VALUE-CALL so that the compiler
4336 ;;; only needs to understand one kind of variable-argument call. It is
4337 ;;; more efficient to convert APPLY to MV-CALL than MV-CALL to APPLY.
4338 (define-source-transform apply (fun arg &rest more-args)
4339 (let ((args (cons arg more-args)))
4340 `(multiple-value-call ,fun
4341 ,@(mapcar (lambda (x) `(values ,x)) (butlast args))
4342 (values-list ,(car (last args))))))
4344 ;;;; transforming references to &REST argument
4346 ;;; We add magical &MORE arguments to all functions with &REST. If ARG names
4347 ;;; the &REST argument, this returns the lambda-vars for the context and
4348 ;;; count.
4349 (defun possible-rest-arg-context (arg)
4350 (when (symbolp arg)
4351 (let* ((var (lexenv-find arg vars))
4352 (info (when (lambda-var-p var)
4353 (lambda-var-arg-info var))))
4354 (when (and info
4355 (eq :rest (arg-info-kind info))
4356 (consp (arg-info-default info)))
4357 (values-list (arg-info-default info))))))
4359 (defun mark-more-context-used (rest-var)
4360 (let ((info (lambda-var-arg-info rest-var)))
4361 (aver (eq :rest (arg-info-kind info)))
4362 (destructuring-bind (context count &optional used) (arg-info-default info)
4363 (unless used
4364 (setf (arg-info-default info) (list context count t))))))
4366 (defun mark-more-context-invalid (rest-var)
4367 (let ((info (lambda-var-arg-info rest-var)))
4368 (aver (eq :rest (arg-info-kind info)))
4369 (setf (arg-info-default info) t)))
4371 ;;; This determines if the REF to a &REST variable is headed towards
4372 ;;; parts unknown, or if we can really use the context.
4373 (defun rest-var-more-context-ok (lvar)
4374 (let* ((use (lvar-use lvar))
4375 (var (when (ref-p use) (ref-leaf use)))
4376 (home (when (lambda-var-p var) (lambda-var-home var)))
4377 (info (when (lambda-var-p var) (lambda-var-arg-info var)))
4378 (restp (when info (eq :rest (arg-info-kind info)))))
4379 (flet ((ref-good-for-more-context-p (ref)
4380 (when (not (node-lvar ref)) ; ref that goes nowhere is ok
4381 (return-from ref-good-for-more-context-p t))
4382 (let ((dest (principal-lvar-end (node-lvar ref))))
4383 (and (combination-p dest)
4384 ;; If the destination is to anything but these, we're going to
4385 ;; actually need the rest list -- and since other operations
4386 ;; might modify the list destructively, the using the context
4387 ;; isn't good anywhere else either.
4388 (lvar-fun-is (combination-fun dest)
4389 '(%rest-values %rest-ref %rest-length
4390 %rest-null %rest-true))
4391 ;; If the home lambda is different and isn't DX, it might
4392 ;; escape -- in which case using the more context isn't safe.
4393 (let ((clambda (node-home-lambda dest)))
4394 (or (eq home clambda)
4395 (leaf-dynamic-extent clambda)))))))
4396 (let ((ok (and restp
4397 (consp (arg-info-default info))
4398 (not (lambda-var-specvar var))
4399 (not (lambda-var-sets var))
4400 (every #'ref-good-for-more-context-p (lambda-var-refs var)))))
4401 (if ok
4402 (mark-more-context-used var)
4403 (when restp
4404 (mark-more-context-invalid var)))
4405 ok))))
4407 ;;; VALUES-LIST -> %REST-VALUES
4408 (define-source-transform values-list (list)
4409 (multiple-value-bind (context count) (possible-rest-arg-context list)
4410 (if context
4411 `(%rest-values ,list ,context ,count)
4412 (values nil t))))
4414 ;;; NTH -> %REST-REF
4415 (define-source-transform nth (n list)
4416 (multiple-value-bind (context count) (possible-rest-arg-context list)
4417 (if context
4418 `(%rest-ref ,n ,list ,context ,count)
4419 `(car (nthcdr ,n ,list)))))
4420 (define-source-transform fast-&rest-nth (n list)
4421 (multiple-value-bind (context count) (possible-rest-arg-context list)
4422 (if context
4423 `(%rest-ref ,n ,list ,context ,count t)
4424 (bug "no &REST context for FAST-REST-NTH"))))
4426 (define-source-transform elt (seq n)
4427 (if (policy *lexenv* (= safety 3))
4428 (values nil t)
4429 (multiple-value-bind (context count) (possible-rest-arg-context seq)
4430 (if context
4431 `(%rest-ref ,n ,seq ,context ,count)
4432 (values nil t)))))
4434 ;;; CAxR -> %REST-REF
4435 (defun source-transform-car (list nth)
4436 (multiple-value-bind (context count) (possible-rest-arg-context list)
4437 (if context
4438 `(%rest-ref ,nth ,list ,context ,count)
4439 (values nil t))))
4441 (define-source-transform car (list)
4442 (source-transform-car list 0))
4444 (define-source-transform cadr (list)
4445 (or (source-transform-car list 1)
4446 `(car (cdr ,list))))
4448 (define-source-transform caddr (list)
4449 (or (source-transform-car list 2)
4450 `(car (cdr (cdr ,list)))))
4452 (define-source-transform cadddr (list)
4453 (or (source-transform-car list 3)
4454 `(car (cdr (cdr (cdr ,list))))))
4456 ;;; LENGTH -> %REST-LENGTH
4457 (defun source-transform-length (list)
4458 (multiple-value-bind (context count) (possible-rest-arg-context list)
4459 (if context
4460 `(%rest-length ,list ,context ,count)
4461 (values nil t))))
4462 (define-source-transform length (list) (source-transform-length list))
4463 (define-source-transform list-length (list) (source-transform-length list))
4465 ;;; ENDP, NULL and NOT -> %REST-NULL
4467 ;;; Outside &REST convert into an IF so that IF optimizations will eliminate
4468 ;;; redundant negations.
4469 (defun source-transform-null (x op)
4470 (multiple-value-bind (context count) (possible-rest-arg-context x)
4471 (cond (context
4472 `(%rest-null ',op ,x ,context ,count))
4473 ((eq 'endp op)
4474 `(if (the list ,x) nil t))
4476 `(if ,x nil t)))))
4477 (define-source-transform not (x) (source-transform-null x 'not))
4478 (define-source-transform null (x) (source-transform-null x 'null))
4479 (define-source-transform endp (x) (source-transform-null x 'endp))
4481 (deftransform %rest-values ((list context count))
4482 (if (rest-var-more-context-ok list)
4483 `(%more-arg-values context 0 count)
4484 `(values-list list)))
4486 (deftransform %rest-ref ((n list context count &optional length-checked-p))
4487 (cond ((not (rest-var-more-context-ok list))
4488 `(nth n list))
4489 ((and (constant-lvar-p length-checked-p)
4490 (lvar-value length-checked-p))
4491 `(%more-arg context n))
4493 `(and (< (the index n) count) (%more-arg context n)))))
4495 (deftransform %rest-length ((list context count))
4496 (if (rest-var-more-context-ok list)
4497 'count
4498 `(length list)))
4500 (deftransform %rest-null ((op list context count))
4501 (aver (constant-lvar-p op))
4502 (if (rest-var-more-context-ok list)
4503 `(eql 0 count)
4504 `(,(lvar-value op) list)))
4506 (deftransform %rest-true ((list context count))
4507 (if (rest-var-more-context-ok list)
4508 `(not (eql 0 count))
4509 `list))
4511 ;;;; transforming FORMAT
4512 ;;;;
4513 ;;;; If the control string is a compile-time constant, then replace it
4514 ;;;; with a use of the FORMATTER macro so that the control string is
4515 ;;;; ``compiled.'' Furthermore, if the destination is either a stream
4516 ;;;; or T and the control string is a function (i.e. FORMATTER), then
4517 ;;;; convert the call to FORMAT to just a FUNCALL of that function.
4519 ;;; for compile-time argument count checking.
4521 ;;; FIXME II: In some cases, type information could be correlated; for
4522 ;;; instance, ~{ ... ~} requires a list argument, so if the lvar-type
4523 ;;; of a corresponding argument is known and does not intersect the
4524 ;;; list type, a warning could be signalled.
4525 (defun check-format-args (string args fun)
4526 (declare (type string string))
4527 (multiple-value-bind (min max)
4528 (handler-case (sb!format:%compiler-walk-format-string string args)
4529 (sb!format:format-error (c)
4530 (compiler-warn "~A" c)))
4531 (when min
4532 (let ((nargs (length args)))
4533 (cond
4534 ((< nargs min)
4535 (warn 'format-too-few-args-warning
4536 :format-control
4537 "Too few arguments (~D) to ~S ~S: requires at least ~D."
4538 :format-arguments (list nargs fun string min)))
4539 ((> nargs max)
4540 (warn 'format-too-many-args-warning
4541 :format-control
4542 "Too many arguments (~D) to ~S ~S: uses at most ~D."
4543 :format-arguments (list nargs fun string max))))))))
4545 (defoptimizer (format optimizer) ((dest control &rest args) node)
4546 (declare (ignore dest))
4547 (when (constant-lvar-p control)
4548 (let ((x (lvar-value control)))
4549 (when (stringp x)
4550 (let ((*compiler-error-context* node))
4551 (check-format-args x args 'format))))))
4553 (defoptimizer (format derive-type) ((dest control &rest args))
4554 (declare (ignore control args))
4555 (when (and (constant-lvar-p dest)
4556 (null (lvar-value dest)))
4557 (specifier-type 'simple-string)))
4559 ;;; We disable this transform in the cross-compiler to save memory in
4560 ;;; the target image; most of the uses of FORMAT in the compiler are for
4561 ;;; error messages, and those don't need to be particularly fast.
4562 #+sb-xc
4563 (deftransform format ((dest control &rest args) (t simple-string &rest t) *
4564 :policy (>= speed space))
4565 (unless (constant-lvar-p control)
4566 (give-up-ir1-transform "The control string is not a constant."))
4567 (let* ((argc (length args))
4568 (arg-names (make-gensym-list argc))
4569 (control (lvar-value control))
4570 ;; Expanding the control string now avoids deferring to FORMATTER
4571 ;; so that we don't need an internal-only variant of it that
4572 ;; passes through extra args to %FORMATTER.
4573 ;; FIXME: instead of checking the condition report, define a
4574 ;; dedicated condition class
4575 (expr (handler-case ; in case %formatter wants to signal an error
4576 (sb!format::%formatter control argc nil)
4577 ;; otherwise, let the macro complain
4578 (sb!format:format-error (c)
4579 (if (string= (sb!format::format-error-complaint c)
4580 "No package named ~S")
4581 ;; "~/apackage:afun/" might become legal later.
4582 ;; To put it in perspective, "~/f" (no closing slash)
4583 ;; *will* be a runtime error, but this only *might* be
4584 ;; a runtime error, so we can't signal a full warning.
4585 ;; At absolute worst it should be a style-warning.
4586 (give-up-ir1-transform "~~// directive mentions unknown package")
4587 `(formatter ,control))))))
4588 `(lambda (dest control ,@arg-names)
4589 (declare (ignore control))
4590 (format dest ,expr ,@arg-names))))
4592 (deftransform format ((stream control &rest args) (stream function &rest t))
4593 (let ((arg-names (make-gensym-list (length args))))
4594 `(lambda (stream control ,@arg-names)
4595 (funcall control stream ,@arg-names)
4596 nil)))
4598 (deftransform format ((tee control &rest args) ((member t) function &rest t))
4599 (let ((arg-names (make-gensym-list (length args))))
4600 `(lambda (tee control ,@arg-names)
4601 (declare (ignore tee))
4602 (funcall control *standard-output* ,@arg-names)
4603 nil)))
4605 (deftransform format ((stream control &rest args) (null function &rest t))
4606 (let ((arg-names (make-gensym-list (length args))))
4607 `(lambda (stream control ,@arg-names)
4608 (declare (ignore stream))
4609 (with-simple-output-to-string (stream)
4610 (funcall control stream ,@arg-names)))))
4612 (defun concatenate-format-p (control args)
4613 (and
4614 (loop for directive in control
4615 always
4616 (or (stringp directive)
4617 (and (sb!format::format-directive-p directive)
4618 (let ((char (sb!format::format-directive-character directive))
4619 (params (sb!format::format-directive-params directive)))
4621 (and
4622 (char-equal char #\a)
4623 (null params)
4624 (pop args))
4625 (and
4626 (or (eql char #\~)
4627 (eql char #\%))
4628 (null (sb!format::format-directive-colonp directive))
4629 (null (sb!format::format-directive-atsignp directive))
4630 (or (null params)
4631 (typep params
4632 '(cons (cons (eql 1) unsigned-byte) null)))))))))
4633 (null args)))
4635 (deftransform format ((stream control &rest args) (null (constant-arg string) &rest string))
4636 (let ((tokenized
4637 (handler-case
4638 (sb!format::tokenize-control-string (coerce (lvar-value control) 'simple-string))
4639 (sb!format:format-error ()
4640 (give-up-ir1-transform)))))
4641 (unless (concatenate-format-p tokenized args)
4642 (give-up-ir1-transform))
4643 (let ((arg-names (make-gensym-list (length args))))
4644 `(lambda (stream control ,@arg-names)
4645 (declare (ignore stream control)
4646 (ignorable ,@arg-names))
4647 (concatenate
4648 'string
4649 ,@(let ((strings
4650 (loop for directive in tokenized
4651 for char = (and (not (stringp directive))
4652 (sb!format::format-directive-character directive))
4653 when
4654 (cond ((not char)
4655 directive)
4656 ((char-equal char #\a)
4657 (let ((arg (pop args))
4658 (arg-name (pop arg-names)))
4660 (constant-lvar-p arg)
4661 (lvar-value arg)
4662 arg-name)))
4664 (let ((n (or (cdar (sb!format::format-directive-params directive))
4665 1)))
4666 (and (plusp n)
4667 (make-string n
4668 :initial-element
4669 (if (eql char #\%)
4670 #\Newline
4671 char))))))
4672 collect it)))
4673 ;; Join adjacent constant strings
4674 (loop with concat
4675 for (string . rest) on strings
4676 when (stringp string)
4677 do (setf concat
4678 (if concat
4679 (concatenate 'string concat string)
4680 string))
4681 else
4682 when concat collect (shiftf concat nil) end
4683 and collect string
4684 when (and concat (not rest))
4685 collect concat)))))))
4687 (deftransform pathname ((pathspec) (pathname) *)
4688 'pathspec)
4690 (deftransform pathname ((pathspec) (string) *)
4691 '(values (parse-namestring pathspec)))
4693 (macrolet
4694 ((def (name)
4695 `(defoptimizer (,name optimizer) ((control &rest args) node)
4696 (when (constant-lvar-p control)
4697 (let ((x (lvar-value control)))
4698 (when (stringp x)
4699 (let ((*compiler-error-context* node))
4700 (check-format-args x args ',name))))))))
4701 (def error)
4702 (def warn)
4703 #+sb-xc-host ; Only we should be using these
4704 (progn
4705 (def style-warn)
4706 (def compiler-error)
4707 (def compiler-warn)
4708 (def compiler-style-warn)
4709 (def compiler-notify)
4710 (def maybe-compiler-notify)
4711 (def bug)))
4713 (defoptimizer (cerror optimizer) ((report control &rest args))
4714 (when (and (constant-lvar-p control)
4715 (constant-lvar-p report))
4716 (let ((x (lvar-value control))
4717 (y (lvar-value report)))
4718 (when (and (stringp x) (stringp y))
4719 (multiple-value-bind (min1 max1)
4720 (handler-case
4721 (sb!format:%compiler-walk-format-string x args)
4722 (sb!format:format-error (c)
4723 (compiler-warn "~A" c)))
4724 (when min1
4725 (multiple-value-bind (min2 max2)
4726 (handler-case
4727 (sb!format:%compiler-walk-format-string y args)
4728 (sb!format:format-error (c)
4729 (compiler-warn "~A" c)))
4730 (when min2
4731 (let ((nargs (length args)))
4732 (cond
4733 ((< nargs (min min1 min2))
4734 (warn 'format-too-few-args-warning
4735 :format-control
4736 "Too few arguments (~D) to ~S ~S ~S: ~
4737 requires at least ~D."
4738 :format-arguments
4739 (list nargs 'cerror y x (min min1 min2))))
4740 ((> nargs (max max1 max2))
4741 (warn 'format-too-many-args-warning
4742 :format-control
4743 "Too many arguments (~D) to ~S ~S ~S: ~
4744 uses at most ~D."
4745 :format-arguments
4746 (list nargs 'cerror y x (max max1 max2))))))))))))))
4748 (defun constant-cons-type (type)
4749 (multiple-value-bind (singleton value)
4750 (type-singleton-p type)
4751 (if singleton
4752 (values value t)
4753 (typecase type
4754 (cons-type
4755 (multiple-value-bind (car car-good)
4756 (constant-cons-type (cons-type-car-type type))
4757 (multiple-value-bind (cdr cdr-good)
4758 (constant-cons-type (cons-type-cdr-type type))
4759 (and car-good cdr-good
4760 (values (cons car cdr) t)))))))))
4762 (defoptimizer (coerce derive-type) ((value type) node)
4763 (multiple-value-bind (type constant)
4764 (if (constant-lvar-p type)
4765 (values (lvar-value type) t)
4766 (constant-cons-type (lvar-type type)))
4767 (when constant
4768 ;; This branch is essentially (RESULT-TYPE-SPECIFIER-NTH-ARG 2),
4769 ;; but dealing with the niggle that complex canonicalization gets
4770 ;; in the way: (COERCE 1 'COMPLEX) returns 1, which is not of
4771 ;; type COMPLEX.
4772 (let ((result-typeoid (careful-specifier-type type)))
4773 (cond
4774 ((null result-typeoid) nil)
4775 ((csubtypep result-typeoid (specifier-type 'number))
4776 ;; the difficult case: we have to cope with ANSI 12.1.5.3
4777 ;; Rule of Canonical Representation for Complex Rationals,
4778 ;; which is a truly nasty delivery to field.
4779 (cond
4780 ((csubtypep result-typeoid (specifier-type 'real))
4781 ;; cleverness required here: it would be nice to deduce
4782 ;; that something of type (INTEGER 2 3) coerced to type
4783 ;; DOUBLE-FLOAT should return (DOUBLE-FLOAT 2.0d0 3.0d0).
4784 ;; FLOAT gets its own clause because it's implemented as
4785 ;; a UNION-TYPE, so we don't catch it in the NUMERIC-TYPE
4786 ;; logic below.
4787 result-typeoid)
4788 ((and (numeric-type-p result-typeoid)
4789 (eq (numeric-type-complexp result-typeoid) :real))
4790 ;; FIXME: is this clause (a) necessary or (b) useful?
4791 result-typeoid)
4792 ((or (csubtypep result-typeoid
4793 (specifier-type '(complex single-float)))
4794 (csubtypep result-typeoid
4795 (specifier-type '(complex double-float)))
4796 #!+long-float
4797 (csubtypep result-typeoid
4798 (specifier-type '(complex long-float))))
4799 ;; float complex types are never canonicalized.
4800 result-typeoid)
4802 ;; if it's not a REAL, or a COMPLEX FLOAToid, it's
4803 ;; probably just a COMPLEX or equivalent. So, in that
4804 ;; case, we will return a complex or an object of the
4805 ;; provided type if it's rational:
4806 (type-union result-typeoid
4807 (type-intersection (lvar-type value)
4808 (specifier-type 'rational))))))
4809 ;; At zero safety the deftransform for COERCE can elide dimension
4810 ;; checks for the things like (COERCE X '(SIMPLE-VECTOR 5)) -- so we
4811 ;; need to simplify the type to drop the dimension information.
4812 ((and (policy node (zerop safety))
4813 (csubtypep result-typeoid (specifier-type '(array * (*))))
4814 (simplify-vector-type result-typeoid)))
4816 result-typeoid))))))
4818 (defoptimizer (compile derive-type) ((nameoid function))
4819 (declare (ignore function))
4820 (when (csubtypep (lvar-type nameoid)
4821 (specifier-type 'null))
4822 (values-specifier-type '(values function boolean boolean))))
4824 ;;; FIXME: Maybe also STREAM-ELEMENT-TYPE should be given some loving
4825 ;;; treatment along these lines? (See discussion in COERCE DERIVE-TYPE
4826 ;;; optimizer, above).
4827 (defoptimizer (array-element-type derive-type) ((array))
4828 (let ((array-type (lvar-type array)))
4829 (labels ((consify (list)
4830 (if (endp list)
4831 '(eql nil)
4832 `(cons (eql ,(car list)) ,(consify (rest list)))))
4833 (get-element-type (a)
4834 (let ((element-type
4835 (type-specifier (array-type-specialized-element-type a))))
4836 (cond ((eq element-type '*)
4837 (specifier-type 'type-specifier))
4838 ((symbolp element-type)
4839 (make-eql-type element-type))
4840 ((consp element-type)
4841 (specifier-type (consify element-type)))
4843 (error "can't understand type ~S~%" element-type))))))
4844 (labels ((recurse (type)
4845 (cond ((array-type-p type)
4846 (get-element-type type))
4847 ((union-type-p type)
4848 (apply #'type-union
4849 (mapcar #'recurse (union-type-types type))))
4851 *universal-type*))))
4852 (recurse array-type)))))
4854 (define-source-transform sb!impl::sort-vector (vector start end predicate key)
4855 ;; Like CMU CL, we use HEAPSORT. However, other than that, this code
4856 ;; isn't really related to the CMU CL code, since instead of trying
4857 ;; to generalize the CMU CL code to allow START and END values, this
4858 ;; code has been written from scratch following Chapter 7 of
4859 ;; _Introduction to Algorithms_ by Corman, Rivest, and Shamir.
4860 `(macrolet ((%index (x) `(truly-the index ,x))
4861 (%parent (i) `(ash ,i -1))
4862 (%left (i) `(%index (ash ,i 1)))
4863 (%right (i) `(%index (1+ (ash ,i 1))))
4864 (%elt (i)
4865 `(aref ,',vector
4866 (%index (+ (%index ,i) start-1))))
4867 (%heapify (i)
4868 `(do* ((i ,i)
4869 (left (%left i) (%left i)))
4870 ((> left current-heap-size))
4871 (declare (type index i left))
4872 (let* ((i-elt (%elt i))
4873 (i-key (funcall keyfun i-elt))
4874 (left-elt (%elt left))
4875 (left-key (funcall keyfun left-elt)))
4876 (multiple-value-bind (large large-elt large-key)
4877 (if (funcall ,',predicate i-key left-key)
4878 (values left left-elt left-key)
4879 (values i i-elt i-key))
4880 (let ((right (%right i)))
4881 (multiple-value-bind (largest largest-elt)
4882 (if (> right current-heap-size)
4883 (values large large-elt)
4884 (let* ((right-elt (%elt right))
4885 (right-key (funcall keyfun right-elt)))
4886 (if (funcall ,',predicate large-key right-key)
4887 (values right right-elt)
4888 (values large large-elt))))
4889 (cond ((= largest i)
4890 (return))
4892 (setf (%elt i) largest-elt
4893 (%elt largest) i-elt
4894 i largest)))))))))
4895 (%sort-vector (keyfun)
4896 `(let ( ;; Heaps prefer 1-based addressing.
4897 (start-1 (1- ,',start))
4898 (current-heap-size (- ,',end ,',start))
4899 (keyfun ,keyfun))
4900 (declare (type (integer -1 #.(1- sb!xc:most-positive-fixnum))
4901 start-1))
4902 (declare (type index current-heap-size))
4903 (declare (type function keyfun))
4904 (loop for i of-type index
4905 from (ash current-heap-size -1) downto 1 do
4906 (%heapify i))
4907 (loop
4908 (when (< current-heap-size 2)
4909 (return))
4910 (rotatef (%elt 1) (%elt current-heap-size))
4911 (decf current-heap-size)
4912 (%heapify 1)))))
4913 (declare (optimize (insert-array-bounds-checks 0) speed))
4914 (if (typep ,vector 'simple-vector)
4915 ;; (VECTOR T) is worth optimizing for, and SIMPLE-VECTOR is
4916 ;; what we get from (VECTOR T) inside WITH-ARRAY-DATA.
4917 (if (null ,key)
4918 ;; Special-casing the KEY=NIL case lets us avoid some
4919 ;; function calls.
4920 (%sort-vector #'identity)
4921 (%sort-vector ,key))
4922 ;; It's hard to anticipate many speed-critical applications for
4923 ;; sorting vector types other than (VECTOR T), so we just lump
4924 ;; them all together in one slow dynamically typed mess.
4925 (locally
4926 (declare (optimize (inhibit-warnings 3)))
4927 (%sort-vector (or ,key #'identity))))))
4929 (deftransform sort ((list predicate &key key)
4930 (list * &rest t) *)
4931 `(sb!impl::stable-sort-list list
4932 (%coerce-callable-to-fun predicate)
4933 (if key (%coerce-callable-to-fun key) #'identity)))
4935 (deftransform stable-sort ((sequence predicate &key key)
4936 ((or vector list) *))
4937 (let ((sequence-type (lvar-type sequence)))
4938 (cond ((csubtypep sequence-type (specifier-type 'list))
4939 `(sb!impl::stable-sort-list sequence
4940 (%coerce-callable-to-fun predicate)
4941 (if key (%coerce-callable-to-fun key) #'identity)))
4942 ((csubtypep sequence-type (specifier-type 'simple-vector))
4943 `(sb!impl::stable-sort-simple-vector sequence
4944 (%coerce-callable-to-fun predicate)
4945 (and key (%coerce-callable-to-fun key))))
4947 `(sb!impl::stable-sort-vector sequence
4948 (%coerce-callable-to-fun predicate)
4949 (and key (%coerce-callable-to-fun key)))))))
4951 ;;;; debuggers' little helpers
4953 ;;; for debugging when transforms are behaving mysteriously,
4954 ;;; e.g. when debugging a problem with an ASH transform
4955 ;;; (defun foo (&optional s)
4956 ;;; (sb-c::/report-lvar s "S outside WHEN")
4957 ;;; (when (and (integerp s) (> s 3))
4958 ;;; (sb-c::/report-lvar s "S inside WHEN")
4959 ;;; (let ((bound (ash 1 (1- s))))
4960 ;;; (sb-c::/report-lvar bound "BOUND")
4961 ;;; (let ((x (- bound))
4962 ;;; (y (1- bound)))
4963 ;;; (sb-c::/report-lvar x "X")
4964 ;;; (sb-c::/report-lvar x "Y"))
4965 ;;; `(integer ,(- bound) ,(1- bound)))))
4966 ;;; (The DEFTRANSFORM doesn't do anything but report at compile time,
4967 ;;; and the function doesn't do anything at all.)
4968 #!+sb-show
4969 (progn
4970 (defknown /report-lvar (t t) null)
4971 (deftransform /report-lvar ((x message) (t t))
4972 (format t "~%/in /REPORT-LVAR~%")
4973 (format t "/(LVAR-TYPE X)=~S~%" (lvar-type x))
4974 (when (constant-lvar-p x)
4975 (format t "/(LVAR-VALUE X)=~S~%" (lvar-value x)))
4976 (format t "/MESSAGE=~S~%" (lvar-value message))
4977 (give-up-ir1-transform "not a real transform"))
4978 (defun /report-lvar (x message)
4979 (declare (ignore x message))))
4981 (deftransform encode-universal-time
4982 ((second minute hour date month year &optional time-zone)
4983 ((constant-arg (mod 60)) (constant-arg (mod 60))
4984 (constant-arg (mod 24))
4985 (constant-arg (integer 1 31))
4986 (constant-arg (integer 1 12))
4987 (constant-arg (integer 1899))
4988 (constant-arg (rational -24 24))))
4989 (let ((second (lvar-value second))
4990 (minute (lvar-value minute))
4991 (hour (lvar-value hour))
4992 (date (lvar-value date))
4993 (month (lvar-value month))
4994 (year (lvar-value year))
4995 (time-zone (lvar-value time-zone)))
4996 (if (zerop (rem time-zone 1/3600))
4997 (encode-universal-time second minute hour date month year time-zone)
4998 (give-up-ir1-transform))))
5000 #!-(and win32 (not sb-thread))
5001 (deftransform sleep ((seconds) ((integer 0 #.(expt 10 8))))
5002 `(if sb!impl::*deadline*
5003 (locally (declare (notinline sleep)) (sleep seconds))
5004 (sb!unix:nanosleep seconds 0)))
5006 #!-(and win32 (not sb-thread))
5007 (deftransform sleep ((seconds) ((constant-arg (real 0))))
5008 (let ((seconds-value (lvar-value seconds)))
5009 (multiple-value-bind (seconds nano)
5010 (sb!impl::split-seconds-for-sleep seconds-value)
5011 (if (> seconds (expt 10 8))
5012 (give-up-ir1-transform)
5013 `(if sb!impl::*deadline*
5014 (locally (declare (notinline sleep)) (sleep seconds))
5015 (sb!unix:nanosleep ,seconds ,nano))))))
5017 ;; On 64-bit architectures the TLS index is in the symbol header,
5018 ;; !DEFINE-PRIMITIVE-OBJECT doesn't define an accessor for it.
5019 ;; In the architectures where tls-index is an ordinary slot holding a tagged
5020 ;; object, it represents the byte offset to an aligned object and looks
5021 ;; in Lisp like a fixnum that is off by a factor of (EXPT 2 N-FIXNUM-TAG-BITS).
5022 ;; We're reading with a raw SAP accessor, so must make it look equally "off".
5023 ;; Also we don't get the defknown automatically.
5024 #!+(and 64-bit sb-thread)
5025 (defknown symbol-tls-index (t) fixnum (flushable))
5026 #!+(and 64-bit sb-thread)
5027 (define-source-transform symbol-tls-index (sym)
5028 `(ash (sap-ref-32 (int-sap (get-lisp-obj-address (the symbol ,sym)))
5029 (- 4 sb!vm:other-pointer-lowtag))
5030 (- sb!vm:n-fixnum-tag-bits)))
5032 (deftransform make-string-output-stream ((&key element-type))
5033 (let ((element-type (cond ((not element-type)
5034 'character)
5035 ((constant-lvar-p element-type)
5036 (let ((specifier (ir1-transform-specifier-type
5037 (lvar-value element-type))))
5038 (and (csubtypep specifier (specifier-type 'character))
5039 (type-specifier specifier)))))))
5040 (if element-type
5041 `(sb!impl::%make-string-output-stream
5042 ',element-type
5043 (function ,(case element-type
5044 (base-char 'sb!impl::string-ouch/base-char)
5045 (t 'sb!impl::string-ouch))))
5046 (give-up-ir1-transform))))
5048 (flet ((xform (symbol match-kind fallback)
5049 (when (constant-lvar-p symbol)
5050 (let* ((symbol (lvar-value symbol))
5051 (kind (info :variable :kind symbol))
5052 (state (deprecated-thing-p 'variable symbol)))
5053 (when state
5054 (check-deprecated-thing 'variable symbol)
5055 (case state
5056 ((:early :late)
5057 (unless (gethash symbol *free-vars*)
5058 (setf (gethash symbol *free-vars*) :deprecated)))))
5059 ;; :global in the test below is redundant if match-kind is :global
5060 ;; but it's harmless and a convenient way to express this.
5061 ;; Note that some 3rd-party libraries use variations on DEFCONSTANT
5062 ;; expanding into expressions such as:
5063 ;; (CL:DEFCONSTANT S (IF (BOUNDP 'S) (SYMBOL-VALUE 'S) (COMPUTE)))
5064 ;; which means we have to use care if S in for-evaluation position would
5065 ;; be converted to (LOAD-TIME-VALUE (SYMBOL-VALUE 'S)).
5066 ;; When S's value is directly dumpable, it works fine, but otherwise
5067 ;; it's dangerous. If the user wishes to avoid eager evaluation entirely,
5068 ;; a local notinline declaration on SYMBOL-VALUE will do.
5069 (when (or (eq kind match-kind)
5070 (eq kind :global)
5071 (and (eq kind :constant)
5072 (boundp symbol)
5073 (typep (symbol-value symbol) '(or number character symbol))))
5074 (return-from xform symbol))))
5075 fallback))
5076 (deftransform symbol-global-value ((symbol))
5077 (xform symbol :global `(sym-global-val symbol)))
5078 (deftransform symbol-value ((symbol))
5079 (xform symbol :special `(symeval symbol))))
5081 (deftransform symeval ((symbol) ((constant-arg symbol)))
5082 (let* ((symbol (lvar-value symbol))
5083 (kind (info :variable :kind symbol)))
5084 (if (and (eq kind :constant)
5085 (boundp symbol)
5086 (typep (symbol-value symbol) '(or number character symbol)))
5087 symbol
5088 (give-up-ir1-transform))))
5090 (flet ((xform (symbol match-kind)
5091 (let* ((symbol (lvar-value symbol))
5092 (kind (info :variable :kind symbol)))
5093 (if (or (eq kind match-kind) (memq kind '(:constant :global))) ; as above
5094 `(setq ,symbol value)
5095 (give-up-ir1-transform)))))
5096 (deftransform set-symbol-global-value ((symbol value) ((constant-arg symbol) *))
5097 (xform symbol :global))
5098 (deftransform set ((symbol value) ((constant-arg symbol) *))
5099 (xform symbol :special)))
5101 (deftransforms (prin1-to-string princ-to-string) ((object) (number))
5102 `(stringify-object object))