|
22 | 22 | "instance.rkt"
|
23 | 23 | "namespace-scope.rkt"
|
24 | 24 | "expr.rkt"
|
| 25 | + "extra-inspector.rkt" |
25 | 26 | "correlate.rkt")
|
26 | 27 |
|
27 | 28 | (provide compile-forms
|
|
230 | 231 | (for/hash ([phase (in-list phases-in-order)])
|
231 | 232 | (define header (hash-ref phase-to-header phase #f))
|
232 | 233 | (define-values (link-module-uses imports extra-inspectorsss def-decls)
|
233 |
| - (generate-links+imports header phase cctx)) |
| 234 | + (generate-links+imports header phase cctx cross-linklet-inlining?)) |
234 | 235 | (values phase (link-info link-module-uses imports extra-inspectorsss def-decls))))
|
235 | 236 |
|
236 | 237 | ;; Generate the phase-specific linking units
|
237 |
| - (define body-linklets+module-uses |
| 238 | + (define body-linklets+module-use*s |
238 | 239 | (for/hasheq ([phase (in-list phases-in-order)])
|
239 | 240 | (define bodys (hash-ref phase-to-body phase))
|
240 | 241 | (define li (hash-ref phase-to-link-info phase))
|
241 | 242 | (define binding-sym-to-define-sym
|
242 | 243 | (header-binding-sym-to-define-sym (hash-ref phase-to-header phase)))
|
243 |
| - (define module-uses (link-info-link-module-uses li)) |
| 244 | + (define module-use*s |
| 245 | + (module-uses-add-extra-inspectorsss (link-info-link-module-uses li) |
| 246 | + (link-info-extra-inspectorsss li))) |
244 | 247 | ;; Compile the linklet with support for cross-module inlining, which
|
245 | 248 | ;; means that the set of imports can change:
|
246 |
| - (define-values (linklet new-module-uses) |
| 249 | + (define-values (linklet new-module-use*s) |
247 | 250 | (performance-region
|
248 | 251 | ['compile '_ 'linklet]
|
249 | 252 | ((if to-source?
|
|
271 | 274 | ;; as keys, plus #f or an instance (=> cannot be pruned) for
|
272 | 275 | ;; each boilerplate linklet
|
273 | 276 | (list->vector (append body-import-instances
|
274 |
| - (link-info-link-module-uses li))) |
| 277 | + module-use*s)) |
275 | 278 | ;; To complete cross-module support, map a key (which is a `module-use`)
|
276 | 279 | ;; to a linklet and an optional vector of keys for that linklet's
|
277 | 280 | ;; imports:
|
278 | 281 | (make-module-use-to-linklet cross-linklet-inlining?
|
279 | 282 | (compile-context-namespace cctx)
|
280 | 283 | get-module-linklet-info
|
281 |
| - (link-info-link-module-uses li))))) |
282 |
| - (values phase (cons linklet (list-tail (vector->list new-module-uses) |
| 284 | + module-use*s)))) |
| 285 | + (values phase (cons linklet (list-tail (vector->list new-module-use*s) |
283 | 286 | (length body-imports))))))
|
284 | 287 |
|
285 | 288 | (define body-linklets
|
286 |
| - (for/hasheq ([(phase l+mus) (in-hash body-linklets+module-uses)]) |
287 |
| - (values phase (car l+mus)))) |
| 289 | + (for/hasheq ([(phase l+mu*s) (in-hash body-linklets+module-use*s)]) |
| 290 | + (values phase (car l+mu*s)))) |
288 | 291 |
|
289 | 292 | (define phase-to-link-module-uses
|
290 |
| - (for/hasheq ([(phase l+mus) (in-hash body-linklets+module-uses)]) |
291 |
| - (values phase (cdr l+mus)))) |
292 |
| - |
| 293 | + (for/hasheq ([(phase l+mu*s) (in-hash body-linklets+module-use*s)]) |
| 294 | + (values phase (module-uses-strip-extra-inspectorsss (cdr l+mu*s))))) |
| 295 | + |
293 | 296 | (define phase-to-link-module-uses-expr
|
294 | 297 | (serialize-phase-to-link-module-uses phase-to-link-module-uses mpis))
|
295 | 298 |
|
296 | 299 | (define phase-to-link-extra-inspectorsss
|
297 |
| - (for/hash ([(phase li) (in-hash phase-to-link-info)]) |
298 |
| - (values phase (link-info-extra-inspectorsss li)))) |
| 300 | + (for*/hash ([(phase l+mu*s) (in-hash body-linklets+module-use*s)] |
| 301 | + [(extra-inspectorsss) (in-value (module-uses-extract-extra-inspectorsss |
| 302 | + (cdr l+mu*s) |
| 303 | + (car l+mu*s) |
| 304 | + cross-linklet-inlining? |
| 305 | + (length body-imports)))] |
| 306 | + #:when extra-inspectorsss) |
| 307 | + (values phase extra-inspectorsss))) |
299 | 308 |
|
300 | 309 | (values body-linklets ; main compilation result
|
301 | 310 | min-phase
|
|
376 | 385 |
|
377 | 386 | ;; ----------------------------------------
|
378 | 387 |
|
379 |
| -(define (make-module-use-to-linklet cross-linklet-inlining? ns get-module-linklet-info init-mus) |
| 388 | +(define (make-module-use-to-linklet cross-linklet-inlining? ns get-module-linklet-info init-mu*s) |
380 | 389 | ;; Inlining might reach the same module though different indirections;
|
381 | 390 | ;; use a consistent `module-use` value so that the compiler knows to
|
382 | 391 | ;; collapse them to a single import
|
383 |
| - (define mu-intern-table (make-hash)) |
384 |
| - (define (intern-module-use mu) |
385 |
| - (define mod-name (module-path-index-resolve (module-use-module mu))) |
386 |
| - (or (hash-ref mu-intern-table (cons mod-name (module-use-phase mu)) #f) |
387 |
| - (begin |
388 |
| - (hash-set! mu-intern-table (cons mod-name (module-use-phase mu)) mu) |
389 |
| - mu))) |
390 |
| - (for-each intern-module-use init-mus) |
| 392 | + (define mu*-intern-table (make-hash)) |
| 393 | + (define (intern-module-use* mu*) |
| 394 | + (define mod-name (module-path-index-resolve (module-use-module mu*))) |
| 395 | + (define existing-mu* (hash-ref mu*-intern-table (cons mod-name (module-use-phase mu*)) #f)) |
| 396 | + (cond |
| 397 | + [existing-mu* |
| 398 | + (module-use-merge-extra-inspectorss! existing-mu* mu*) |
| 399 | + existing-mu*] |
| 400 | + [else |
| 401 | + (hash-set! mu*-intern-table (cons mod-name (module-use-phase mu*)) mu*) |
| 402 | + mu*])) |
| 403 | + (for ([mu* (in-list init-mu*s)]) |
| 404 | + (intern-module-use* mu*)) |
391 | 405 | ;; The callback function supplied to `compile-linklet`:
|
392 |
| - (lambda (mu) |
| 406 | + (lambda (mu*-or-instance) |
393 | 407 | (cond
|
394 |
| - [(instance? mu) |
| 408 | + [(instance? mu*-or-instance) |
395 | 409 | ;; An instance represents a boilerplate linklet. An instance
|
396 | 410 | ;; doesn't enable inlining (and we don't want inlining, since
|
397 | 411 | ;; that would change the overall protocol for module or
|
398 |
| - ;; top-level linklets], but it can describe shapes. |
399 |
| - (values mu #f)] |
| 412 | + ;; top-level linklets), but it can describe shapes. |
| 413 | + (values mu*-or-instance #f)] |
400 | 414 | [(not cross-linklet-inlining?)
|
401 | 415 | ;; Although we let instances through, because that's cheap,
|
402 | 416 | ;; don't track down linklets and allow inlining of functions
|
403 | 417 | (values #f #f)]
|
404 |
| - [mu |
405 |
| - (define mod-name (module-path-index-resolve (module-use-module mu))) |
406 |
| - (define mli (or (get-module-linklet-info mod-name (module-use-phase mu)) |
| 418 | + [mu*-or-instance |
| 419 | + (define mu* mu*-or-instance) |
| 420 | + (define mod-name (module-path-index-resolve (module-use-module mu*))) |
| 421 | + (define mli (or (get-module-linklet-info mod-name (module-use-phase mu*)) |
407 | 422 | (namespace->module-linklet-info ns
|
408 | 423 | mod-name
|
409 |
| - (module-use-phase mu)))) |
| 424 | + (module-use-phase mu*)))) |
| 425 | + (when mli |
| 426 | + ;; Record the module's declaration-time inspector, for use |
| 427 | + ;; later recording extra inspectors for inlined referenced |
| 428 | + (module-use*-declaration-inspector! mu* (module-linklet-info-inspector mli))) |
410 | 429 | (if mli
|
411 | 430 | ;; Found info for inlining:
|
412 | 431 | (values (module-linklet-info-linklet-or-instance mli)
|
413 |
| - (and (module-linklet-info-module-uses mli) |
| 432 | + (and (module-linklet-info-module-uses mli) ; => linklet |
414 | 433 | (list->vector
|
415 | 434 | (append
|
416 | 435 | '(#f #f) ; boilerplate imports common to all modules
|
417 |
| - (for/list ([sub-mu (in-list (module-linklet-info-module-uses mli))]) |
418 |
| - (intern-module-use |
419 |
| - (module-use (module-path-index-shift |
420 |
| - (module-use-module sub-mu) |
421 |
| - (module-linklet-info-self mli) |
422 |
| - (module-use-module mu)) |
423 |
| - (module-use-phase sub-mu)))))))) |
| 436 | + (let ([mus (module-linklet-info-module-uses mli)] |
| 437 | + [extra-inspectorsss (module-linklet-info-extra-inspectorsss mli)]) |
| 438 | + (for/list ([sub-mu (in-list mus)] |
| 439 | + [imports (in-list |
| 440 | + (linklet-import-variables |
| 441 | + (module-linklet-info-linklet-or-instance mli)))] |
| 442 | + [extra-inspectorss (in-list (or extra-inspectorsss |
| 443 | + ;; a list of the right length: |
| 444 | + mus))]) |
| 445 | + (intern-module-use* |
| 446 | + (module-use+extra-inspectors (module-path-index-shift |
| 447 | + (module-use-module sub-mu) |
| 448 | + (module-linklet-info-self mli) |
| 449 | + (module-use-module mu*)) |
| 450 | + (module-use-phase sub-mu) |
| 451 | + ;; The remaining arguments are used to |
| 452 | + ;; make an `module-use*` instead of a |
| 453 | + ;; plain `module-use` |
| 454 | + imports |
| 455 | + (module-linklet-info-inspector mli) |
| 456 | + (module-linklet-info-extra-inspector mli) |
| 457 | + (and extra-inspectorsss |
| 458 | + extra-inspectorss))))))))) |
424 | 459 | ;; Didn't find info, for some reason:
|
425 | 460 | (values #f #f))]
|
426 | 461 | [else
|
|
0 commit comments