~ chicken-core (chicken-5) 2b2fab29c5fdde110f10bc787ecd0cccbc5841fd


commit 2b2fab29c5fdde110f10bc787ecd0cccbc5841fd
Author:     felix <felix@call-with-current-continuation.org>
AuthorDate: Wed Dec 23 15:03:04 2009 +0100
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Wed Dec 23 15:03:04 2009 +0100

    drop previous safe toplevel assigns if assigned multiple times

diff --git a/optimizer.scm b/optimizer.scm
index 415e7009..aca264eb 100644
--- a/optimizer.scm
+++ b/optimizer.scm
@@ -39,11 +39,17 @@
 ;;; Scan toplevel expressions for assignments:
 
 (define (scan-toplevel-assignments node)
-  (let ([safe '()]
-	[unsafe '()] )
+  (let ((safe '())
+	(unsafe '()) 
+	(dropped '())
+	(previous '()))
 
     (define (mark v)
-      (if (not (memq v unsafe)) (set! safe (cons v safe))) )
+      (unless (memq v unsafe)
+	(set! safe (cons v safe))) )
+
+    (define (remember v x)
+      (set! previous (alist-update! v x previous)))
 
     (debugging 'p "scanning toplevel assignments...")
     (call-with-current-continuation
@@ -59,8 +65,8 @@
 
 	     [(##core#variable)
 	      (let ([var (first params)])
-		(if (and (not (memq var e)) (not (memq var safe)))
-		    (set! unsafe (cons var unsafe)) ) ) ]
+		(when (and (not (memq var e)) (not (memq var safe)))
+		  (set! unsafe (cons var unsafe)) ) ) ]
 
 	     [(if ##core#cond ##core#switch)
 	      (scan (first subs) e)
@@ -70,19 +76,31 @@
 	      (scan (first subs) e)
 	      (scan (second subs) (append params e)) ]
 
-	     [(lambda ##core#callunit) #f]
+	     [(lambda ##core#lambda ##core#callunit) #f]
 
 	     [(##core#call) (return #f)]
 
 	     [(set!)
 	      (let ([var (first params)])
-		(if (not (memq var e)) (mark var))
-		(scan (first subs) e) ) ]
+		(and-let* ((p (alist-ref var previous)))
+		  (copy-node!
+		   (make-node '##core#undefined '() '())
+		   p)
+		  (let ((a (assq var dropped)))
+		    (if a
+			(set-cdr! a (add1 (cdr a)))
+			(set! dropped (alist-cons var 1 dropped)))))
+		(unless (memq var e) (mark var))
+		(scan (first subs) e)
+		(remember var n) )]
 
 	     [else (scan-each subs e)] ) ) )
 
        (scan node '()) ) )
-    (debugging 'o "safe globals" safe)
+    (when (pair? safe)
+      (debugging 'o "safe globals" (delete-duplicates safe eq?)))
+    (when (pair? dropped)
+      (debugging 'x "dropped unused toplevel assignments" dropped))
     (for-each (cut mark-variable <> '##compiler#always-bound) safe)))
 
 
diff --git a/tests/compiler-tests.scm b/tests/compiler-tests.scm
index 79de1eb3..ec3adb2b 100644
--- a/tests/compiler-tests.scm
+++ b/tests/compiler-tests.scm
@@ -1,6 +1,18 @@
 ;;;; compiler-tests.scm
 
 
+;; test dropping of previous toplevel assignments
+
+(define (foo) (define (bar) 1) (bar 2))	; will trigger error later
+(define bar 1)
+(define (baz) 2)
+(define (foo) 'ok)
+
+(assert (eq? 'ok (foo)))
+
+
+;; test hiding of unexported toplevel variables
+
 (module foo (bar)
   (import scheme chicken)
   (declare (hide bar))
Trap