1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-12 06:41:13 +02:00

Beginning of u64 phi unboxing

* module/language/cps/specialize-numbers.scm
  (compute-specializable-u64-vars): New stub.
* module/language/cps/specialize-numbers.scm
  (compute-specializable-phis): Rename from
  compute-specializable-f64-phis, and return an intmap instead of an
  intset.  The values distinguish f64 from u64 vars.
* module/language/cps/specialize-numbers.scm (apply-specialization):
  Start of u64 phi unboxing.
* module/language/cps/specialize-numbers.scm (specialize-phis):
  (specialize-numbers): Adapt.
This commit is contained in:
Andy Wingo 2015-11-20 10:13:16 +01:00
parent 163fcf5adb
commit 4305b39336

View file

@ -151,6 +151,10 @@
(_ defs))) (_ defs)))
labels empty-intmap)) labels empty-intmap))
;; Placeholder until we add the real implementation.
(define (compute-specializable-u64-vars cps body preds defs)
empty-intset)
;; Compute vars whose definitions are all inexact reals and whose uses ;; Compute vars whose definitions are all inexact reals and whose uses
;; include an unbox operation. ;; include an unbox operation.
(define (compute-specializable-f64-vars cps body preds defs) (define (compute-specializable-f64-vars cps body preds defs)
@ -245,33 +249,44 @@
preds empty-intset)) preds empty-intset))
;; Compute the set of variables which have more than one definition, ;; Compute the set of variables which have more than one definition,
;; whose definitions are always f64-valued, and which have at least one ;; whose definitions are always f64-valued or u64-valued, and which have
;; use that is an unbox operation. ;; at least one use that is an unbox operation.
(define (compute-specializable-f64-phis cps body preds defs) (define (compute-specializable-phis cps body preds defs)
(intset-intersect (let ((f64-vars (compute-specializable-f64-vars cps body preds defs))
(compute-specializable-f64-vars cps body preds defs) (u64-vars (compute-specializable-u64-vars cps body preds defs))
(compute-phi-vars cps preds))) (phi-vars (compute-phi-vars cps preds)))
(unless (eq? empty-intset (intset-intersect f64-vars u64-vars))
(error "expected f64 and u64 vars to be disjoint sets"))
(intset-fold (lambda (var out) (intmap-add out var 'u64))
(intset-intersect u64-vars phi-vars)
(intset-fold (lambda (var out) (intmap-add out var 'f64))
(intset-intersect f64-vars phi-vars)
empty-intmap))))
;; Each definition of an f64 variable should unbox that variable. The ;; Each definition of an f64/u64 variable should unbox that variable.
;; cont that binds the variable should re-box it under its original ;; The cont that binds the variable should re-box it under its original
;; name, and rely on CSE to remove the boxing as appropriate. ;; name, and rely on CSE to remove the boxing as appropriate.
(define (apply-f64-specialization cps kfun body preds defs phis) (define (apply-specialization cps kfun body preds defs phis)
(define (compute-unbox-labels) (define (compute-unbox-labels)
(intset-fold (lambda (phi labels) (intmap-fold (lambda (phi kind labels)
(fold1 (lambda (pred labels) (fold1 (lambda (pred labels)
(intset-add labels pred)) (intset-add labels pred))
(intmap-ref preds (intmap-ref defs phi)) (intmap-ref preds (intmap-ref defs phi))
labels)) labels))
phis empty-intset)) phis empty-intset))
(define (unbox-op var)
(match (intmap-ref phis var)
('f64 'scm->f64)
('u64 'scm->u64)))
(define (unbox-operands) (define (unbox-operands)
(define (unbox-arg cps arg def-var have-arg) (define (unbox-arg cps arg def-var have-arg)
(if (intset-ref phis def-var) (if (intmap-ref phis def-var (lambda (_) #f))
(with-cps cps (with-cps cps
(letv f64) (letv unboxed)
(let$ body (have-arg f64)) (let$ body (have-arg unboxed))
(letk kunboxed ($kargs ('f64) (f64) ,body)) (letk kunboxed ($kargs ('unboxed) (unboxed) ,body))
(build-term (build-term
($continue kunboxed #f ($primcall 'scm->f64 (arg))))) ($continue kunboxed #f ($primcall (unbox-op def-var) (arg)))))
(have-arg cps arg))) (have-arg cps arg)))
(define (unbox-args cps args def-vars have-args) (define (unbox-args cps args def-vars have-args)
(match args (match args
@ -288,33 +303,35 @@
(lambda (label cps) (lambda (label cps)
(match (intmap-ref cps label) (match (intmap-ref cps label)
(($ $kargs names vars ($ $continue k src exp)) (($ $kargs names vars ($ $continue k src exp))
;; For expressions that define a single value, we know we need (match (intmap-ref cps k)
;; to unbox that value. For $values though we might have to (($ $kargs _ defs)
;; unbox just a subset of values. (match exp
(match exp ;; For expressions that define a single value, we know we need
(($ $values args) ;; to unbox that value. For $values though we might have to
(let ((def-vars (match (intmap-ref cps k) ;; unbox just a subset of values.
(($ $kargs _ defs) defs)))) (($ $values args)
(with-cps cps (with-cps cps
(let$ term (unbox-args (let$ term (unbox-args
args def-vars args defs
(lambda (cps args) (lambda (cps args)
(with-cps cps (with-cps cps
(build-term (build-term
($continue k src ($values args))))))) ($continue k src ($values args)))))))
(setk label ($kargs names vars ,term))))) (setk label ($kargs names vars ,term))))
(_ (_
(with-cps cps (match defs
(letv const) ((def)
(letk kunbox ($kargs ('const) (const) (with-cps cps
($continue k src (letv boxed)
($primcall 'scm->f64 (const))))) (letk kunbox ($kargs ('boxed) (boxed)
(setk label ($kargs names vars ($continue k src
($continue k src ,exp))))))))) ($primcall (unbox-op def) (boxed)))))
(setk label ($kargs names vars
($continue kunbox src ,exp)))))))))))))
(compute-unbox-labels) (compute-unbox-labels)
cps)) cps))
(define (compute-box-labels) (define (compute-box-labels)
(intset-fold (lambda (phi labels) (intmap-fold (lambda (phi kind labels)
(intset-add labels (intmap-ref defs phi))) (intset-add labels (intmap-ref defs phi)))
phis empty-intset)) phis empty-intset))
(define (box-results cps) (define (box-results cps)
@ -323,7 +340,7 @@
(match (intmap-ref cps label) (match (intmap-ref cps label)
(($ $kargs names vars term) (($ $kargs names vars term)
(let* ((boxed (fold1 (lambda (var boxed) (let* ((boxed (fold1 (lambda (var boxed)
(if (intset-ref phis var) (if (intmap-ref phis var (lambda (_) #f))
(intmap-add boxed var (fresh-var)) (intmap-add boxed var (fresh-var))
boxed)) boxed))
vars empty-intmap)) vars empty-intmap))
@ -357,15 +374,15 @@
cps)) cps))
(box-results (unbox-operands))) (box-results (unbox-operands)))
(define (specialize-f64-phis cps) (define (specialize-phis cps)
(intmap-fold (intmap-fold
(lambda (kfun body cps) (lambda (kfun body cps)
(let* ((preds (compute-predecessors cps kfun #:labels body)) (let* ((preds (compute-predecessors cps kfun #:labels body))
(defs (compute-defs cps body)) (defs (compute-defs cps body))
(phis (compute-specializable-f64-phis cps body preds defs))) (phis (compute-specializable-phis cps body preds defs)))
(if (eq? phis empty-intset) (if (eq? phis empty-intmap)
cps cps
(apply-f64-specialization cps kfun body preds defs phis)))) (apply-specialization cps kfun body preds defs phis))))
(compute-reachable-functions cps) (compute-reachable-functions cps)
cps)) cps))
@ -373,4 +390,4 @@
;; Type inference wants a renumbered graph; OK. ;; Type inference wants a renumbered graph; OK.
(let ((cps (renumber cps))) (let ((cps (renumber cps)))
(with-fresh-name-state cps (with-fresh-name-state cps
(specialize-f64-phis (specialize-operations cps))))) (specialize-phis (specialize-operations cps)))))