4e987026 |
;;; This file handles common subexpressions in the interface file.
;;; Common subexpressions are detected in two places: gtypes and strictness
;;; properties.
;;; Compressing strictness signatures
;;; A strictness is represented by a list of booleans. We do two things to
;;; compress strictnesses: all lists less than *pre-defined-strictness-size*
;;; are pre-computed in a vector and the first *pre-defined-strictness-vars*
;;; vector elements are cached in global vars. The strictness will dump as
;;; as either a global or as a vector reference into the vector.
(define (initialize-strictness-table)
(setf (dynamic *pre-defined-strictness-table*)
(make-vector (expt 2 (1+ (dynamic *pre-defined-strictness-size*)))))
(setf (vector-ref *pre-defined-strictness-table* 1) '())
(do ((i 1 (1+ i))
(j 1 (* j 2))
(k 2 (* k 2)))
((> i *pre-defined-strictness-size*))
(do ((l 0 (1+ l)))
((>= l j))
(setf (vector-ref *pre-defined-strictness-table* (+ k l))
(cons '#f (vector-ref *pre-defined-strictness-table* (+ j l))))
(setf (vector-ref *pre-defined-strictness-table* (+ k j l))
(cons '#t (vector-ref *pre-defined-strictness-table* (+ j l))))))
(set-strictness-vars))
(define (strictness-table-ref x)
(vector-ref (dynamic *pre-defined-strictness-table*) x))
(define (dump-strictness s)
(if (null? s)
''()
(dump-strictness-1 s s 0 0)))
(define (dump-strictness-1 s s1 n size)
(if (null? s1)
(if (> size *pre-defined-strictness-size*)
(dump-big-strictness (- size *pre-defined-strictness-size*) s)
(let ((k (+ n (expt 2 size))))
(if (< k *pre-defined-strictness-vars*)
`(dynamic ,(vector-ref *pre-defined-strictness-names* k))
`(strictness-table-ref ,k))))
(dump-strictness-1 s (cdr s1) (+ (* 2 n) (if (car s1) 1 0)) (1+ size))))
(define (dump-big-strictness k s)
(if (= k 0)
(dump-strictness s)
`(cons ',(car s)
,(dump-big-strictness (1- k) (cdr s)))))
;;; This routine handles saving type signatures (gtypes).
;;; common subexpressions are detected in two places: the type body
;;; and the the contexts.
(define (init-predefined-gtyvars)
(setf *saved-gtyvars* (make-vector *num-saved-gtyvars*))
(dotimes (i *num-saved-gtyvars*)
(setf (vector-ref *saved-gtyvars* i) (**gtyvar i)))
(setup-gtyvar-vars))
(define (init-cse-structs)
(initialize-strictness-table)
(init-predefined-gtyvars))
(define (save-cse-value v)
(setf (vector-ref (dynamic *saved-cse-values*) (dynamic *cse-value-num*)) v)
(incf (dynamic *cse-value-num*)))
(define (cse-init-code)
(let* ((n (length *cse-objects*))
(init-code '()))
(do ((i (1- n) (1- i))
(init *cse-objects* (cdr init)))
((null? init))
(push `(save-cse-value ,(car init)) init-code))
`((setf *saved-cse-values* (make-vector ,n))
(setf *cse-value-num* 0)
,@init-code)))
(define (remember-dumped-object init-code)
(push init-code *cse-objects*)
(incf *cse-object-num*)
*cse-object-num*)
(define (cse-value-ref x)
(vector-ref (dynamic *saved-cse-values*) x))
(define (cse-ref-code n)
(cond ((eqv? n 0)
''())
((<= n *num-saved-gtyvars*)
`(dynamic ,(vector-ref *saved-gtyvar-varnames* (1- n))))
(else
`(cse-value-ref ,(- n *num-saved-gtyvars* 1)))))
(define (dump-gtyvar g)
(let ((n (gtyvar-varnum g)))
(if (< n *num-saved-gtyvars*)
(1+ n)
(remember-dumped-object `(**gtyvar ,n)))))
(define (dump-context-list contexts)
(if (null? contexts)
0
(let* ((rest (dump-context-list (cdr contexts)))
(classes (dump-class-list (car contexts)))
(t1 (assq/insert-l classes *gtype-class-index*))
(res (assq/insert rest (cdr t1))))
(if (eq? (cdr res) '#f)
(let ((z (remember-dumped-object
`(cons ,(cse-ref-code classes) ,(cse-ref-code rest)))))
(setf (cdr res) z)
z)
(cdr res)))))
(define (dump-class-list classes)
(if (null? classes)
0
(let* ((rest (dump-class-list (cdr classes)))
(class (dump-class/n (car classes)))
(t1 (assq/insert-l class *context-class-index*))
(res (assq/insert rest (cdr t1))))
(if (eq? (cdr res) '#f)
(let ((z (remember-dumped-object
`(cons ,class ,(cse-ref-code rest)))))
(setf (cdr res) z)
z)
(cdr res)))))
(define (dump-gtype-1 g)
(cond ((gtyvar? g)
(dump-gtyvar g))
((ntyvar? g)
(dump-gtype-1 (prune g)))
(else
(dump-gtycon g))))
(define (dump-gtycon g)
(let* ((ty (ntycon-tycon g))
(tycon (if (algdata? ty) (dump-algdata/n ty) (dump-synonym/n ty)))
(l (dump-gtype-list (ntycon-args g)))
(t1 (assq/insert-l tycon *gtype-tycon-index*))
(res (assq/insert l (cdr t1))))
(if (eq? (cdr res) '#f)
(let ((z (remember-dumped-object
`(**ntycon ,tycon ,(cse-ref-code l)))))
(setf (cdr res) z)
z)
(cdr res))))
(define (dump-gtype-list l)
(if (null? l)
0
(let* ((g (dump-gtype-1 (car l)))
(rest (dump-gtype-list (cdr l)))
(t1 (assq/insert-l g *gtype-list-index*))
(res (assq/insert rest (cdr t1))))
(if (eq? (cdr res) '#f)
(let ((z (remember-dumped-object
`(cons ,(cse-ref-code g)
,(cse-ref-code rest)))))
(setf (cdr res) z)
z)
(cdr res)))))
(define (dump-gtype/cse g)
(cse-ref-code
(let* ((context (dump-context-list (gtype-context g)))
(type (dump-gtype-1 (gtype-type g)))
(t1 (assq/insert-l type *gtype-index*))
(res (assq/insert context (cdr t1))))
(if (eq? (cdr res) '#f)
(let ((z (remember-dumped-object
`(**gtype ,(cse-ref-code context)
,(cse-ref-code type)))))
(setf (cdr res) z)
z)
(cdr res)))))
|