- ;; The CMU CL approach sometimes fails, e.g. in IR1-CONVERT of
- ;; one of the legs of an IF, now that SBCL uses this operation
- ;; more aggressively than CMU CL did.
- ;;
- ;; In this case we reason that previous-in-target-execution-order
- ;; blocks should be in the same lambda, and that they seem in
- ;; practice to be previous-in-compilation-order blocks too,
- ;; so we look back to find one which is sufficiently
- ;; initialized to tell us what the home lambda is. We could
- ;; get fancy about this, flooding the graph of all the
- ;; previous blocks, but in practice it seems to work just
- ;; to grab the first previous block and use it.
- (node-home-lambda (block-last (first (block-pred block))))))
+ ;; Now that SBCL uses this operation more aggressively than CMU
+ ;; CL did, the old CMU CL way of doing it can fail in two ways.
+ ;; 1. It can fail in a few cases even when a meaningful home
+ ;; lambda exists, e.g. in IR1-CONVERT of one of the legs of
+ ;; an IF.
+ ;; 2. It can fail when converting a form which is born orphaned
+ ;; so that it never had a meaningful home lambda, e.g. a form
+ ;; which follows a RETURN-FROM or GO form.
+ (let ((pred-list (block-pred block)))
+ ;; To deal with case 1, we reason that
+ ;; previous-in-target-execution-order blocks should be in the
+ ;; same lambda, and that they seem in practice to be
+ ;; previous-in-compilation-order blocks too, so we look back
+ ;; to find one which is sufficiently initialized to tell us
+ ;; what the home lambda is.
+ (if pred-list
+ ;; We could get fancy about this, flooding through the
+ ;; graph of all the previous blocks, but in practice it
+ ;; seems to work just to grab the first previous block and
+ ;; use it.
+ (node-home-lambda (block-last (first pred-list)))
+ ;; In case 2, we end up with an empty PRED-LIST and
+ ;; have to punt: There's no home lambda.
+ nil))))
+
+;;; Return the non-LET LAMBDA that holds BLOCK's code.
+(defun block-home-lambda (block)
+ (the clambda
+ (block-home-lambda-or-null block)))