~ chicken-core (chicken-5) 80708c08b4da846879ccd2b320fe1525931f211f
commit 80708c08b4da846879ccd2b320fe1525931f211f
Author: felix <felix@call-with-current-continuation.org>
AuthorDate: Sun Jul 10 14:35:02 2011 +0200
Commit: felix <felix@call-with-current-continuation.org>
CommitDate: Sun Jul 10 14:35:02 2011 +0200
trying to do sensible closure-conversion
diff --git a/compiler.scm b/compiler.scm
index 1779d6f4..64f9bcd9 100644
--- a/compiler.scm
+++ b/compiler.scm
@@ -4,7 +4,7 @@
; "This is insane. What we clearly want to do is not exactly clear, and is rooted in NCOMPLR."
;
;
-;--------------------------------------------------------------------------------------------------
+;--------------------------------------------------------------------------------------------
; Copyright (c) 2008-2011, The Chicken Team
; Copyright (c) 2000-2007, Felix L. Winkelmann
; All rights reserved.
@@ -2097,11 +2097,14 @@
;;; Collect unsafe global procedure calls that are assigned:
-;;; Convert closures to explicit data structures (effectively flattens function-binding structure):
+;;; Convert closures to explicit data structures (effectively flattens function-binding
+; structure):
(define (perform-closure-conversion node db)
- (let ([direct-calls 0]
- [customizable '()] )
+ (let ((direct-calls 0)
+ (customizable '())
+ (captured '())
+ (lexicals '()))
(define (test sym item) (get db sym item))
@@ -2113,6 +2116,9 @@
(set! direct-calls (add1 direct-calls))
(set! direct-call-ids (lset-adjoin eq? direct-call-ids id)) )
+ (define (capture var)
+ (set! captured (lset-adjoin eq? captured var)))
+
;; Gather free-variable information:
;; (and: - register direct calls
;; - update (by mutation) call information in "##core#call" nodes)
@@ -2121,12 +2127,24 @@
(params (node-parameters n)) )
(case (node-class n)
- ((quote ##core#variable ##core#undefined ##core#proc ##core#primitive ##core#global-ref) #f)
+ ((##core#variable)
+ (let ((var (first params)))
+ (when (memq var lexicals)
+ (capture var))))
+
+ ((quote ##core#undefined ##core#proc ##core#primitive ##core#global-ref)
+ #f)
((let)
- (receive (vals body) (split-at subs (length params))
- (for-each (lambda (n) (gather n here env)) vals)
- (gather (first body) here (append params env)) ) )
+ ;;XXX remove this test later:
+ (when (pair? (cdr params)) (bomb "let-node has invalid format" params))
+ (gather (first subs) here env)
+ (gather (second subs) here (cons (first params) env)))
+
+ ((set!)
+ (let ((var (first params)))
+ (when (memq var lexicals) (capture var))
+ (gather (first subs) here env)))
((##core#call)
(let* ([fn (first subs)]
@@ -2170,18 +2188,22 @@
'() ) )
'() ) )
'() ) ) )
- (for-each (lambda (n) (gather n here env)) subs) ) )
+ (for-each (cut gather <> here env) subs) ) )
((##core#lambda ##core#direct_lambda)
(decompose-lambda-list
(third params)
(lambda (vars argc rest)
- (let* ([id (if here (first params) 'toplevel)]
- [capturedvars (captured-variables (car subs) env)]
- [csize (length capturedvars)] )
- (put! db id 'closure-size csize)
- (put! db id 'captured-variables capturedvars)
- (gather (car subs) id (append vars env)) ) ) ) )
+ (let* ((id (if here (first params) 'toplevel))
+ (cap0 captured)
+ (n (length cap0)))
+ (fluid-let ((lexicals env))
+ (gather (first subs) id (append vars env))
+ (let* ((n2 (length captured))
+ (capt (take captured (- n2 n))))
+ (print "captured: " capt " of " lexicals)
+ (put! db id 'closure-size n2)
+ (put! db id 'captured-variables capt)))))))
(else (for-each (lambda (n) (gather n here env)) subs)) ) ) )
@@ -2331,24 +2353,6 @@
(list (varnode here)) ) ) )
(else n) ) ) )
- (define (captured-variables node env)
- (let ([vars '()])
- (let walk ([n node])
- (let ((subs (node-subexpressions n))
- (params (node-parameters n)) )
- (case (node-class n)
- ((##core#variable)
- (let ([var (first params)])
- (when (memq var env)
- (set! vars (lset-adjoin eq? vars var)) ) ) )
- ((quote ##core#undefined ##core#primitive ##core#proc ##core#inline_ref ##core#global-ref) #f)
- ((set!)
- (let ([var (first params)])
- (when (memq var env) (set! vars (lset-adjoin eq? vars var)))
- (walk (car subs)) ) )
- (else (for-each walk subs)) ) ) )
- vars) )
-
(debugging 'p "closure conversion gathering phase...")
(gather node #f '())
(when (pair? customizable)
Trap