X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Flocall.lisp;h=ed3e34fabc6e5e2dad342ba0f3d291c7c9ec9f83;hb=13fb19c3183a0effb7c35a2d453d6c6c91726e26;hp=1c6db26ec5390103b5c7821db9902f8dbb5d16ab;hpb=757091b10a73a7f6e2bd673bcf990ac93f23f77c;p=sbcl.git diff --git a/src/compiler/locall.lisp b/src/compiler/locall.lisp index 1c6db26..ed3e34f 100644 --- a/src/compiler/locall.lisp +++ b/src/compiler/locall.lisp @@ -99,6 +99,37 @@ (setf (lvar-dynamic-extent (cdr cell)) cleanup))))) (values)) +;;; Called after a transform has been applied to CALL: if the call has a DX +;;; result, propagate the DXness to the new functional as well. +;;; +;;; This is needed in case an earlier call to LOCALL-ANALYZE-COMPONENT +;;; collected DX information before the transformation, in which case a later +;;; call to LOCALL-ANALYZE-COMPONENT would not pick up the DX declaration +;;; again, since the call has already been converted. (In other words, work +;;; around the fact that optimization iterates, and locall analysis may have +;;; already run by the time we are able to transform something.) +(defun maybe-propagate-dynamic-extent (call fun) + (when (lambda-p fun) + (let* ((lvar (combination-lvar call)) + (cleanup (or (and lvar (lvar-dynamic-extent lvar)) + (return-from maybe-propagate-dynamic-extent))) + (ret (lambda-return fun)) + (res (if ret + (return-result ret) + (return-from maybe-propagate-dynamic-extent))) + (dx (car (rassoc lvar (cleanup-info cleanup) :test #'eq))) + (new-dx-lvars (if (and dx res) + (handle-nested-dynamic-extent-lvars dx res) + (return-from maybe-propagate-dynamic-extent)))) + (when new-dx-lvars + ;; This builds on what RECOGNIZE-DYNAMIC-EXTENT-LVARS does above. + (aver (eq call (block-last (node-block call)))) + (dolist (cell new-dx-lvars) + (let ((lvar (cdr cell))) + (aver (not (lvar-dynamic-extent lvar))) + (push cell (cleanup-info cleanup)) + (setf (lvar-dynamic-extent (cdr cell)) cleanup))))))) + ;;; This function handles merging the tail sets if CALL is potentially ;;; tail-recursive, and is a call to a function with a different ;;; TAIL-SET than CALL's FUN. This must be called whenever we alter