~ chicken-core (chicken-5) 4b48d71b26ad9d2eb1641e03cc1e50e93d3a040b


commit 4b48d71b26ad9d2eb1641e03cc1e50e93d3a040b
Author:     felix <felix@call-with-current-continuation.org>
AuthorDate: Thu May 12 06:58:58 2011 -0400
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Thu May 12 06:58:58 2011 -0400

    first go at let-alias handling

diff --git a/scrutinizer.scm b/scrutinizer.scm
index 97e81d5b..61fc0e1a 100755
--- a/scrutinizer.scm
+++ b/scrutinizer.scm
@@ -93,6 +93,7 @@
 
 (define (scrutinize node db complain specialize)
   (let ((blist '())
+	(aliased '())
 	(safe-calls 0))
 
     (define (constant-result lit)
@@ -567,6 +568,14 @@
 	  (set! n (add1 n))
 	  n)))
 
+    (define (add-to-blist var flow type)
+      (let loop ((var var))
+	(set! blist (alist-cons (cons var flow) type blist))
+	(let ((a (assq var aliased)))
+	  (when a
+	    (d "  applying to alias: ~a -> ~a" (cdr a) type)
+	    (loop (cdr a))))))
+
     (define (walk n e loc dest tail flow ctags) ; returns result specifier
       (let ((subs (node-subexpressions n))
 	    (params (node-parameters n)) 
@@ -602,18 +611,21 @@
 				  r1 r2))
 			    (else '*)))))
 		 ((let)
-		  ;;XXX it would be nice to have some sort of alias-information:
-		  ;;    binding a variable to another variable could propagate
-		  ;;    type-information from the former to the latter.
-		  ;;
 		  ;; before CPS-conversion, `let'-nodes may have multiple bindings
 		  (let loop ((vars params) (body subs) (e2 '()))
 		    (if (null? vars)
 			(walk (car body) (append e2 e) loc dest tail flow ctags)
-			(let ((t (single 
-				  (sprintf "in `let' binding of `~a'" (real-name (car vars)))
-				  (walk (car body) e loc (car vars) #f flow #f) 
-				  loc)))
+			(let* ((var (car vars))
+			       (val (car body))
+			       (t (single 
+				   (sprintf "in `let' binding of `~a'" (real-name var))
+				   (walk val e loc var #f flow #f) 
+				   loc)))
+			  (when (and (eq? (node-class val) '##core#variable)
+				     (not (get db var 'assigned)))
+			    (let ((var2 (first (node-parameters val))))
+			      (unless (get db var2 'assigned) ;XXX too conservative?
+				(set! aliased (alist-cons var var2 aliased)))))
 			  (loop (cdr vars) (cdr body) (alist-cons (car vars) t e2))))))
 		 ((##core#lambda lambda)
 		  (decompose-lambda-list
@@ -628,7 +640,8 @@
 					e)))
 		       (when dest 
 			 (d "~a: initial-argument types: ~a" dest inits))
-		       (fluid-let ((blist '()))
+		       (fluid-let ((blist '())
+				   (aliased '()))
 			 (let* ((initial-tag (tag))
 				(r (walk (first subs)
 					 (if rest (alist-cons rest 'list e2) e2)
@@ -648,19 +661,19 @@
 				(cond ((zero? argc) args)
 				      ((and (not (get db (car vars) 'assigned))
 					    (assoc (cons (car vars) initial-tag) blist))
-				      =>
-				      (lambda (a)
-					(cons
-					 (cond ((eq? (cdr a) '*) '*)
-					       (else
-						(d "adjusting procedure argument type for `~a' to: ~a"
-						 (car vars) (cdr a))
-						(cdr a) ))
-					 (loop (sub1 argc) (cdr vars) (cdr args)))))
-				     (else 
-				      (cons 
-				       (car args)
-				       (loop (sub1 argc) (cdr vars) (cdr args)))))))
+				       =>
+				       (lambda (a)
+					 (cons
+					  (cond ((eq? (cdr a) '*) '*)
+						(else
+						 (d "adjusting procedure argument type for `~a' to: ~a"
+						    (car vars) (cdr a))
+						 (cdr a) ))
+					  (loop (sub1 argc) (cdr vars) (cdr args)))))
+				      (else 
+				       (cons 
+					(car args)
+					(loop (sub1 argc) (cdr vars) (cdr args)))))))
 			     r))))))))
 		 ((set! ##core#set!)
 		  (let* ((var (first params))
@@ -705,6 +718,7 @@
 				    var ot rt)
 				  #t)))))
 		      (when strict-variable-types
+			;; don't use "add-to-blist" since this does not affect aliases
 			(set! blist (alist-cons (cons var (car flow)) rt blist))))
 		    '(undefined)))
 		 ((##core#primitive ##core#inline_ref) '*)
@@ -737,11 +751,9 @@
 			     (cond (pred
 				    (d "  predicate `~a' indicates `~a' is ~a in flow ~a" pn var pt
 				       (car ctags))
-				    (set! blist 
-				      (alist-cons
-				       (cons var (car ctags)) 
-				       (if (and a (type<=? (cdr a) pt)) (cdr a) pt)
-				       blist)))
+				    (add-to-blist 
+				     var (car ctags)
+				     (if (and a (type<=? (cdr a) pt)) (cdr a) pt)))
 				   (a
 				    (when enforces
 				      (let ((ar (cond ((blist-type var flow) =>
@@ -753,15 +765,10 @@
 						      ((type<=? (cdr a) argr) (cdr a))
 						      (else argr))))
 					(d "  assuming: ~a -> ~a (flow: ~a)" var ar (car flow))
-					(set! blist
-					  (alist-cons (cons var (car flow)) ar blist))
+					(add-to-blist var (car flow) ar)
 					(when ctags
-					  (set! blist
-					    (alist-cons
-					     (cons var (car ctags)) ar
-					     (alist-cons
-					      (cons var (cdr ctags)) ar
-					      blist)))))))
+					  (add-to-blist var (car ctags) ar)
+					  (add-to-blist var (cdr ctags) ar)))))
 				   ((and oparg?
 					 (variable-mark var '##compiler#special-result-type))
 				    => (lambda (srt)
Trap