
Correct the second-biggest design flaw in the bytecode optimizer: instead of using a de Bruijn-like representation of variable references in the optimizer pass, use variable objects. This change is intended to address limitations on programs like the one in http://bugs.racket-lang.org/query/?cmd=view&pr=15244 where the optimizer could not perform a straightforward-seeming transformation due to the constraints of its representation. Besides handling the bug-report example better, there are other minor optimization improvements as a side effect of refactoring the code. To simplify the optimizer's implementation (e.g., eliminate code that I didn't want to convert) and also preserve success for optimizer tests, the optimizer ended up getting a little better at flattening and eliminating `let` forms and `begin`--`let` combinations. Overall, the optimizer tests in "optimize.rktl" pass, which helps ensure that no optimizations were lost. I had to modify just a few tests: * The test at line 2139 didn't actually check against reordering as intended, but was instead checking that the bug-report limitation was intact (and now it's not). * The tests around 3095 got extra `p` references, because the optimizer is now able to eliminate an unused `let` around the second case, but it still doesn't discover the unusedness of `p` in the first case soon enough to eliminate the `let`. The extra references prevent eliminating the `let` in both case, since that's not the point of the tests. Thanks to Gustavo for taking a close look at the changes. LocalWords: pkgs rkt
21 lines
573 B
Racket
21 lines
573 B
Racket
#lang racket/base
|
|
|
|
;; vectors as method tables
|
|
(struct kons (kar kdr)
|
|
#:methods gen:equal+hash
|
|
[(define (equal-proc x y rec)
|
|
(and (rec (kons-kar x) (kons-kar y))
|
|
(rec (kons-kdr x) (kons-kdr y))))
|
|
(define (hash-proc x rec) 12)
|
|
(define (hash2-proc x rec) 13)])
|
|
|
|
(module+ test
|
|
(require rackunit)
|
|
|
|
(check-equal? (kons 1 2) (kons 1 2))
|
|
(check-false (equal? (kons 1 2) 2))
|
|
(check-false (equal? 2 (kons 1 2)))
|
|
(check-false (equal? (kons 1 2) (kons 3 4)))
|
|
(check-equal? (equal-hash-code (kons 1 2)) 62)
|
|
)
|