- (let ((refs (leaf-refs clambda)))
- (when (and refs
- (null (rest refs))
- (member (functional-kind clambda) '(nil :assignment))
- (not (functional-entry-fun clambda)))
- (let* ((ref-cont (node-cont (first refs)))
- (dest (continuation-dest ref-cont)))
- (when (and dest
- (basic-combination-p dest)
- (eq (basic-combination-fun dest) ref-cont)
- (eq (basic-combination-kind dest) :local)
- (not (block-delete-p (node-block dest)))
- (cond ((ok-initial-convert-p clambda) t)
- (t
- (reoptimize-continuation ref-cont)
- nil)))
- (unless (eq (functional-kind clambda) :assignment)
- (let-convert clambda dest))
- (reoptimize-call dest)
- (setf (functional-kind clambda)
- (if (mv-combination-p dest) :mv-let :let))))
- t)))
+ (unless (declarations-suppress-let-conversion-p clambda)
+ ;; We only convert to a LET when the function is a normal local
+ ;; function, has no XEP, and is referenced in exactly one local
+ ;; call. Conversion is also inhibited if the only reference is in
+ ;; a block about to be deleted.
+ ;;
+ ;; These rules limiting LET conversion may seem unnecessarily
+ ;; restrictive, since there are some cases where we could do the
+ ;; return with a jump that don't satisfy these requirements. The
+ ;; reason for doing things this way is that it makes the concept
+ ;; of a LET much more useful at the level of IR1 semantics. The
+ ;; :ASSIGNMENT function kind provides another way to optimize
+ ;; calls to single-return/multiple call functions.
+ ;;
+ ;; We don't attempt to convert calls to functions that have an
+ ;; XEP, since we might be embarrassed later when we want to
+ ;; convert a newly discovered local call. Also, see
+ ;; OK-INITIAL-CONVERT-P.
+ (let ((refs (leaf-refs clambda)))
+ (when (and refs
+ (null (rest refs))
+ (memq (functional-kind clambda) '(nil :assignment))
+ (not (functional-entry-fun clambda)))
+ (binding* ((ref (first refs))
+ (ref-lvar (node-lvar ref) :exit-if-null)
+ (dest (lvar-dest ref-lvar)))
+ (when (and (basic-combination-p dest)
+ (eq (basic-combination-fun dest) ref-lvar)
+ (eq (basic-combination-kind dest) :local)
+ (not (node-to-be-deleted-p dest))
+ (not (block-delete-p (lambda-block clambda)))
+ (cond ((ok-initial-convert-p clambda) t)
+ (t
+ (reoptimize-lvar ref-lvar)
+ nil)))
+ (when (eq clambda (node-home-lambda dest))
+ (delete-lambda clambda)
+ (return-from maybe-let-convert nil))
+ (unless (eq (functional-kind clambda) :assignment)
+ (let-convert clambda dest))
+ (reoptimize-call dest)
+ (setf (functional-kind clambda)
+ (if (mv-combination-p dest) :mv-let :let))))
+ t))))