|
404 | 404 | (return)))) |
405 | 405 | (values)) |
406 | 406 |
|
407 | | -;;; Return true if TN represents a closed-over variable with an |
408 | | -;;; "implicit" value-cell. |
409 | | -(defun implicit-value-cell-tn-p (tn) |
410 | | - (let ((leaf (tn-leaf tn))) |
411 | | - (and (lambda-var-p leaf) |
412 | | - (lambda-var-indirect leaf) |
413 | | - (not (lambda-var-explicit-value-cell leaf))))) |
414 | | - |
415 | | -;;; If BLOCK ends with a TAIL LOCAL COMBINATION, the function called. |
416 | | -;;; Otherwise, NIL. |
417 | | -(defun block-tail-local-call-fun (block) |
418 | | - (let ((node (block-last block))) |
419 | | - (when (and (combination-p node) |
420 | | - (eq :local (combination-kind node)) |
421 | | - (combination-tail-p node)) |
422 | | - (ref-leaf (lvar-uses (combination-fun node)))))) |
423 | | - |
424 | 407 | ;;; Iterate over all the blocks in ENV, setting up :LIVE conflicts for |
425 | 408 | ;;; TN. We make the TN global if it isn't already. The TN must have at |
426 | 409 | ;;; least one reference. |
|
443 | 426 | (setup-environment-tn-conflict tn b debug-p))))) |
444 | 427 | (values)) |
445 | 428 |
|
446 | | -;;; Implicit value cells are allocated on the stack and local |
447 | | -;;; functions can access closed over values of the parent function |
448 | | -;;; that way, but when the parent function tail calls a local function |
449 | | -;;; its environment ceases to exist, yet the indirect TNs should still |
450 | | -;;; be accessible within the tail-called function. Find all the users |
451 | | -;;; of the TN, returning their environments, in which the TN should be |
452 | | -;;; marked as live. |
453 | | -(defun find-implicit-value-cell-users (home-env tn) |
454 | | - (let (result) |
455 | | - (labels ((recur (lambda) |
456 | | - (let ((env (lambda-environment lambda))) |
457 | | - (unless (or (eq env home-env) |
458 | | - (memq env result)) |
459 | | - (push env result) |
460 | | - (loop for ref in (leaf-refs lambda) |
461 | | - do (recur (node-home-lambda ref))))))) |
462 | | - (loop for ref in (leaf-refs (tn-leaf tn)) |
463 | | - do (recur (node-home-lambda ref))) |
464 | | - (loop for set in (basic-var-sets (tn-leaf tn)) |
465 | | - do (recur (node-home-lambda set)))) |
466 | | - result)) |
| 429 | +;;; Iterate over all functions in the tail-set of FUN which close-over |
| 430 | +;;; TN, adding appropriate conflict information. Indirect TNs should |
| 431 | +;;; still be accessible within tail-called functions, even if the |
| 432 | +;;; environment of the caller which contains the implicit value cell |
| 433 | +;;; ceases to exist. |
| 434 | +(defun setup-implicit-value-cell-tn-conflicts (component fun tn) |
| 435 | + (declare (type component component) (type clambda fun) |
| 436 | + (type tn tn)) |
| 437 | + (let ((leaf (tn-leaf tn))) |
| 438 | + (dolist (tail-set-fun (tail-set-funs (lambda-tail-set fun))) |
| 439 | + (let ((env (lambda-environment tail-set-fun))) |
| 440 | + (when (memq leaf (environment-closure env)) |
| 441 | + (setup-environment-tn-conflicts component tn env nil)))))) |
467 | 442 |
|
468 | 443 | ;;; Iterate over all the environment TNs, adding always-live conflicts |
469 | 444 | ;;; as appropriate. |
|
474 | 449 | (2env (environment-info env))) |
475 | 450 | (dolist (tn (ir2-environment-live-tns 2env)) |
476 | 451 | (setup-environment-tn-conflicts component tn env nil) |
477 | | - (when (implicit-value-cell-tn-p tn) |
478 | | - (loop for env in (find-implicit-value-cell-users env tn) |
479 | | - ;; See the comment above FIND-IMPLICIT-VALUE-CELL-USERS |
480 | | - when (memq (environment-lambda env) |
481 | | - (tail-set-funs (lambda-tail-set fun))) |
482 | | - do |
483 | | - (setup-environment-tn-conflicts component tn env nil)))) |
| 452 | + (let ((leaf (tn-leaf tn))) |
| 453 | + (when (and (lambda-var-p leaf) |
| 454 | + (lambda-var-indirect leaf) |
| 455 | + (not (lambda-var-explicit-value-cell leaf))) |
| 456 | + (setup-implicit-value-cell-tn-conflicts component fun tn)))) |
484 | 457 | (dolist (tn (ir2-environment-debug-live-tns 2env)) |
485 | 458 | (setup-environment-tn-conflicts component tn env t)))) |
486 | 459 | (values)) |
|
682 | 655 | (or (null succ) |
683 | 656 | (eq (first succ) |
684 | 657 | (component-tail (block-component 1block))) |
685 | | - (block-tail-local-call-fun 1block))) |
| 658 | + (let ((node (block-last 1block))) |
| 659 | + (and (combination-p node) |
| 660 | + (eq (combination-kind node) :local) |
| 661 | + (node-tail-p node))))) |
686 | 662 | (do ((conf (ir2-block-global-tns block) |
687 | 663 | (global-conflicts-next-blockwise conf))) |
688 | 664 | ((null conf)) |
|
0 commit comments