expander: repair and further improve flattener
Delay reporting of potential problems until an actual problem is detected. Correct a mismatch between original and renamed symbols to restore detection of problems.
This commit is contained in:
parent
62ef3ed1ee
commit
98ae91e0ba
|
@ -22,11 +22,6 @@ KNOT = ++knot read read/api.rkt \
|
||||||
# a direct use of the primitive name:
|
# a direct use of the primitive name:
|
||||||
DIRECT = ++direct linklet ++direct kernel
|
DIRECT = ++direct linklet ++direct kernel
|
||||||
|
|
||||||
# The linklet compiler's simple inference cannot tell that this
|
|
||||||
# module's keyword-function declarations will have no side effect, but
|
|
||||||
# we promise that it's pure:
|
|
||||||
PURE =
|
|
||||||
|
|
||||||
# Set `BUILDDIR` as a prefix on "compiled" output (defaults to empty).
|
# Set `BUILDDIR` as a prefix on "compiled" output (defaults to empty).
|
||||||
# Set `DEPENDSDIR` as the same sort of prefix in the generated
|
# Set `DEPENDSDIR` as the same sort of prefix in the generated
|
||||||
# makefile-dependency file (also defaults to empty). The `BUILDDIR`
|
# makefile-dependency file (also defaults to empty). The `BUILDDIR`
|
||||||
|
@ -36,7 +31,7 @@ PURE =
|
||||||
|
|
||||||
expander:
|
expander:
|
||||||
$(RACO) make bootstrap-run.rkt
|
$(RACO) make bootstrap-run.rkt
|
||||||
$(RACKET) bootstrap-run.rkt -c compiled/cache-src $(KNOT) $(DIRECT) $(PURE) -O $(TREE)
|
$(RACKET) bootstrap-run.rkt -c compiled/cache-src $(KNOT) $(DIRECT) -O $(TREE)
|
||||||
|
|
||||||
expander-src:
|
expander-src:
|
||||||
$(RACO) make bootstrap-run.rkt
|
$(RACO) make bootstrap-run.rkt
|
||||||
|
@ -47,7 +42,7 @@ GENERATE_ARGS = -c $(BUILDDIR)compiled/cache-src \
|
||||||
++depend-module bootstrap-run.rkt \
|
++depend-module bootstrap-run.rkt \
|
||||||
--depends $(BUILDDIR)compiled/expander-dep.rktd \
|
--depends $(BUILDDIR)compiled/expander-dep.rktd \
|
||||||
--makefile-depends $(DEPENDSDIR)compiled/expander.rktl $(BUILDDIR)compiled/expander.d \
|
--makefile-depends $(DEPENDSDIR)compiled/expander.rktl $(BUILDDIR)compiled/expander.d \
|
||||||
$(KNOT) $(DIRECT) $(PURE) -k $(TREE) -s -x \
|
$(KNOT) $(DIRECT) -k $(TREE) -s -x \
|
||||||
-o $(BUILDDIR)compiled/expander.rktl
|
-o $(BUILDDIR)compiled/expander.rktl
|
||||||
|
|
||||||
# This target can be used with a `RACKET` that builds via `-l- setup --chain ...`
|
# This target can be used with a `RACKET` that builds via `-l- setup --chain ...`
|
||||||
|
@ -75,11 +70,11 @@ run-no-cache:
|
||||||
# Writes the extracted, compiled, decompiled expander to compiled/exp.rkt
|
# Writes the extracted, compiled, decompiled expander to compiled/exp.rkt
|
||||||
decompile:
|
decompile:
|
||||||
$(RACO) make bootstrap-run.rkt
|
$(RACO) make bootstrap-run.rkt
|
||||||
$(RACKET) $(RKT_ARGS) bootstrap-run.rkt -c compiled/cache-src $(KNOT) $(PURE) -s -x -D -o compiled/exp.rkt
|
$(RACKET) $(RKT_ARGS) bootstrap-run.rkt -c compiled/cache-src $(KNOT) -s -x -D -o compiled/exp.rkt
|
||||||
|
|
||||||
# Writes the extracted, compiled expander to compiled/exp.zo
|
# Writes the extracted, compiled expander to compiled/exp.zo
|
||||||
bytecode:
|
bytecode:
|
||||||
$(RACO) make bootstrap-run.rkt
|
$(RACO) make bootstrap-run.rkt
|
||||||
$(RACKET) $(RKT_ARGS) bootstrap-run.rkt -c compiled/cache-src $(KNOT) $(PURE) -s -x -B -o compiled/exp.zo
|
$(RACKET) $(RKT_ARGS) bootstrap-run.rkt -c compiled/cache-src $(KNOT) -s -x -B -o compiled/exp.zo
|
||||||
|
|
||||||
.PHONY: expander expander-src expander-src-generate demo run run-no-cache
|
.PHONY: expander expander-src expander-src-generate demo run run-no-cache
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
#lang racket/base
|
#lang racket/base
|
||||||
(require "../run/status.rkt"
|
(require "../common/set.rkt"
|
||||||
|
"../run/status.rkt"
|
||||||
"../boot/runtime-primitive.rkt"
|
"../boot/runtime-primitive.rkt"
|
||||||
"link.rkt"
|
"link.rkt"
|
||||||
"linklet-info.rkt"
|
"linklet-info.rkt"
|
||||||
"linklet.rkt")
|
"linklet.rkt"
|
||||||
|
"variable.rkt")
|
||||||
|
|
||||||
(provide check-and-report!)
|
(provide check-and-record-report!)
|
||||||
|
|
||||||
;; Check for bootstrap obstacles and report the results
|
;; Check for bootstrap obstacles, and prepare to report if the
|
||||||
(define (check-and-report! #:compiled-modules compiled-modules
|
;; obstacles persist
|
||||||
#:linklets linklets
|
(define (check-and-record-report! #:compiled-modules compiled-modules
|
||||||
#:linklets-in-order linklets-in-order
|
#:linklets linklets
|
||||||
#:needed needed
|
#:linklets-in-order linklets-in-order
|
||||||
#:instance-knot-ties instance-knot-ties)
|
#:needed needed
|
||||||
|
#:instance-knot-ties instance-knot-ties)
|
||||||
|
|
||||||
(log-status "Traversed ~s modules" (hash-count compiled-modules))
|
(log-status "Traversed ~s modules" (hash-count compiled-modules))
|
||||||
(log-status "Got ~s relevant linklets" (hash-count linklets))
|
(log-status "Got ~s relevant linklets" (hash-count linklets))
|
||||||
|
@ -40,7 +43,7 @@
|
||||||
;; Check whether any needed linklet needs an instance of a
|
;; Check whether any needed linklet needs an instance of a
|
||||||
;; pre-defined instance that is not part of the runtime system:
|
;; pre-defined instance that is not part of the runtime system:
|
||||||
(define complained? #f)
|
(define complained? #f)
|
||||||
(define needed-vars null)
|
(define check-later-vars (make-hash)) ; variable -> (listof complain-proc)
|
||||||
(for ([lnk (in-list (unbox linklets-in-order))])
|
(for ([lnk (in-list (unbox linklets-in-order))])
|
||||||
(define needed-reason (hash-ref needed lnk #f))
|
(define needed-reason (hash-ref needed lnk #f))
|
||||||
(when needed-reason
|
(when needed-reason
|
||||||
|
@ -54,20 +57,25 @@
|
||||||
(not (eq? p '#%linklet))
|
(not (eq? p '#%linklet))
|
||||||
(not (hash-ref instance-knot-ties p #f))
|
(not (hash-ref instance-knot-ties p #f))
|
||||||
(hash-ref needed in-lnk #t))
|
(hash-ref needed in-lnk #t))
|
||||||
(unless complained?
|
;; Delay the complaint until we know whether the name is
|
||||||
(log-status "~a\n ~a"
|
;; actually used after flattening and pruning
|
||||||
"Unfortunately, some linklets depend on pre-defined host instances"
|
(define (complain really-used-var?)
|
||||||
"that are not part of the runtime system:")
|
(unless complained?
|
||||||
(set! complained? #t))
|
(log-status "~a\n ~a\n ~a\n ~a\n ~a"
|
||||||
(unless complained-this?
|
"Unfortunately, some linklets depend on pre-defined host instances"
|
||||||
(log-status " - ~a at ~s" (link-name lnk) (link-phase lnk))
|
"that are not part of the runtime system; at least one the following"
|
||||||
(set! complained-this? #t))
|
"references is a problem, but not necessarily all of them, because"
|
||||||
(log-status "~a" (lines (format " needs ~s:" p) in-vars))
|
"some references may be detected as unused by the flattener (but"
|
||||||
(set! needed-vars (append in-vars needed-vars))))
|
"we've lost track of the connection):")
|
||||||
(when complained-this?
|
(set! complained? #t))
|
||||||
(log-status " needed by ~s" needed-reason))))
|
(unless complained-this?
|
||||||
(when complained?
|
(log-status " - ~a at ~s" (link-name lnk) (link-phase lnk))
|
||||||
(log-status "~a\n ~a"
|
(log-status "~a" (lines (format " needs ~s:" p)
|
||||||
"If these dependencies are not removed by subsequent flattening"
|
(for/list ([in-var (in-list in-vars)]
|
||||||
"and simplification, extraction cannot succeed."))
|
#:when (really-used-var? (variable in-lnk in-var)))
|
||||||
(and complained? needed-vars))
|
in-var)))
|
||||||
|
(log-status " needed by ~s" needed-reason)
|
||||||
|
(set! complained-this? #t)))
|
||||||
|
(for ([in-var (in-list in-vars)])
|
||||||
|
(hash-update! check-later-vars (variable in-lnk in-var) (lambda (l) (cons complain l)) null))))))
|
||||||
|
check-later-vars)
|
||||||
|
|
|
@ -18,13 +18,14 @@
|
||||||
#:exports exports
|
#:exports exports
|
||||||
#:instance-knot-ties instance-knot-ties
|
#:instance-knot-ties instance-knot-ties
|
||||||
#:primitive-table-directs primitive-table-directs
|
#:primitive-table-directs primitive-table-directs
|
||||||
#:check-later-names check-later-names)
|
#:check-later-vars check-later-vars)
|
||||||
(log-status "Flattening to a single linklet...")
|
(log-status "Flattening to a single linklet...")
|
||||||
(define needed-linklets-in-order
|
(define needed-linklets-in-order
|
||||||
(for/list ([lnk (in-list (unbox linklets-in-order))]
|
(for/list ([lnk (in-list (unbox linklets-in-order))]
|
||||||
#:when (hash-ref needed lnk #f))
|
#:when (hash-ref needed lnk #f))
|
||||||
lnk))
|
lnk))
|
||||||
|
|
||||||
|
;; variable -> symbol
|
||||||
(define variable-names (pick-variable-names
|
(define variable-names (pick-variable-names
|
||||||
#:linklets linklets
|
#:linklets linklets
|
||||||
#:needed-linklets-in-order needed-linklets-in-order
|
#:needed-linklets-in-order needed-linklets-in-order
|
||||||
|
@ -32,32 +33,34 @@
|
||||||
|
|
||||||
(for ([var (in-hash-keys variable-names)]
|
(for ([var (in-hash-keys variable-names)]
|
||||||
#:when (symbol? (link-name (variable-link var)))
|
#:when (symbol? (link-name (variable-link var)))
|
||||||
#:unless (memq (variable-name var) check-later-names))
|
#:unless (hash-ref check-later-vars var #f))
|
||||||
(error 'flatten "found a dependency on a non-primitive: ~s from ~s"
|
(error 'flatten "found a dependency on a non-primitive: ~s from ~s"
|
||||||
(variable-name var)
|
(variable-name var)
|
||||||
(link-name (variable-link var))))
|
(link-name (variable-link var))))
|
||||||
|
|
||||||
`(linklet
|
(values
|
||||||
;; imports
|
variable-names
|
||||||
()
|
`(linklet
|
||||||
;; exports
|
;; imports
|
||||||
,(for/list ([ex-sym (in-list (sort (hash-keys exports) symbol<?))])
|
()
|
||||||
(define var (hash-ref exports ex-sym))
|
;; exports
|
||||||
(define int-sym (hash-ref variable-names var #f))
|
,(for/list ([ex-sym (in-list (sort (hash-keys exports) symbol<?))])
|
||||||
(unless int-sym
|
(define var (hash-ref exports ex-sym))
|
||||||
(error 'flatten "export does not map to an instance variable: ~s" ex-sym))
|
(define int-sym (hash-ref variable-names var #f))
|
||||||
`[,int-sym ,ex-sym])
|
(unless int-sym
|
||||||
;; body
|
(error 'flatten "export does not map to an instance variable: ~s" ex-sym))
|
||||||
,@(apply
|
`[,int-sym ,ex-sym])
|
||||||
append
|
;; body
|
||||||
(for/list ([lnk (in-list (reverse needed-linklets-in-order))])
|
,@(apply
|
||||||
(define body
|
append
|
||||||
(body-with-substituted-variable-names lnk
|
(for/list ([lnk (in-list (reverse needed-linklets-in-order))])
|
||||||
(hash-ref linklets lnk)
|
(define body
|
||||||
variable-names
|
(body-with-substituted-variable-names lnk
|
||||||
#:linklets linklets
|
(hash-ref linklets lnk)
|
||||||
#:instance-knot-ties instance-knot-ties))
|
variable-names
|
||||||
(substitute-primitive-table-access body primitive-table-directs)))))
|
#:linklets linklets
|
||||||
|
#:instance-knot-ties instance-knot-ties))
|
||||||
|
(substitute-primitive-table-access body primitive-table-directs))))))
|
||||||
|
|
||||||
(define (pick-variable-names #:linklets linklets
|
(define (pick-variable-names #:linklets linklets
|
||||||
#:needed-linklets-in-order needed-linklets-in-order
|
#:needed-linklets-in-order needed-linklets-in-order
|
||||||
|
|
|
@ -100,12 +100,12 @@
|
||||||
#:needed needed)))
|
#:needed needed)))
|
||||||
|
|
||||||
;; Check for bootstrap obstacles, and report what we've found
|
;; Check for bootstrap obstacles, and report what we've found
|
||||||
(define needed-vars
|
(define check-later-vars
|
||||||
(check-and-report! #:compiled-modules compiled-modules
|
(check-and-record-report! #:compiled-modules compiled-modules
|
||||||
#:linklets linklets
|
#:linklets linklets
|
||||||
#:linklets-in-order linklets-in-order
|
#:linklets-in-order linklets-in-order
|
||||||
#:needed needed
|
#:needed needed
|
||||||
#:instance-knot-ties instance-knot-ties))
|
#:instance-knot-ties instance-knot-ties))
|
||||||
|
|
||||||
;; If we're in source mode, we can generate a single linklet
|
;; If we're in source mode, we can generate a single linklet
|
||||||
;; that combines all the ones we found
|
;; that combines all the ones we found
|
||||||
|
@ -118,7 +118,7 @@
|
||||||
#:cache cache))
|
#:cache cache))
|
||||||
|
|
||||||
;; Generate the flattened linklet
|
;; Generate the flattened linklet
|
||||||
(define flattened-linklet-expr
|
(define-values (variable-names flattened-linklet-expr)
|
||||||
(flatten! start-link
|
(flatten! start-link
|
||||||
#:linklets linklets
|
#:linklets linklets
|
||||||
#:linklets-in-order linklets-in-order
|
#:linklets-in-order linklets-in-order
|
||||||
|
@ -126,7 +126,7 @@
|
||||||
#:exports exports
|
#:exports exports
|
||||||
#:instance-knot-ties instance-knot-ties
|
#:instance-knot-ties instance-knot-ties
|
||||||
#:primitive-table-directs primitive-table-directs
|
#:primitive-table-directs primitive-table-directs
|
||||||
#:check-later-names needed-vars))
|
#:check-later-vars check-later-vars))
|
||||||
|
|
||||||
(define simplified-expr
|
(define simplified-expr
|
||||||
(simplify-definitions flattened-linklet-expr))
|
(simplify-definitions flattened-linklet-expr))
|
||||||
|
@ -135,16 +135,18 @@
|
||||||
(define gced-linklet-expr
|
(define gced-linklet-expr
|
||||||
(garbage-collect-definitions simplified-expr))
|
(garbage-collect-definitions simplified-expr))
|
||||||
|
|
||||||
(log-status "Checking that references to the runtime were removed by simplification ...")
|
(log-status "Checking that references outside the runtime were removed by simplification...")
|
||||||
(define used-names (all-used-symbols gced-linklet-expr))
|
(define really-used-names (all-used-symbols gced-linklet-expr))
|
||||||
(define still-needed (filter (lambda (v) (set-member? used-names v)) needed-vars))
|
(define complained? #f)
|
||||||
(unless (null? still-needed)
|
(for ([(var complains) (in-hash check-later-vars)])
|
||||||
(log-status "Simplification failed to remove references to: ~a"
|
(when (set-member? really-used-names (hash-ref variable-names var))
|
||||||
(lines still-needed))
|
(for ([complain (in-list (reverse complains))])
|
||||||
|
(complain (lambda (var)
|
||||||
|
(set-member? really-used-names (hash-ref variable-names var))))
|
||||||
|
(set! complained? #t))))
|
||||||
|
(when complained?
|
||||||
(exit 1))
|
(exit 1))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;; Avoid gratuitous differences due to names generated during
|
;; Avoid gratuitous differences due to names generated during
|
||||||
;; expansion
|
;; expansion
|
||||||
(define re-renamed-linklet-expr
|
(define re-renamed-linklet-expr
|
||||||
|
|
|
@ -4,11 +4,6 @@
|
||||||
RACKET = ../../bin/racket
|
RACKET = ../../bin/racket
|
||||||
RACO = $(RACKET) -N raco -l- raco
|
RACO = $(RACKET) -N raco -l- raco
|
||||||
|
|
||||||
# Ignoring functions from `#%read` works beause they won't appear in
|
|
||||||
# the simplified expansion, and declaring "collect.rkt" pure works
|
|
||||||
# around a limitation of the flattener:
|
|
||||||
IGNORE = ++knot read - ++pure ../../collects/racket/private/collect.rkt
|
|
||||||
|
|
||||||
# Can be set to empty to avoid building rktio
|
# Can be set to empty to avoid building rktio
|
||||||
RKTIO_DEP=../build/so-rktio/Makefile
|
RKTIO_DEP=../build/so-rktio/Makefile
|
||||||
|
|
||||||
|
@ -23,7 +18,7 @@ GENERATE_ARGS = -t main.rkt --submod main \
|
||||||
--depends $(BUILDDIR)compiled/io-dep.rktd \
|
--depends $(BUILDDIR)compiled/io-dep.rktd \
|
||||||
--makefile-depends $(DEPENDSDIR)compiled/io.rktl $(BUILDDIR)compiled/io.d \
|
--makefile-depends $(DEPENDSDIR)compiled/io.rktl $(BUILDDIR)compiled/io.d \
|
||||||
-c $(BUILDDIR)compiled/cache-src \
|
-c $(BUILDDIR)compiled/cache-src \
|
||||||
-k ../.. $(IGNORE) -s -x \
|
-k ../.. -s -x \
|
||||||
-o $(BUILDDIR)compiled/io.rktl
|
-o $(BUILDDIR)compiled/io.rktl
|
||||||
|
|
||||||
# This target can be used with a `RACKET` that builds via `-l- setup --chain ...`
|
# This target can be used with a `RACKET` that builds via `-l- setup --chain ...`
|
||||||
|
|
|
@ -4,11 +4,6 @@
|
||||||
RACKET = ../../bin/racket
|
RACKET = ../../bin/racket
|
||||||
RACO = $(RACKET) -N raco -l- raco
|
RACO = $(RACKET) -N raco -l- raco
|
||||||
|
|
||||||
# Ignoring functions from `#%read` works beause they won't appear in
|
|
||||||
# the simplified expansion, and declaring "collect.rkt" pure works
|
|
||||||
# around a limitation of the flattener:
|
|
||||||
IGNORE = ++knot read - ++pure ../../collects/racket/private/collect.rkt
|
|
||||||
|
|
||||||
regexp-src:
|
regexp-src:
|
||||||
$(RACO) make ../expander/bootstrap-run.rkt
|
$(RACO) make ../expander/bootstrap-run.rkt
|
||||||
$(MAKE) regexp-src-generate
|
$(MAKE) regexp-src-generate
|
||||||
|
@ -19,7 +14,7 @@ GENERATE_ARGS = -t main.rkt \
|
||||||
--depends $(BUILDDIR)compiled/regexp-dep.rktd \
|
--depends $(BUILDDIR)compiled/regexp-dep.rktd \
|
||||||
--makefile-depends $(DEPENDSDIR)compiled/regexp.rktl $(BUILDDIR)compiled/regexp.d \
|
--makefile-depends $(DEPENDSDIR)compiled/regexp.rktl $(BUILDDIR)compiled/regexp.d \
|
||||||
-c $(BUILDDIR)compiled/cache-src \
|
-c $(BUILDDIR)compiled/cache-src \
|
||||||
-k ../.. $(IGNORE) -s -x \
|
-k ../.. -s -x \
|
||||||
-o $(BUILDDIR)compiled/regexp.rktl
|
-o $(BUILDDIR)compiled/regexp.rktl
|
||||||
|
|
||||||
# This target can be used with a `RACKET` that builds via `-l- setup --chain ...`
|
# This target can be used with a `RACKET` that builds via `-l- setup --chain ...`
|
||||||
|
@ -33,6 +28,6 @@ demo:
|
||||||
# Writes the extracted, compiled, decompiled expander to compiled/regexp.rkt
|
# Writes the extracted, compiled, decompiled expander to compiled/regexp.rkt
|
||||||
decompile:
|
decompile:
|
||||||
$(RACO) make ../expander/bootstrap-run.rkt
|
$(RACO) make ../expander/bootstrap-run.rkt
|
||||||
$(RACKET) $(RKT_ARGS) ../expander/bootstrap-run.rkt -t main.rkt -c compiled/cache-src $(IGNORE) -s -x -D -o compiled/regexp.rkt
|
$(RACKET) $(RKT_ARGS) ../expander/bootstrap-run.rkt -t main.rkt -c compiled/cache-src -s -x -D -o compiled/regexp.rkt
|
||||||
|
|
||||||
.PHONY: regexp-src regexp-src-generate demo decompile
|
.PHONY: regexp-src regexp-src-generate demo decompile
|
||||||
|
|
|
@ -4,11 +4,6 @@
|
||||||
RACKET = ../../bin/racket
|
RACKET = ../../bin/racket
|
||||||
RACO = $(RACKET) -N raco -l- raco
|
RACO = $(RACKET) -N raco -l- raco
|
||||||
|
|
||||||
# Ignoring functions from `#%read` works beause they won't appear in
|
|
||||||
# the simplified expansion, and declaring "collect.rkt" pure works
|
|
||||||
# around a limitation of the flattener:
|
|
||||||
IGNORE = ++knot read - ++direct pthread ++pure ../../collects/racket/private/collect.rkt
|
|
||||||
|
|
||||||
thread-src:
|
thread-src:
|
||||||
$(RACO) make ../expander/bootstrap-run.rkt
|
$(RACO) make ../expander/bootstrap-run.rkt
|
||||||
$(MAKE) thread-src-generate
|
$(MAKE) thread-src-generate
|
||||||
|
@ -19,7 +14,7 @@ GENERATE_ARGS = -t main.rkt --submod main \
|
||||||
--depends $(BUILDDIR)compiled/thread-dep.rktd \
|
--depends $(BUILDDIR)compiled/thread-dep.rktd \
|
||||||
--makefile-depends $(DEPENDSDIR)compiled/thread.rktl $(BUILDDIR)compiled/thread.d \
|
--makefile-depends $(DEPENDSDIR)compiled/thread.rktl $(BUILDDIR)compiled/thread.d \
|
||||||
-c $(BUILDDIR)compiled/cache-src \
|
-c $(BUILDDIR)compiled/cache-src \
|
||||||
-k ../.. $(IGNORE) -s -x \
|
-k ../.. -s -x \
|
||||||
-o $(BUILDDIR)compiled/thread.rktl
|
-o $(BUILDDIR)compiled/thread.rktl
|
||||||
|
|
||||||
# This target can be used with a `RACKET` that builds via `-l- setup --chain ...`
|
# This target can be used with a `RACKET` that builds via `-l- setup --chain ...`
|
||||||
|
|
Loading…
Reference in New Issue
Block a user