1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-18 10:10:23 +02:00

Source information goes on the $continue, not the $cont.

* module/language/cps.scm ($continue, $cont): Put source information on
  the $continue, not on the $cont.  Otherwise it is difficult for CPS
  conversion to preserve source information.
  ($fun): Add a src member to $fun.  Otherwise we might miss the source
  info for the start of the function.

* .dir-locals.el:
* module/language/cps/arities.scm:
* module/language/cps/closure-conversion.scm:
* module/language/cps/compile-rtl.scm:
* module/language/cps/constructors.scm:
* module/language/cps/contification.scm:
* module/language/cps/dfg.scm:
* module/language/cps/elide-values.scm:
* module/language/cps/reify-primitives.scm:
* module/language/cps/slot-allocation.scm:
* module/language/cps/verify.scm:
* module/language/tree-il/compile-cps.scm: Update the whole CPS world
  for this change.
This commit is contained in:
Andy Wingo 2013-11-07 10:32:21 +01:00
parent 963d95f1d9
commit 6e422a3599
13 changed files with 767 additions and 784 deletions

View file

@ -21,7 +21,7 @@
(eval . (put '$letk 'scheme-indent-function 1))
(eval . (put '$letk* 'scheme-indent-function 1))
(eval . (put '$letconst 'scheme-indent-function 1))
(eval . (put '$continue 'scheme-indent-function 1))
(eval . (put '$continue 'scheme-indent-function 2))
(eval . (put '$kargs 'scheme-indent-function 2))
(eval . (put '$kentry 'scheme-indent-function 2))
(eval . (put '$kclause 'scheme-indent-function 1))

View file

