Better simplification of literal constants that continue to branches
[bpt/guile.git] / module / language / cps / types.scm
CommitLineData
8bc65d2d
AW
1;;; Type analysis on CPS
2;;; Copyright (C) 2014 Free Software Foundation, Inc.
3;;;
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.
8;;;
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.
13;;;
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/>.
17
18;;; Commentary:
19;;;
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.
26;;;
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.
34;;;
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.
44;;;
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.
50;;;
51;;; It is not practical to precisely compute value ranges in all cases.
52;;; For example, in the following case:
53;;;
54;;; (let lp ((n 0)) (when (foo) (lp (1+ n))))
55;;;
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
68;;; appropriate).
69;;;
ec412d75
AW
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
3a12f2ce
AW
73;;; use _intmaps_ from (language cps intmap) to share state between
74;;; connected program points.
8bc65d2d
AW
75;;;
76;;; Code:
77
78(define-module (language cps types)
79 #:use-module (ice-9 match)
80 #:use-module (language cps)
81 #:use-module (language cps dfg)
3a12f2ce 82 #:use-module (language cps intmap)
8bc65d2d 83 #:use-module (rnrs bytevectors)
ec412d75
AW
84 #:use-module (srfi srfi-9)
85 #:use-module (srfi srfi-11)
8bc65d2d
AW
86 #:export (;; Specific types.
87 &exact-integer
88 &flonum
89 &complex
90 &fraction
91
92 &char
93 &unspecified
94 &unbound
95 &boolean
96 &nil
97 &null
98 &symbol
99 &keyword
100
101 &procedure
102
103 &pointer
104 &fluid
105 &pair
106 &vector
107 &box
108 &struct
109 &string
110 &bytevector
111 &bitvector
112 &array
113 &hash-table
114
115 ;; Union types.
116 &number &real
117
118 infer-types
119 lookup-pre-type
120 lookup-post-type
121 primcall-types-check?))
122
123(define-syntax define-flags
124 (lambda (x)
125 (syntax-case x ()
126 ((_ all shift name ...)
127 (let ((count (length #'(name ...))))
128 (with-syntax (((n ...) (iota count))
129 (count count))
130 #'(begin
131 (define-syntax name (identifier-syntax (ash 1 n)))
132 ...
133 (define-syntax all (identifier-syntax (1- (ash 1 count))))
134 (define-syntax shift (identifier-syntax count)))))))))
135
136;; More precise types have fewer bits.
137(define-flags &all-types &type-bits
138 &exact-integer
139 &flonum
140 &complex
141 &fraction
142
143 &char
144 &unspecified
145 &unbound
146 &boolean
147 &nil
148 &null
149 &symbol
150 &keyword
151
152 &procedure
153
154 &pointer
155 &fluid
156 &pair
157 &vector
158 &box
159 &struct
160 &string
161 &bytevector
162 &bitvector
163 &array
164 &hash-table)
165
166(define-syntax &no-type (identifier-syntax 0))
167
168(define-syntax &number
169 (identifier-syntax (logior &exact-integer &flonum &complex &fraction)))
170(define-syntax &real
171 (identifier-syntax (logior &exact-integer &flonum &fraction)))
172
173(define-syntax *max-s32* (identifier-syntax (- (ash 1 31) 1)))
174(define-syntax *min-s32* (identifier-syntax (- 0 (ash 1 31))))
175
176;; Versions of min and max that do not coerce exact numbers to become
177;; inexact.
178(define min
179 (case-lambda
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))))
183(define max
184 (case-lambda
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))))
188
3a12f2ce
AW
189\f
190
191(define-syntax-rule (define-compile-time-value name val)
192 (define-syntax name
193 (make-variable-transformer
194 (lambda (x)
195 (syntax-case x (set!)
196 (var (identifier? #'var)
197 (datum->syntax #'var val)))))))
198
199(define-compile-time-value min-fixnum most-negative-fixnum)
200(define-compile-time-value max-fixnum most-positive-fixnum)
201
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))
210
211(define-syntax-rule (clamp-range val)
212 (cond
213 ((< val min-fixnum) min-fixnum)
214 ((< max-fixnum val) max-fixnum)
215 (else val)))
216
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)))
225
226(define all-types-entry (make-type-entry &all-types -inf.0 +inf.0))
227
228(define* (var-type-entry typeset var #:optional (default all-types-entry))
229 (or (intmap-ref typeset var) default))
230
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)))
237
238;; Is the type entry A contained entirely within B?
239(define (type-entry<=? a b)
240 (match (cons 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))
243 (<= b-min a-min)
244 (>= b-max a-max)))))
245
246(define (type-entry-union a b)
247 (cond
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))))))
254
255(define (type-entry-intersection a b)
256 (cond
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))))))
263
264(define (adjoin-var typeset var entry)
265 (intmap-add typeset var entry type-entry-union))
266
267(define (restrict-var typeset var entry)
268 (intmap-add typeset var entry type-entry-intersection))
269
8bc65d2d
AW
270(define (constant-type val)
271 "Compute the type and range of VAL. Return three values: the type,
272minimum, and maximum."
273 (define (return type val)
274 (if val
3a12f2ce
AW
275 (make-type-entry type val val)
276 (make-type-entry type -inf.0 +inf.0)))
8bc65d2d
AW
277 (cond
278 ((number? val)
279 (cond
280 ((exact-integer? val) (return &exact-integer val))
281 ((eqv? (imag-part val) 0)
ec412d75 282 (if (nan? val)
3a12f2ce
AW
283 (make-type-entry &flonum -inf.0 +inf.0)
284 (make-type-entry
285 (if (exact? val) &fraction &flonum)
286 (if (rational? val) (inexact->exact (floor val)) val)
287 (if (rational? val) (inexact->exact (ceiling val)) val))))
8bc65d2d
AW
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))
303
304 (else (error "unhandled constant" val))))
305
8bc65d2d
AW
306(define *type-checkers* (make-hash-table))
307(define *type-inferrers* (make-hash-table))
8bc65d2d
AW
308
309(define-syntax-rule (define-type-helper name)
310 (define-syntax-parameter name
311 (lambda (stx)
312 (syntax-violation 'name
313 "macro used outside of define-type"
314 stx))))
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)
320
321(define-syntax-rule (define-type-checker (name arg ...) body ...)
322 (hashq-set!
323 *type-checkers*
324 'name
ec412d75 325 (lambda (typeset arg ...)
8bc65d2d 326 (syntax-parameterize
ec412d75
AW
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)))))
8bc65d2d
AW
330 body ...))))
331
332(define-syntax-rule (check-type arg type min max)
333 ;; If the arg is negative, it is a closure variable.
334 (and (>= arg 0)
335 (zero? (logand (lognot type) (&type arg)))
336 (<= min (&min arg))
337 (<= (&max arg) max)))
338
ec412d75 339(define-syntax-rule (define-type-inferrer* (name succ var ...) body ...)
8bc65d2d
AW
340 (hashq-set!
341 *type-inferrers*
342 'name
ec412d75
AW
343 (lambda (in succ var ...)
344 (let ((out in))
345 (syntax-parameterize
346 ((define!
347 (syntax-rules ()
348 ((_ val type min max)
3a12f2ce
AW
349 (set! out (adjoin-var out val
350 (make-type-entry type min max))))))
ec412d75
AW
351 (restrict!
352 (syntax-rules ()
353 ((_ val type min max)
3a12f2ce
AW
354 (set! out (restrict-var out val
355 (make-type-entry type min max))))))
ec412d75
AW
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)))))
359 body ...
360 out)))))
361
362(define-syntax-rule (define-type-inferrer (name arg ...) body ...)
363 (define-type-inferrer* (name succ arg ...) body ...))
364
365(define-syntax-rule (define-predicate-inferrer (name arg ... true?) body ...)
366 (define-type-inferrer* (name succ arg ...)
367 (let ((true? (not (zero? succ))))
368 body ...)))
8bc65d2d
AW
369
370(define-syntax define-simple-type-checker
371 (lambda (x)
372 (define (parse-spec l)
373 (syntax-case l ()
374 (() '())
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)))))
378 (syntax-case x ()
379 ((_ (name arg-spec ...) result-spec ...)
380 (with-syntax
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)
385 ...)))))))
386
387(define-syntax define-simple-type-inferrer
388 (lambda (x)
389 (define (parse-spec l)
390 (syntax-case l ()
391 (() '())
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)))))
395 (syntax-case x ()
396 ((_ (name arg-spec ...) result-spec ...)
397 (with-syntax
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)
404 ...
405 (define! res res-type res-min res-max)
406 ...))))))
407
408(define-syntax-rule (define-simple-type (name arg-spec ...) result-spec ...)
409 (begin
410 (define-simple-type-checker (name arg-spec ...))
411 (define-simple-type-inferrer (name arg-spec ...) result-spec ...)))
412
413(define-syntax-rule (define-simple-types
414 ((name arg-spec ...) result-spec ...)
415 ...)
416 (begin
417 (define-simple-type (name arg-spec ...) result-spec ...)
418 ...))
419
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)
423 ...))
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)
427 ...))
428(define-syntax-rule (define-type-aliases orig alias ...)
429 (begin
430 (define-type-checker-aliases orig alias ...)
431 (define-type-inferrer-aliases orig alias ...)))
432
433
434\f
435
436;;; This list of primcall type definitions follows the order of
437;;; effects-analysis.scm; please keep it in a similar order.
438;;;
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.
444;;;
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.
448
449
450\f
451
8bc65d2d
AW
452;;;
453;;; Generic effect-free predicates.
454;;;
455
456(define-predicate-inferrer (eq? a b true?)
457 ;; We can only propagate information down the true leg.
458 (when true?
459 (let ((type (logand (&type a) (&type b)))
460 (min (max (&min a) (&min b)))
461 (max (min (&max a) (&max b))))
462 (restrict! a type min max)
463 (restrict! b type min max))))
464(define-type-inferrer-aliases eq? eqv? equal?)
465
466(define-syntax-rule (define-simple-predicate-inferrer predicate type)
467 (define-predicate-inferrer (predicate val true?)
468 (let ((type (if true?
469 type
470 (logand (&type val) (lognot type)))))
471 (restrict! val type -inf.0 +inf.0))))
472(define-simple-predicate-inferrer pair? &pair)
473(define-simple-predicate-inferrer null? &null)
474(define-simple-predicate-inferrer nil? &nil)
475(define-simple-predicate-inferrer symbol? &symbol)
476(define-simple-predicate-inferrer variable? &box)
477(define-simple-predicate-inferrer vector? &vector)
478(define-simple-predicate-inferrer struct? &struct)
479(define-simple-predicate-inferrer string? &string)
480(define-simple-predicate-inferrer number? &number)
481(define-simple-predicate-inferrer char? &char)
482(define-simple-predicate-inferrer procedure? &procedure)
483(define-simple-predicate-inferrer thunk? &procedure)
484
485\f
486
487;;;
488;;; Fluids. Note that we can't track bound-ness of fluids, as pop-fluid
489;;; can change boundness.
490;;;
491
492(define-simple-types
493 ((fluid-ref (&fluid 1)) &all-types)
494 ((fluid-set! (&fluid 0 1) &all-types))
495 ((push-fluid (&fluid 0 1) &all-types))
496 ((pop-fluid)))
497
498
499\f
500
501;;;
502;;; Prompts. (Nothing to do.)
503;;;
504
505
506\f
507
508;;;
509;;; Pairs.
510;;;
511
512(define-simple-types
513 ((cons &all-types &all-types) &pair)
514 ((car &pair) &all-types)
515 ((set-car! &pair &all-types))
516 ((cdr &pair) &all-types)
517 ((set-cdr! &pair &all-types)))
518
519
520\f
521
522;;;
523;;; Variables.
524;;;
525
526(define-simple-types
527 ((box &all-types) (&box 1))
528 ((box-ref (&box 1)) &all-types))
529
530(define-simple-type-checker (box-set! (&box 0 1) &all-types))
531(define-type-inferrer (box-set! box val)
532 (restrict! box &box 1 1))
533
534
535\f
536
537;;;
538;;; Vectors.
539;;;
540
541;; This max-vector-len computation is a hack.
542(define *max-vector-len* (ash most-positive-fixnum -5))
543
544(define-simple-type-checker (make-vector (&exact-integer 0 *max-vector-len*)
545 &all-types))
546(define-type-inferrer (make-vector size init result)
547 (restrict! size &exact-integer 0 *max-vector-len*)
ec412d75 548 (define! result &vector (max (&min size) 0) (&max size)))
8bc65d2d
AW
549
550(define-type-checker (vector-ref v idx)
551 (and (check-type v &vector 0 *max-vector-len*)
552 (check-type idx &exact-integer 0 (1- (&min v)))))
553(define-type-inferrer (vector-ref v idx result)
554 (restrict! v &vector (1+ (&min idx)) +inf.0)
555 (restrict! idx &exact-integer 0 (1- (&max v)))
556 (define! result &all-types -inf.0 +inf.0))
557
558(define-type-checker (vector-set! v idx val)
559 (and (check-type v &vector 0 *max-vector-len*)
560 (check-type idx &exact-integer 0 (1- (&min v)))))
561(define-type-inferrer (vector-set! v idx val)
562 (restrict! v &vector (1+ (&min idx)) +inf.0)
563 (restrict! idx &exact-integer 0 (1- (&max v))))
564
565(define-type-aliases make-vector make-vector/immediate)
566(define-type-aliases vector-ref vector-ref/immediate)
567(define-type-aliases vector-set! vector-set!/immediate)
568
569(define-simple-type-checker (vector-length &vector))
570(define-type-inferrer (vector-length v result)
571 (restrict! v &vector 0 *max-vector-len*)
ec412d75
AW
572 (define! result &exact-integer (max (&min v) 0)
573 (min (&max v) *max-vector-len*)))
8bc65d2d
AW
574
575
576\f
577
578;;;
579;;; Structs.
580;;;
581
582;; No type-checker for allocate-struct, as we can't currently check that
583;; vt is actually a vtable.
584(define-type-inferrer (allocate-struct vt size result)
585 (restrict! vt &struct vtable-offset-user +inf.0)
586 (restrict! size &exact-integer 0 +inf.0)
587 (define! result &struct (max (&min size) 0) (&max size)))
588
589(define-type-checker (struct-ref s idx)
590 (and (check-type s &struct 0 +inf.0)
591 (check-type idx &exact-integer 0 +inf.0)
592 ;; FIXME: is the field readable?
593 (< (&max idx) (&min s))))
594(define-type-inferrer (struct-ref s idx result)
595 (restrict! s &struct (1+ (&min idx)) +inf.0)
596 (restrict! idx &exact-integer 0 (1- (&max s)))
597 (define! result &all-types -inf.0 +inf.0))
598
599(define-type-checker (struct-set! s idx val)
600 (and (check-type s &struct 0 +inf.0)
601 (check-type idx &exact-integer 0 +inf.0)
602 ;; FIXME: is the field writable?
603 (< (&max idx) (&min s))))
604(define-type-inferrer (struct-set! s idx val)
605 (restrict! s &struct (1+ (&min idx)) +inf.0)
606 (restrict! idx &exact-integer 0 (1- (&max s))))
607
608(define-type-aliases allocate-struct allocate-struct/immediate)
609(define-type-aliases struct-ref struct-ref/immediate)
610(define-type-aliases struct-set! struct-set!/immediate)
611
612(define-simple-type (struct-vtable (&struct 0 +inf.0))
613 (&struct vtable-offset-user +inf.0))
614
615
616\f
617
618;;;
619;;; Strings.
620;;;
621
622(define *max-char* (1- (ash 1 24)))
623
624(define-type-checker (string-ref s idx)
625 (and (check-type s &string 0 +inf.0)
626 (check-type idx &exact-integer 0 +inf.0)
627 (< (&max idx) (&min s))))
628(define-type-inferrer (string-ref s idx result)
629 (restrict! s &string (1+ (&min idx)) +inf.0)
630 (restrict! idx &exact-integer 0 (1- (&max s)))
631 (define! result &char 0 *max-char*))
632
633(define-type-checker (string-set! s idx val)
634 (and (check-type s &string 0 +inf.0)
635 (check-type idx &exact-integer 0 +inf.0)
636 (check-type val &char 0 *max-char*)
637 (< (&max idx) (&min s))))
638(define-type-inferrer (string-set! s idx val)
639 (restrict! s &string (1+ (&min idx)) +inf.0)
640 (restrict! idx &exact-integer 0 (1- (&max s)))
641 (restrict! val &char 0 *max-char*))
642
643(define-simple-type-checker (string-length &string))
644(define-type-inferrer (string-length s result)
645 (restrict! s &string 0 +inf.0)
646 (define! result &exact-integer (max (&min s) 0) (&max s)))
647
648(define-simple-type (number->string &number) (&string 0 +inf.0))
649(define-simple-type (string->number (&string 0 +inf.0))
650 ((logior &number &boolean) -inf.0 +inf.0))
651
652
653\f
654
655;;;
656;;; Bytevectors.
657;;;
658
659(define-simple-type-checker (bytevector-length &bytevector))
660(define-type-inferrer (bytevector-length bv result)
661 (restrict! bv &bytevector 0 +inf.0)
662 (define! result &exact-integer (max (&min bv) 0) (&max bv)))
663
664(define-syntax-rule (define-bytevector-accessors ref set type size min max)
665 (begin
666 (define-type-checker (ref bv idx)
667 (and (check-type bv &bytevector 0 +inf.0)
668 (check-type idx &exact-integer 0 +inf.0)
669 (< (&max idx) (- (&min bv) size))))
670 (define-type-inferrer (ref bv idx result)
671 (restrict! bv &bytevector (+ (&min idx) size) +inf.0)
672 (restrict! idx &exact-integer 0 (- (&max bv) size))
673 (define! result type min max))
674 (define-type-checker (set bv idx val)
675 (and (check-type bv &bytevector 0 +inf.0)
676 (check-type idx &exact-integer 0 +inf.0)
677 (check-type val type min max)
678 (< (&max idx) (- (&min bv) size))))
679 (define-type-inferrer (set! bv idx val)
680 (restrict! bv &bytevector (+ (&min idx) size) +inf.0)
681 (restrict! idx &exact-integer 0 (- (&max bv) size))
682 (restrict! val type min max))))
683
684(define-syntax-rule (define-short-bytevector-accessors ref set size signed?)
685 (define-bytevector-accessors ref set &exact-integer size
686 (if signed? (- (ash 1 (1- (* size 8)))) 0)
687 (1- (ash 1 (if signed? (1- (* size 8)) (* size 8))))))
688
689(define-short-bytevector-accessors bv-u8-ref bv-u8-set! 1 #f)
690(define-short-bytevector-accessors bv-s8-ref bv-s8-set! 1 #t)
691(define-short-bytevector-accessors bv-u16-ref bv-u16-set! 2 #f)
692(define-short-bytevector-accessors bv-s16-ref bv-s16-set! 2 #t)
693
694;; The range analysis only works on signed 32-bit values, so some limits
695;; are out of range.
696(define-bytevector-accessors bv-u32-ref bv-u32-set! &exact-integer 4 0 +inf.0)
697(define-bytevector-accessors bv-s32-ref bv-s32-set! &exact-integer 4 -inf.0 +inf.0)
698(define-bytevector-accessors bv-u64-ref bv-u64-set! &exact-integer 8 0 +inf.0)
699(define-bytevector-accessors bv-s64-ref bv-s64-set! &exact-integer 8 -inf.0 +inf.0)
700(define-bytevector-accessors bv-f32-ref bv-f32-set! &real 4 -inf.0 +inf.0)
701(define-bytevector-accessors bv-f64-ref bv-f64-set! &real 8 -inf.0 +inf.0)
702
703
704\f
705
706;;;
707;;; Numbers.
708;;;
709
710;; First, branching primitives with no results.
711(define-simple-type-checker (= &number &number))
712(define-predicate-inferrer (= a b true?)
713 (when (and true?
714 (zero? (logand (logior (&type a) (&type b)) (lognot &number))))
715 (let ((min (max (&min a) (&min b)))
716 (max (min (&max a) (&max b))))
717 (restrict! a &number min max)
718 (restrict! b &number min max))))
719
720(define-simple-type-checker (< &real &real))
721(define-predicate-inferrer (< a b true?)
722 (when (zero? (logand (logior (&type a) (&type b)) (lognot &number)))
723 (restrict! a &real -inf.0 +inf.0)
724 (restrict! b &real -inf.0 +inf.0)))
725(define-type-aliases < <= > >=)
726
727;; Arithmetic.
728(define-syntax-rule (define-unary-result! a result min max)
729 (let ((min* min)
730 (max* max)
731 (type (logand (&type a) &number)))
732 (cond
733 ((not (= type (&type a)))
734 ;; Not a number. Punt and do nothing.
735 (define! result &all-types -inf.0 +inf.0))
736 ;; Complex numbers don't have a range.
737 ((eqv? type &complex)
738 (define! result &complex -inf.0 +inf.0))
739 (else
740 (define! result type min* max*)))))
741
742(define-syntax-rule (define-binary-result! a b result closed? min max)
743 (let ((min* min)
744 (max* max)
745 (a-type (logand (&type a) &number))
746 (b-type (logand (&type b) &number)))
747 (cond
748 ((or (not (= a-type (&type a))) (not (= b-type (&type b))))
749 ;; One input not a number. Perhaps we end up dispatching to
750 ;; GOOPS.
751 (define! result &all-types -inf.0 +inf.0))
752 ;; Complex and floating-point numbers are contagious.
753 ((or (eqv? a-type &complex) (eqv? b-type &complex))
754 (define! result &complex -inf.0 +inf.0))
755 ((or (eqv? a-type &flonum) (eqv? b-type &flonum))
756 (define! result &flonum min* max*))
757 ;; Exact integers are closed under some operations.
758 ((and closed? (eqv? a-type &exact-integer) (eqv? b-type &exact-integer))
759 (define! result &exact-integer min* max*))
760 (else
761 ;; Fractions may become integers.
762 (let ((type (logior a-type b-type)))
763 (define! result
764 (if (zero? (logand type &fraction))
765 type
766 (logior type &exact-integer))
767 min* max*))))))
768
769(define-simple-type-checker (add &number &number))
770(define-type-inferrer (add a b result)
771 (define-binary-result! a b result #t
772 (+ (&min a) (&min b))
773 (+ (&max a) (&max b))))
774
775(define-simple-type-checker (sub &number &number))
776(define-type-inferrer (sub a b result)
777 (define-binary-result! a b result #t
778 (- (&min a) (&max b))
779 (- (&max a) (&min b))))
780
781(define-simple-type-checker (mul &number &number))
782(define-type-inferrer (mul a b result)
783 (let ((min-a (&min a)) (max-a (&max a))
784 (min-b (&min b)) (max-b (&max b)))
42b544eb
AW
785 (define (nan* a b)
786 ;; We only really get +inf.0 at runtime for flonums and compnums.
787 ;; If we have inferred that the arguments are not flonums and not
788 ;; compnums, then the result of (* +inf.0 0) at range inference
789 ;; time is 0 and not +nan.0.
790 (if (or (and (inf? a) (zero? b))
791 (and (zero? a) (inf? b))
792 (not (logtest (logior (&type a) (&type b))
793 (logior &flonum &complex))))
794 0
795 (* a b)))
796 (let ((-- (nan* min-a min-b))
797 (-+ (nan* min-a max-b))
798 (++ (nan* max-a max-b))
799 (+- (nan* max-a min-b)))
800 (let ((has-nan? (or (nan? --) (nan? -+) (nan? ++) (nan? +-))))
801 (define-binary-result! a b result #t
802 (cond
803 ((eqv? a b) 0)
804 (has-nan? -inf.0)
805 (else (min -- -+ ++ +-)))
806 (if has-nan?
807 +inf.0
808 (max -- -+ ++ +-)))))))
8bc65d2d
AW
809
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
814 ;; zero.
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)))
819 (call-with-values
820 (lambda ()
821 (if (<= min-b 0 max-b)
822 ;; If the range of the divisor crosses 0, the result spans
823 ;; the whole range.
824 (values -inf.0 +inf.0)
825 ;; Otherwise min-b and max-b have the same sign, and cannot both
826 ;; be infinity.
42b544eb
AW
827 (let ((--- (if (inf? min-b) 0 (floor/ min-a min-b)))
828 (-+- (if (inf? max-b) 0 (floor/ min-a max-b)))
829 (++- (if (inf? max-b) 0 (floor/ max-a max-b)))
830 (+-- (if (inf? min-b) 0 (floor/ max-a min-b)))
831 (--+ (if (inf? min-b) 0 (ceiling/ min-a min-b)))
832 (-++ (if (inf? max-b) 0 (ceiling/ min-a max-b)))
833 (+++ (if (inf? max-b) 0 (ceiling/ max-a max-b)))
834 (+-+ (if (inf? min-b) 0 (ceiling/ max-a min-b))))
835 (values (min (min --- -+- ++- +--)
836 (min --+ -++ +++ +-+))
837 (max (max --- -+- ++- +--)
838 (max --+ -++ +++ +-+))))))
8bc65d2d
AW
839 (lambda (min max)
840 (define-binary-result! a b result #f min max)))))
841
842(define-simple-type-checker (add1 &number))
843(define-type-inferrer (add1 a result)
844 (define-unary-result! a result (1+ (&min a)) (1+ (&max a))))
845
846(define-simple-type-checker (sub1 &number))
847(define-type-inferrer (sub1 a result)
848 (define-unary-result! a result (1- (&min a)) (1- (&max a))))
849
850(define-type-checker (quo a b)
851 (and (check-type a &exact-integer -inf.0 +inf.0)
852 (check-type b &exact-integer -inf.0 +inf.0)
853 ;; We only know that there will not be an exception if b is not
854 ;; zero.
855 (not (<= (&min b) 0 (&max b)))))
856(define-type-inferrer (quo a b result)
857 (restrict! a &exact-integer -inf.0 +inf.0)
858 (restrict! b &exact-integer -inf.0 +inf.0)
859 (define! result &exact-integer -inf.0 +inf.0))
860
861(define-type-checker-aliases quo rem)
862(define-type-inferrer (rem a b result)
863 (restrict! a &exact-integer -inf.0 +inf.0)
864 (restrict! b &exact-integer -inf.0 +inf.0)
865 ;; Same sign as A.
866 (let ((max-abs-rem (1- (max (abs (&min b)) (abs (&max b))))))
867 (cond
868 ((< (&min a) 0)
869 (if (< 0 (&max a))
870 (define! result &exact-integer (- max-abs-rem) max-abs-rem)
871 (define! result &exact-integer (- max-abs-rem) 0)))
872 (else
873 (define! result &exact-integer 0 max-abs-rem)))))
874
875(define-type-checker-aliases quo mod)
876(define-type-inferrer (mod a b result)
877 (restrict! a &exact-integer -inf.0 +inf.0)
878 (restrict! b &exact-integer -inf.0 +inf.0)
879 ;; Same sign as B.
880 (let ((max-abs-mod (1- (max (abs (&min b)) (abs (&max b))))))
881 (cond
882 ((< (&min b) 0)
883 (if (< 0 (&max b))
884 (define! result &exact-integer (- max-abs-mod) max-abs-mod)
885 (define! result &exact-integer (- max-abs-mod) 0)))
886 (else
887 (define! result &exact-integer 0 max-abs-mod)))))
888
889;; Predicates.
890(define-syntax-rule (define-number-kind-predicate-inferrer name type)
891 (define-type-inferrer (name val result)
892 (cond
893 ((zero? (logand (&type val) type))
894 (define! result &boolean 0 0))
895 ((zero? (logand (&type val) (lognot type)))
896 (define! result &boolean 1 1))
897 (else
898 (define! result &boolean 0 1)))))
899(define-number-kind-predicate-inferrer complex? &number)
900(define-number-kind-predicate-inferrer real? &real)
901(define-number-kind-predicate-inferrer rational?
902 (logior &exact-integer &fraction))
903(define-number-kind-predicate-inferrer integer?
904 (logior &exact-integer &flonum))
905(define-number-kind-predicate-inferrer exact-integer?
906 &exact-integer)
907
908(define-simple-type-checker (exact? &number))
909(define-type-inferrer (exact? val result)
910 (restrict! val &number -inf.0 +inf.0)
911 (cond
912 ((zero? (logand (&type val) (logior &exact-integer &fraction)))
913 (define! result &boolean 0 0))
914 ((zero? (logand (&type val) (lognot (logior &exact-integer &fraction))))
915 (define! result &boolean 1 1))
916 (else
917 (define! result &boolean 0 1))))
918
919(define-simple-type-checker (inexact? &number))
920(define-type-inferrer (inexact? val result)
921 (restrict! val &number -inf.0 +inf.0)
922 (cond
923 ((zero? (logand (&type val) (logior &flonum &complex)))
924 (define! result &boolean 0 0))
ec412d75
AW
925 ((zero? (logand (&type val) (logand &number
926 (lognot (logior &flonum &complex)))))
8bc65d2d
AW
927 (define! result &boolean 1 1))
928 (else
929 (define! result &boolean 0 1))))
930
931(define-simple-type-checker (inf? &real))
932(define-type-inferrer (inf? val result)
933 (restrict! val &real -inf.0 +inf.0)
934 (cond
935 ((or (zero? (logand (&type val) (logior &flonum &complex)))
936 (and (not (inf? (&min val))) (not (inf? (&max val)))))
937 (define! result &boolean 0 0))
938 (else
939 (define! result &boolean 0 1))))
940
941(define-type-aliases inf? nan?)
942
943(define-simple-type (even? &exact-integer) (&boolean 0 1))
944(define-type-aliases even? odd?)
945
946;; Bit operations.
947(define-simple-type-checker (ash &exact-integer &exact-integer))
948(define-type-inferrer (ash val count result)
949 (define (ash* val count)
950 ;; As we can only represent a 32-bit range, don't bother inferring
951 ;; shifts that might exceed that range.
952 (cond
953 ((inf? val) val) ; Preserves sign.
954 ((< -32 count 32) (ash val count))
955 ((zero? val) 0)
956 ((positive? val) +inf.0)
957 (else -inf.0)))
958 (restrict! val &exact-integer -inf.0 +inf.0)
959 (restrict! count &exact-integer -inf.0 +inf.0)
960 (let ((-- (ash* (&min val) (&min count)))
961 (-+ (ash* (&min val) (&max count)))
962 (++ (ash* (&max val) (&max count)))
963 (+- (ash* (&max val) (&min count))))
964 (define! result &exact-integer
965 (min -- -+ ++ +-)
966 (max -- -+ ++ +-))))
967
968(define (next-power-of-two n)
969 (let lp ((out 1))
970 (if (< n out)
971 out
972 (lp (ash out 1)))))
973
974(define-simple-type-checker (logand &exact-integer &exact-integer))
975(define-type-inferrer (logand a b result)
976 (define (logand-min a b)
74fe7fae 977 (if (and (negative? a) (negative? b))
8bc65d2d
AW
978 (min a b)
979 0))
980 (define (logand-max a b)
74fe7fae
AW
981 (if (and (positive? a) (positive? b))
982 (min a b)
983 0))
8bc65d2d
AW
984 (restrict! a &exact-integer -inf.0 +inf.0)
985 (restrict! b &exact-integer -inf.0 +inf.0)
986 (define! result &exact-integer
987 (logand-min (&min a) (&min b))
988 (logand-max (&max a) (&max b))))
989
990(define-simple-type-checker (logior &exact-integer &exact-integer))
991(define-type-inferrer (logior a b result)
992 ;; Saturate all bits of val.
993 (define (saturate val)
994 (1- (next-power-of-two val)))
995 (define (logior-min a b)
996 (cond ((and (< a 0) (<= 0 b)) a)
997 ((and (< b 0) (<= 0 a)) b)
998 (else (max a b))))
999 (define (logior-max a b)
1000 ;; If either operand is negative, just assume the max is -1.
1001 (cond
1002 ((or (< a 0) (< b 0)) -1)
1003 ((or (inf? a) (inf? b)) +inf.0)
1004 (else (saturate (logior a b)))))
1005 (restrict! a &exact-integer -inf.0 +inf.0)
1006 (restrict! b &exact-integer -inf.0 +inf.0)
1007 (define! result &exact-integer
1008 (logior-min (&min a) (&min b))
1009 (logior-max (&max a) (&max b))))
1010
1011;; For our purposes, treat logxor the same as logior.
1012(define-type-aliases logior logxor)
1013
1014(define-simple-type-checker (lognot &exact-integer))
1015(define-type-inferrer (lognot a result)
1016 (restrict! a &exact-integer -inf.0 +inf.0)
1017 (define! result &exact-integer
1018 (- -1 (&max a))
1019 (- -1 (&min a))))
1020
8006d2d6 1021(define-simple-type-checker (logtest &exact-integer &exact-integer))
d613ccaa 1022(define-predicate-inferrer (logtest a b true?)
8006d2d6 1023 (restrict! a &exact-integer -inf.0 +inf.0)
d613ccaa 1024 (restrict! b &exact-integer -inf.0 +inf.0))
8006d2d6
AW
1025
1026(define-simple-type-checker (logbit? (&exact-integer 0 +inf.0) &exact-integer))
1027(define-type-inferrer (logbit? a b result)
1028 (let ((a-min (&min a))
1029 (a-max (&max a))
1030 (b-min (&min b))
1031 (b-max (&max b)))
1032 (if (and (eqv? a-min a-max) (>= a-min 0) (not (inf? a-min))
1033 (eqv? b-min b-max) (>= b-min 0) (not (inf? b-min)))
1034 (let ((res (if (logbit? a-min b-min) 1 0)))
1035 (define! result &boolean res res))
1036 (define! result &boolean 0 1))))
1037
8bc65d2d
AW
1038;; Flonums.
1039(define-simple-type-checker (sqrt &number))
1040(define-type-inferrer (sqrt x result)
8bc65d2d
AW
1041 (let ((type (&type x)))
1042 (cond
1043 ((and (zero? (logand type &complex)) (<= 0 (&min x)))
1044 (define! result
1045 (logior type &flonum)
1046 (inexact->exact (floor (sqrt (&min x))))
1047 (if (inf? (&max x))
1048 +inf.0
1049 (inexact->exact (ceiling (sqrt (&max x)))))))
1050 (else
1051 (define! result (logior type &flonum &complex) -inf.0 +inf.0)))))
1052
1053(define-simple-type-checker (abs &real))
1054(define-type-inferrer (abs x result)
ec412d75
AW
1055 (let ((type (&type x)))
1056 (cond
1057 ((eqv? type (logand type &number))
1058 (restrict! x &real -inf.0 +inf.0)
1059 (define! result (logand type &real)
1060 (min (abs (&min x)) (abs (&max x)))
1061 (max (abs (&min x)) (abs (&max x)))))
1062 (else
1063 (define! result (logior (logand (&type x) (lognot &number))
1064 (logand (&type x) &real))
1065 (max (&min x) 0)
1066 (max (abs (&min x)) (abs (&max x))))))))
8bc65d2d
AW
1067
1068
1069\f
1070
1071;;;
1072;;; Characters.
1073;;;
1074
1075(define-simple-type (char<? &char &char) (&boolean 0 1))
1076(define-type-aliases char<? char<=? char>=? char>?)
1077
1078(define-simple-type-checker (integer->char (&exact-integer 0 #x10ffff)))
1079(define-type-inferrer (integer->char i result)
1080 (restrict! i &exact-integer 0 #x10ffff)
ec412d75 1081 (define! result &char (max (&min i) 0) (min (&max i) #x10ffff)))
8bc65d2d
AW
1082
1083(define-simple-type-checker (char->integer &char))
1084(define-type-inferrer (char->integer c result)
1085 (restrict! c &char 0 #x10ffff)
ec412d75 1086 (define! result &exact-integer (max (&min c) 0) (min (&max c) #x10ffff)))
8bc65d2d
AW
1087
1088
1089\f
1090
1091;;;
1092;;; Type flow analysis: the meet (ahem) of the algorithm.
1093;;;
1094
ec412d75 1095(define (infer-types* dfg min-label label-count)
8bc65d2d
AW
1096 "Compute types for all variables in @var{fun}. Returns a hash table
1097mapping symbols to types."
ec412d75
AW
1098 (let ((typev (make-vector label-count))
1099 (idoms (compute-idoms dfg min-label label-count))
1100 (revisit-label #f)
1101 (types-changed? #f)
1102 (saturate-ranges? #f))
8bc65d2d 1103 (define (label->idx label) (- label min-label))
ec412d75
AW
1104
1105 (define (get-entry label) (vector-ref typev (label->idx label)))
1106
1107 (define (in-types entry) (vector-ref entry 0))
1108 (define (out-types entry succ) (vector-ref entry (1+ succ)))
1109
1110 (define (update-in-types! entry types)
1111 (vector-set! entry 0 types))
1112 (define (update-out-types! entry succ types)
1113 (vector-set! entry (1+ succ) types))
1114
1115 (define (prepare-initial-state!)
1116 ;; The result is a vector with an entry for each label. Each entry
1117 ;; is a vector. The first slot in the entry vector corresponds to
1118 ;; the types that flow into the labelled expression. The following
1119 ;; slot is for the types that flow out to the first successor, and
1120 ;; so on for additional successors.
1121 (let lp ((label min-label))
1122 (when (< label (+ min-label label-count))
1123 (let* ((nsuccs (match (lookup-cont label dfg)
1124 (($ $kargs _ _ term)
1125 (match (find-call term)
1126 (($ $continue k src (or ($ $branch) ($ $prompt))) 2)
1127 (_ 1)))
1128 (($ $kfun src meta self tail clause) (if clause 1 0))
1129 (($ $kclause arity body alt) (if alt 2 1))
1130 (($ $kreceive) 1)
1131 (($ $ktail) 0)))
1132 (entry (make-vector (1+ nsuccs) #f)))
1133 (vector-set! typev (label->idx label) entry)
1134 (lp (1+ label)))))
1135
1136 ;; Initial state: nothing flows into the $kfun.
1137 (let ((entry (get-entry min-label)))
3a12f2ce 1138 (update-in-types! entry empty-intmap)))
ec412d75 1139
3a12f2ce 1140 (define (adjoin-vars types vars entry)
ec412d75
AW
1141 (match vars
1142 (() types)
1143 ((var . vars)
3a12f2ce 1144 (adjoin-vars (adjoin-var types var entry) vars entry))))
ec412d75
AW
1145
1146 (define (infer-primcall types succ name args result)
1147 (cond
1148 ((hashq-ref *type-inferrers* name)
1149 => (lambda (inferrer)
1150 ;; FIXME: remove the apply?
1151 ;(pk 'primcall name args result)
1152 (apply inferrer types succ
1153 (if result
1154 (append args (list result))
1155 args))))
1156 (result
3a12f2ce 1157 (adjoin-var types result all-types-entry))
ec412d75
AW
1158 (else
1159 types)))
1160
3a12f2ce
AW
1161 (define (type-entry-saturating-union a b)
1162 (cond
1163 ((type-entry<=? b a) a)
1164 #;
1165 ((and (not saturate-ranges?)
1166 (eqv? (a-type ))
1167 (type-entry<=? a b)) b)
1168 (else (make-type-entry
1169 (let* ((a-type (type-entry-type a))
1170 (b-type (type-entry-type b))
1171 (type (logior a-type b-type)))
1172 (unless (eqv? a-type type)
1173 (set! types-changed? #t))
1174 type)
1175 (let ((a-min (type-entry-clamped-min a))
1176 (b-min (type-entry-clamped-min b)))
1177 (if (< b-min a-min)
1178 (if saturate-ranges? min-fixnum b-min)
1179 a-min))
1180 (let ((a-max (type-entry-clamped-max a))
1181 (b-max (type-entry-clamped-max b)))
1182 (if (> b-max a-max)
1183 (if saturate-ranges? max-fixnum b-max)
1184 a-max))))))
1185
ec412d75
AW
1186 (define (propagate-types! pred-label pred-entry succ-idx succ-label out)
1187 ;; Update "in" set of continuation.
1188 (let ((succ-entry (get-entry succ-label)))
1189 (match (lookup-predecessors succ-label dfg)
1190 ((_)
1191 ;; A normal edge.
1192 (update-in-types! succ-entry out))
1193 (_
1194 ;; A control-flow join.
1195 (let* ((succ-dom-label (vector-ref idoms (label->idx succ-label)))
1196 (succ-dom-entry (get-entry succ-dom-label))
1197 (old-in (in-types succ-entry))
3a12f2ce
AW
1198 (in (if old-in
1199 (intmap-intersect old-in out
1200 type-entry-saturating-union)
1201 out)))
1202 ;; If the "in" set changed, update the entry and possibly
1203 ;; arrange to iterate again.
1204 (unless (eq? old-in in)
1205 (update-in-types! succ-entry in)
1206 ;; If the changed successor is a back-edge, ensure that
1207 ;; we revisit the function.
1208 (when (<= succ-label pred-label)
1209 (unless (and revisit-label (<= revisit-label succ-label))
1210 ;; (pk 'marking-revisit pred-label succ-label)
1211 (set! revisit-label succ-label))))))))
ec412d75
AW
1212 ;; Finally update "out" set for current expression.
1213 (update-out-types! pred-entry succ-idx out))
1214
1215 (define (visit-exp label entry k types exp)
1216 (define (propagate! succ-idx succ-label types)
1217 (propagate-types! label entry succ-idx succ-label types))
1218 ;; Each of these branches must propagate! to its successors.
1219 (match exp
1220 (($ $branch kt ($ $values (arg)))
1221 ;; The "normal" continuation is the #f branch.
3a12f2ce
AW
1222 (let ((types (restrict-var types arg
1223 (make-type-entry (logior &boolean &nil)
1224 0
1225 0))))
ec412d75
AW
1226 (propagate! 0 k types))
1227 ;; No additional information on the #t branch,
1228 ;; as there's no way currently to remove #f
1229 ;; from the typeset (because it would remove
1230 ;; #t as well: they are both &boolean).
1231 (propagate! 1 kt types))
1232 (($ $branch kt ($ $primcall name args))
1233 ;; The "normal" continuation is the #f branch.
1234 (let ((types (infer-primcall types 0 name args #f)))
1235 (propagate! 0 k types))
1236 (let ((types (infer-primcall types 1 name args #f)))
1237 (propagate! 1 kt types)))
1238 (($ $prompt escape? tag handler)
1239 ;; The "normal" continuation enters the prompt.
1240 (propagate! 0 k types)
1241 (propagate! 1 handler types))
1242 (($ $primcall name args)
1243 (propagate! 0 k
1244 (match (lookup-cont k dfg)
1245 (($ $kargs _ defs)
1246 (infer-primcall types 0 name args
1247 (match defs ((var) var) (() #f))))
1248 (_
1249 ;(pk 'warning-no-restrictions name)
1250 types))))
1251 (($ $values args)
1252 (match (lookup-cont k dfg)
1253 (($ $kargs _ defs)
1254 (let ((in types))
1255 (let lp ((defs defs) (args args) (out types))
1256 (match (cons defs args)
1257 ((() . ())
1258 (propagate! 0 k out))
1259 (((def . defs) . (arg . args))
1260 (lp defs args
3a12f2ce 1261 (adjoin-var out def (var-type-entry in arg))))))))
ec412d75
AW
1262 (_
1263 (propagate! 0 k types))))
1264 ((or ($ $call) ($ $callk))
1265 (propagate! 0 k types))
8bc65d2d 1266 (_
3a12f2ce
AW
1267 (match (lookup-cont k dfg)
1268 (($ $kargs (_) (var))
1269 (let ((entry (match exp
1270 (($ $void)
1271 (make-type-entry &unspecified -inf.0 +inf.0))
1272 (($ $const val)
1273 (constant-type val))
1274 ((or ($ $prim) ($ $fun) ($ $closure))
1275 ;; Could be more precise here.
1276 (make-type-entry &procedure -inf.0 +inf.0)))))
1277 (propagate! 0 k (adjoin-var types var entry))))))))
ec412d75
AW
1278
1279 (prepare-initial-state!)
1280
1281 ;; Iterate over all labelled expressions in the function,
1282 ;; propagating types and ranges to all successors.
8bc65d2d 1283 (let lp ((label min-label))
ec412d75 1284 ;(pk 'visit label)
8bc65d2d
AW
1285 (cond
1286 ((< label (+ min-label label-count))
ec412d75
AW
1287 (let* ((entry (vector-ref typev (label->idx label)))
1288 (types (in-types entry)))
1289 (define (propagate! succ-idx succ-label types)
1290 (propagate-types! label entry succ-idx succ-label types))
8bc65d2d
AW
1291 ;; Add types for new definitions, and restrict types of
1292 ;; existing variables due to side effects.
1293 (match (lookup-cont label dfg)
8bc65d2d 1294 (($ $kargs names vars term)
ec412d75 1295 (let visit-term ((term term) (types types))
8bc65d2d
AW
1296 (match term
1297 (($ $letrec names vars funs term)
ec412d75
AW
1298 (visit-term term
1299 (adjoin-vars types vars
3a12f2ce
AW
1300 (make-type-entry &procedure
1301 -inf.0 +inf.0))))
8bc65d2d 1302 (($ $letk conts term)
ec412d75 1303 (visit-term term types))
8bc65d2d 1304 (($ $continue k src exp)
ec412d75
AW
1305 (visit-exp label entry k types exp)))))
1306 (($ $kreceive arity k)
1307 (match (lookup-cont k dfg)
1308 (($ $kargs names vars)
1309 (propagate! 0 k
3a12f2ce 1310 (adjoin-vars types vars all-types-entry)))))
8bc65d2d 1311 (($ $kfun src meta self tail clause)
3a12f2ce 1312 (let ((types (adjoin-var types self all-types-entry)))
8bc65d2d
AW
1313 (match clause
1314 (#f #f)
ec412d75
AW
1315 (($ $cont kclause)
1316 (propagate! 0 kclause types)))))
1317 (($ $kclause arity ($ $cont kbody ($ $kargs names vars)) alt)
1318 (propagate! 0 kbody
3a12f2ce 1319 (adjoin-vars types vars all-types-entry))
ec412d75
AW
1320 (match alt
1321 (#f #f)
1322 (($ $cont kclause)
1323 (propagate! 1 kclause types))))
1324 (($ $ktail) #t)))
8bc65d2d
AW
1325
1326 ;; And loop.
1327 (lp (1+ label)))
1328
ec412d75
AW
1329 ;; Iterate until we reach a fixed point.
1330 (revisit-label
1331 ;; Once the types have a fixed point, iterate until ranges also
1332 ;; reach a fixed point, saturating ranges to accelerate
1333 ;; convergence.
1334 (unless types-changed?
1335 (set! saturate-ranges? #t))
1336 (set! types-changed? #f)
1337 (let ((label revisit-label))
1338 (set! revisit-label #f)
1339 ;(pk 'looping)
1340 (lp label)))
8bc65d2d
AW
1341
1342 ;; All done! Return the computed types.
1343 (else typev)))))
1344
ec412d75
AW
1345(define-record-type <type-analysis>
1346 (make-type-analysis min-label label-count types)
1347 type-analysis?
1348 (min-label type-analysis-min-label)
1349 (label-count type-analysis-label-count)
1350 (types type-analysis-types))
1351
1352(define (infer-types fun dfg)
8bc65d2d
AW
1353 ;; Fun must be renumbered.
1354 (match fun
ec412d75
AW
1355 (($ $cont min-label ($ $kfun))
1356 (let ((label-count ((make-local-cont-folder label-count)
1357 (lambda (k cont label-count) (1+ label-count))
1358 fun 0)))
1359 (make-type-analysis min-label label-count
1360 (infer-types* dfg min-label label-count))))))
1361
1362(define (lookup-pre-type analysis label def)
1363 (match analysis
1364 (($ <type-analysis> min-label label-count typev)
3a12f2ce
AW
1365 (let* ((entry (vector-ref typev (- label min-label)))
1366 (tentry (var-type-entry (vector-ref entry 0) def)))
1367 (values (type-entry-type tentry)
1368 (type-entry-min tentry)
1369 (type-entry-max tentry))))))
ec412d75
AW
1370
1371(define (lookup-post-type analysis label def succ-idx)
1372 (match analysis
1373 (($ <type-analysis> min-label label-count typev)
3a12f2ce
AW
1374 (let* ((entry (vector-ref typev (- label min-label)))
1375 (tentry (var-type-entry (vector-ref entry (1+ succ-idx)) def)))
1376 (values (type-entry-type tentry)
1377 (type-entry-min tentry)
1378 (type-entry-max tentry))))))
ec412d75
AW
1379
1380(define (primcall-types-check? analysis label name args)
1381 (match (hashq-ref *type-checkers* name)
1382 (#f #f)
1383 (checker
1384 (match analysis
1385 (($ <type-analysis> min-label label-count typev)
1386 (let ((entry (vector-ref typev (- label min-label))))
1387 (apply checker (vector-ref entry 0) args)))))))