racket/pkgs/racket-test/tests/generic/base-interfaces.rkt
Matthew Flatt 0c38da0ee2 change intermediate representation for the bytecode optimizer
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
2016-02-16 21:05:15 -07:00

32 lines
930 B
Racket

#lang racket/base
;; Test the existence of forged generic functions for
;; gen:custom-write and gen:equal+hash
(require racket/generic)
(struct tuple (ref)
#:methods gen:custom-write
[(define/generic super write-proc)
(define (write-proc v p w)
(super v p w))]
#:methods gen:equal+hash
[(define/generic super-eq equal-proc)
(define/generic hash1 hash-proc)
(define/generic hash2 hash2-proc)
(define (equal-proc a b e)
(super-eq (tuple-ref a) (tuple-ref b) e))
(define (hash-proc a h)
(hash1 (tuple-ref a) h))
(define (hash2-proc a h)
(hash2 (tuple-ref a) h))])
(module+ test
(require rackunit racket/port)
;; ok if these don't raise unbound id errors
(check-equal? (with-output-to-string (lambda () (write (tuple 5)))) "#0=#0#")
(check-equal? (tuple 5) (tuple 5))
(check-equal? (equal-hash-code (tuple 5)) 55)
(check-equal? (equal-secondary-hash-code (tuple 5)) 46))