@ -25,15 +25,15 @@
;;; and terms that call continuations.
;;;
;;; $letk binds a set of mutually recursive continuations, each one an
;;; instance of $cont. A $cont declares the name and source of a
;;; continuation, and then contains as a subterm the particular
;;; continuation instance: $kif for test continuations, $kargs for
;;; continuations that bind values, etc.
;;; instance of $cont. A $cont declares the name of a continuation, and
;;; then contains as a subterm the particular continuation instance:
;;; $kif for test continuations, $kargs for continuations that bind
;;; values, etc.
;;;
;;; $continue nodes call continuations. The expression contained in the
;;; $continue node determines the value or values that are passed to the
;;; target continuation: $const to pass a constant value, $values to
;;; pass multiple named values, etc.
;;; pass multiple named values, etc. $continue nodes also record the source at which
;;;
;;; Additionally there is $letrec, a term that binds mutually recursive
;;; functions. The contification pass will turn $letrec into $letk if
@ -71,8 +71,8 @@
;;; That's to say that a $fun can be matched like this:
;;;
;;; (match f
;;; (($ $fun meta free
;;; ($ $cont kentry src
;;; (($ $fun src meta free
;;; ($ $cont kentry
;;; ($ $kentry self ($ $cont ktail _ ($ $ktail))
;;; (($ $kclause arity
;;; ($ $cont kbody _ ($ $kargs names syms body)))
@ -165,11 +165,11 @@
;; Terms.
(define-cps-type $letk conts body)
(define-cps-type $continue k exp)
(define-cps-type $continue k src exp)
(define-cps-type $letrec names syms funs body)
;; Continuations
(define-cps-type $cont k src cont)
(define-cps-type $cont k cont)
(define-cps-type $kif kt kf)
(define-cps-type $ktrunc arity k)
(define-cps-type $kargs names syms body)
@ -182,7 +182,7 @@
(define-cps-type $void)
(define-cps-type $const val)
(define-cps-type $prim name)
(define-cps-type $fun meta free body)
(define-cps-type $fun src meta free body)
(define-cps-type $call proc args)
(define-cps-type $primcall name args)
(define-cps-type $values args)
@ -224,7 +224,7 @@
(define-syntax build-cps-cont
(syntax-rules (unquote)
((_ (unquote exp)) exp)
((_ (k src cont)) (make-$cont k src (build-cont-body cont)))))
((_ (k cont)) (make-$cont k (build-cont-body cont)))))
(define-syntax build-cps-exp
(syntax-rules (unquote
@ -234,7 +234,8 @@
((_ ($void)) (make-$void))
((_ ($const val)) (make-$const val))
((_ ($prim name)) (make-$prim name))
((_ ($fun meta free body)) (make-$fun meta free (build-cps-cont body)))
((_ ($fun src meta free body))
(make-$fun src meta free (build-cps-cont body)))
((_ ($call proc (arg ...))) (make-$call proc (list arg ...)))
((_ ($call proc args)) (make-$call proc args))
((_ ($primcall name (arg ...))) (make-$primcall name (list arg ...)))
@ -262,12 +263,14 @@
((_ ($letconst ((name sym val) tail ...) body))
(let-gensyms (kconst)
(build-cps-term
($letk ((kconst #f ($kargs (name) (sym) ($letconst (tail ...) body))))
($continue kconst ($const val))))))
($letk ((kconst ($kargs (name) (sym) ($letconst (tail ...) body))))
($continue kconst (let ((props (source-properties val)))
(and (pair? props) props))
($const val))))))
((_ ($letrec names gensyms funs body))
(make-$letrec names gensyms funs (build-cps-term body)))
((_ ($continue k exp))
(make-$continue k (build-cps-exp exp)))))
((_ ($continue k src exp))
(make-$continue k src (build-cps-exp exp)))))
(define-syntax-rule (rewrite-cps-term x (pat body) ...)
(match x
@ -287,12 +290,12 @@
;; Continuations.
(('letconst k (name sym c) body)
(build-cps-term
($letk ((k (src exp) ($kargs (name) (sym)
($letk ((k ($kargs (name) (sym)
,(parse-cps body))))
($continue k ($const c)))))
($continue k (src exp) ($const c)))))
(('let k (name sym val) body)
(build-cps-term
($letk ((k (src exp) ($kargs (name) (sym)
($letk ((k ($kargs (name) (sym)
,(parse-cps body))))
,(parse-cps val))))
(('letk (cont ...) body)
@ -300,7 +303,7 @@
($letk ,(map parse-cps cont) ,(parse-cps body))))
(('k sym body)
(build-cps-cont
(sym (src exp) ,(parse-cps body))))
(sym ,(parse-cps body))))
(('kif kt kf)
(build-cont-body ($kif kt kf)))
(('ktrunc req rest k)
@ -322,7 +325,7 @@
;; Calls.
(('continue k exp)
(build-cps-term ($continue k ,(parse-cps exp))))
(build-cps-term ($continue k (src exp) ,(parse-cps exp))))
(('var sym)
(build-cps-exp ($var sym)))
(('void)
@ -332,7 +335,7 @@
(('prim name)
(build-cps-exp ($prim name)))
(('fun meta free body)
(build-cps-exp ($fun meta free ,(parse-cps body))))
(build-cps-exp ($fun (src exp) meta free ,(parse-cps body))))
(('letrec ((name sym fun) ...) body)
(build-cps-term
($letrec name sym (map parse-cps fun) ,(parse-cps body))))
@ -350,16 +353,16 @@
(define (unparse-cps exp)
(match exp
;; Continuations.
(($ $letk (($ $cont k src ($ $kargs (name) (sym) body)))
($ $continue k ($ $const c)))
(($ $letk (($ $cont k ($ $kargs (name) (sym) body)))
($ $continue k src ($ $const c)))
`(letconst ,k (,name ,sym ,c)
,(unparse-cps body)))
(($ $letk (($ $cont k src ($ $kargs (name) (sym) body))) val)
(($ $letk (($ $cont k ($ $kargs (name) (sym) body))) val)
`(let ,k (,name ,sym ,(unparse-cps val))
,(unparse-cps body)))
(($ $letk conts body)
`(letk ,(map unparse-cps conts) ,(unparse-cps body)))
(($ $cont sym src body)
(($ $cont sym body)
`(k ,sym ,(unparse-cps body)))
(($ $kif kt kf)
`(kif ,kt ,kf))
@ -377,7 +380,7 @@
`(kclause (,req ,opt ,rest ,kw ,allow-other-keys?) ,(unparse-cps body)))
;; Calls.
(($ $continue k exp)
(($ $continue k src exp)
`(continue ,k ,(unparse-cps exp)))
(($ $var sym)
`(var ,sym))
@ -387,7 +390,7 @@
`(const ,val))
(($ $prim name)
`(prim ,name))
(($ $fun meta free body)
(($ $fun src meta free body)
`(fun ,meta ,free ,(unparse-cps body)))
(($ $letrec names syms funs body)
`(letrec ,(map (lambda (name sym fun)
@ -408,8 +411,8 @@
(define (fold-conts proc seed fun)
(define (cont-folder cont seed)
(match cont
(($ $cont k src cont)
(let ((seed (proc k src cont seed)))
(($ $cont k cont)
(let ((seed (proc k cont seed)))
(match cont
(($ $kargs names syms body)
(term-folder body seed))
@ -424,7 +427,7 @@
(define (fun-folder fun seed)
(match fun
(($ $fun meta free body)
(($ $fun src meta free body)
(cont-folder body seed))))
(define (term-folder term seed)
@ -432,7 +435,7 @@
(($ $letk conts body)
(fold cont-folder (term-folder body seed) conts))
(($ $continue k exp)
(($ $continue k src exp)
(match exp
(($ $fun) (fun-folder exp seed))
(_ seed)))
@ -445,8 +448,8 @@
(define (fold-local-conts proc seed cont)
(define (cont-folder cont seed)
(match cont
(($ $cont k src cont)
(let ((seed (proc k src cont seed)))
(($ $cont k cont)
(let ((seed (proc k cont seed)))
(match cont
(($ $kargs names syms body)
(term-folder body seed))

View file

@ -35,105 +35,105 @@
(define (fix-clause-arities clause)
(let ((conts (build-local-cont-table clause))
(ktail (match clause
(($ $cont _ _ ($ $kentry _ ($ $cont ktail) _)) ktail))))
(($ $cont _ ($ $kentry _ ($ $cont ktail) _)) ktail))))
(define (visit-term term)
(rewrite-cps-term term
(($ $letk conts body)
($letk ,(map visit-cont conts) ,(visit-term body)))
(($ $letrec names syms funs body)
($letrec names syms (map fix-arities funs) ,(visit-term body)))
(($ $continue k exp)
,(visit-exp k exp))))
(($ $continue k src exp)
,(visit-exp k src exp))))
(define (adapt-exp nvals k exp)
(define (adapt-exp nvals k src exp)
(match nvals
(0
(rewrite-cps-term (lookup-cont k conts)
(($ $ktail)
,(let-gensyms (kvoid kunspec unspec)
(build-cps-term
($letk* ((kunspec #f ($kargs (unspec) (unspec)
($continue k
($letk* ((kunspec ($kargs (unspec) (unspec)
($continue k src
($primcall 'return (unspec)))))
(kvoid #f ($kargs () ()
($continue kunspec ($void)))))
($continue kvoid ,exp)))))
(kvoid ($kargs () ()
($continue kunspec src ($void)))))
($continue kvoid src ,exp)))))
(($ $ktrunc arity kargs)
,(rewrite-cps-term arity
(($ $arity () () #f () #f)
($continue kargs ,exp))
($continue kargs src ,exp))
(_
,(let-gensyms (kvoid kvalues void)
(build-cps-term
($letk* ((kvalues #f ($kargs ('void) (void)
($continue k
($letk* ((kvalues ($kargs ('void) (void)
($continue k src
($primcall 'values (void)))))
(kvoid #f ($kargs () ()
($continue kvalues
(kvoid ($kargs () ()
($continue kvalues src
($void)))))
($continue kvoid ,exp)))))))
($continue kvoid src ,exp)))))))
(($ $kargs () () _)
($continue k ,exp))
($continue k src ,exp))
(_
,(let-gensyms (k*)
(build-cps-term
($letk ((k* #f ($kargs () () ($continue k ($void)))))
($continue k* ,exp)))))))
($letk ((k* ($kargs () () ($continue k src ($void)))))
($continue k* src ,exp)))))))
(1
(rewrite-cps-term (lookup-cont k conts)
(($ $ktail)
,(rewrite-cps-term exp
(($var sym)
($continue ktail ($primcall 'return (sym))))
($continue ktail src ($primcall 'return (sym))))
(_
,(let-gensyms (k* v)
(build-cps-term
($letk ((k* #f ($kargs (v) (v)
($continue k
($letk ((k* ($kargs (v) (v)
($continue k src
($primcall 'return (v))))))
($continue k* ,exp)))))))
($continue k* src ,exp)))))))
(($ $ktrunc arity kargs)
,(rewrite-cps-term arity
(($ $arity (_) () #f () #f)
($continue kargs ,exp))
($continue kargs src ,exp))
(_
,(let-gensyms (kvalues value)
(build-cps-term
($letk ((kvalues #f ($kargs ('value) (value)
($continue k
($letk ((kvalues ($kargs ('value) (value)
($continue k src
($primcall 'values (value))))))
($continue kvalues ,exp)))))))
($continue kvalues src ,exp)))))))
(($ $kargs () () _)
,(let-gensyms (k* drop)
(build-cps-term
($letk ((k* #f ($kargs ('drop) (drop)
($continue k ($values ())))))
($continue k* ,exp)))))
($letk ((k* ($kargs ('drop) (drop)
($continue k src ($values ())))))
($continue k* src ,exp)))))
(_
($continue k ,exp))))))
($continue k src ,exp))))))
(define (visit-exp k exp)
(define (visit-exp k src exp)
(rewrite-cps-term exp
((or ($ $void)
($ $const)
($ $prim)
($ $var))
,(adapt-exp 1 k exp))
,(adapt-exp 1 k src exp))
(($ $fun)
,(adapt-exp 1 k (fix-arities exp)))
,(adapt-exp 1 k src (fix-arities exp)))
(($ $call)
;; In general, calls have unknown return arity. For that
;; reason every non-tail call has an implicit adaptor
;; continuation to adapt the return to the target
;; continuation, and we don't need to do any adapting here.
($continue k ,exp))
($continue k src ,exp))
(($ $primcall 'return (arg))
;; Primcalls to return are in tail position.
($continue ktail ,exp))
($continue ktail src ,exp))
(($ $primcall (? (lambda (name)
(and (not (prim-rtl-instruction name))
(not (branching-primitive? name))))))
($continue k ,exp))
($continue k src ,exp))
(($ $primcall 'struct-set! (obj pos val))
;; Unhappily, and undocumentedly, struct-set! returns the value
;; that was set. There is code that relies on this. Hackety
@ -142,63 +142,63 @@
(($ $ktail)
,(let-gensyms (kvoid)
(build-cps-term
($letk* ((kvoid #f ($kargs () ()
($continue ktail
($letk* ((kvoid ($kargs () ()
($continue ktail src
($primcall 'return (val))))))
($continue kvoid ,exp)))))
($continue kvoid src ,exp)))))
(($ $ktrunc arity kargs)
,(rewrite-cps-term arity
(($ $arity () () #f () #f)
($continue kargs ,exp))
($continue kargs src ,exp))
(_
,(let-gensyms (kvoid)
(build-cps-term
($letk* ((kvoid #f ($kargs () ()
($continue k
($letk* ((kvoid ($kargs () ()
($continue k src
($primcall 'values (val))))))
($continue kvoid ,exp)))))))
($continue kvoid src ,exp)))))))
(($ $kargs () () _)
($continue k ,exp))
($continue k src ,exp))
(_
,(let-gensyms (k*)
(build-cps-term
($letk ((k* #f ($kargs () () ($continue k ($var val)))))
($continue k* ,exp)))))))
($letk ((k* ($kargs () () ($continue k src ($var val)))))
($continue k* src ,exp)))))))
(($ $primcall name args)
,(match (prim-arity name)
((out . in)
(if (= in (length args))
(adapt-exp out k
(adapt-exp out k src
(let ((inst (prim-rtl-instruction name)))
(if (and inst (not (eq? inst name)))
(build-cps-exp ($primcall inst args))
exp)))
(let-gensyms (k* p*)
(build-cps-term
($letk ((k* #f ($kargs ('prim) (p*)
($continue k ($call p* args)))))
($continue k* ($prim name)))))))))
($letk ((k* ($kargs ('prim) (p*)
($continue k src ($call p* args)))))
($continue k* src ($prim name)))))))))
(($ $values)
;; Values nodes are inserted by CPS optimization passes, so
;; we assume they are correct.
($continue k ,exp))
($continue k src ,exp))
(($ $prompt)
($continue k ,exp))))
($continue k src ,exp))))
(define (visit-cont cont)
(rewrite-cps-cont cont
(($ $cont sym src ($ $kargs names syms body))
(sym src ($kargs names syms ,(visit-term body))))
(($ $cont sym src ($ $kclause arity body))
(sym src ($kclause ,arity ,(visit-cont body))))
(($ $cont sym ($ $kargs names syms body))
(sym ($kargs names syms ,(visit-term body))))
(($ $cont sym ($ $kclause arity body))
(sym ($kclause ,arity ,(visit-cont body))))
(($ $cont)
,cont)))
(rewrite-cps-cont clause
(($ $cont sym src ($ $kentry self tail clauses))
(sym src ($kentry self ,tail ,(map visit-cont clauses)))))))
(($ $cont sym ($ $kentry self tail clauses))
(sym ($kentry self ,tail ,(map visit-cont clauses)))))))
(define (fix-arities fun)
(rewrite-cps-exp fun
(($ $fun meta free body)
($fun meta free ,(fix-clause-arities body)))))
(($ $fun src meta free body)
($fun src meta free ,(fix-clause-arities body)))))

View file

@ -63,8 +63,8 @@ values in the term."
(let-gensyms (k* sym*)
(receive (exp free) (k sym*)
(values (build-cps-term
($letk ((k* #f ($kargs (sym*) (sym*) ,exp)))
($continue k* ($primcall 'free-ref (self sym)))))
($letk ((k* ($kargs (sym*) (sym*) ,exp)))
($continue k* #f ($primcall 'free-ref (self sym)))))
(cons sym free))))))
(define (convert-free-vars syms self bound k)
@ -88,13 +88,13 @@ performed, and @var{outer-bound} is the list of bound variables there."
(fold (lambda (free idx body)
(let-gensyms (k idxsym)
(build-cps-term
($letk ((k src ($kargs () () ,body)))
($letk ((k ($kargs () () ,body)))
,(convert-free-var
free outer-self outer-bound
(lambda (free)
(values (build-cps-term
($letconst (('idx idxsym idx))
($continue k
($continue k src
($primcall 'free-set! (v idxsym free)))))
'())))))))
body
@ -123,19 +123,19 @@ convert functions to flat closures."
(values (build-cps-term ($letk ,conts ,body))
(union free free*)))))
(($ $cont sym src ($ $kargs names syms body))
(($ $cont sym ($ $kargs names syms body))
(receive (body free) (cc body self (append syms bound))
(values (build-cps-cont (sym src ($kargs names syms ,body)))
(values (build-cps-cont (sym ($kargs names syms ,body)))
free)))
(($ $cont sym src ($ $kentry self tail clauses))
(($ $cont sym ($ $kentry self tail clauses))
(receive (clauses free) (cc* clauses self (list self))
(values (build-cps-cont (sym src ($kentry self ,tail ,clauses)))
(values (build-cps-cont (sym ($kentry self ,tail ,clauses)))
free)))
(($ $cont sym src ($ $kclause arity body))
(($ $cont sym ($ $kclause arity body))
(receive (body free) (cc body self bound)
(values (build-cps-cont (sym src ($kclause ,arity ,body)))
(values (build-cps-cont (sym ($kclause ,arity ,body)))
free)))
(($ $cont)
@ -153,76 +153,76 @@ convert functions to flat closures."
(free free))
(match in
(() (values (bindings body) free))
(((name sym ($ $fun meta () fun-body)) . in)
(((name sym ($ $fun src meta () fun-body)) . in)
(receive (fun-body fun-free) (cc fun-body #f '())
(lp in
(lambda (body)
(let-gensyms (k)
(build-cps-term
($letk ((k #f ($kargs (name) (sym) ,(bindings body))))
($continue k
($fun meta fun-free ,fun-body))))))
(init-closure #f sym fun-free self bound body)
($letk ((k ($kargs (name) (sym) ,(bindings body))))
($continue k src
($fun src meta fun-free ,fun-body))))))
(init-closure src sym fun-free self bound body)
(union free (difference fun-free bound))))))))))
(($ $continue k ($ $var sym))
(($ $continue k src ($ $var sym))
(convert-free-var sym self bound
(lambda (sym)
(values (build-cps-term ($continue k ($var sym)))
(values (build-cps-term ($continue k src ($var sym)))
'()))))
(($ $continue k
(($ $continue k src
(or ($ $void)
($ $const)
($ $prim)))
(values exp '()))
(($ $continue k ($ $fun meta () body))
(($ $continue k src ($ $fun src* meta () body))
(receive (body free) (cc body #f '())
(match free
(()
(values (build-cps-term
($continue k ($fun meta free ,body)))
($continue k src ($fun src* meta free ,body)))
free))
(_
(values
(let-gensyms (kinit v)
(build-cps-term
($letk ((kinit #f ($kargs (v) (v)
,(init-closure #f v free self bound
($letk ((kinit ($kargs (v) (v)
,(init-closure src v free self bound
(build-cps-term
($continue k ($var v)))))))
($continue kinit ($fun meta free ,body)))))
($continue k src ($var v)))))))
($continue kinit src ($fun src* meta free ,body)))))
(difference free bound))))))
(($ $continue k ($ $call proc args))
(($ $continue k src ($ $call proc args))
(convert-free-vars (cons proc args) self bound
(match-lambda
((proc . args)
(values (build-cps-term
($continue k ($call proc args)))
($continue k src ($call proc args)))
'())))))
(($ $continue k ($ $primcall name args))
(($ $continue k src ($ $primcall name args))
(convert-free-vars args self bound
(lambda (args)
(values (build-cps-term
($continue k ($primcall name args)))
($continue k src ($primcall name args)))
'()))))
(($ $continue k ($ $values args))
(($ $continue k src ($ $values args))
(convert-free-vars args self bound
(lambda (args)
(values (build-cps-term
($continue k ($values args)))
($continue k src ($values args)))
'()))))
(($ $continue k ($ $prompt escape? tag handler pop))
(($ $continue k src ($ $prompt escape? tag handler pop))
(convert-free-var
tag self bound
(lambda (tag)
(values (build-cps-term
($continue k ($prompt escape? tag handler pop)))
($continue k src ($prompt escape? tag handler pop)))
'()))))
(_ (error "what" exp))))
@ -237,37 +237,38 @@ convert functions to flat closures."
(rewrite-cps-term term
(($ $letk conts body)
($letk ,(map visit-cont conts) ,(visit-term body)))
(($ $continue k ($ $primcall 'free-ref (closure sym)))
(($ $continue k src ($ $primcall 'free-ref (closure sym)))
,(let-gensyms (idx)
(build-cps-term
($letconst (('idx idx (free-index sym)))
($continue k ($primcall 'free-ref (closure idx)))))))
(($ $continue k ($ $fun meta free body))
($continue k ($fun meta free ,(convert-to-indices body free))))
($continue k src ($primcall 'free-ref (closure idx)))))))
(($ $continue k src ($ $fun src* meta free body))
($continue k src
($fun src* meta free ,(convert-to-indices body free))))
(($ $continue)
,term)))
(define (visit-cont cont)
(rewrite-cps-cont cont
(($ $cont sym src ($ $kargs names syms body))
(sym src ($kargs names syms ,(visit-term body))))
(($ $cont sym src ($ $kclause arity body))
(sym src ($kclause ,arity ,(visit-cont body))))
(($ $cont sym ($ $kargs names syms body))
(sym ($kargs names syms ,(visit-term body))))
(($ $cont sym ($ $kclause arity body))
(sym ($kclause ,arity ,(visit-cont body))))
;; Other kinds of continuations don't bind values and don't have
;; bodies.
(($ $cont)
,cont)))
(rewrite-cps-cont body
(($ $cont sym src ($ $kentry self tail clauses))
(sym src ($kentry self ,tail ,(map visit-cont clauses))))))
(($ $cont sym ($ $kentry self tail clauses))
(sym ($kentry self ,tail ,(map visit-cont clauses))))))
(define (convert-closures exp)
"Convert free reference in @var{exp} to primcalls to @code{free-ref},
and allocate and initialize flat closures."
(match exp
(($ $fun meta () body)
(($ $fun src meta () body)
(receive (body free) (cc body #f '())
(unless (null? free)
(error "Expected no free vars in toplevel thunk" exp body free))
(build-cps-exp
($fun meta free ,(convert-to-indices body free)))))))
($fun src meta free ,(convert-to-indices body free)))))))

View file

@ -76,39 +76,26 @@
exp))
(define (collect-conts f cfa)
(let ((srcv (make-vector (cfa-k-count cfa) #f))
(contv (make-vector (cfa-k-count cfa) #f)))
(let ((contv (make-vector (cfa-k-count cfa) #f)))
(fold-local-conts
(lambda (k src cont tail)
(lambda (k cont tail)
(let ((idx (cfa-k-idx cfa k #:default (lambda (k) #f))))
(when idx
(when src
(vector-set! srcv idx src))
(vector-set! contv idx cont))))
'()
(match f
(($ $fun meta free entry)
(($ $fun src meta free entry)
entry)))
(values srcv contv)))
contv))
(define (compile-fun f asm)
(let* ((dfg (compute-dfg f #:global? #f))
(cfa (analyze-control-flow f dfg))
(allocation (allocate-slots f dfg)))
(call-with-values (lambda () (collect-conts f cfa))
(lambda (srcv contv)
(allocation (allocate-slots f dfg))
(contv (collect-conts f cfa)))
(define (lookup-cont k)
(vector-ref contv (cfa-k-idx cfa k)))
(define (maybe-emit-source n)
(let ((src (vector-ref srcv n)))
(when src
(emit-source asm src))))
(define (emit-label-and-maybe-source n)
(emit-label asm (cfa-k-sym cfa n))
(maybe-emit-source n))
(define (immediate-u8? val)
(and (integer? val) (exact? val) (<= 0 val 255)))
@ -141,7 +128,6 @@
(match (vector-ref contv 0)
(($ $kentry self tail clauses)
(emit-begin-program asm (cfa-k-sym cfa 0) meta)
(maybe-emit-source 0)
(let lp ((n 1)
(ks (map (match-lambda (($ $cont k) k)) clauses)))
(match ks
@ -158,12 +144,13 @@
(define (compile-clause n alternate)
(match (vector-ref contv n)
(($ $kclause ($ $arity req opt rest kw allow-other-keys?))
(let ((kw-indices (map (match-lambda
(let* ((kw-indices (map (match-lambda
((key name sym)
(cons key (lookup-slot sym allocation))))
kw))
(nlocals (lookup-nlocals (cfa-k-sym cfa n) allocation)))
(emit-label-and-maybe-source n)
(k (cfa-k-sym cfa n))
(nlocals (lookup-nlocals k allocation)))
(emit-label asm k)
(emit-begin-kw-arity asm req opt rest kw-indices
allow-other-keys? nlocals alternate)
(let ((next (compile-body (1+ n) nlocals)))
@ -177,16 +164,18 @@
(match (vector-ref contv n)
(($ $kclause) n)
(($ $kargs _ _ term)
(emit-label-and-maybe-source n)
(emit-label asm (cfa-k-sym cfa n))
(let find-exp ((term term))
(match term
(($ $letk conts term)
(find-exp term))
(($ $continue k exp)
(($ $continue k src exp)
(when src
(emit-source asm src))
(compile-expression n k exp nlocals)
(compile-cont (1+ n))))))
(_
(emit-label-and-maybe-source n)
(emit-label asm (cfa-k-sym cfa n))
(compile-cont (1+ n)))))))
(define (compile-expression n k exp nlocals)
@ -256,9 +245,9 @@
(emit-load-constant asm dst *unspecified*))
(($ $const exp)
(emit-load-constant asm dst exp))
(($ $fun meta () ($ $cont k))
(($ $fun src meta () ($ $cont k))
(emit-load-static-procedure asm dst k))
(($ $fun meta free ($ $cont k))
(($ $fun src meta free ($ $cont k))
(emit-make-closure asm dst k (length free)))
(($ $call proc args)
(let ((proc-slot (lookup-call-proc-slot label allocation))
@ -474,15 +463,18 @@
(lp (1+ n) args))))))))
(match f
(($ $fun meta free ($ $cont k src ($ $kentry self tail clauses)))
(compile-entry (or meta '()))))))))
(($ $fun src meta free ($ $cont k ($ $kentry self tail clauses)))
;; FIXME: src on kentry instead?
(when src
(emit-source asm src))
(compile-entry (or meta '()))))))
(define (visit-funs proc exp)
(match exp
(($ $continue _ exp)
(($ $continue _ _ exp)
(visit-funs proc exp))
(($ $fun meta free body)
(($ $fun src meta free body)
(proc exp)
(visit-funs proc body))
@ -490,13 +482,13 @@
(visit-funs proc body)
(for-each (lambda (cont) (visit-funs proc cont)) conts))
(($ $cont sym src ($ $kargs names syms body))
(($ $cont sym ($ $kargs names syms body))
(visit-funs proc body))
(($ $cont sym src ($ $kclause arity body))
(($ $cont sym ($ $kclause arity body))
(visit-funs proc body))
(($ $cont sym src ($ $kentry self tail clauses))
(($ $cont sym ($ $kentry self tail clauses))
(for-each (lambda (clause) (visit-funs proc clause)) clauses))
(_ (values))))

View file

@ -32,12 +32,12 @@
(define (inline-constructors fun)
(define (visit-cont cont)
(rewrite-cps-cont cont
(($ $cont sym src ($ $kargs names syms body))
(sym src ($kargs names syms ,(visit-term body))))
(($ $cont sym src ($ $kentry self tail clauses))
(sym src ($kentry self ,tail ,(map visit-cont clauses))))
(($ $cont sym src ($ $kclause arity body))
(sym src ($kclause ,arity ,(visit-cont body))))
(($ $cont sym ($ $kargs names syms body))
(sym ($kargs names syms ,(visit-term body))))
(($ $cont sym ($ $kentry self tail clauses))
(sym ($kentry self ,tail ,(map visit-cont clauses))))
(($ $cont sym ($ $kclause arity body))
(sym ($kclause ,arity ,(visit-cont body))))
(($ $cont)
,cont)))
(define (visit-term term)
@ -48,51 +48,51 @@
(($ $letrec names syms funs body)
($letrec names syms (map inline-constructors funs)
,(visit-term body)))
(($ $continue k ($ $primcall 'list args))
(($ $continue k src ($ $primcall 'list args))
,(let-gensyms (kvalues val)
(build-cps-term
($letk ((kvalues #f ($kargs ('val) (val)
($continue k
($letk ((kvalues ($kargs ('val) (val)
($continue k src
($primcall 'values (val))))))
,(let lp ((args args) (k kvalues))
(match args
(()
(build-cps-term
($continue k ($const '()))))
($continue k src ($const '()))))
((arg . args)
(let-gensyms (ktail tail)
(build-cps-term
($letk ((ktail #f ($kargs ('tail) (tail)
($continue k
($letk ((ktail ($kargs ('tail) (tail)
($continue k src
($primcall 'cons (arg tail))))))
,(lp args ktail)))))))))))
(($ $continue k ($ $primcall 'vector args))
(($ $continue k src ($ $primcall 'vector args))
,(let-gensyms (kalloc vec len init)
(define (initialize args n)
(match args
(()
(build-cps-term
($continue k ($primcall 'values (vec)))))
($continue k src ($primcall 'values (vec)))))
((arg . args)
(let-gensyms (knext idx)
(build-cps-term
($letk ((knext #f ($kargs () ()
($letk ((knext ($kargs () ()
,(initialize args (1+ n)))))
($letconst (('idx idx n))
($continue knext
($continue knext src
($primcall 'vector-set! (vec idx arg))))))))))
(build-cps-term
($letk ((kalloc #f ($kargs ('vec) (vec)
($letk ((kalloc ($kargs ('vec) (vec)
,(initialize args 0))))
($letconst (('len len (length args))
('init init #f))
($continue kalloc
($continue kalloc src
($primcall 'make-vector (len init))))))))
(($ $continue k (and fun ($ $fun)))
($continue k ,(inline-constructors fun)))
(($ $continue k src (and fun ($ $fun)))
($continue k src ,(inline-constructors fun)))
(($ $continue)
,term)))
(rewrite-cps-exp fun
(($ $fun meta free body)
($fun meta free ,(visit-cont body)))))
(($ $fun src meta free body)
($fun src meta free ,(visit-cont body)))))

View file

@ -95,7 +95,7 @@
;; target continuation. Otherwise return #f.
(define (call-target use proc)
(match (find-call (lookup-cont use cont-table))
(($ $continue k ($ $call proc* args))
(($ $continue k src ($ $call proc* args))
(and (eq? proc proc*) (not (memq proc args)) (applicable? proc args)
k))
(_ #f)))
@ -141,7 +141,7 @@
;; bail.
(($ $kentry self tail clauses)
(match clauses
((($ $cont _ _ ($ $kclause arity ($ $cont kargs))))
((($ $cont _ ($ $kclause arity ($ $cont kargs))))
kargs)
(_ #f)))
(_ scope)))))
@ -168,15 +168,15 @@
(define (visit-fun term)
(match term
(($ $fun meta free body)
(($ $fun src meta free body)
(visit-cont body))))
(define (visit-cont cont)
(match cont
(($ $cont sym src ($ $kargs _ _ body))
(($ $cont sym ($ $kargs _ _ body))
(visit-term body sym))
(($ $cont sym src ($ $kentry self tail clauses))
(($ $cont sym ($ $kentry self tail clauses))
(for-each visit-cont clauses))
(($ $cont sym src ($ $kclause arity body))
(($ $cont sym ($ $kclause arity body))
(visit-cont body))
(($ $cont)
#t)))
@ -199,7 +199,7 @@
(if (null? rec)
'()
(list rec)))
(((and elt (n s ($ $fun meta free ($ $cont kentry))))
(((and elt (n s ($ $fun src meta free ($ $cont kentry))))
. nsf)
(if (recursive? kentry)
(lp nsf (cons elt rec))
@ -208,11 +208,11 @@
(match component
(((name sym fun) ...)
(match fun
((($ $fun meta free
($ $cont fun-k _
((($ $fun src meta free
($ $cont fun-k
($ $kentry self
($ $cont tail-k _ ($ $ktail))
(($ $cont _ _ ($ $kclause arity body))
($ $cont tail-k ($ $ktail))
(($ $cont _ ($ $kclause arity body))
...))))
...)
(unless (contify-funs term-k sym self tail-k arity body)
@ -220,13 +220,13 @@
(visit-term body term-k)
(for-each visit-component
(split-components (map list names syms funs))))
(($ $continue k exp)
(($ $continue k src exp)
(match exp
(($ $fun meta free
($ $cont fun-k _
(($ $fun src meta free
($ $cont fun-k
($ $kentry self
($ $cont tail-k _ ($ $ktail))
(($ $cont _ _ ($ $kclause arity body)) ...))))
($ $cont tail-k ($ $ktail))
(($ $cont _ ($ $kclause arity body)) ...))))
(if (and=> (bound-symbol k)
(lambda (sym)
(contify-fun term-k sym self tail-k arity body)))
@ -238,7 +238,7 @@
(values call-substs cont-substs fun-elisions cont-splices)))
(define (apply-contification fun call-substs cont-substs fun-elisions cont-splices)
(define (contify-call proc args)
(define (contify-call src proc args)
(and=> (assq-ref call-substs proc)
(lambda (clauses)
(let lp ((clauses clauses))
@ -247,11 +247,11 @@
(((($ $arity req () #f () #f) . k) . clauses)
(if (= (length req) (length args))
(build-cps-term
($continue k
($continue k src
($values args)))
(lp clauses)))
((_ . clauses) (lp clauses)))))))
(define (continue k exp)
(define (continue k src exp)
(define (lookup-return-cont k)
(match (assq-ref cont-substs k)
(#f k)
@ -260,13 +260,13 @@
;; We are contifying this return. It must be a call or a
;; primcall to values, return, or return-values.
(if (eq? k k*)
(build-cps-term ($continue k ,exp))
(build-cps-term ($continue k src ,exp))
(rewrite-cps-term exp
(($ $primcall 'return (val))
($continue k* ($primcall 'values (val))))
($continue k* src ($primcall 'values (val))))
(($ $values vals)
($continue k* ($primcall 'values vals)))
(_ ($continue k* ,exp))))))
($continue k* src ($primcall 'values vals)))
(_ ($continue k* src ,exp))))))
(define (splice-continuations term-k term)
(match (hashq-ref cont-splices term-k)
(#f term)
@ -283,19 +283,19 @@
,body)))))))
(define (visit-fun term)
(rewrite-cps-exp term
(($ $fun meta free body)
($fun meta free ,(visit-cont body)))))
(($ $fun src meta free body)
($fun src meta free ,(visit-cont body)))))
(define (visit-cont cont)
(rewrite-cps-cont cont
(($ $cont (? (cut assq <> fun-elisions)))
;; This cont gets inlined in place of the $fun.
,#f)
(($ $cont sym src ($ $kargs names syms body))
(sym src ($kargs names syms ,(visit-term body sym))))
(($ $cont sym src ($ $kentry self tail clauses))
(sym src ($kentry self ,tail ,(map visit-cont clauses))))
(($ $cont sym src ($ $kclause arity body))
(sym src ($kclause ,arity ,(visit-cont body))))
(($ $cont sym ($ $kargs names syms body))
(sym ($kargs names syms ,(visit-term body sym))))
(($ $cont sym ($ $kentry self tail clauses))
(sym ($kentry self ,tail ,(map visit-cont clauses))))
(($ $cont sym ($ $kclause arity body))
(sym ($kclause ,arity ,(visit-cont body))))
(($ $cont)
,cont)))
(define (visit-term term term-k)
@ -324,7 +324,7 @@
(((names syms funs) ...)
($letrec names syms (map visit-fun funs)
,(visit-term body term-k)))))
(($ $continue k exp)
(($ $continue k src exp)
(splice-continuations
term-k
(match exp
@ -335,11 +335,11 @@
(($ $kargs (_) (_) body)
(visit-term body k))))
(else
(continue k (visit-fun exp)))))
(continue k src (visit-fun exp)))))
(($ $call proc args)
(or (contify-call proc args)
(continue k exp)))
(_ (continue k exp)))))))
(or (contify-call src proc args)
(continue k src exp)))
(_ (continue k src exp)))))))
(visit-fun fun))
(define (contify fun)

View file

@ -73,14 +73,14 @@
print-dfa))
(define (build-cont-table fun)
(fold-conts (lambda (k src cont table)
(fold-conts (lambda (k cont table)
(hashq-set! table k cont)
table)
(make-hash-table)
fun))
(define (build-local-cont-table cont)
(fold-local-conts (lambda (k src cont table)
(fold-local-conts (lambda (k cont table)
(hashq-set! table k cont)
table)
(make-hash-table)
@ -206,10 +206,10 @@
(reachable-preds k-map block-preds))))
(make-cfa k-map order preds)))
(match fun
(($ $fun meta free
($ $cont kentry src
(($ $fun src meta free
($ $cont kentry
(and entry
($ $kentry self ($ $cont ktail _ tail) clauses))))
($ $kentry self ($ $cont ktail tail) clauses))))
(if reverse?
(build-cfa ktail block-preds block-succs)
(build-cfa kentry block-succs block-preds)))))
@ -549,13 +549,13 @@
(map (cut hashq-ref mapping <>)
((block-accessor blocks accessor) k))))
(match fun
(($ $fun meta free
(($ $fun src meta free
(and entry
($ $cont kentry src ($ $kentry self ($ $cont ktail _ tail)))))
($ $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 src cont seed) (f k seed))
(fold-local-conts (lambda (k cont seed) (f k seed))
seed entry))
(let* ((blocks (dfg-blocks dfg))
(order (reverse-post-order ktail
@ -662,7 +662,7 @@
(define (recur exp)
(visit exp exp-k))
(match exp
(($ $letk (($ $cont k src cont) ...) body)
(($ $letk (($ $cont k cont) ...) body)
;; Set up recursive environment before visiting cont bodies.
(for-each (lambda (cont k)
(declare-block! k cont exp-k))
@ -688,7 +688,7 @@
(for-each (cut visit-fun <> conts blocks use-maps global?) funs)
(visit body exp-k))
(($ $continue k exp)
(($ $continue k src exp)
(use-k! k)
(match exp
(($ $var sym)
@ -726,10 +726,10 @@
(_ #f)))))
(match fun
(($ $fun meta free
($ $cont kentry src
(($ $fun src meta free
($ $cont kentry
(and entry
($ $kentry self ($ $cont ktail _ tail) clauses))))
($ $kentry self ($ $cont ktail tail) clauses))))
(declare-block! kentry entry #f 0)
(add-def! #f self kentry)
@ -737,8 +737,8 @@
(for-each
(match-lambda
(($ $cont kclause _
(and clause ($ $kclause arity ($ $cont kbody _ body))))
(($ $cont kclause
(and clause ($ $kclause arity ($ $cont kbody body))))
(declare-block! kclause clause kentry)
(link-blocks! kentry kclause)
@ -811,7 +811,7 @@
(define (call-expression call)
(match call
(($ $continue k exp) exp)))
(($ $continue k src exp) exp)))
(define (find-expression term)
(call-expression (find-call term)))
@ -827,7 +827,7 @@
(match (find-defining-expression sym dfg)
(($ $const val)
(values #t val))
(($ $continue k ($ $void))
(($ $continue k src ($ $void))
(values #t *unspecified*))
(else
(values #f #f))))

View file

@ -37,15 +37,15 @@
(define (elide-values fun)
(let ((conts (build-local-cont-table
(match fun (($ $fun meta free body) body)))))
(match fun (($ $fun src meta free body) body)))))
(define (visit-cont cont)
(rewrite-cps-cont cont
(($ $cont sym src ($ $kargs names syms body))
(sym src ($kargs names syms ,(visit-term body))))
(($ $cont sym src ($ $kentry self tail clauses))
(sym src ($kentry self ,tail ,(map visit-cont clauses))))
(($ $cont sym src ($ $kclause arity body))
(sym src ($kclause ,arity ,(visit-cont body))))
(($ $cont sym ($ $kargs names syms body))
(sym ($kargs names syms ,(visit-term body))))
(($ $cont sym ($ $kentry self tail clauses))
(sym ($kentry self ,tail ,(map visit-cont clauses))))
(($ $cont sym ($ $kclause arity body))
(sym ($kclause ,arity ,(visit-cont body))))
(($ $cont)
,cont)))
(define (visit-term term)
@ -56,27 +56,27 @@
(($ $letrec names syms funs body)
($letrec names syms (map elide-values funs)
,(visit-term body)))
(($ $continue k ($ $primcall 'values vals))
(($ $continue k src ($ $primcall 'values vals))
,(rewrite-cps-term (lookup-cont k conts)
(($ $ktail)
($continue k ($values vals)))
($continue k src ($values vals)))
(($ $ktrunc ($ $arity req () rest () #f) kargs)
,(if (or rest (< (length vals) (length req)))
term
(let ((vals (list-head vals (length req))))
(build-cps-term
($continue kargs ($values vals))))))
($continue kargs src ($values vals))))))
(($ $kargs args)
,(if (< (length vals) (length args))
term
(let ((vals (list-head vals (length args))))
(build-cps-term
($continue k ($values vals))))))))
(($ $continue k (and fun ($ $fun)))
($continue k ,(elide-values fun)))
($continue k src ($values vals))))))))
(($ $continue k src (and fun ($ $fun)))
($continue k src ,(elide-values fun)))
(($ $continue)
,term)))
(rewrite-cps-exp fun
(($ $fun meta free body)
($fun meta free ,(visit-cont body))))))
(($ $fun src meta free body)
($fun src meta free ,(visit-cont body))))))

View file

@ -39,8 +39,8 @@
('name name-sym name)
('public? public?-sym public?)
('bound? bound?-sym bound?))
($letk ((kbox src ($kargs ('box) (box) ,(val-proc box))))
($continue kbox
($letk ((kbox ($kargs ('box) (box) ,(val-proc box))))
($continue kbox src
($primcall 'cached-module-box
(module-sym name-sym public?-sym bound?-sym))))))))
@ -72,63 +72,61 @@
((class-of @slot-ref @slot-set!) '(oop goops))
(else '(guile))))
(define (primitive-ref name k)
(define (primitive-ref name k src)
(module-box #f (primitive-module name) name #f #t
(lambda (box)
(build-cps-term
($continue k ($primcall 'box-ref (box)))))))
($continue k src ($primcall 'box-ref (box)))))))
(define (builtin-ref idx k)
(define (builtin-ref idx k src)
(let-gensyms (idx-sym)
(build-cps-term
($letconst (('idx idx-sym idx))
($continue k
($continue k src
($primcall 'builtin-ref (idx-sym)))))))
(define (reify-clause ktail)
(let-gensyms (kclause kbody wna false str eol kthrow throw)
(build-cps-cont
(kclause #f ($kclause ('() '() #f '() #f)
(kclause ($kclause ('() '() #f '() #f)
(kbody
#f
($kargs () ()
($letconst (('wna wna 'wrong-number-of-args)
('false false #f)
('str str "Wrong number of arguments")
('eol eol '()))
($letk ((kthrow
#f
($kargs ('throw) (throw)
($continue ktail
($continue ktail #f
($call throw
(wna false str eol false))))))
,(primitive-ref 'throw kthrow))))))))))
,(primitive-ref 'throw kthrow #f))))))))))
;; FIXME: Operate on one function at a time, for efficiency.
(define (reify-primitives fun)
(let ((conts (build-cont-table fun)))
(define (visit-fun term)
(rewrite-cps-exp term
(($ $fun meta free body)
($fun meta free ,(visit-cont body)))))
(($ $fun src meta free body)
($fun src meta free ,(visit-cont body)))))
(define (visit-cont cont)
(rewrite-cps-cont cont
(($ $cont sym src ($ $kargs names syms body))
(sym src ($kargs names syms ,(visit-term body))))
(($ $cont sym src ($ $kentry self (and tail ($ $cont ktail)) ()))
(($ $cont sym ($ $kargs names syms body))
(sym ($kargs names syms ,(visit-term body))))
(($ $cont sym ($ $kentry self (and tail ($ $cont ktail)) ()))
;; A case-lambda with no clauses. Reify a clause.
(sym src ($kentry self ,tail (,(reify-clause ktail)))))
(($ $cont sym src ($ $kentry self tail clauses))
(sym src ($kentry self ,tail ,(map visit-cont clauses))))
(($ $cont sym src ($ $kclause arity body))
(sym src ($kclause ,arity ,(visit-cont body))))
(sym ($kentry self ,tail (,(reify-clause ktail)))))
(($ $cont sym ($ $kentry self tail clauses))
(sym ($kentry self ,tail ,(map visit-cont clauses))))
(($ $cont sym ($ $kclause arity body))
(sym ($kclause ,arity ,(visit-cont body))))
(($ $cont)
,cont)))
(define (visit-term term)
(rewrite-cps-term term
(($ $letk conts body)
($letk ,(map visit-cont conts) ,(visit-term body)))
(($ $continue k exp)
(($ $continue k src exp)
,(match exp
(($ $prim name)
(match (lookup-cont k conts)
@ -136,14 +134,14 @@
(cond
((builtin-name->index name)
=> (lambda (idx)
(builtin-ref idx k)))
(else (primitive-ref name k))))
(_ (build-cps-term ($continue k ($void))))))
(builtin-ref idx k src)))
(else (primitive-ref name k src))))
(_ (build-cps-term ($continue k src ($void))))))
(($ $fun)
(build-cps-term ($continue k ,(visit-fun exp))))
(build-cps-term ($continue k src ,(visit-fun exp))))
(($ $primcall 'call-thunk/no-inline (proc))
(build-cps-term
($continue k ($call proc ()))))
($continue k src ($call proc ()))))
(($ $primcall name args)
(cond
((or (prim-rtl-instruction name) (branching-primitive? name))
@ -152,13 +150,13 @@
(else
(let-gensyms (k* v)
(build-cps-term
($letk ((k* #f ($kargs (v) (v)
($continue k ($call v args)))))
($letk ((k* ($kargs (v) (v)
($continue k src ($call v args)))))
,(cond
((builtin-name->index name)
=> (lambda (idx)
(builtin-ref idx k*)))
(else (primitive-ref name k*)))))))))
(builtin-ref idx k* src)))
(else (primitive-ref name k* src)))))))))
(_ term)))))
(visit-fun fun)))

View file

@ -235,7 +235,7 @@ are comparable with eqv?. A tmp slot may be used."
(define nlocals (compute-slot live-slots #f))
(define nargs
(match clause
(($ $cont _ _ ($ $kclause _ ($ $cont _ _ ($ $kargs names syms))))
(($ $cont _ ($ $kclause _ ($ $cont _ ($ $kargs names syms))))
(length syms))))
(define (allocate! sym k hint live-slots)
@ -310,7 +310,7 @@ are comparable with eqv?. A tmp slot may be used."
live-slots))
(match cont
(($ $kclause arity ($ $cont k src body))
(($ $kclause arity ($ $cont k body))
(visit-cont body k live-slots))
(($ $kargs names syms body)
@ -328,12 +328,12 @@ are comparable with eqv?. A tmp slot may be used."
(($ $letk conts body)
(let ((live-slots (visit-term body label live-slots)))
(for-each (match-lambda
(($ $cont k src cont)
(($ $cont k cont)
(visit-cont cont k live-slots)))
conts))
live-slots)
(($ $continue k exp)
(($ $continue k src exp)
(visit-exp exp label k live-slots))))
(define (visit-exp exp label k live-slots)
@ -420,12 +420,12 @@ are comparable with eqv?. A tmp slot may be used."
(_ live-slots)))
(match clause
(($ $cont k _ body)
(($ $cont k body)
(visit-cont body k live-slots)
(hashq-set! allocation k nlocals))))
(match fun
(($ $fun meta free ($ $cont k _ ($ $kentry self tail clauses)))
(($ $fun src meta free ($ $cont k ($ $kentry self tail clauses)))
(let* ((dfa (compute-live-variables fun dfg))
(allocation (make-hash-table))
(slots (make-vector (dfa-var-count dfa) #f))

View file

@ -71,7 +71,7 @@
(define (visit-clause clause k-env v-env)
(match clause
(($ $cont kclause src*
(($ $cont kclause
($ $kclause
($ $arity
((? symbol? req) ...)
@ -79,9 +79,7 @@
(and rest (or #f (? symbol?)))
(((? keyword? kw) (? symbol? kwname) (? symbol? kwsym)) ...)
(or #f #t))
($ $cont kbody src (and body ($ $kargs names syms _)))))
(check-src src*)
(check-src src)
($ $cont kbody (and body ($ $kargs names syms _)))))
(for-each (lambda (sym)
(unless (memq sym syms)
(error "bad keyword sym" sym)))
@ -98,9 +96,9 @@
(define (visit-fun fun k-env v-env)
(match fun
(($ $fun meta ((? symbol? free) ...)
($ $cont kbody src
($ $kentry (? symbol? self) ($ $cont ktail _ ($ $ktail)) clauses)))
(($ $fun src meta ((? symbol? free) ...)
($ $cont kbody
($ $kentry (? symbol? self) ($ $cont ktail ($ $ktail)) clauses)))
(when (and meta (not (and (list? meta) (and-map pair? meta))))
(error "meta should be alist" meta))
(for-each (cut check-var <> v-env) free)
@ -142,9 +140,8 @@
(define (visit-term term k-env v-env)
(match term
(($ $letk (($ $cont (? symbol? k) src cont) ...) body)
(($ $letk (($ $cont (? symbol? k) cont) ...) body)
(let ((k-env (add-env k k-env)))
(for-each check-src src)
(for-each (cut visit-cont-body <> k-env v-env) cont)
(visit-term body k-env v-env)))
@ -155,8 +152,9 @@
(for-each (cut visit-fun <> k-env v-env) fun)
(visit-term body k-env v-env)))
(($ $continue k exp)
(($ $continue k src exp)
(check-var k k-env)
(check-src src)
(visit-expression exp k-env v-env))
(_

View file

@ -81,18 +81,18 @@
(build-cps-term
($letconst (('name name-sym name)
('bound? bound?-sym bound?))
($letk ((kbox src ($kargs ('box) (box) ,(val-proc box))))
($letk ((kbox ($kargs ('box) (box) ,(val-proc box))))
,(match (current-topbox-scope)
(#f
(build-cps-term
($continue kbox
($continue kbox src
($primcall 'resolve
(name-sym bound?-sym)))))
(scope
(let-gensyms (scope-sym)
(build-cps-term
($letconst (('scope scope-sym scope))
($continue kbox
($continue kbox src
($primcall 'cached-toplevel-box
(scope-sym name-sym bound?-sym)))))))))))))
@ -103,8 +103,8 @@
('name name-sym name)
('public? public?-sym public?)
('bound? bound?-sym bound?))
($letk ((kbox src ($kargs ('box) (box) ,(val-proc box))))
($continue kbox
($letk ((kbox ($kargs ('box) (box) ,(val-proc box))))
($continue kbox src
($primcall 'cached-module-box
(module-sym name-sym public?-sym bound?-sym))))))))
@ -112,11 +112,11 @@
(let-gensyms (module scope-sym kmodule)
(build-cps-term
($letconst (('scope scope-sym scope))
($letk ((kmodule src ($kargs ('module) (module)
($continue k
($letk ((kmodule ($kargs ('module) (module)
($continue k src
($primcall 'cache-current-module!
(module scope-sym))))))
($continue kmodule
($continue kmodule src
($primcall 'current-module ())))))))
(define (fold-formals proc seed arity gensyms inits)
@ -162,8 +162,8 @@
(let-gensyms (unbound ktest)
(build-cps-term
($letconst (('unbound unbound (pointer->scm (make-pointer unbound-bits))))
($letk ((ktest src ($kif kt kf)))
($continue ktest
($letk ((ktest ($kif kt kf)))
($continue ktest src
($primcall 'eq? (sym unbound))))))))
(define (init-default-value name sym subst init body)
@ -174,19 +174,19 @@
(if box?
(let-gensyms (kbox phi)
(build-cps-term
($letk ((kbox src ($kargs (name) (phi)
($continue k ($primcall 'box (phi))))))
($letk ((kbox ($kargs (name) (phi)
($continue k src ($primcall 'box (phi))))))
,(make-body kbox))))
(make-body k)))
(let-gensyms (knext kbound kunbound)
(build-cps-term
($letk ((knext src ($kargs (name) (subst-sym) ,body)))
($letk ((knext ($kargs (name) (subst-sym) ,body)))
,(maybe-box
knext
(lambda (k)
(build-cps-term
($letk ((kbound src ($kargs () () ($continue k ($var sym))))
(kunbound src ($kargs () () ,(convert init k subst))))
($letk ((kbound ($kargs () () ($continue k src ($var sym))))
(kunbound ($kargs () () ,(convert init k subst))))
,(unbound? src sym kunbound kbound))))))))))))
;; exp k-name alist -> term
@ -199,16 +199,15 @@
((box #t)
(let-gensyms (kunboxed unboxed)
(build-cps-term
($letk ((kunboxed src ($kargs ('unboxed) (unboxed) ,(k unboxed))))
($continue kunboxed ($primcall 'box-ref (box)))))))
($letk ((kunboxed ($kargs ('unboxed) (unboxed) ,(k unboxed))))
($continue kunboxed src ($primcall 'box-ref (box)))))))
((subst #f) (k subst))
(#f (k sym))))
(else
(let ((src (tree-il-src exp)))
(let-gensyms (karg arg)
(build-cps-term
($letk ((karg src ($kargs ('arg) (arg) ,(k arg))))
,(convert exp karg subst))))))))
($letk ((karg ($kargs ('arg) (arg) ,(k arg))))
,(convert exp karg subst)))))))
;; (exp ...) ((v-name ...) -> term) -> term
(define (convert-args exps k)
(match exps
@ -224,25 +223,25 @@
((box #t)
(let-gensyms (k)
(build-cps-term
($letk ((k #f ($kargs (name) (box) ,body)))
($continue k ($primcall 'box (sym)))))))
($letk ((k ($kargs (name) (box) ,body)))
($continue k #f ($primcall 'box (sym)))))))
(else body)))
(match exp
(($ <lexical-ref> src name sym)
(match (assq-ref subst sym)
((box #t) (build-cps-term ($continue k ($primcall 'box-ref (box)))))
((subst #f) (build-cps-term ($continue k ($var subst))))
(#f (build-cps-term ($continue k ($var sym))))))
((box #t) (build-cps-term ($continue k src ($primcall 'box-ref (box)))))
((subst #f) (build-cps-term ($continue k src ($var subst))))
(#f (build-cps-term ($continue k src ($var sym))))))
(($ <void> src)
(build-cps-term ($continue k ($void))))
(build-cps-term ($continue k src ($void))))
(($ <const> src exp)
(build-cps-term ($continue k ($const exp))))
(build-cps-term ($continue k src ($const exp))))
(($ <primitive-ref> src name)
(build-cps-term ($continue k ($prim name))))
(build-cps-term ($continue k src ($prim name))))
(($ <lambda> fun-src meta body)
(let ()
@ -260,10 +259,8 @@
(let-gensyms (kclause kargs)
(build-cps-cont
(kclause
src
($kclause ,arity
(kargs
src
($kargs names gensyms
,(fold-formals
(lambda (name sym init body)
@ -276,15 +273,13 @@
(if (current-topbox-scope)
(let-gensyms (kentry self ktail)
(build-cps-term
($continue k
($fun meta '()
(kentry fun-src
($kentry self (ktail #f ($ktail))
($continue k fun-src
($fun fun-src meta '()
(kentry ($kentry self (ktail ($ktail))
,(convert-clauses body ktail)))))))
(let-gensyms (scope kscope)
(build-cps-term
($letk ((kscope fun-src
($kargs () ()
($letk ((kscope ($kargs () ()
,(parameterize ((current-topbox-scope scope))
(convert exp k subst)))))
,(capture-toplevel-scope fun-src scope kscope)))))))
@ -293,7 +288,7 @@
(module-box
src mod name public? #t
(lambda (box)
(build-cps-term ($continue k ($primcall 'box-ref (box)))))))
(build-cps-term ($continue k src ($primcall 'box-ref (box)))))))
(($ <module-set> src mod name public? exp)
(convert-arg exp
@ -301,13 +296,14 @@
(module-box
src mod name public? #f
(lambda (box)
(build-cps-term ($continue k ($primcall 'box-set! (box val)))))))))
(build-cps-term
($continue k src ($primcall 'box-set! (box val)))))))))
(($ <toplevel-ref> src name)
(toplevel-box
src name #t
(lambda (box)
(build-cps-term ($continue k ($primcall 'box-ref (box)))))))
(build-cps-term ($continue k src ($primcall 'box-ref (box)))))))
(($ <toplevel-set> src name exp)
(convert-arg exp
@ -315,7 +311,8 @@
(toplevel-box
src name #f
(lambda (box)
(build-cps-term ($continue k ($primcall 'box-set! (box val)))))))))
(build-cps-term
($continue k src ($primcall 'box-set! (box val)))))))))
(($ <toplevel-define> src name exp)
(convert-arg exp
@ -323,13 +320,13 @@
(let-gensyms (kname name-sym)
(build-cps-term
($letconst (('name name-sym name))
($continue k ($primcall 'define! (name-sym val)))))))))
($continue k src ($primcall 'define! (name-sym val)))))))))
(($ <call> src proc args)
(convert-args (cons proc args)
(match-lambda
((proc . args)
(build-cps-term ($continue k ($call proc args)))))))
(build-cps-term ($continue k src ($call proc args)))))))
(($ <primcall> src name args)
(cond
@ -389,22 +386,21 @@
(match args
(()
(build-cps-term
($continue k ($const '()))))
($continue k src ($const '()))))
((arg . args)
(let-gensyms (ktail tail)
(build-cps-term
($letk ((ktail src
($kargs ('tail) (tail)
($letk ((ktail ($kargs ('tail) (tail)
,(convert-arg arg
(lambda (head)
(build-cps-term
($continue k
($continue k src
($primcall 'cons (head tail)))))))))
,(lp args ktail))))))))
(else
(convert-args args
(lambda (args)
(build-cps-term ($continue k ($primcall name args))))))))
(build-cps-term ($continue k src ($primcall name args))))))))
;; Prompts with inline handlers.
(($ <prompt> src escape-only? tag body
@ -427,42 +423,38 @@
(let ((hnames (append hreq (if hrest (list hrest) '()))))
(let-gensyms (khargs khbody kret kprim prim kpop krest vals kbody)
(build-cps-term
($letk* ((khbody hsrc ($kargs hnames hsyms
;; FIXME: Attach hsrc to $ktrunc.
($letk* ((khbody ($kargs hnames hsyms
,(fold box-bound-var
(convert hbody k subst)
hnames hsyms)))
(khargs hsrc ($ktrunc hreq hrest khbody))
(kpop src
($kargs ('rest) (vals)
(khargs ($ktrunc hreq hrest khbody))
(kpop ($kargs ('rest) (vals)
($letk ((kret
src
($kargs () ()
($letk ((kprim
src
($kargs ('prim) (prim)
($continue k
($continue k src
($primcall 'apply
(prim vals))))))
($continue kprim
($continue kprim src
($prim 'values))))))
($continue kret
($continue kret src
($primcall 'unwind ())))))
(krest src ($ktrunc '() 'rest kpop)))
(krest ($ktrunc '() 'rest kpop)))
,(if escape-only?
(build-cps-term
($letk ((kbody (tree-il-src body)
($kargs () ()
($letk ((kbody ($kargs () ()
,(convert body krest subst))))
($continue kbody ($prompt #t tag khargs kpop))))
($continue kbody src ($prompt #t tag khargs kpop))))
(convert-arg body
(lambda (thunk)
(build-cps-term
($letk ((kbody (tree-il-src body)
($kargs () ()
($continue krest
($letk ((kbody ($kargs () ()
($continue krest (tree-il-src body)
($primcall 'call-thunk/no-inline
(thunk))))))
($continue kbody
($continue kbody (tree-il-src body)
($prompt #f tag khargs kpop))))))))))))))
;; Eta-convert prompts without inline handlers.
@ -503,7 +495,8 @@
(convert-args (cons tag args)
(lambda (args*)
(build-cps-term
($continue k ($primcall 'abort-to-prompt args*))))))
($continue k src
($primcall 'abort-to-prompt args*))))))
(($ <abort> src tag args tail)
(convert-args (append (list (make-primitive-ref #f 'abort-to-prompt)
@ -512,24 +505,24 @@
(list tail))
(lambda (args*)
(build-cps-term
($continue k ($primcall 'apply args*))))))
($continue k src ($primcall 'apply args*))))))
(($ <conditional> src test consequent alternate)
(let-gensyms (kif kt kf)
(build-cps-term
($letk* ((kt (tree-il-src consequent) ($kargs () ()
,(convert consequent k subst)))
(kf (tree-il-src alternate) ($kargs () ()
,(convert alternate k subst)))
(kif src ($kif kt kf)))
($letk* ((kt ($kargs () () ,(convert consequent k subst)))
(kf ($kargs () () ,(convert alternate k subst)))
(kif ($kif kt kf)))
,(match test
(($ <primcall> src (? branching-primitive? name) args)
(convert-args args
(lambda (args)
(build-cps-term ($continue kif ($primcall name args))))))
(build-cps-term
($continue kif src ($primcall name args))))))
(_ (convert-arg test
(lambda (test)
(build-cps-term ($continue kif ($var test)))))))))))
(build-cps-term
($continue kif src ($var test)))))))))))
(($ <lexical-set> src name gensym exp)
(convert-arg exp
@ -537,14 +530,14 @@
(match (assq-ref subst gensym)
((box #t)
(build-cps-term
($continue k ($primcall 'box-set! (box exp)))))))))
($continue k src ($primcall 'box-set! (box exp)))))))))
(($ <seq> src head tail)
(let-gensyms (ktrunc kseq)
(build-cps-term
($letk* ((kseq (tree-il-src tail) ($kargs () ()
($letk* ((kseq ($kargs () ()
,(convert tail k subst)))
(ktrunc src ($ktrunc '() #f kseq)))
(ktrunc ($ktrunc '() #f kseq)))
,(convert head ktrunc subst)))))
(($ <let> src names syms vals body)
@ -554,7 +547,7 @@
(((name . names) (sym . syms) (val . vals))
(let-gensyms (klet)
(build-cps-term
($letk ((klet src ($kargs (name) (sym)
($letk ((klet ($kargs (name) (sym)
,(box-bound-var name sym
(lp names syms vals)))))
,(convert val klet subst))))))))
@ -568,13 +561,13 @@
gensyms
(map (lambda (fun)
(match (convert fun k subst)
(($ $continue _ (and fun ($ $fun)))
(($ $continue _ _ (and fun ($ $fun)))
fun)))
funs)
,(convert body k subst))))
(let-gensyms (scope kscope)
(build-cps-term
($letk ((kscope src ($kargs () ()
($letk ((kscope ($kargs () ()
,(parameterize ((current-topbox-scope scope))
(convert exp k subst)))))
,(capture-toplevel-scope src scope kscope))))))
@ -584,11 +577,11 @@
(let ((names (append req (if rest (list rest) '()))))
(let-gensyms (ktrunc kargs)
(build-cps-term
($letk* ((kargs src ($kargs names syms
($letk* ((kargs ($kargs names syms
,(fold box-bound-var
(convert body k subst)
names syms)))
(ktrunc src ($ktrunc req rest kargs)))
(ktrunc ($ktrunc req rest kargs)))
,(convert exp ktrunc subst))))))))
(define (build-subst exp)
@ -628,14 +621,12 @@ indicates that the replacement variable is in a box."
(let ((src (tree-il-src exp)))
(let-gensyms (kinit init ktail kclause kbody)
(build-cps-exp
($fun '() '()
(kinit src
($kentry init
(ktail #f ($ktail))
((kclause src
($fun src '() '()
(kinit ($kentry init
(ktail ($ktail))
((kclause
($kclause ('() '() #f '() #f)
(kbody src
($kargs () ()
(kbody ($kargs () ()
,(convert exp ktail
(build-subst exp))))))))))))))