racket/pkgs/compiler-lib/compiler/demodularizer/linklet.rkt
Matthew Flatt b9fdb503c1 raco demodularize: adapt to CS
Really, `raco demod` is adapted here to work with any linklet-based VM
by compiling modules to machine-independent form, which is essentially
a wrapper around linklet S-expressions. The BC-specific implementation
remains in place, and it has the advantage of being able to work with
existing module compilations, while the implementation based on
machine-independent form must recompile all modules before attempting
to combine them (but that recompilation is easily cached).

Use `--work <dir>` to use `<dir>` as a cache for multiple
demodularizations.

Getting `raco demod` to work involved several incidental improvements:

 * make `racket/linklet` work with machine-independent forms;

 * add `linklet-body-reserved-symbol?`;

 * fix schemify for linklets that have unexported definitions (which
   the expander never generates, but the demodularizer does);

 * add `current-multi-compile-any` to expose CM's multi-target
   compilation mode programmatically; and

 * repair a bug in CS JIT mode.

The demodularizer could be a lot smarter to prune demodularized code
before sending it off to the compiler. Of course, the compiler should
be able to figure out improvements itself, but sending a smaller chunk
of code to the compiler can avoid the hybrid interpreter--compiler
mode that is used for large linklets and that prevents optimizers like
cp0 from doing much to prune definitions.

The demodularizer has a lot in common with the expander's flattener
that is used for bootstrapping, and a smarter demodularizer would have
even more in common. It would be nice to have one implementation
instead of two.
2021-04-10 08:13:29 -06:00

96 lines
3.2 KiB
Racket

#lang racket/base
(require racket/match
racket/linklet
compiler/zo-structs
compiler/private/deserialize)
(provide linklet*-exports
linklet*-internals
linklet*-importss
linklet*-internal-exports
linklet*-internal-importss
linklet*-import-shapess
linklet*-lifts
linklet*-body
s-exp->linklet)
(define (get-exports linkl select)
(cond
[(linkl? linkl) (linkl-exports linkl)]
[(faslable-correlated-linklet? linkl)
(match (faslable-correlated-linklet-expr linkl)
[`(linklet ,imports ,exports . ,_) (for/list ([ex (in-list exports)])
(strip-correlated
(if (pair? ex)
(select ex)
ex)))])]
[else (unsupported linkl)]))
(define (linklet*-exports linkl)
(get-exports linkl cadr))
(define (linklet*-internal-exports linkl)
(get-exports linkl car))
(define (linklet*-internals linkl)
(cond
[(linkl? linkl) (linkl-internals linkl)]
[(faslable-correlated-linklet? linkl)
(match (faslable-correlated-linklet-expr linkl)
[`(linklet ,imports ,exports . ,body)
(for/fold ([l '()]) ([form (in-list body)])
(match form
[`(define-values ,ids ,_)
(append (map strip-correlated ids) l)]
[else l]))])]
[else (unsupported linkl)]))
(define (linklet*-importss linkl)
(get-importss linkl car))
(define (linklet*-internal-importss linkl)
(get-importss linkl cadr))
(define (get-importss linkl select)
(cond
[(linkl? linkl) (linkl-importss linkl)]
[(faslable-correlated-linklet? linkl)
(match (faslable-correlated-linklet-expr linkl)
[`(linklet ,importss ,exports . ,_) (for/list ([imports (in-list importss)])
(for/list ([im (in-list imports)])
(strip-correlated
(if (pair? im)
(select im)
im))))])]
[else (unsupported linkl)]))
(define (linklet*-import-shapess linkl)
(cond
[(linkl? linkl) (linkl-import-shapess linkl)]
[(faslable-correlated-linklet? linkl)
(match (faslable-correlated-linklet-expr linkl)
[`(linklet ,importss ,exports . ,_) (for/list ([imports (in-list importss)])
(for/list ([im (in-list imports)])
#f))])]
[else (unsupported linkl)]))
(define (linklet*-lifts linkl)
(cond
[(linkl? linkl) (linkl-lifts linkl)]
[(faslable-correlated-linklet? linkl) '()]
[else (unsupported linkl)]))
(define (linklet*-body linkl)
(cond
[(faslable-correlated-linklet? linkl)
(match (faslable-correlated-linklet-expr linkl)
[`(linklet ,imports ,exports . ,body)
(strip-correlated body)])]
[else #f]))
(define (s-exp->linklet name expr)
(faslable-correlated-linklet expr name))
(define (unsupported linkl)
(error 'demodularize "unsupported linklet format"))