(component-lambdas component))
(find-non-local-exits component)
+ (recheck-dynamic-extent-lvars component)
(find-cleanup-points component)
(tail-annotate component)
(setf (functional-kind fun) nil)
(delete-functional fun)))))
+ (setf (component-nlx-info-generated-p component) t)
(values))
;;; This is to be called on a COMPONENT with top level LAMBDAs before
;;; knows what entry is being done.
;;;
;;; The link from the EXIT block to the entry stub is changed to be a
-;;; link to the component head. Similarly, the EXIT block is linked to
-;;; the component tail. This leaves the entry stub reachable, but
+;;; link from the component head. Similarly, the EXIT block is linked
+;;; to the component tail. This leaves the entry stub reachable, but
;;; makes the flow graph less confusing to flow analysis.
;;;
;;; If a CATCH or an UNWIND-protect, then we set the LEXENV for the
;;; function reference. This will cause the escape function to
;;; be deleted (although not removed from the DFO.) The escape
;;; function is no longer needed, and we don't want to emit code
-;;; for it. We then also change the %NLX-ENTRY call to use the
-;;; NLX continuation so that there will be a use to represent
-;;; the NLX use.
+;;; for it.
+;;; -- Change the %NLX-ENTRY call to use the NLX lvar so that 1) there
+;;; will be a use to represent the NLX use; 2) make life easier for
+;;; the stack analysis.
(defun note-non-local-exit (env exit)
(declare (type physenv env) (type exit exit))
(let ((lvar (node-lvar exit))
(mapc (lambda (x)
(setf (node-derived-type x) *wild-type*))
(leaf-refs exit-fun))
- (substitute-leaf (find-constant info) exit-fun)
- (let ((node (block-last (nlx-info-target info))))
- (delete-lvar-use node)
- (aver (eq lvar (node-lvar exit)))
- (add-lvar-use node lvar)))))
+ (substitute-leaf (find-constant info) exit-fun))
+ (when lvar
+ (let ((node (block-last (nlx-info-target info))))
+ (unless (node-lvar node)
+ (aver (eq lvar (node-lvar exit)))
+ (setf (node-derived-type node) (lvar-derived-type lvar))
+ (add-lvar-use node lvar))))))
(values))
;;; Iterate over the EXITs in COMPONENT, calling NOTE-NON-LOCAL-EXIT
(note-non-local-exit target-physenv exit))))))
(values))
\f
+;;;; final decision on stack allocation of dynamic-extent structores
+(defun recheck-dynamic-extent-lvars (component)
+ (declare (type component component))
+ (dolist (lambda (component-lambdas component))
+ (loop for entry in (lambda-entries lambda)
+ for cleanup = (entry-cleanup entry)
+ do (when (eq (cleanup-kind cleanup) :dynamic-extent)
+ (collect ((real-dx-lvars))
+ (loop for lvar in (cleanup-info cleanup)
+ do (let ((use (lvar-uses lvar)))
+ (if (and (combination-p use)
+ (eq (basic-combination-kind use) :known)
+ (awhen (fun-info-stack-allocate-result
+ (basic-combination-fun-info use))
+ (funcall it use)))
+ (real-dx-lvars lvar)
+ (setf (lvar-dynamic-extent lvar) nil))))
+ (setf (cleanup-info cleanup) (real-dx-lvars))
+ (setf (component-dx-lvars component)
+ (append (real-dx-lvars) (component-dx-lvars component)))))))
+ (values))
+\f
;;;; cleanup emission
;;; Zoom up the cleanup nesting until we hit CLEANUP1, accumulating
(dolist (nlx (cleanup-nlx-info cleanup))
(code `(%lexical-exit-breakup ',nlx))))
(:dynamic-extent
- (code `(%dynamic-extent-end))))))
+ (when (not (null (cleanup-info cleanup)))
+ (code `(%cleanup-point)))))))
(when (code)
(aver (not (node-tail-p (block-last block1))))