compute-live-variables uses CFA analysis
authorAndy Wingo <wingo@pobox.com>
Thu, 9 Jan 2014 09:56:22 +0000 (10:56 +0100)
committerAndy Wingo <wingo@pobox.com>
Sat, 11 Jan 2014 15:01:10 +0000 (16:01 +0100)
* module/language/cps/dfg.scm ($dfa): Store a CFA instead of a separate
  k-map and order.
  (dfa-k-idx, dfa-k-sym, dfa-k-count): Adapt.
  (compute-live-variables): Use analyze-control-flow instead of rolling
  out own RPO numbering.  Will allow us to fix some prompt-related
  things in a central place.

module/language/cps/dfg.scm

index 99eadab..55b589b 100644 (file)
 
 ;; Data-flow analysis.
 (define-record-type $dfa
-  (make-dfa k-map order var-map names syms in out)
+  (make-dfa cfa var-map names syms in out)
   dfa?
-  ;; Hash table mapping k-sym -> k-idx
-  (k-map dfa-k-map)
-  ;; Vector of k-idx -> k-sym
-  (order dfa-order)
+  ;; CFA, for its reverse-post-order numbering
+  (cfa dfa-cfa)
   ;; Hash table mapping var-sym -> var-idx
   (var-map dfa-var-map)
   ;; Vector of var-idx -> name
   (out dfa-out))
 
 (define (dfa-k-idx dfa k)
-  (or (hashq-ref (dfa-k-map dfa) k)
-      (error "unknown k" k)))
+  (cfa-k-idx (dfa-cfa dfa) k))
 
 (define (dfa-k-sym dfa idx)
-  (vector-ref (dfa-order dfa) idx))
+  (cfa-k-sym (dfa-cfa dfa) idx))
 
 (define (dfa-k-count dfa)
-  (vector-length (dfa-order dfa)))
+  (cfa-k-count (dfa-cfa dfa)))
 
 (define (dfa-var-idx dfa var)
   (or (hashq-ref (dfa-var-map dfa) var)
                        (set! n (1+ n)))
                      use-maps)
       (values mapping n)))
-  (define (block-accessor blocks accessor)
-    (lambda (k)
-      (accessor (lookup-block k blocks))))
-  (define (renumbering-accessor mapping blocks accessor)
-    (lambda (k)
-      (map (cut hashq-ref mapping <>)
-           ((block-accessor blocks accessor) k))))
-  (match fun
-    (($ $fun src meta free
-        (and entry
-             ($ $cont kentry ($ $kentry self ($ $cont ktail tail)))))
-     (call-with-values (lambda () (make-variable-mapping (dfg-use-maps dfg)))
-       (lambda (var-map nvars)
-         (define (fold-all-conts f seed)
-           (fold-local-conts (lambda (k cont seed) (f k seed))
-                             seed entry))
-         (let* ((blocks (dfg-blocks dfg))
-                (order (reverse-post-order ktail
-                                           (block-accessor blocks block-preds)
-                                           fold-all-conts))
-                (k-map (make-block-mapping order))
-                (succs (convert-predecessors
-                        order
-                        (renumbering-accessor k-map blocks block-succs)))
-                (syms (make-vector nvars #f))
-                (names (make-vector nvars #f))
-                (usev (make-vector (vector-length order) '()))
-                (defv (make-vector (vector-length order) '()))
-                (live-in (make-vector (vector-length order) #f))
-                (live-out (make-vector (vector-length order) #f)))
-           (define (k->idx k)
-             (or (hashq-ref k-map k) (error "unknown k" k)))
-           ;; Initialize syms, names, defv, and usev.
-           (hash-for-each
-            (lambda (sym use-map)
-              (match use-map
-                (($ $use-map name sym def uses)
-                 (let ((v (or (hashq-ref var-map sym)
-                              (error "unknown var" sym))))
-                   (vector-set! syms v sym)
-                   (vector-set! names v name)
-                   (for-each (lambda (def)
-                               (vector-push! defv (k->idx def) v))
-                             ((block-accessor blocks block-preds) def))
-                   (for-each (lambda (use)
-                               (vector-push! usev (k->idx use) v))
-                             uses)))))
-            (dfg-use-maps dfg))
-
-           ;; Initialize live-in and live-out sets.
-           (let lp ((n 0))
-             (when (< n (vector-length live-out))
-               (vector-set! live-in n (make-bitvector nvars #f))
-               (vector-set! live-out n (make-bitvector nvars #f))
-               (lp (1+ n))))
-
-           ;; Liveness is a reverse data-flow problem, so we give
-           ;; compute-maximum-fixed-point a reversed graph, swapping in
-           ;; and out, usev and defv, using successors instead of
-           ;; predecessors, and starting with ktail instead of the
-           ;; entry.
-           (compute-maximum-fixed-point succs live-out live-in defv usev #t)
-
-           (make-dfa k-map order var-map names syms live-in live-out)))))))
+  (call-with-values (lambda () (make-variable-mapping (dfg-use-maps dfg)))
+    (lambda (var-map nvars)
+      (let* ((cfa (analyze-control-flow fun dfg #:reverse? #t))
+             (syms (make-vector nvars #f))
+             (names (make-vector nvars #f))
+             (usev (make-vector (cfa-k-count cfa) '()))
+             (defv (make-vector (cfa-k-count cfa) '()))
+             (live-in (make-vector (cfa-k-count cfa) #f))
+             (live-out (make-vector (cfa-k-count cfa) #f)))
+        ;; Initialize syms, names, defv, and usev.
+        (hash-for-each
+         (lambda (sym use-map)
+           (match use-map
+             (($ $use-map name sym def uses)
+              (let ((v (or (hashq-ref var-map sym)
+                           (error "unknown var" sym))))
+                (vector-set! syms v sym)
+                (vector-set! names v name)
+                (for-each (lambda (def)
+                            (vector-push! defv (cfa-k-idx cfa def) v))
+                          (block-preds (lookup-block def (dfg-blocks dfg))))
+                (for-each (lambda (use)
+                            (vector-push! usev (cfa-k-idx cfa use) v))
+                          uses)))))
+         (dfg-use-maps dfg))
+
+        ;; Initialize live-in and live-out sets.
+        (let lp ((n 0))
+          (when (< n (vector-length live-out))
+            (vector-set! live-in n (make-bitvector nvars #f))
+            (vector-set! live-out n (make-bitvector nvars #f))
+            (lp (1+ n))))
+
+        ;; Liveness is a reverse data-flow problem, so we give
+        ;; compute-maximum-fixed-point a reversed graph, swapping in
+        ;; for out, and usev for defv.  Note that since we are using
+        ;; a reverse CFA, cfa-preds are actually successors, and
+        ;; continuation 0 is ktail.
+        (compute-maximum-fixed-point (cfa-preds cfa)
+                                     live-out live-in defv usev #t)
+
+        (make-dfa cfa var-map names syms live-in live-out)))))
 
 (define (print-dfa dfa)
   (match dfa
-    (($ $dfa k-map order var-map names syms in out)
+    (($ $dfa cfa var-map names syms in out)
      (define (print-var-set bv)
        (let lp ((n 0))
          (let ((n (bit-position #t bv n)))
              (format #t " ~A" (vector-ref syms n))
              (lp (1+ n))))))
      (let lp ((n 0))
-       (when (< n (vector-length order))
-         (format #t "~A:\n" (vector-ref order n))
+       (when (< n (cfa-k-count cfa))
+         (format #t "~A:\n" (cfa-k-sym cfa n))
          (format #t "  in:")
          (print-var-set (vector-ref in n))
          (newline)