[plt-scheme] dead code elimination/closure optimization?
At Sat, 7 Apr 2007 20:30:35 -0400 (EDT), Dimitris Vyzovitis wrote:
> Does the bytecode compiler or the jitter do dead code elimination for
> closures?
In easy cases.
> For example in
> (let ((foo (lambda () ...))) body ...)
> where foo is not referenced in the body (other than perhaps in in
> turn unreferenced macros), is the lambda closure construction and variable
> assignment code present in bytecode and ultimately in the
> code generated by the jit?
No, the procedure will be dropped. But if there are assignments in the
procedure, they will lead to worse code, anyway.
> What about
> (letrec ((foo (lambda () ... (set! foo ...) ...))) body ...) with
> similar body conditions for foo?
Not currently. The bytecode compiler does not currently detect dead
code bound by `letrec'. The `set!' would likely create trouble if
`letrec' wasn't already a problem.
Here's a way to get some idea of what the optimizer will do, as Eli
showed a few weeks ago:
(define (comp=? c1 c2)
(let ([s1 (open-output-bytes)]
[s2 (open-output-bytes)])
(write c1 s1)
(write c2 s2)
(let ([t1 (get-output-bytes s1)]
[t2 (get-output-bytes s2)])
(bytes=? t1 t2))))
(comp=? (compile '(let ([f (lambda () 10)]) (display 2)))
(compile '(display 2)))
; => #t
(comp=? (compile '(let* ([x 8][f (lambda () x)]) (display x)))
(compile '(display 8)))
; => #t
(comp=? (compile '(let* ([x 8][f (lambda () (set! x 5))])
(display x)))
(compile '(display 8)))
; => #f
; because the `set!' prevents constant propagation `x', even though
; the `set!' is eventually removed
(comp=? (compile '(letrec ([f (lambda () 10)]) (display 2)))
(compile '(display 2)))
; => #f
; because the optimizer is currently conservative about `letrec'
(comp=? (compile '(let* ([f (lambda () 10)][g (lambda () (f 6))]) (display 2)))
(compile '(display 2)))
; => #f
; because `g' is eliminated, but only after the decision is made to
; keep `f'
See also the middle part of "collects/tests/mzscheme/optimize.ss".
Matthew