~ 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