git.fiddlerwoaroof.com
csys/dump-cse.scm
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)))))