~ chicken-core (chicken-5) 756e891c705a5da8a55f51876042736f3feb8cd0
commit 756e891c705a5da8a55f51876042736f3feb8cd0 Author: felix <felix@call-with-current-continuation.org> AuthorDate: Sun Jul 10 13:33:55 2011 +0200 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Sun Jul 10 13:33:55 2011 +0200 propagate bindings to globals until invalidated diff --git a/compiler.scm b/compiler.scm index 1779d6f4..cf6cb598 100644 --- a/compiler.scm +++ b/compiler.scm @@ -2176,9 +2176,9 @@ (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)] ) + (let* ((id (if here (first params) 'toplevel)) + (capturedvars (captured-variables (first subs) env)) + (csize (length capturedvars)) ) (put! db id 'closure-size csize) (put! db id 'captured-variables capturedvars) (gather (car subs) id (append vars env)) ) ) ) ) @@ -2201,8 +2201,10 @@ (make-node '##core#unbox '() (list val)) val) ) ) - ((if ##core#call ##core#inline ##core#inline_allocate ##core#callunit ##core#inline_ref ##core#inline_update - ##core#switch ##core#cond ##core#direct_call ##core#recurse ##core#return ##core#inline_loc_ref + ((if ##core#call ##core#inline ##core#inline_allocate ##core#callunit + ##core#inline_ref ##core#inline_update + ##core#switch ##core#cond ##core#direct_call ##core#recurse ##core#return + ##core#inline_loc_ref ##core#inline_loc_update) (make-node (node-class n) params (maptransform subs here closure)) ) @@ -2262,10 +2264,12 @@ (list (let ((body (transform (car subs) cvar capturedvars))) (if (pair? boxedvars) (fold-right - (lambda (alias val body) (make-node 'let (list alias) (list val body))) + (lambda (alias val body) + (make-node 'let (list alias) (list val body))) body (unzip1 boxedaliases) - (map (lambda (a) (make-node '##core#box '() (list (varnode (cdr a))))) + (map (lambda (a) + (make-node '##core#box '() (list (varnode (cdr a))))) boxedaliases) ) body) ) ) ) (let ((cvars (map (lambda (v) (ref-var (varnode v) here closure)) diff --git a/optimizer.scm b/optimizer.scm index c3f5b6eb..cf9025b6 100644 --- a/optimizer.scm +++ b/optimizer.scm @@ -142,6 +142,9 @@ (define (node-value n) (first (node-parameters n))) (define (touch) (set! dirty #t)) + (define (invalidate-gae! gae) + (for-each (cut set-cdr! <> #f) gae)) + (define (simplify n) (or (and-let* ([entry (##sys#hash-table-ref simplifications (node-class n))]) (any (lambda (s) @@ -159,23 +162,23 @@ entry) ) n) ) - (define (walk n fids) + (define (walk n fids gae) (if (memq n broken-constant-nodes) n (simplify (let* ((odirty dirty) - (n1 (walk1 n fids)) + (n1 (walk1 n fids gae)) (subs (node-subexpressions n1)) ) (case (node-class n1) ((if) ; (This can be done by the simplifier...) (cond ((constant-node? (car subs)) - (set! removed-ifs (+ removed-ifs 1)) + (set! removed-ifs (add1 removed-ifs)) (touch) (walk (if (node-value (car subs)) (cadr subs) (caddr subs) ) - fids) ) + fids gae) ) (else n1) ) ) ((##core#call) @@ -219,7 +222,7 @@ (else n1) ) ) ) ) ) - (define (walk1 n fids) + (define (walk1 n fids gae) (let ((subs (node-subexpressions n)) (params (node-parameters n)) (class (node-class n)) ) @@ -232,55 +235,69 @@ (touch) (debugging 'o "substituted constant variable" var) (qnode (car (node-parameters (test var 'value)))) ) - (else - (if (not (eq? var (first params))) - (begin - (touch) - (set! replaced-vars (+ replaced-vars 1)) ) ) - (varnode var) ) ) ) ) + ((not (eq? var (first params))) + (touch) + (set! replaced-vars (+ replaced-vars 1)) + (varnode var)) + ((assq var gae) => + (lambda (a) + (cond ((cdr a) + (debugging 'o "propagated global variable" var (cdr a)) + (varnode (cdr a))) + (else (varnode var))))) + (else (varnode var))))) ((let) - (let ([var (first params)]) - (cond [(or (test var 'removable) + (let ((var (first params))) + (cond ((or (test var 'removable) (and (test var 'contractable) (not (test var 'replacing))) ) (touch) (set! removed-lets (add1 removed-lets)) - (walk (second subs) fids) ] - [else (make-node 'let params (map (cut walk <> fids) subs))] ) ) ) + (walk (second subs) fids gae) ) + (else + (let ((gae (if (and (eq? '##core#variable (node-class (first subs))) + (test (first (node-parameters (first subs))) + 'global)) + (alist-cons var (first (node-parameters (first subs))) + gae) + gae))) + (make-node 'let params (map (cut walk <> fids gae) subs))) ) ) )) ((##core#lambda) (let ((llist (third params)) (id (first params))) - (cond [(test id 'has-unused-parameters) - (decompose-lambda-list - llist - (lambda (vars argc rest) - (receive (unused used) (partition (lambda (v) (test v 'unused)) vars) + (fluid-let ((gae '())) + (cond [(test id 'has-unused-parameters) + (decompose-lambda-list + llist + (lambda (vars argc rest) + (receive (unused used) (partition (lambda (v) (test v 'unused)) vars) + (touch) + (debugging 'o "removed unused formal parameters" unused) + (make-node + '##core#lambda + (list (first params) (second params) + (cond [(and rest (test id 'explicit-rest)) + (debugging + 'o "merged explicitly consed rest parameter" rest) + (build-lambda-list used (add1 argc) #f) ] + [else (build-lambda-list used argc rest)] ) + (fourth params) ) + (list (walk (first subs) (cons id fids) '())) ) ) ) ) ] + [(test id 'explicit-rest) + (decompose-lambda-list + llist + (lambda (vars argc rest) (touch) - (debugging 'o "removed unused formal parameters" unused) + (debugging 'o "merged explicitly consed rest parameter" rest) (make-node '##core#lambda - (list (first params) (second params) - (cond [(and rest (test id 'explicit-rest)) - (debugging 'o "merged explicitly consed rest parameter" rest) - (build-lambda-list used (add1 argc) #f) ] - [else (build-lambda-list used argc rest)] ) + (list (first params) + (second params) + (build-lambda-list vars (add1 argc) #f) (fourth params) ) - (list (walk (first subs) (cons id fids))) ) ) ) ) ] - [(test id 'explicit-rest) - (decompose-lambda-list - llist - (lambda (vars argc rest) - (touch) - (debugging 'o "merged explicitly consed rest parameter" rest) - (make-node - '##core#lambda - (list (first params) - (second params) - (build-lambda-list vars (add1 argc) #f) - (fourth params) ) - (list (walk (first subs) (cons id fids))) ) ) ) ] - [else (walk-generic n class params subs (cons id fids))] ) ) ) + (list (walk (first subs) (cons id fids) '())) ) ) ) ] + [else (walk-generic n class params subs (cons id fids) '() #f)] ) ) )) ((##core#call) (let* ([fun (car subs)] @@ -304,7 +321,7 @@ (inline-lambda-bindings llist args (first (node-subexpressions lval)) #f db void) - fids) ) ) + fids gae) ) ) ((variable-mark var '##compiler#pure) => (lambda (pb) (or (and-let* ((k (car args)) @@ -328,7 +345,7 @@ (make-node '##core#call '(#t) (list k (make-node '##core#undefined '() '())) ) ) - (walk-generic n class params subs fids)) ) ) + (walk-generic n class params subs fids gae #f)) ) ) ((and lval (eq? '##core#lambda (node-class lval))) (let* ([lparams (node-parameters lval)] @@ -363,22 +380,26 @@ 'i "not inlining procedure because it refers to contractable" var cvar) - (return (walk-generic n class params subs fids))) + (return + (walk-generic n class params subs fids gae #t))) (let ((n2 (inline-lambda-bindings llist args (first (node-subexpressions lval)) #t db cfk))) (touch) - (walk n2 fids))))) + (walk n2 fids gae))))) ((test ifid 'has-unused-parameters) (if (< (length args) argc) ; Expression was already optimized (should this happen?) - (walk-generic n class params subs fids) + (walk-generic n class params subs fids gae #t) (let loop ((vars vars) (argc argc) (args args) (used '())) (cond [(or (null? vars) (zero? argc)) (touch) - (make-node - '##core#call - params - (map (cut walk <> fids) (cons fun (append-reverse used args))) ) ] + (let ((args + (map (cut walk <> fids gae) + (cons + fun + (append-reverse used args))) ) ) + (invalidate-gae! gae) + (make-node '##core#call params args))] [(test (car vars) 'unused) (touch) (debugging @@ -388,7 +409,7 @@ (make-node 'let (list (gensym 't)) - (list (walk (car args) fids) + (list (walk (car args) fids gae) (loop (cdr vars) (sub1 argc) (cdr args) used) ) ) (loop (cdr vars) (sub1 argc) (cdr args) used) ) ] [else (loop (cdr vars) @@ -399,14 +420,14 @@ (not (memq n rest-consers)) ) ; make sure we haven't inlined rest-list already (let ([n (llist-length llist)]) (if (< (length args) n) - (walk-generic n class params subs fids) + (walk-generic n class params subs fids gae #t) (begin (debugging 'o "consed rest parameter at call site" var n) (let-values ([(args rargs) (split-at args n)]) (let ([n2 (make-node '##core#call params - (map (cut walk <> fids) + (map (cut walk <> fids gae) (cons fun (append args @@ -418,14 +439,18 @@ (list "C_a_i_list" (* 3 (length rargs))) rargs) ) ) ) ) ) ) ] ) (set! rest-consers (cons n2 rest-consers)) + (invalidate-gae! gae) n2) ) ) ) ) ) - (else (walk-generic n class params subs fids)) ) ) ) ) ) ) - (else (walk-generic n class params subs fids)) ) ) ] + (else (walk-generic n class params subs fids gae #t)) ) ) ) ) ) ) + (else (walk-generic n class params subs fids gae #t)) ) ) ] [(##core#lambda) (if (first params) - (walk-generic n class params subs fids) - (make-node '##core#call (cons #t (cdr params)) (map (cut walk <> fids) subs)) ) ] - [else (walk-generic n class params subs fids)] ) ) ) + (walk-generic n class params subs fids gae #f) + (let ((n2 (make-node '##core#call (cons #t (cdr params)) + (map (cut walk <> fids gae) subs)) )) + (invalidate-gae! gae) + n2))] + [else (walk-generic n class params subs fids gae #t)] ) ) ) ((set!) (let ([var (first params)]) @@ -437,20 +462,24 @@ ((test var 'replacable) (touch) (make-node '##core#undefined '() '()) ) - [(and (or (not (test var 'global)) + ((and (or (not (test var 'global)) (not (variable-visible? var))) (not (test var 'inline-transient)) (not (test var 'references)) (not (expression-has-side-effects? (first subs) db)) ) (touch) (debugging 'o "removed side-effect free assignment to unused variable" var) - (make-node '##core#undefined '() '()) ] - [else (make-node 'set! params (list (walk (car subs) fids)))] ) ) ) + (make-node '##core#undefined '() '()) ) + (else + (let ((n2 (make-node 'set! params (list (walk (car subs) fids gae))))) + (cond ((assq var gae) => (cut set-cdr! <> #f))) + n2))))) - (else (walk-generic n class params subs fids)) ) ) ) + (else (walk-generic n class params subs fids gae #f)) ) ) ) - (define (walk-generic n class params subs fids) - (let ((subs2 (map (cut walk <> fids) subs))) + (define (walk-generic n class params subs fids gae invgae) + (let ((subs2 (map (cut walk <> fids gae) subs))) + (when invgae (invalidate-gae! gae)) (if (every eq? subs subs2) n (make-node class params subs2) ) ) ) @@ -460,7 +489,7 @@ (begin (debugging 'p "traversal phase...") (set! simplified-ops '()) - (let ((node2 (walk node '()))) + (let ((node2 (walk node '() '()))) (when (pair? simplified-classes) (debugging 'o "simplifications" simplified-classes)) (when (and (pair? simplified-ops) (debugging 'o " call simplifications:")) (for-eachTrap