1 ;;; Type analysis on CPS
2 ;;; Copyright (C) 2014 Free Software Foundation, Inc.
4 ;;; This library is free software: you can redistribute it and/or modify
5 ;;; it under the terms of the GNU Lesser General Public License as
6 ;;; published by the Free Software Foundation, either version 3 of the
7 ;;; License, or (at your option) any later version.
9 ;;; This library is distributed in the hope that it will be useful, but
10 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
11 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ;;; Lesser General Public License for more details.
14 ;;; You should have received a copy of the GNU Lesser General Public
15 ;;; License along with this program. If not, see
16 ;;; <http://www.gnu.org/licenses/>.
20 ;;; Type analysis computes the possible types and ranges that values may
21 ;;; have at all program positions. This analysis can help to prove that
22 ;;; a primcall has no side-effects, if its arguments have the
23 ;;; appropriate type and range. It can also enable constant folding of
24 ;;; type predicates and, in the future, enable the compiler to choose
25 ;;; untagged, unboxed representations for numbers.
27 ;;; For the purposes of this analysis, a "type" is an aspect of a value
28 ;;; that will not change. Guile's CPS intermediate language does not
29 ;;; carry manifest type information that asserts properties about given
30 ;;; values; instead, we recover this information via flow analysis,
31 ;;; garnering properties from type predicates, constant literals,
32 ;;; primcall results, and primcalls that assert that their arguments are
33 ;;; of particular types.
35 ;;; A range denotes a subset of the set of values in a type, bounded by
36 ;;; a minimum and a maximum. The precise meaning of a range depends on
37 ;;; the type. For real numbers, the range indicates an inclusive lower
38 ;;; and upper bound on the integer value of a type. For vectors, the
39 ;;; range indicates the length of the vector. The range is limited to a
40 ;;; signed 32-bit value, with the smallest and largest values indicating
41 ;;; -inf.0 and +inf.0, respectively. For some types, like pairs, the
42 ;;; concept of "range" makes no sense. In these cases we consider the
43 ;;; range to be -inf.0 to +inf.0.
45 ;;; Types are represented as a bitfield. Fewer bits means a more precise
46 ;;; type. Although normally only values that have a single type will
47 ;;; have an associated range, this is not enforced. The range applies
48 ;;; to all types in the bitfield. When control flow meets, the types and
49 ;;; ranges meet with the union operator.
51 ;;; It is not practical to precisely compute value ranges in all cases.
52 ;;; For example, in the following case:
54 ;;; (let lp ((n 0)) (when (foo) (lp (1+ n))))
56 ;;; The first time that range analysis visits the program, N is
57 ;;; determined to be the exact integer 0. The second time, it is an
58 ;;; exact integer in the range [0, 1]; the third, [0, 2]; and so on.
59 ;;; This analysis will terminate, but only after the positive half of
60 ;;; the 32-bit range has been fully explored and we decide that the
61 ;;; range of N is [0, +inf.0]. At the same time, we want to do range
62 ;;; analysis and type analysis at the same time, as there are
63 ;;; interactions between them, notably in the case of `sqrt' which
64 ;;; returns a complex number if its argument cannot be proven to be
65 ;;; non-negative. So what we do is, once the types reach a fixed point,
66 ;;; we cause control-flow joins that would expand the range of a value
67 ;;; to saturate that range towards positive or infinity (as
70 ;;; A naive approach to type analysis would build up a table that has
71 ;;; entries for all variables at all program points, but this has
72 ;;; N-squared complexity and quickly grows unmanageable. Instead, we
73 ;;; use _intmaps_ from (language cps intmap) to share state between
74 ;;; connected program points.
78 (define-module (language cps types)
79 #:use-module (ice-9 match)
80 #:use-module (language cps)
81 #:use-module (language cps dfg)
82 #:use-module (language cps intmap)
83 #:use-module (rnrs bytevectors)
84 #:use-module (srfi srfi-9)
85 #:use-module (srfi srfi-11)
86 #:export (;; Specific types.
121 primcall-types-check?))
123 (define-syntax define-flags
126 ((_ all shift name ...)
127 (let ((count (length #'(name ...))))
128 (with-syntax (((n ...) (iota count))
131 (define-syntax name (identifier-syntax (ash 1 n)))
133 (define-syntax all (identifier-syntax (1- (ash 1 count))))
134 (define-syntax shift (identifier-syntax count)))))))))
136 ;; More precise types have fewer bits.
137 (define-flags &all-types &type-bits
166 (define-syntax &no-type (identifier-syntax 0))
168 (define-syntax &number
169 (identifier-syntax (logior &exact-integer &flonum &complex &fraction)))
171 (identifier-syntax (logior &exact-integer &flonum &fraction)))
173 (define-syntax *max-s32* (identifier-syntax (- (ash 1 31) 1)))
174 (define-syntax *min-s32* (identifier-syntax (- 0 (ash 1 31))))
176 ;; Versions of min and max that do not coerce exact numbers to become
180 ((a b) (if (< a b) a b))
181 ((a b c) (min (min a b) c))
182 ((a b c d) (min (min a b) c d))))
185 ((a b) (if (> a b) a b))
186 ((a b c) (max (max a b) c))
187 ((a b c d) (max (max a b) c d))))
191 (define-syntax-rule (define-compile-time-value name val)
193 (make-variable-transformer
195 (syntax-case x (set!)
196 (var (identifier? #'var)
197 (datum->syntax #'var val)))))))
199 (define-compile-time-value min-fixnum most-negative-fixnum)
200 (define-compile-time-value max-fixnum most-positive-fixnum)
202 (define-inlinable (make-unclamped-type-entry type min max)
203 (vector type min max))
204 (define-inlinable (type-entry-type tentry)
205 (vector-ref tentry 0))
206 (define-inlinable (type-entry-clamped-min tentry)
207 (vector-ref tentry 1))
208 (define-inlinable (type-entry-clamped-max tentry)
209 (vector-ref tentry 2))
211 (define-syntax-rule (clamp-range val)
213 ((< val min-fixnum) min-fixnum)
214 ((< max-fixnum val) max-fixnum)
217 (define-inlinable (make-type-entry type min max)
218 (vector type (clamp-range min) (clamp-range max)))
219 (define-inlinable (type-entry-min tentry)
220 (let ((min (type-entry-clamped-min tentry)))
221 (if (eq? min min-fixnum) -inf.0 min)))
222 (define-inlinable (type-entry-max tentry)
223 (let ((max (type-entry-clamped-max tentry)))
224 (if (eq? max max-fixnum) +inf.0 max)))
226 (define all-types-entry (make-type-entry &all-types -inf.0 +inf.0))
228 (define* (var-type-entry typeset var #:optional (default all-types-entry))
229 (or (intmap-ref typeset var) default))
231 (define (var-type typeset var)
232 (type-entry-type (var-type-entry typeset var)))
233 (define (var-min typeset var)
234 (type-entry-min (var-type-entry typeset var)))
235 (define (var-max typeset var)
236 (type-entry-max (var-type-entry typeset var)))
238 ;; Is the type entry A contained entirely within B?
239 (define (type-entry<=? a b)
241 ((#(a-type a-min a-max) . #(b-type b-min b-max))
242 (and (eqv? b-type (logior a-type b-type))
246 (define (type-entry-union a b)
248 ((type-entry<=? b a) a)
249 ((type-entry<=? a b) b)
250 (else (make-type-entry
251 (logior (type-entry-type a) (type-entry-type b))
252 (min (type-entry-clamped-min a) (type-entry-clamped-min b))
253 (max (type-entry-clamped-max a) (type-entry-clamped-max b))))))
255 (define (type-entry-intersection a b)
257 ((type-entry<=? a b) a)
258 ((type-entry<=? b a) b)
259 (else (make-type-entry
260 (logand (type-entry-type a) (type-entry-type b))
261 (max (type-entry-clamped-min a) (type-entry-clamped-min b))
262 (min (type-entry-clamped-max a) (type-entry-clamped-max b))))))
264 (define (adjoin-var typeset var entry)
265 (intmap-add typeset var entry type-entry-union))
267 (define (restrict-var typeset var entry)
268 (intmap-add typeset var entry type-entry-intersection))
270 (define (constant-type val)
271 "Compute the type and range of VAL. Return three values: the type,
272 minimum, and maximum."
273 (define (return type val)
275 (make-type-entry type val val)
276 (make-type-entry type -inf.0 +inf.0)))
280 ((exact-integer? val) (return &exact-integer val))
281 ((eqv? (imag-part val) 0)
283 (make-type-entry &flonum -inf.0 +inf.0)
285 (if (exact? val) &fraction &flonum)
286 (if (rational? val) (inexact->exact (floor val)) val)
287 (if (rational? val) (inexact->exact (ceiling val)) val))))
288 (else (return &complex #f))))
289 ((eq? val '()) (return &null #f))
290 ((eq? val #nil) (return &nil #f))
291 ((char? val) (return &char (char->integer val)))
292 ((eqv? val *unspecified*) (return &unspecified #f))
293 ((boolean? val) (return &boolean (if val 1 0)))
294 ((symbol? val) (return &symbol #f))
295 ((keyword? val) (return &keyword #f))
296 ((pair? val) (return &pair #f))
297 ((vector? val) (return &vector (vector-length val)))
298 ((string? val) (return &string (string-length val)))
299 ((bytevector? val) (return &bytevector (bytevector-length val)))
300 ((bitvector? val) (return &bitvector (bitvector-length val)))
301 ((array? val) (return &array (array-rank val)))
302 ((not (variable-bound? (make-variable val))) (return &unbound #f))
304 (else (error "unhandled constant" val))))
306 (define *type-checkers* (make-hash-table))
307 (define *type-inferrers* (make-hash-table))
309 (define-syntax-rule (define-type-helper name)
310 (define-syntax-parameter name
312 (syntax-violation 'name
313 "macro used outside of define-type"
315 (define-type-helper define!)
316 (define-type-helper restrict!)
317 (define-type-helper &type)
318 (define-type-helper &min)
319 (define-type-helper &max)
321 (define-syntax-rule (define-type-checker (name arg ...) body ...)
325 (lambda (typeset arg ...)
327 ((&type (syntax-rules () ((_ val) (var-type typeset val))))
328 (&min (syntax-rules () ((_ val) (var-min typeset val))))
329 (&max (syntax-rules () ((_ val) (var-max typeset val)))))
332 (define-syntax-rule (check-type arg type min max)
333 ;; If the arg is negative, it is a closure variable.
335 (zero? (logand (lognot type) (&type arg)))
337 (<= (&max arg) max)))
339 (define-syntax-rule (define-type-inferrer* (name succ var ...) body ...)
343 (lambda (in succ var ...)
348 ((_ val type min max)
349 (set! out (adjoin-var out val
350 (make-type-entry type min max))))))
353 ((_ val type min max)
354 (set! out (restrict-var out val
355 (make-type-entry type min max))))))
356 (&type (syntax-rules () ((_ val) (var-type in val))))
357 (&min (syntax-rules () ((_ val) (var-min in val))))
358 (&max (syntax-rules () ((_ val) (var-max in val)))))
362 (define-syntax-rule (define-type-inferrer (name arg ...) body ...)
363 (define-type-inferrer* (name succ arg ...) body ...))
365 (define-syntax-rule (define-predicate-inferrer (name arg ... true?) body ...)
366 (define-type-inferrer* (name succ arg ...)
367 (let ((true? (not (zero? succ))))
370 (define-syntax define-simple-type-checker
372 (define (parse-spec l)
375 (((type min max) . l) (cons #'(type min max) (parse-spec #'l)))
376 (((type min+max) . l) (cons #'(type min+max min+max) (parse-spec #'l)))
377 ((type . l) (cons #'(type -inf.0 +inf.0) (parse-spec #'l)))))
379 ((_ (name arg-spec ...) result-spec ...)
381 (((arg ...) (generate-temporaries #'(arg-spec ...)))
382 (((arg-type arg-min arg-max) ...) (parse-spec #'(arg-spec ...))))
383 #'(define-type-checker (name arg ...)
384 (and (check-type arg arg-type arg-min arg-max)
387 (define-syntax define-simple-type-inferrer
389 (define (parse-spec l)
392 (((type min max) . l) (cons #'(type min max) (parse-spec #'l)))
393 (((type min+max) . l) (cons #'(type min+max min+max) (parse-spec #'l)))
394 ((type . l) (cons #'(type -inf.0 +inf.0) (parse-spec #'l)))))
396 ((_ (name arg-spec ...) result-spec ...)
398 (((arg ...) (generate-temporaries #'(arg-spec ...)))
399 (((arg-type arg-min arg-max) ...) (parse-spec #'(arg-spec ...)))
400 ((res ...) (generate-temporaries #'(result-spec ...)))
401 (((res-type res-min res-max) ...) (parse-spec #'(result-spec ...))))
402 #'(define-type-inferrer (name arg ... res ...)
403 (restrict! arg arg-type arg-min arg-max)
405 (define! res res-type res-min res-max)
408 (define-syntax-rule (define-simple-type (name arg-spec ...) result-spec ...)
410 (define-simple-type-checker (name arg-spec ...))
411 (define-simple-type-inferrer (name arg-spec ...) result-spec ...)))
413 (define-syntax-rule (define-simple-types
414 ((name arg-spec ...) result-spec ...)
417 (define-simple-type (name arg-spec ...) result-spec ...)
420 (define-syntax-rule (define-type-checker-aliases orig alias ...)
421 (let ((check (hashq-ref *type-checkers* 'orig)))
422 (hashq-set! *type-checkers* 'alias check)
424 (define-syntax-rule (define-type-inferrer-aliases orig alias ...)
425 (let ((check (hashq-ref *type-inferrers* 'orig)))
426 (hashq-set! *type-inferrers* 'alias check)
428 (define-syntax-rule (define-type-aliases orig alias ...)
430 (define-type-checker-aliases orig alias ...)
431 (define-type-inferrer-aliases orig alias ...)))
436 ;;; This list of primcall type definitions follows the order of
437 ;;; effects-analysis.scm; please keep it in a similar order.
439 ;;; There is no need to add checker definitions for expressions that do
440 ;;; not exhibit the &type-check effect, as callers should not ask if
441 ;;; such an expression does or does not type-check. For those that do
442 ;;; exhibit &type-check, you should define a type inferrer unless the
443 ;;; primcall will never typecheck.
445 ;;; Likewise there is no need to define inferrers for primcalls which
446 ;;; return &all-types values and which never raise exceptions from which
447 ;;; we can infer the types of incoming values.
456 (define-simple-type-checker (not &all-types))
457 (define-type-inferrer (not val result)
459 ((and (eqv? (&type val) &boolean)
460 (eqv? (&min val) (&max val)))
461 (let ((val (if (zero? (&min val)) 1 0)))
462 (define! result &boolean val val)))
464 (define! result &boolean 0 1))))
470 ;;; Generic effect-free predicates.
473 (define-predicate-inferrer (eq? a b true?)
474 ;; We can only propagate information down the true leg.
476 (let ((type (logand (&type a) (&type b)))
477 (min (max (&min a) (&min b)))
478 (max (min (&max a) (&max b))))
479 (restrict! a type min max)
480 (restrict! b type min max))))
481 (define-type-inferrer-aliases eq? eqv? equal?)
483 (define-syntax-rule (define-simple-predicate-inferrer predicate type)
484 (define-predicate-inferrer (predicate val true?)
485 (let ((type (if true?
487 (logand (&type val) (lognot type)))))
488 (restrict! val type -inf.0 +inf.0))))
489 (define-simple-predicate-inferrer pair? &pair)
490 (define-simple-predicate-inferrer null? &null)
491 (define-simple-predicate-inferrer nil? &nil)
492 (define-simple-predicate-inferrer symbol? &symbol)
493 (define-simple-predicate-inferrer variable? &box)
494 (define-simple-predicate-inferrer vector? &vector)
495 (define-simple-predicate-inferrer struct? &struct)
496 (define-simple-predicate-inferrer string? &string)
497 (define-simple-predicate-inferrer number? &number)
498 (define-simple-predicate-inferrer char? &char)
499 (define-simple-predicate-inferrer procedure? &procedure)
500 (define-simple-predicate-inferrer thunk? &procedure)
505 ;;; Fluids. Note that we can't track bound-ness of fluids, as pop-fluid
506 ;;; can change boundness.
510 ((fluid-ref (&fluid 1)) &all-types)
511 ((fluid-set! (&fluid 0 1) &all-types))
512 ((push-fluid (&fluid 0 1) &all-types))
519 ;;; Prompts. (Nothing to do.)
530 ((cons &all-types &all-types) &pair)
531 ((car &pair) &all-types)
532 ((set-car! &pair &all-types))
533 ((cdr &pair) &all-types)
534 ((set-cdr! &pair &all-types)))
544 ((box &all-types) (&box 1))
545 ((box-ref (&box 1)) &all-types))
547 (define-simple-type-checker (box-set! (&box 0 1) &all-types))
548 (define-type-inferrer (box-set! box val)
549 (restrict! box &box 1 1))
558 ;; This max-vector-len computation is a hack.
559 (define *max-vector-len* (ash most-positive-fixnum -5))
561 (define-simple-type-checker (make-vector (&exact-integer 0 *max-vector-len*)
563 (define-type-inferrer (make-vector size init result)
564 (restrict! size &exact-integer 0 *max-vector-len*)
565 (define! result &vector (max (&min size) 0) (&max size)))
567 (define-type-checker (vector-ref v idx)
568 (and (check-type v &vector 0 *max-vector-len*)
569 (check-type idx &exact-integer 0 (1- (&min v)))))
570 (define-type-inferrer (vector-ref v idx result)
571 (restrict! v &vector (1+ (&min idx)) +inf.0)
572 (restrict! idx &exact-integer 0 (1- (&max v)))
573 (define! result &all-types -inf.0 +inf.0))
575 (define-type-checker (vector-set! v idx val)
576 (and (check-type v &vector 0 *max-vector-len*)
577 (check-type idx &exact-integer 0 (1- (&min v)))))
578 (define-type-inferrer (vector-set! v idx val)
579 (restrict! v &vector (1+ (&min idx)) +inf.0)
580 (restrict! idx &exact-integer 0 (1- (&max v))))
582 (define-type-aliases make-vector make-vector/immediate)
583 (define-type-aliases vector-ref vector-ref/immediate)
584 (define-type-aliases vector-set! vector-set!/immediate)
586 (define-simple-type-checker (vector-length &vector))
587 (define-type-inferrer (vector-length v result)
588 (restrict! v &vector 0 *max-vector-len*)
589 (define! result &exact-integer (max (&min v) 0)
590 (min (&max v) *max-vector-len*)))
599 ;; No type-checker for allocate-struct, as we can't currently check that
600 ;; vt is actually a vtable.
601 (define-type-inferrer (allocate-struct vt size result)
602 (restrict! vt &struct vtable-offset-user +inf.0)
603 (restrict! size &exact-integer 0 +inf.0)
604 (define! result &struct (max (&min size) 0) (&max size)))
606 (define-type-checker (struct-ref s idx)
607 (and (check-type s &struct 0 +inf.0)
608 (check-type idx &exact-integer 0 +inf.0)
609 ;; FIXME: is the field readable?
610 (< (&max idx) (&min s))))
611 (define-type-inferrer (struct-ref s idx result)
612 (restrict! s &struct (1+ (&min idx)) +inf.0)
613 (restrict! idx &exact-integer 0 (1- (&max s)))
614 (define! result &all-types -inf.0 +inf.0))
616 (define-type-checker (struct-set! s idx val)
617 (and (check-type s &struct 0 +inf.0)
618 (check-type idx &exact-integer 0 +inf.0)
619 ;; FIXME: is the field writable?
620 (< (&max idx) (&min s))))
621 (define-type-inferrer (struct-set! s idx val)
622 (restrict! s &struct (1+ (&min idx)) +inf.0)
623 (restrict! idx &exact-integer 0 (1- (&max s))))
625 (define-type-aliases allocate-struct allocate-struct/immediate)
626 (define-type-aliases struct-ref struct-ref/immediate)
627 (define-type-aliases struct-set! struct-set!/immediate)
629 (define-simple-type (struct-vtable (&struct 0 +inf.0))
630 (&struct vtable-offset-user +inf.0))
639 (define *max-char* (1- (ash 1 24)))
641 (define-type-checker (string-ref s idx)
642 (and (check-type s &string 0 +inf.0)
643 (check-type idx &exact-integer 0 +inf.0)
644 (< (&max idx) (&min s))))
645 (define-type-inferrer (string-ref s idx result)
646 (restrict! s &string (1+ (&min idx)) +inf.0)
647 (restrict! idx &exact-integer 0 (1- (&max s)))
648 (define! result &char 0 *max-char*))
650 (define-type-checker (string-set! s idx val)
651 (and (check-type s &string 0 +inf.0)
652 (check-type idx &exact-integer 0 +inf.0)
653 (check-type val &char 0 *max-char*)
654 (< (&max idx) (&min s))))
655 (define-type-inferrer (string-set! s idx val)
656 (restrict! s &string (1+ (&min idx)) +inf.0)
657 (restrict! idx &exact-integer 0 (1- (&max s)))
658 (restrict! val &char 0 *max-char*))
660 (define-simple-type-checker (string-length &string))
661 (define-type-inferrer (string-length s result)
662 (restrict! s &string 0 +inf.0)
663 (define! result &exact-integer (max (&min s) 0) (&max s)))
665 (define-simple-type (number->string &number) (&string 0 +inf.0))
666 (define-simple-type (string->number (&string 0 +inf.0))
667 ((logior &number &boolean) -inf.0 +inf.0))
676 (define-simple-type-checker (bytevector-length &bytevector))
677 (define-type-inferrer (bytevector-length bv result)
678 (restrict! bv &bytevector 0 +inf.0)
679 (define! result &exact-integer (max (&min bv) 0) (&max bv)))
681 (define-syntax-rule (define-bytevector-accessors ref set type size min max)
683 (define-type-checker (ref bv idx)
684 (and (check-type bv &bytevector 0 +inf.0)
685 (check-type idx &exact-integer 0 +inf.0)
686 (< (&max idx) (- (&min bv) size))))
687 (define-type-inferrer (ref bv idx result)
688 (restrict! bv &bytevector (+ (&min idx) size) +inf.0)
689 (restrict! idx &exact-integer 0 (- (&max bv) size))
690 (define! result type min max))
691 (define-type-checker (set bv idx val)
692 (and (check-type bv &bytevector 0 +inf.0)
693 (check-type idx &exact-integer 0 +inf.0)
694 (check-type val type min max)
695 (< (&max idx) (- (&min bv) size))))
696 (define-type-inferrer (set! bv idx val)
697 (restrict! bv &bytevector (+ (&min idx) size) +inf.0)
698 (restrict! idx &exact-integer 0 (- (&max bv) size))
699 (restrict! val type min max))))
701 (define-syntax-rule (define-short-bytevector-accessors ref set size signed?)
702 (define-bytevector-accessors ref set &exact-integer size
703 (if signed? (- (ash 1 (1- (* size 8)))) 0)
704 (1- (ash 1 (if signed? (1- (* size 8)) (* size 8))))))
706 (define-short-bytevector-accessors bv-u8-ref bv-u8-set! 1 #f)
707 (define-short-bytevector-accessors bv-s8-ref bv-s8-set! 1 #t)
708 (define-short-bytevector-accessors bv-u16-ref bv-u16-set! 2 #f)
709 (define-short-bytevector-accessors bv-s16-ref bv-s16-set! 2 #t)
711 ;; The range analysis only works on signed 32-bit values, so some limits
713 (define-bytevector-accessors bv-u32-ref bv-u32-set! &exact-integer 4 0 +inf.0)
714 (define-bytevector-accessors bv-s32-ref bv-s32-set! &exact-integer 4 -inf.0 +inf.0)
715 (define-bytevector-accessors bv-u64-ref bv-u64-set! &exact-integer 8 0 +inf.0)
716 (define-bytevector-accessors bv-s64-ref bv-s64-set! &exact-integer 8 -inf.0 +inf.0)
717 (define-bytevector-accessors bv-f32-ref bv-f32-set! &real 4 -inf.0 +inf.0)
718 (define-bytevector-accessors bv-f64-ref bv-f64-set! &real 8 -inf.0 +inf.0)
727 ;; First, branching primitives with no results.
728 (define-simple-type-checker (= &number &number))
729 (define-predicate-inferrer (= a b true?)
731 (zero? (logand (logior (&type a) (&type b)) (lognot &number))))
732 (let ((min (max (&min a) (&min b)))
733 (max (min (&max a) (&max b))))
734 (restrict! a &number min max)
735 (restrict! b &number min max))))
737 (define-simple-type-checker (< &real &real))
738 (define-predicate-inferrer (< a b true?)
739 (when (zero? (logand (logior (&type a) (&type b)) (lognot &number)))
740 (restrict! a &real -inf.0 +inf.0)
741 (restrict! b &real -inf.0 +inf.0)))
742 (define-type-aliases < <= > >=)
745 (define-syntax-rule (define-unary-result! a result min max)
748 (type (logand (&type a) &number)))
750 ((not (= type (&type a)))
751 ;; Not a number. Punt and do nothing.
752 (define! result &all-types -inf.0 +inf.0))
753 ;; Complex numbers don't have a range.
754 ((eqv? type &complex)
755 (define! result &complex -inf.0 +inf.0))
757 (define! result type min* max*)))))
759 (define-syntax-rule (define-binary-result! a b result closed? min max)
762 (a-type (logand (&type a) &number))
763 (b-type (logand (&type b) &number)))
765 ((or (not (= a-type (&type a))) (not (= b-type (&type b))))
766 ;; One input not a number. Perhaps we end up dispatching to
768 (define! result &all-types -inf.0 +inf.0))
769 ;; Complex and floating-point numbers are contagious.
770 ((or (eqv? a-type &complex) (eqv? b-type &complex))
771 (define! result &complex -inf.0 +inf.0))
772 ((or (eqv? a-type &flonum) (eqv? b-type &flonum))
773 (define! result &flonum min* max*))
774 ;; Exact integers are closed under some operations.
775 ((and closed? (eqv? a-type &exact-integer) (eqv? b-type &exact-integer))
776 (define! result &exact-integer min* max*))
778 ;; Fractions may become integers.
779 (let ((type (logior a-type b-type)))
781 (if (zero? (logand type &fraction))
783 (logior type &exact-integer))
786 (define-simple-type-checker (add &number &number))
787 (define-type-inferrer (add a b result)
788 (define-binary-result! a b result #t
789 (+ (&min a) (&min b))
790 (+ (&max a) (&max b))))
792 (define-simple-type-checker (sub &number &number))
793 (define-type-inferrer (sub a b result)
794 (define-binary-result! a b result #t
795 (- (&min a) (&max b))
796 (- (&max a) (&min b))))
798 (define-simple-type-checker (mul &number &number))
799 (define-type-inferrer (mul a b result)
800 (let ((min-a (&min a)) (max-a (&max a))
801 (min-b (&min b)) (max-b (&max b)))
802 (let ((-- (* min-a min-b))
805 (+- (* max-a min-b)))
806 (define-binary-result! a b result #t
807 (if (eqv? a b) 0 (min -- -+ ++ +-))
808 (max -- -+ ++ +-)))))
810 (define-type-checker (div a b)
811 (and (check-type a &number -inf.0 +inf.0)
812 (check-type b &number -inf.0 +inf.0)
813 ;; We only know that there will not be an exception if b is not
815 (not (<= (&min b) 0 (&max b)))))
816 (define-type-inferrer (div a b result)
817 (let ((min-a (&min a)) (max-a (&max a))
818 (min-b (&min b)) (max-b (&max b)))
821 (if (<= min-b 0 max-b)
822 ;; If the range of the divisor crosses 0, the result spans
824 (values -inf.0 +inf.0)
825 ;; Otherwise min-b and max-b have the same sign, and cannot both
827 (let ((-- (if (inf? min-b) 0 (* min-a min-b)))
828 (-+ (if (inf? max-b) 0 (* min-a max-b)))
829 (++ (if (inf? max-b) 0 (* max-a max-b)))
830 (+- (if (inf? min-b) 0 (* max-a min-b))))
831 (values (min -- -+ ++ +-)
832 (max -- -+ ++ +-)))))
834 (define-binary-result! a b result #f min max)))))
836 (define-simple-type-checker (add1 &number))
837 (define-type-inferrer (add1 a result)
838 (define-unary-result! a result (1+ (&min a)) (1+ (&max a))))
840 (define-simple-type-checker (sub1 &number))
841 (define-type-inferrer (sub1 a result)
842 (define-unary-result! a result (1- (&min a)) (1- (&max a))))
844 (define-type-checker (quo a b)
845 (and (check-type a &exact-integer -inf.0 +inf.0)
846 (check-type b &exact-integer -inf.0 +inf.0)
847 ;; We only know that there will not be an exception if b is not
849 (not (<= (&min b) 0 (&max b)))))
850 (define-type-inferrer (quo a b result)
851 (restrict! a &exact-integer -inf.0 +inf.0)
852 (restrict! b &exact-integer -inf.0 +inf.0)
853 (define! result &exact-integer -inf.0 +inf.0))
855 (define-type-checker-aliases quo rem)
856 (define-type-inferrer (rem a b result)
857 (restrict! a &exact-integer -inf.0 +inf.0)
858 (restrict! b &exact-integer -inf.0 +inf.0)
860 (let ((max-abs-rem (1- (max (abs (&min b)) (abs (&max b))))))
864 (define! result &exact-integer (- max-abs-rem) max-abs-rem)
865 (define! result &exact-integer (- max-abs-rem) 0)))
867 (define! result &exact-integer 0 max-abs-rem)))))
869 (define-type-checker-aliases quo mod)
870 (define-type-inferrer (mod a b result)
871 (restrict! a &exact-integer -inf.0 +inf.0)
872 (restrict! b &exact-integer -inf.0 +inf.0)
874 (let ((max-abs-mod (1- (max (abs (&min b)) (abs (&max b))))))
878 (define! result &exact-integer (- max-abs-mod) max-abs-mod)
879 (define! result &exact-integer (- max-abs-mod) 0)))
881 (define! result &exact-integer 0 max-abs-mod)))))
884 (define-syntax-rule (define-number-kind-predicate-inferrer name type)
885 (define-type-inferrer (name val result)
887 ((zero? (logand (&type val) type))
888 (define! result &boolean 0 0))
889 ((zero? (logand (&type val) (lognot type)))
890 (define! result &boolean 1 1))
892 (define! result &boolean 0 1)))))
893 (define-number-kind-predicate-inferrer complex? &number)
894 (define-number-kind-predicate-inferrer real? &real)
895 (define-number-kind-predicate-inferrer rational?
896 (logior &exact-integer &fraction))
897 (define-number-kind-predicate-inferrer integer?
898 (logior &exact-integer &flonum))
899 (define-number-kind-predicate-inferrer exact-integer?
902 (define-simple-type-checker (exact? &number))
903 (define-type-inferrer (exact? val result)
904 (restrict! val &number -inf.0 +inf.0)
906 ((zero? (logand (&type val) (logior &exact-integer &fraction)))
907 (define! result &boolean 0 0))
908 ((zero? (logand (&type val) (lognot (logior &exact-integer &fraction))))
909 (define! result &boolean 1 1))
911 (define! result &boolean 0 1))))
913 (define-simple-type-checker (inexact? &number))
914 (define-type-inferrer (inexact? val result)
915 (restrict! val &number -inf.0 +inf.0)
917 ((zero? (logand (&type val) (logior &flonum &complex)))
918 (define! result &boolean 0 0))
919 ((zero? (logand (&type val) (logand &number
920 (lognot (logior &flonum &complex)))))
921 (define! result &boolean 1 1))
923 (define! result &boolean 0 1))))
925 (define-simple-type-checker (inf? &real))
926 (define-type-inferrer (inf? val result)
927 (restrict! val &real -inf.0 +inf.0)
929 ((or (zero? (logand (&type val) (logior &flonum &complex)))
930 (and (not (inf? (&min val))) (not (inf? (&max val)))))
931 (define! result &boolean 0 0))
933 (define! result &boolean 0 1))))
935 (define-type-aliases inf? nan?)
937 (define-simple-type (even? &exact-integer) (&boolean 0 1))
938 (define-type-aliases even? odd?)
941 (define-simple-type-checker (ash &exact-integer &exact-integer))
942 (define-type-inferrer (ash val count result)
943 (define (ash* val count)
944 ;; As we can only represent a 32-bit range, don't bother inferring
945 ;; shifts that might exceed that range.
947 ((inf? val) val) ; Preserves sign.
948 ((< -32 count 32) (ash val count))
950 ((positive? val) +inf.0)
952 (restrict! val &exact-integer -inf.0 +inf.0)
953 (restrict! count &exact-integer -inf.0 +inf.0)
954 (let ((-- (ash* (&min val) (&min count)))
955 (-+ (ash* (&min val) (&max count)))
956 (++ (ash* (&max val) (&max count)))
957 (+- (ash* (&max val) (&min count))))
958 (define! result &exact-integer
962 (define (next-power-of-two n)
968 (define-simple-type-checker (logand &exact-integer &exact-integer))
969 (define-type-inferrer (logand a b result)
970 (define (logand-min a b)
974 (define (logand-max a b)
978 (restrict! a &exact-integer -inf.0 +inf.0)
979 (restrict! b &exact-integer -inf.0 +inf.0)
980 (define! result &exact-integer
981 (logand-min (&min a) (&min b))
982 (logand-max (&max a) (&max b))))
984 (define-simple-type-checker (logior &exact-integer &exact-integer))
985 (define-type-inferrer (logior a b result)
986 ;; Saturate all bits of val.
987 (define (saturate val)
988 (1- (next-power-of-two val)))
989 (define (logior-min a b)
990 (cond ((and (< a 0) (<= 0 b)) a)
991 ((and (< b 0) (<= 0 a)) b)
993 (define (logior-max a b)
994 ;; If either operand is negative, just assume the max is -1.
996 ((or (< a 0) (< b 0)) -1)
997 ((or (inf? a) (inf? b)) +inf.0)
998 (else (saturate (logior a b)))))
999 (restrict! a &exact-integer -inf.0 +inf.0)
1000 (restrict! b &exact-integer -inf.0 +inf.0)
1001 (define! result &exact-integer
1002 (logior-min (&min a) (&min b))
1003 (logior-max (&max a) (&max b))))
1005 ;; For our purposes, treat logxor the same as logior.
1006 (define-type-aliases logior logxor)
1008 (define-simple-type-checker (lognot &exact-integer))
1009 (define-type-inferrer (lognot a result)
1010 (restrict! a &exact-integer -inf.0 +inf.0)
1011 (define! result &exact-integer
1016 (define-simple-type-checker (sqrt &number))
1017 (define-type-inferrer (sqrt x result)
1018 (let ((type (&type x)))
1020 ((and (zero? (logand type &complex)) (<= 0 (&min x)))
1022 (logior type &flonum)
1023 (inexact->exact (floor (sqrt (&min x))))
1026 (inexact->exact (ceiling (sqrt (&max x)))))))
1028 (define! result (logior type &flonum &complex) -inf.0 +inf.0)))))
1030 (define-simple-type-checker (abs &real))
1031 (define-type-inferrer (abs x result)
1032 (let ((type (&type x)))
1034 ((eqv? type (logand type &number))
1035 (restrict! x &real -inf.0 +inf.0)
1036 (define! result (logand type &real)
1037 (min (abs (&min x)) (abs (&max x)))
1038 (max (abs (&min x)) (abs (&max x)))))
1040 (define! result (logior (logand (&type x) (lognot &number))
1041 (logand (&type x) &real))
1043 (max (abs (&min x)) (abs (&max x))))))))
1052 (define-simple-type (char<? &char &char) (&boolean 0 1))
1053 (define-type-aliases char<? char<=? char>=? char>?)
1055 (define-simple-type-checker (integer->char (&exact-integer 0 #x10ffff)))
1056 (define-type-inferrer (integer->char i result)
1057 (restrict! i &exact-integer 0 #x10ffff)
1058 (define! result &char (max (&min i) 0) (min (&max i) #x10ffff)))
1060 (define-simple-type-checker (char->integer &char))
1061 (define-type-inferrer (char->integer c result)
1062 (restrict! c &char 0 #x10ffff)
1063 (define! result &exact-integer (max (&min c) 0) (min (&max c) #x10ffff)))
1069 ;;; Type flow analysis: the meet (ahem) of the algorithm.
1072 (define (infer-types* dfg min-label label-count)
1073 "Compute types for all variables in @var{fun}. Returns a hash table
1074 mapping symbols to types."
1075 (let ((typev (make-vector label-count))
1076 (idoms (compute-idoms dfg min-label label-count))
1079 (saturate-ranges? #f))
1080 (define (label->idx label) (- label min-label))
1082 (define (get-entry label) (vector-ref typev (label->idx label)))
1084 (define (in-types entry) (vector-ref entry 0))
1085 (define (out-types entry succ) (vector-ref entry (1+ succ)))
1087 (define (update-in-types! entry types)
1088 (vector-set! entry 0 types))
1089 (define (update-out-types! entry succ types)
1090 (vector-set! entry (1+ succ) types))
1092 (define (prepare-initial-state!)
1093 ;; The result is a vector with an entry for each label. Each entry
1094 ;; is a vector. The first slot in the entry vector corresponds to
1095 ;; the types that flow into the labelled expression. The following
1096 ;; slot is for the types that flow out to the first successor, and
1097 ;; so on for additional successors.
1098 (let lp ((label min-label))
1099 (when (< label (+ min-label label-count))
1100 (let* ((nsuccs (match (lookup-cont label dfg)
1101 (($ $kargs _ _ term)
1102 (match (find-call term)
1103 (($ $continue k src (or ($ $branch) ($ $prompt))) 2)
1105 (($ $kfun src meta self tail clause) (if clause 1 0))
1106 (($ $kclause arity body alt) (if alt 2 1))
1109 (entry (make-vector (1+ nsuccs) #f)))
1110 (vector-set! typev (label->idx label) entry)
1113 ;; Initial state: nothing flows into the $kfun.
1114 (let ((entry (get-entry min-label)))
1115 (update-in-types! entry empty-intmap)))
1117 (define (adjoin-vars types vars entry)
1121 (adjoin-vars (adjoin-var types var entry) vars entry))))
1123 (define (infer-primcall types succ name args result)
1125 ((hashq-ref *type-inferrers* name)
1126 => (lambda (inferrer)
1127 ;; FIXME: remove the apply?
1128 ;(pk 'primcall name args result)
1129 (apply inferrer types succ
1131 (append args (list result))
1134 (adjoin-var types result all-types-entry))
1138 (define (type-entry-saturating-union a b)
1140 ((type-entry<=? b a) a)
1142 ((and (not saturate-ranges?)
1144 (type-entry<=? a b)) b)
1145 (else (make-type-entry
1146 (let* ((a-type (type-entry-type a))
1147 (b-type (type-entry-type b))
1148 (type (logior a-type b-type)))
1149 (unless (eqv? a-type type)
1150 (set! types-changed? #t))
1152 (let ((a-min (type-entry-clamped-min a))
1153 (b-min (type-entry-clamped-min b)))
1155 (if saturate-ranges? min-fixnum b-min)
1157 (let ((a-max (type-entry-clamped-max a))
1158 (b-max (type-entry-clamped-max b)))
1160 (if saturate-ranges? max-fixnum b-max)
1163 (define (propagate-types! pred-label pred-entry succ-idx succ-label out)
1164 ;; Update "in" set of continuation.
1165 (let ((succ-entry (get-entry succ-label)))
1166 (match (lookup-predecessors succ-label dfg)
1169 (update-in-types! succ-entry out))
1171 ;; A control-flow join.
1172 (let* ((succ-dom-label (vector-ref idoms (label->idx succ-label)))
1173 (succ-dom-entry (get-entry succ-dom-label))
1174 (old-in (in-types succ-entry))
1176 (intmap-intersect old-in out
1177 type-entry-saturating-union)
1179 ;; If the "in" set changed, update the entry and possibly
1180 ;; arrange to iterate again.
1181 (unless (eq? old-in in)
1182 (update-in-types! succ-entry in)
1183 ;; If the changed successor is a back-edge, ensure that
1184 ;; we revisit the function.
1185 (when (<= succ-label pred-label)
1186 (unless (and revisit-label (<= revisit-label succ-label))
1187 ;; (pk 'marking-revisit pred-label succ-label)
1188 (set! revisit-label succ-label))))))))
1189 ;; Finally update "out" set for current expression.
1190 (update-out-types! pred-entry succ-idx out))
1192 (define (visit-exp label entry k types exp)
1193 (define (propagate! succ-idx succ-label types)
1194 (propagate-types! label entry succ-idx succ-label types))
1195 ;; Each of these branches must propagate! to its successors.
1197 (($ $branch kt ($ $values (arg)))
1198 ;; The "normal" continuation is the #f branch.
1199 (let ((types (restrict-var types arg
1200 (make-type-entry (logior &boolean &nil)
1203 (propagate! 0 k types))
1204 ;; No additional information on the #t branch,
1205 ;; as there's no way currently to remove #f
1206 ;; from the typeset (because it would remove
1207 ;; #t as well: they are both &boolean).
1208 (propagate! 1 kt types))
1209 (($ $branch kt ($ $primcall name args))
1210 ;; The "normal" continuation is the #f branch.
1211 (let ((types (infer-primcall types 0 name args #f)))
1212 (propagate! 0 k types))
1213 (let ((types (infer-primcall types 1 name args #f)))
1214 (propagate! 1 kt types)))
1215 (($ $prompt escape? tag handler)
1216 ;; The "normal" continuation enters the prompt.
1217 (propagate! 0 k types)
1218 (propagate! 1 handler types))
1219 (($ $primcall name args)
1221 (match (lookup-cont k dfg)
1223 (infer-primcall types 0 name args
1224 (match defs ((var) var) (() #f))))
1226 ;(pk 'warning-no-restrictions name)
1229 (match (lookup-cont k dfg)
1232 (let lp ((defs defs) (args args) (out types))
1233 (match (cons defs args)
1235 (propagate! 0 k out))
1236 (((def . defs) . (arg . args))
1238 (adjoin-var out def (var-type-entry in arg))))))))
1240 (propagate! 0 k types))))
1241 ((or ($ $call) ($ $callk))
1242 (propagate! 0 k types))
1244 (match (lookup-cont k dfg)
1245 (($ $kargs (_) (var))
1246 (let ((entry (match exp
1248 (make-type-entry &unspecified -inf.0 +inf.0))
1250 (constant-type val))
1251 ((or ($ $prim) ($ $fun) ($ $closure))
1252 ;; Could be more precise here.
1253 (make-type-entry &procedure -inf.0 +inf.0)))))
1254 (propagate! 0 k (adjoin-var types var entry))))))))
1256 (prepare-initial-state!)
1258 ;; Iterate over all labelled expressions in the function,
1259 ;; propagating types and ranges to all successors.
1260 (let lp ((label min-label))
1263 ((< label (+ min-label label-count))
1264 (let* ((entry (vector-ref typev (label->idx label)))
1265 (types (in-types entry)))
1266 (define (propagate! succ-idx succ-label types)
1267 (propagate-types! label entry succ-idx succ-label types))
1268 ;; Add types for new definitions, and restrict types of
1269 ;; existing variables due to side effects.
1270 (match (lookup-cont label dfg)
1271 (($ $kargs names vars term)
1272 (let visit-term ((term term) (types types))
1274 (($ $letrec names vars funs term)
1276 (adjoin-vars types vars
1277 (make-type-entry &procedure
1279 (($ $letk conts term)
1280 (visit-term term types))
1281 (($ $continue k src exp)
1282 (visit-exp label entry k types exp)))))
1283 (($ $kreceive arity k)
1284 (match (lookup-cont k dfg)
1285 (($ $kargs names vars)
1287 (adjoin-vars types vars all-types-entry)))))
1288 (($ $kfun src meta self tail clause)
1289 (let ((types (adjoin-var types self all-types-entry)))
1293 (propagate! 0 kclause types)))))
1294 (($ $kclause arity ($ $cont kbody ($ $kargs names vars)) alt)
1296 (adjoin-vars types vars all-types-entry))
1300 (propagate! 1 kclause types))))
1306 ;; Iterate until we reach a fixed point.
1308 ;; Once the types have a fixed point, iterate until ranges also
1309 ;; reach a fixed point, saturating ranges to accelerate
1311 (unless types-changed?
1312 (set! saturate-ranges? #t))
1313 (set! types-changed? #f)
1314 (let ((label revisit-label))
1315 (set! revisit-label #f)
1319 ;; All done! Return the computed types.
1322 (define-record-type <type-analysis>
1323 (make-type-analysis min-label label-count types)
1325 (min-label type-analysis-min-label)
1326 (label-count type-analysis-label-count)
1327 (types type-analysis-types))
1329 (define (infer-types fun dfg)
1330 ;; Fun must be renumbered.
1332 (($ $cont min-label ($ $kfun))
1333 (let ((label-count ((make-local-cont-folder label-count)
1334 (lambda (k cont label-count) (1+ label-count))
1336 (make-type-analysis min-label label-count
1337 (infer-types* dfg min-label label-count))))))
1339 (define (lookup-pre-type analysis label def)
1341 (($ <type-analysis> min-label label-count typev)
1342 (let* ((entry (vector-ref typev (- label min-label)))
1343 (tentry (var-type-entry (vector-ref entry 0) def)))
1344 (values (type-entry-type tentry)
1345 (type-entry-min tentry)
1346 (type-entry-max tentry))))))
1348 (define (lookup-post-type analysis label def succ-idx)
1350 (($ <type-analysis> min-label label-count typev)
1351 (let* ((entry (vector-ref typev (- label min-label)))
1352 (tentry (var-type-entry (vector-ref entry (1+ succ-idx)) def)))
1353 (values (type-entry-type tentry)
1354 (type-entry-min tentry)
1355 (type-entry-max tentry))))))
1357 (define (primcall-types-check? analysis label name args)
1358 (match (hashq-ref *type-checkers* name)
1362 (($ <type-analysis> min-label label-count typev)
1363 (let ((entry (vector-ref typev (- label min-label))))
1364 (apply checker (vector-ref entry 0) args)))))))